Esempio n. 1
0
        /// <summary cref="IValueVisitor.Visit(LoadElementAddress)"/>
        public void Visit(LoadElementAddress value)
        {
            var pointerType  = value.Type as PointerType;
            var elementIndex = LoadAs <PrimitiveVariable>(value.ElementIndex);
            var target       = AllocatePointerType(pointerType.ElementType, pointerType.AddressSpace);

            PointerVariable address;

            if (value.IsPointerAccess)
            {
                address = LoadAs <PointerVariable>(value.Source);
            }
            else
            {
                var viewSource = LoadAs <ViewVariable>(value.Source);
                address = viewSource.Pointer;
            }

            MakeLoadElementAddress(
                elementIndex,
                target,
                address);

            Bind(value, target);
        }
Esempio n. 2
0
        /// <summary>
        /// Converts a load node into an SSA value.
        /// </summary>
        private static void Convert <TConstructionData>(
            SSARewriterContext <Value> context,
            TConstructionData data,
            LoadElementAddress loadElementAddress)
            where TConstructionData : IConstructionData
        {
            if (!data.TryGetConverted(loadElementAddress.Source, out var leaRef))
            {
                return;
            }

            // Get the primitive constant field offset
            loadElementAddress.Assert(loadElementAddress.IsViewAccess);
            var fieldOffset = loadElementAddress.Offset.ResolveAs <PrimitiveValue>();

            loadElementAddress.AssertNotNull(fieldOffset);

            // Map the field index + 1 to skip the initial array length
            int fieldIndex = fieldOffset.Int32Value + 1;

            data.AddConverted(
                loadElementAddress,
                leaRef.Access(new FieldAccess(fieldIndex)));
            context.Remove(loadElementAddress);
        }
Esempio n. 3
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(LoadElementAddress)"/>
        public void GenerateCode(LoadElementAddress value)
        {
            var elementIndex          = LoadPrimitive(value.ElementIndex);
            var targetAddressRegister = AllocatePlatformRegister(
                value,
                out RegisterDescription _);

            Debug.Assert(value.IsPointerAccess, "Invalid pointer access");

            var address        = LoadPrimitive(value.Source);
            var sourceType     = value.Source.Type as AddressSpaceType;
            var elementSize    = sourceType.ElementType.Size;
            var offsetRegister = AllocatePlatformRegister(out RegisterDescription _);

            using (var command = BeginCommand(
                       PTXInstructions.GetLEAMulOperation(Backend.PointerArithmeticType)))
            {
                command.AppendArgument(offsetRegister);
                command.AppendArgument(elementIndex);
                command.AppendConstant(elementSize);
            }

            using (var command = BeginCommand(
                       PTXInstructions.GetArithmeticOperation(
                           BinaryArithmeticKind.Add,
                           Backend.PointerArithmeticType,
                           false)))
            {
                command.AppendArgument(targetAddressRegister);
                command.AppendArgument(address);
                command.AppendArgument(offsetRegister);
            }

            FreeRegister(offsetRegister);
        }
Esempio n. 4
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(LoadElementAddress)"/>
        public void GenerateCode(LoadElementAddress value)
        {
            var elementIndex          = LoadPrimitive(value.Offset);
            var targetAddressRegister = AllocatePlatformRegister(
                value,
                out RegisterDescription _);

            Debug.Assert(value.IsPointerAccess, "Invalid pointer access");

            var address     = LoadPrimitive(value.Source);
            var sourceType  = value.Source.Type as AddressSpaceType;
            var elementSize = sourceType.ElementType.Size;

            if (value.Is32BitAccess)
            {
                // Perform two efficient operations TODO
                var offsetRegister = AllocatePlatformRegister(out RegisterDescription _);
                using (var command = BeginCommand(
                           PTXInstructions.GetLEAMulOperation(Backend.PointerArithmeticType)))
                {
                    command.AppendArgument(offsetRegister);
                    command.AppendArgument(elementIndex);
                    command.AppendConstant(elementSize);
                }

                using (var command = BeginCommand(
                           PTXInstructions.GetArithmeticOperation(
                               BinaryArithmeticKind.Add,
                               Backend.PointerArithmeticType,
                               Backend.Capabilities,
                               false)))
                {
                    command.AppendArgument(targetAddressRegister);
                    command.AppendArgument(address);
                    command.AppendArgument(offsetRegister);
                }

                FreeRegister(offsetRegister);
            }
            else
            {
                // Use an efficient MAD instruction to compute the effective address
                using var command = BeginCommand(
                          PTXInstructions.GetArithmeticOperation(
                              TernaryArithmeticKind.MultiplyAdd,
                              Backend.PointerArithmeticType));
                command.AppendArgument(targetAddressRegister);
                command.AppendArgument(elementIndex);
                command.AppendConstant(elementSize);
                command.AppendArgument(address);
            }
        }
Esempio n. 5
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(LoadElementAddress)"/>
        public void GenerateCode(LoadElementAddress value)
        {
            var elementIndex = LoadAs <PrimitiveVariable>(value.Offset);
            var source       = Load(value.Source);
            var target       = AllocatePointerType(value.Type as PointerType);

            using (var statement = BeginStatement(target))
            {
                statement.AppendCommand(CLInstructions.AddressOfOperation);
                statement.Append(source);
                statement.AppendIndexer(elementIndex);
            }

            Bind(value, target);
        }
Esempio n. 6
0
        /// <summary cref="IValueVisitor.Visit(LoadElementAddress)"/>
        public void Visit(LoadElementAddress value)
        {
            var pointerType  = value.Type as PointerType;
            var elementIndex = LoadAs <PrimitiveVariable>(value.ElementIndex);
            var source       = Load(value.Source);
            var target       = AllocatePointerType(pointerType.ElementType, pointerType.AddressSpace);

            using (var statement = BeginStatement(target))
            {
                statement.AppendCommand(CLInstructions.AddressOfOperation);
                statement.Append(source);
                statement.TryAppendViewPointerField(source);
                statement.AppendIndexer(elementIndex);
            }

            Bind(value, target);
        }
Esempio n. 7
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);
        }
Esempio n. 8
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);
        }
Esempio n. 9
0
        /// <summary cref="IValueVisitor.Visit(LoadElementAddress)"/>
        public void Visit(LoadElementAddress value)
        {
            var elementIndex          = LoadPrimitive(value.ElementIndex);
            var targetAddressRegister = AllocatePlatformRegister(value, out RegisterDescription _);

            PrimitiveRegister address;

            if (value.IsPointerAccess)
            {
                address = LoadPrimitive(value.Source);
            }
            else
            {
                var viewSource = LoadAs <ViewImplementationRegister>(value.Source);
                address = viewSource.Pointer;
            }

            MakeLoadElementAddress(
                value.Type as AddressSpaceType,
                elementIndex,
                targetAddressRegister,
                address);
        }
Esempio n. 10
0
 public void Visit(LoadElementAddress value)
 {
 }
Esempio n. 11
0
 /// <summary cref="IValueVisitor.Visit(LoadElementAddress)"/>
 public void Visit(LoadElementAddress value) =>
 CodeGenerator.GenerateCode(value);
Esempio n. 12
0
 /// <summary>
 /// Returns true if the given <see cref="LoadElementAddress"/> value requires
 /// an explicit address in memory (e.g. the offset being accessed could not be
 /// resolved to a statically known index value).
 /// </summary>
 /// <param name="lea">The lea node.</param>
 /// <param name="arrayLength">The array length.</param>
 /// <returns>True, if an explicit address is required.</returns>
 private static bool RequiresAddress(
     LoadElementAddress lea,
     int arrayLength) =>
 !(lea.Offset.Resolve() is PrimitiveValue index &&