Пример #1
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> _,
            AddressSpaceCast value)
        {
            var builder  = context.Builder;
            var location = value.Location;
            var pointer  = builder.CreateGetField(
                location,
                value.Value,
                new FieldSpan(0));
            var length = builder.CreateGetField(
                location,
                value.Value,
                new FieldSpan(1));

            var newPointer = builder.CreateAddressSpaceCast(
                location,
                pointer,
                value.TargetAddressSpace);
            var newInstance = builder.CreateDynamicStructure(
                location,
                newPointer,
                length);

            context.ReplaceAndRemove(value, newInstance);
        }
Пример #2
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> _,
            SubViewValue value)
        {
            var builder  = context.Builder;
            var location = value.Location;
            var pointer  = builder.CreateGetField(
                location,
                value.Source,
                new FieldSpan(0));
            var newPointer = builder.CreateLoadElementAddress(
                location,
                pointer,
                value.Offset);

            var length = value.Length;

            if (length.BasicValueType != BasicValueType.Int64)
            {
                length = builder.CreateConvertToInt64(
                    value.Location,
                    length);
            }
            var subView = builder.CreateDynamicStructure(
                location,
                newPointer,
                length);

            context.ReplaceAndRemove(value, subView);
        }
Пример #3
0
        /// <summary>
        /// Lowers an as-aligned-view operation.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> typeLowering,
            AsAligned value)
        {
            var builder  = context.Builder;
            var location = value.Location;

            // Extract basic view information from the converted structure
            var pointer = builder.CreateGetField(
                location,
                value.Source,
                new FieldSpan(0));
            var length = builder.CreateGetField(
                location,
                value.Source,
                new FieldSpan(1));

            // Ensure that the underyling pointer is aligned
            var aligned = builder.CreateAsAligned(
                location,
                pointer,
                value.AlignmentInBytes);

            // Create a new wrapped instance
            var newInstance = builder.CreateDynamicStructure(
                location,
                aligned,
                length);

            context.ReplaceAndRemove(value, newInstance);
        }
Пример #4
0
        /// <summary>
        /// Lowers a primitive type.
        /// </summary>
        /// <typeparam name="TValue">The value type.</typeparam>
        /// <typeparam name="TLoweringImplementation">
        /// The implementation type.
        /// </typeparam>
        /// <param name="context">The current rewriter context.</param>
        /// <param name="sourceValue">The source value to get the values from.</param>
        /// <param name="variable">The source variable.</param>
        /// <returns>The lowered thread value.</returns>
        private static Value LowerPrimitive <TValue, TLoweringImplementation>(
            RewriterContext context,
            TValue sourceValue,
            Value variable)
            where TValue : ThreadValue
            where TLoweringImplementation : struct, ILoweringImplementation <TValue>
        {
            var   builder       = context.Builder;
            var   primitiveType = variable.Type as PrimitiveType;
            Value value         = variable;

            if (primitiveType.BasicValueType < BasicValueType.Int32)
            {
                value = builder.CreateConvert(
                    sourceValue.Location,
                    value,
                    builder.GetPrimitiveType(BasicValueType.Int32));
            }

            TLoweringImplementation loweringImplementation = default;
            var result = loweringImplementation.Lower(
                builder,
                sourceValue,
                value);

            if (primitiveType.BasicValueType < BasicValueType.Int32)
            {
                result = builder.CreateConvert(
                    sourceValue.Location,
                    result,
                    variable.Type);
            }
            return(result);
        }
Пример #5
0
        /// <summary>
        /// Lowers leae nodes to linear <see cref="LoadElementAddress"/> values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            LoadArrayElementAddress value)
        {
            var   builder  = context.Builder;
            var   location = value.Location;
            Value array    = value.ArrayValue;

            // Get and validate the array type
            var structureType = array.Type.As <StructureType>(location);

            // Compute linear address based on the .Net array layouts
            Value elementIndex = builder.CreatePrimitiveValue(location, 0L);

            // (((0 * Width + x) * Height) + y) * Depth + z...
            for (int i = 0, e = structureType.NumFields - 1; i < e; ++i)
            {
                Value length = builder.CreateGetField(
                    location,
                    array,
                    new FieldAccess(1 + i));

                // Create a debug assertion to check for out-of-bounds accesses
                builder.CreateDebugAssert(
                    location,
                    builder.CreateCompare(
                        location,
                        value.Dimensions[i],
                        length,
                        CompareKind.LessThan),
                    builder.CreatePrimitiveValue(
                        location,
                        $"{i}-th array index out of range"));

                // Update index computation
                elementIndex = builder.CreateArithmetic(
                    location,
                    elementIndex,
                    length,
                    BinaryArithmeticKind.Mul);
                elementIndex = builder.CreateArithmetic(
                    location,
                    elementIndex,
                    value.Dimensions[i],
                    BinaryArithmeticKind.Add);
            }

            // Extract the actual view field from the structure and compute the
            // appropriate target element address.
            var view = GetViewFromArray(builder, location, array);
            var lea  = builder.CreateLoadElementAddress(
                location,
                view,
                elementIndex);

            context.ReplaceAndRemove(value, lea);
        }
Пример #6
0
        /// <summary>
        /// Specializes accelerator-specific values.
        /// </summary>
        private static void Specialize(
            RewriterContext context,
            Value value,
            int constant)
        {
            var newValue = context.Builder.CreatePrimitiveValue(
                value.Location,
                constant);

            context.ReplaceAndRemove(value, newValue);
        }
Пример #7
0
 /// <summary>
 /// Specializes warp size values.
 /// </summary>
 private static void Specialize(
     RewriterContext context,
     AcceleratorSpecializer specializer,
     WarpSizeValue value)
 {
     if (!specializer.WarpSize.HasValue)
     {
         return;
     }
     Specialize(context, value, specializer.WarpSize.Value);
 }
Пример #8
0
        /// <summary>
        /// Lowers null values with nested types.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            NullValue value)
        {
            var targetType = typeConverter.ConvertType(value);
            var newValue   = context.Builder.CreateNull(
                value.Location,
                targetType);

            context.ReplaceAndRemove(value, newValue);
        }
Пример #9
0
        /// <summary>
        /// Specializes native pointer casts.
        /// </summary>
        private static void Specialize(
            RewriterContext context,
            AcceleratorSpecializer specializer,
            IntAsPointerCast value)
        {
            var convert = context.Builder.CreateConvert(
                value.Location,
                value.Value,
                specializer.IntPointerType);

            context.ReplaceAndRemove(value, convert);
        }
Пример #10
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> _,
            GetViewLength value)
        {
            var length = context.Builder.CreateGetField(
                value.Location,
                value.View,
                new FieldSpan(1));

            context.ReplaceAndRemove(value, length);
        }
Пример #11
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> _,
            NewView value)
        {
            var viewInstance = context.Builder.CreateDynamicStructure(
                value.Location,
                value.Pointer,
                value.Length);

            context.ReplaceAndRemove(value, viewInstance);
        }
Пример #12
0
        /// <summary>
        /// Specializes warp size values.
        /// </summary>
        private static void Specialize(
            RewriterContext context,
            SpecializerData data,
            WarpSizeValue value)
        {
            var warpSizeValue = data.WarpSize;

            if (!warpSizeValue.HasValue)
            {
                return;
            }
            Specialize(context, value, warpSizeValue.Value);
        }
Пример #13
0
 /// <summary>
 /// Removes or collects IO operations.
 /// </summary>
 private static void Specialize(
     RewriterContext context,
     SpecializerData data,
     WriteToOutput value)
 {
     if (data.EnableIOOperations)
     {
         data.ToImplement.Add(value);
     }
     else
     {
         context.Remove(value);
     }
 }
Пример #14
0
 /// <summary>
 /// Specializes debug operations via the instance method
 /// <see cref="Specialize(in RewriterContext, IRContext, DebugAssertOperation)"/>
 /// of the parent <paramref name="data"/> instance.
 /// </summary>
 private static void Specialize(
     RewriterContext context,
     SpecializerData data,
     DebugAssertOperation value)
 {
     if (data.EnableAssertions)
     {
         data.Specializer.Specialize(context, data.Context, value);
     }
     else
     {
         context.Remove(value);
     }
 }
Пример #15
0
        /// <summary>
        /// Lowers LFA operations into an adapted version.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            LoadFieldAddress lfa)
        {
            // Compute the new span
            var span     = typeConverter.ComputeSpan(lfa, lfa.FieldSpan);
            var newValue = context.Builder.CreateLoadFieldAddress(
                lfa.Location,
                lfa.Source,
                span);

            context.ReplaceAndRemove(lfa, newValue);
        }
Пример #16
0
        /// <summary>
        /// Lowers pointer cast values into their appropriate counter parts.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            PointerCast cast)
        {
            // Compute the cast type
            var newType = typeConverter.ConvertType(cast);
            var newCast = context.Builder.CreatePointerCast(
                cast.Location,
                cast.Value,
                newType);

            context.ReplaceAndRemove(cast, newCast);
        }
Пример #17
0
        /// <summary>
        /// Lowers alloca values into their appropriate counter parts.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            Alloca alloca)
        {
            // Compute the alloca type
            var newType   = typeConverter.ConvertType(alloca);
            var newAlloca = context.Builder.CreateAlloca(
                alloca.Location,
                newType,
                alloca.AddressSpace);

            context.ReplaceAndRemove(alloca, newAlloca);
        }
Пример #18
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> typeLowering,
            ViewCast value)
        {
            var builder  = context.Builder;
            var location = value.Location;
            var pointer  = builder.CreateGetField(
                location,
                value.Value,
                new FieldSpan(0));
            var length = builder.CreateGetField(
                location,
                value.Value,
                new FieldSpan(1));

            // New pointer
            var newPointer = builder.CreatePointerCast(
                location,
                pointer,
                value.TargetElementType);

            // Compute new length:
            // newLength = length * sourceElementSize / targetElementSize;
            var sourceElementType = (typeLowering[value] as ViewType).ElementType;
            var sourceElementSize = builder.CreateLongSizeOf(
                location,
                sourceElementType);
            var targetElementSize = builder.CreateLongSizeOf(
                location,
                value.TargetElementType);
            var newLength = builder.CreateArithmetic(
                location,
                builder.CreateArithmetic(
                    location,
                    length,
                    sourceElementSize,
                    BinaryArithmeticKind.Mul),
                targetElementSize, BinaryArithmeticKind.Div);

            var newInstance = builder.CreateDynamicStructure(
                location,
                newPointer,
                newLength);

            context.ReplaceAndRemove(value, newInstance);
        }
Пример #19
0
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            GetArrayLength value)
        {
            var builder  = context.Builder;
            var location = value.Location;

            Value length;

            if (value.IsFullLength)
            {
                // Extract the view from the underlying array-implementation structure
                var view = GetViewFromArray(builder, location, value.ArrayValue);
                length = builder.CreateGetViewLength(location, view);
            }
            else
            {
                // Check whether the dimension is a compile-time known constant
                Value dimension = value.Dimension;
                if (!(dimension is PrimitiveValue primitiveValue))
                {
                    throw location.GetNotSupportedException(
                              ErrorMessages.NotSupportNonConstArrayDimension,
                              dimension.ToString());
                }

                // Check whether the field index is out of range
                var structType = value.ArrayValue.Type.As <StructureType>(location);
                int index      = primitiveValue.Int32Value;
                if (index < 0 || index >= structType.NumFields - 1)
                {
                    throw location.GetNotSupportedException(
                              ErrorMessages.NotSupportNonConstArrayDimension,
                              index.ToString());
                }

                // BaseView + dimension offset
                length = builder.CreateGetField(
                    location,
                    value.ArrayValue,
                    new FieldAccess(1 + index));
            }

            // Replace the actual length information
            context.ReplaceAndRemove(value, length);
        }
Пример #20
0
        /// <summary>
        /// Lowers new array values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            ArrayValue value)
        {
            var builder         = context.Builder;
            var location        = value.Location;
            int currentPosition = builder.InsertPosition;

            // Allocate a memory array in the entry block
            var methodBuilder = builder.MethodBuilder;
            var entryBlock    = methodBuilder[methodBuilder.EntryBlock];

            entryBlock.InsertPosition = 0;
            var arrayLength = entryBlock.ComputeArrayLength(
                location,
                value.Extent);
            var newArray = entryBlock.CreateStaticAllocaArray(
                location,
                arrayLength,
                value.ArrayType.ElementType,
                MemoryAddressSpace.Local);

            // Create resulting structure in current block
            builder.InsertPosition = currentPosition;
            var instance = builder.CreateDynamicStructure(
                location,
                typeLowering.GetNumFields(value.ArrayType));

            // Insert pointer field
            instance.Add(newArray);

            // Insert all dimensions
            for (int i = 0, e = value.ArrayType.Dimensions; i < e; ++i)
            {
                instance.Add(builder.CreateGetField(
                                 location,
                                 value.Extent,
                                 new FieldSpan(i)));
            }

            var newStructure = instance.Seal();

            context.ReplaceAndRemove(value, newStructure);
        }
Пример #21
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> _,
            LoadElementAddress value)
        {
            var builder  = context.Builder;
            var location = value.Location;
            var pointer  = builder.CreateGetField(
                location,
                value.Source,
                new FieldSpan(0));
            var newLea = builder.CreateLoadElementAddress(
                location,
                pointer,
                value.Offset);

            context.ReplaceAndRemove(value, newLea);
        }
Пример #22
0
        /// <summary>
        /// Lowers address-computation values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> _,
            LoadElementAddress value)
        {
            var linearAddress = GetLinearAddress(
                context,
                value.Source,
                value.ElementIndex,
                out var ptr);

            var newLea = context.Builder.CreateLoadElementAddress(
                value.Location,
                ptr,
                linearAddress);

            context.ReplaceAndRemove(value, newLea);
        }
Пример #23
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> _,
            GetViewLength value)
        {
            var builder = context.Builder;
            var length  = builder.CreateGetField(
                value.Location,
                value.View,
                new FieldSpan(1));

            // Convert to a 32bit length value
            if (value.Is32BitProperty)
            {
                length = builder.CreateConvertToInt32(
                    value.Location,
                    length);
            }
            context.ReplaceAndRemove(value, length);
        }
Пример #24
0
        /// <summary>
        /// Lower array to view casts to direct references to the underyling view.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            ArrayToViewCast value)
        {
            var builder  = context.Builder;
            var location = value.Location;

            // Get the view from the array implementation structure
            Value array = value.Value;
            var   view  = GetViewFromArray(builder, location, array);

            // Cast this view into the generic address space to match all invariants
            view = builder.CreateAddressSpaceCast(
                location,
                view,
                MemoryAddressSpace.Generic);

            // Replace the current cast with the actual view pointing to the elements
            context.ReplaceAndRemove(value, view);
        }
Пример #25
0
        /// <summary>
        /// Specializes int to native pointer casts.
        /// </summary>
        private static void Specialize(
            RewriterContext context,
            SpecializerData data,
            IntAsPointerCast value)
        {
            // Convert from int -> native int type -> pointer
            var builder = context.Builder;

            // int -> native int type
            var convertToNativeInt = builder.CreateConvert(
                value.Location,
                value.Value,
                data.IntPointerType);

            // native int type -> pointer
            var convert = builder.CreateIntAsPointerCast(
                value.Location,
                convertToNativeInt);

            context.ReplaceAndRemove(value, convert);
        }
Пример #26
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            SetField setValue)
        {
            var builder  = context.Builder;
            var location = setValue.Location;

            // Compute the new base index
            var span = typeConverter.ComputeSpan(setValue, setValue.FieldSpan);

            // Check whether we have to insert multiple elements
            Value targetValue = setValue.ObjectValue;

            if (typeConverter[setValue] is TType)
            {
                for (int i = 0; i < span.Span; ++i)
                {
                    var viewField = builder.CreateGetField(
                        location,
                        setValue.Value,
                        new FieldSpan(i));
                    targetValue = builder.CreateSetField(
                        location,
                        targetValue,
                        new FieldSpan(span.Index + i),
                        viewField);
                }
            }
            else
            {
                // Simple field access
                targetValue = builder.CreateSetField(
                    location,
                    targetValue,
                    span,
                    setValue.Value);
            }
            context.ReplaceAndRemove(setValue, targetValue);
        }
Пример #27
0
        /// <summary>
        /// Lowers get element values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> _,
            GetArrayElement value)
        {
            var linearAddress = GetLinearAddress(
                context,
                value.ObjectValue,
                value.Index,
                out var ptr);

            var builder = context.Builder;
            var address = builder.CreateLoadElementAddress(
                value.Location,
                ptr,
                linearAddress);
            var newLoad = builder.CreateLoad(
                value.Location,
                address);

            context.ReplaceAndRemove(value, newLoad);
        }
Пример #28
0
        /// <summary>
        /// Specializes native pointer to int casts.
        /// </summary>
        private static void Specialize(
            RewriterContext context,
            SpecializerData data,
            PointerAsIntCast value)
        {
            // Convert from ptr -> native int type -> desired int type
            var builder = context.Builder;

            // ptr -> native int type
            var convertToNativeType = builder.CreatePointerAsIntCast(
                value.Location,
                value.Value,
                data.IntPointerType.BasicValueType);

            // native int type -> desired int type
            var convert = builder.CreateConvert(
                value.Location,
                convertToNativeType,
                value.TargetType);

            context.ReplaceAndRemove(value, convert);
        }
Пример #29
0
        /// <summary>
        /// Lowers set field operations into separate SSA values.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            GetField getValue)
        {
            var builder  = context.Builder;
            var location = getValue.Location;

            // Compute the new base index
            var span = typeConverter.ComputeSpan(getValue, getValue.FieldSpan);

            // Check whether we have to extract a nested type implementation
            Value newValue;

            if (typeConverter[getValue] is TType)
            {
                // We have to extract multiple elements from this structure
                var instance = builder.CreateDynamicStructure(location, span.Span);
                for (int i = 0; i < span.Span; ++i)
                {
                    var viewField = builder.CreateGetField(
                        location,
                        getValue.ObjectValue,
                        new FieldSpan(span.Index + i));
                    instance.Add(viewField);
                }
                newValue = instance.Seal();
            }
            else
            {
                // Simple field access
                newValue = builder.CreateGetField(
                    location,
                    getValue.ObjectValue,
                    span);
            }
            context.ReplaceAndRemove(getValue, newValue);
        }
Пример #30
0
        private static Value GetLinearAddress(
            RewriterContext context,
            Value array,
            Value index,
            out Value ptr)
        {
            var builder = context.Builder;

            ptr = builder.CreateGetField(
                array.Location,
                array,
                new FieldSpan(0));
            var extent = builder.CreateGetField(
                array.Location,
                array,
                new FieldSpan(1));

            return(builder.ComputeArrayAddress(
                       index.Location,
                       index,
                       extent,
                       ArrayTypeLowering.DimensionOffset));
        }