Пример #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 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);
        }
Пример #5
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);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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);
        }
Пример #11
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);
        }
Пример #12
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);
        }
Пример #13
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);
        }
Пример #14
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);
        }
Пример #15
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);
        }
Пример #16
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);
        }
Пример #17
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);
        }
Пример #18
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);
        }
Пример #19
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);
        }
Пример #20
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);
        }
Пример #21
0
        /// <summary>
        /// Lowers structure values with nested types.
        /// </summary>
        protected static void Lower(
            RewriterContext context,
            TypeLowering <TType> typeConverter,
            StructureValue value)
        {
            var builder  = context.Builder;
            var location = value.Location;

            var sourceType = typeConverter[value] as StructureType;
            var instance   = builder.CreateStructure(
                location,
                typeConverter.ConvertType(sourceType) as StructureType);

            for (int i = 0, e = sourceType.NumFields; i < e; ++i)
            {
                if (sourceType[i] is TType ttype)
                {
                    var numFields = typeConverter.GetNumFields(ttype);
                    for (int j = 0; j < numFields; ++j)
                    {
                        var viewField = builder.CreateGetField(
                            location,
                            value[i],
                            new FieldSpan(j));
                        instance.Add(viewField);
                    }
                }
                else
                {
                    instance.Add(value[i]);
                }
            }

            var newValue = instance.Seal();

            context.ReplaceAndRemove(value, newValue);
        }
Пример #22
0
        /// <summary>
        /// Lowers array extent values.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            GetArrayExtent value)
        {
            var builder = context.Builder;

            // Create new extent structure based on all dimension entries
            int dimensions = StructureType.GetNumFields(typeLowering[value]);
            var instance   = builder.CreateDynamicStructure(value.Location, dimensions);

            // Insert all dimension values
            for (int i = 0; i < dimensions; ++i)
            {
                instance.Add(builder.CreateGetField(
                                 value.Location,
                                 value.ObjectValue,
                                 new FieldSpan(i + ArrayTypeLowering.DimensionOffset)));
            }

            var newStructure = instance.Seal();

            context.ReplaceAndRemove(value, newStructure);
        }
Пример #23
0
 /// <summary>
 /// Registers a type-mapping entry and returns always true.
 /// </summary>
 protected static bool Register <TValue>(
     TypeLowering <TType> typeConverter,
     TValue value,
     TypeNode type)
     where TValue : Value =>
 typeConverter.Register(value, type);
Пример #24
0
 /// <summary>
 /// Lowers Phi nodes into an adapted version.
 /// </summary>
 protected static void Lower(
     RewriterContext context,
     TypeLowering <TType> typeConverter,
     PhiValue phi) =>
 context.Builder.UpdatePhiType(phi, typeConverter);
Пример #25
0
        /// <summary>
        /// Lowers an align-view-to operation.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ViewType> typeLowering,
            AlignViewTo value)
        {
            var builder  = context.Builder;
            var location = value.Location;

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

            // Create IR code that represents the required operations to create aligned
            // views (see ArrayView.AlignToInternal for more information).
            var viewType = typeLowering[value].As <ViewType>(value);

            // long elementsToSkip = Min(
            //      AlignmentOffset(ptr, alignmentInBytes) / elementSize,
            //      Length);

            var elementsToSkip = builder.CreateArithmetic(
                location,
                builder.CreateAlignmentOffset(
                    location,
                    builder.CreatePointerAsIntCast(
                        location,
                        pointer,
                        BasicValueType.Int64),
                    value.AlignmentInBytes),
                builder.CreateSizeOf(location, viewType.ElementType),
                BinaryArithmeticKind.Div);

            elementsToSkip = builder.CreateArithmetic(
                location,
                elementsToSkip,
                length,
                BinaryArithmeticKind.Min);

            // Build the final result structure instance
            var resultBuilder = builder.CreateDynamicStructure(location);

            // Create the prefix view that starts at the original pointer offset and
            // includes elementsToSkip many elements.
            {
                resultBuilder.Add(pointer);
                resultBuilder.Add(elementsToSkip);
            }

            // Create the main view that starts at the original pointer offset +
            // elementsToSkip and has a length of remainingLength
            {
                var mainPointer = builder.CreateLoadElementAddress(
                    location,
                    pointer,
                    elementsToSkip);
                resultBuilder.Add(mainPointer);
                var remainingLength = builder.CreateArithmetic(
                    location,
                    length,
                    elementsToSkip,
                    BinaryArithmeticKind.Sub);
                resultBuilder.Add(remainingLength);
            }

            var result = resultBuilder.Seal();

            context.ReplaceAndRemove(value, result);
        }
Пример #26
0
        /// <summary>
        /// Lowers new array values into static allocation instances and structures.
        /// </summary>
        private static void Lower(
            RewriterContext context,
            TypeLowering <ArrayType> typeLowering,
            NewArray value)
        {
            var builder            = context.Builder;
            var location           = value.Location;
            var targetAddressSpace = (typeLowering as ArrayTypeLowering)
                                     .TargetAddressSpace;

            // Compute array length
            Value totalLength = builder.CreatePrimitiveValue(location, 1);

            foreach (Value length in value)
            {
                totalLength = builder.CreateArithmetic(
                    location,
                    totalLength,
                    length,
                    BinaryArithmeticKind.Mul);
            }

            // Check for a compile-time known constant
            if (!(totalLength is PrimitiveValue primitiveLength) ||
                primitiveLength.Int32Value < 0)
            {
                throw location.GetNotSupportedException(
                          ErrorMessages.NotSupportNonConstArrayDimension,
                          totalLength.ToString());
            }

            // Create array structure.
            var arrayType = typeLowering
                            .ConvertType(value.Type)
                            .As <StructureType>(location);
            var   result = builder.CreateStructure(location, arrayType);
            Value view;

            // Check for empty array allocations
            if (primitiveLength.HasIntValue(0))
            {
                // Create an empty view.
                view = builder.CreateNewView(
                    location,
                    builder.CreateNull(
                        location,
                        builder.CreatePointerType(
                            value.ElementType,
                            targetAddressSpace)),
                    primitiveLength);
                result.Add(view);

                // Insert a dimension length of 0 in each dimension
                for (int i = 0, e = value.Count; i < e; ++i)
                {
                    result.Add(primitiveLength);
                }
            }
            else
            {
                // Create the allocation and the base view
                var allocation = builder.CreateStaticAllocaArray(
                    location,
                    totalLength,
                    value.ElementType,
                    targetAddressSpace);
                view = builder.CreateNewView(location, allocation, totalLength);
                result.Add(view);

                // Insert dimension information for each array rank
                foreach (Value length in value)
                {
                    result.Add(length);
                }
            }

            // Clear all array elements using explicit stores. We emit the code in
            // the form of an unrolled loop to avoid additional loops from being
            // generated.
            // TODO: replace this loop with a high-level memset operation later on
            var defaultElement = builder.CreateNull(location, value.Type.ElementType);

            for (int i = 0, e = primitiveLength.Int32Value; i < e; ++i)
            {
                var address = builder.CreateLoadElementAddress(
                    location,
                    view,
                    builder.CreatePrimitiveValue(location, i));
                builder.CreateStore(location, address, defaultElement);
            }

            // Replace the current value with a new structure instance
            context.ReplaceAndRemove(value, result.Seal());
        }
Пример #27
0
 /// <summary>
 /// Invalidates the type of the given value.
 /// </summary>
 protected static void InvalidateType <TValue>(
     RewriterContext context,
     TypeLowering <TType> typeConverter,
     TValue value)
     where TValue : Value =>
 value.InvalidateType();
Пример #28
0
 /// <summary>
 /// Registers a type-mapping entry and returns always true.
 /// </summary>
 protected static bool Register <TValue>(
     TypeLowering <TType> typeConverter,
     TValue value)
     where TValue : Value => Register(typeConverter, value, value.Type);
Пример #29
0
 /// <summary>
 /// Returns true if the type is type dependent and registers a type-mapping
 /// entry.
 /// </summary>
 private static bool IsTypeDependent <TValue>(
     TypeLowering <TType> typeConverter,
     TValue value)
     where TValue : Value =>
 IsTypeDependent(typeConverter, value, value.Type);
Пример #30
0
 /// <summary>
 /// Returns true if the type is type dependent and registers a type-mapping
 /// entry.
 /// </summary>
 private static bool IsTypeDependent <TValue>(
     TypeLowering <TType> typeConverter,
     TValue value,
     TypeNode type)
     where TValue : Value =>
 typeConverter.TryRegister(value, type);