/// <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); }
/// <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); }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
public void Visit(LoadElementAddress value) { }
/// <summary cref="IValueVisitor.Visit(LoadElementAddress)"/> public void Visit(LoadElementAddress value) => CodeGenerator.GenerateCode(value);
/// <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 &&