/// <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); }
public void Visit(AddressSpaceCast value) { if (Get <AddressSpaceCast>().TargetAddressSpace != value.TargetAddressSpace) { Fail(); } }
/// <summary cref="IBackendCodeGenerator.GenerateCode(AddressSpaceCast)"/> public void GenerateCode(AddressSpaceCast value) { var targetType = value.TargetType as AddressSpaceType; var source = Load(value.Value); var target = Allocate(value); bool isOperation = CLInstructions.TryGetAddressSpaceCast( value.TargetAddressSpace, out string operation); void GeneratePointerCast(StatementEmitter statement) { if (isOperation) { // There is a specific cast operation statement.AppendCommand(operation); statement.BeginArguments(); statement.Append(source); } else { statement.AppendPointerCast(TypeGenerator[targetType.ElementType]); } statement.Append(source); } using (var statement = BeginStatement(target)) { GeneratePointerCast(statement); if (isOperation) { statement.EndArguments(); } } }
/// <summary> /// Converts an address-space cast into an SSA binding. /// </summary> private static void Convert( SSARewriterContext <Value> context, ConstructionData data, AddressSpaceCast addressSpaceCast) { if (!data.TryGetConverted(addressSpaceCast.Value, out var castRef)) { return; } data.AddConverted(addressSpaceCast, castRef); context.Remove(addressSpaceCast); }
/// <summary> /// Converts an address-space cast into an SSA binding. /// </summary> protected static void Convert <TConstructionData>( SSARewriterContext <Value> context, TConstructionData data, AddressSpaceCast addressSpaceCast) where TConstructionData : IConstructionData { if (!data.TryGetConverted(addressSpaceCast.Value, out var castRef)) { return; } data.AddConverted(addressSpaceCast, castRef); context.Remove(addressSpaceCast); }
/// <summary cref="IValueVisitor.Visit(AddressSpaceCast)"/> public void Visit(AddressSpaceCast value) { var targetType = value.TargetType as AddressSpaceType; var target = AllocatePointerType(targetType.ElementType, value.TargetAddressSpace); PointerVariable address; if (value.IsPointerCast) { address = LoadAs <PointerVariable>(value.Value); Bind(value, target); } else { var viewSource = LoadAs <ViewVariable>(value.Value); address = viewSource.Pointer; var viewTarget = new ViewVariable( value.Type as ViewType, target, viewSource.Length); Bind(value, viewTarget); } if (CLInstructions.TryGetAddressSpaceCast( value.TargetAddressSpace, out string operation)) { // There is a specific cast operation using (var statement = BeginStatement(target)) { statement.AppendCommand(operation); statement.BeginArguments(); statement.AppendArgument(address); statement.EndArguments(); } } else { // Use an unspecific generic pointer cast using (var statement = BeginStatement(target)) { statement.AppendCast( TypeGenerator[targetType.ElementType] + CLInstructions.DereferenceOperation); statement.Append(address); } } }
/// <summary cref="IBackendCodeGenerator.GenerateCode(AddressSpaceCast)"/> public void GenerateCode(AddressSpaceCast value) { var sourceType = value.SourceType.As <AddressSpaceType>(value); var targetAdressRegister = AllocateHardware(value); value.Assert(value.IsPointerCast); var address = LoadPrimitive(value.Value); CreateAddressSpaceCast( address, targetAdressRegister, sourceType.AddressSpace, value.TargetAddressSpace); }
/// <summary cref="IBackendCodeGenerator.GenerateCode(AddressSpaceCast)"/> public void GenerateCode(AddressSpaceCast value) { var sourceType = value.SourceType as AddressSpaceType; var targetAdressRegister = AllocatePlatformRegister( value, out RegisterDescription _); Debug.Assert(value.IsPointerCast, "Invalid pointer access"); var address = LoadPrimitive(value.Value); CreateAddressSpaceCast( address, targetAdressRegister, sourceType.AddressSpace, value.TargetAddressSpace); }
/// <summary> /// Returns true if the given cast is redundant. /// </summary> /// <param name="cast">The cast to check.</param> /// <returns>True, if the given cast is redundant.</returns> private static bool IsRedundant(AddressSpaceCast cast) { Debug.Assert(cast != null, "Invalid cast"); foreach (var use in cast.Uses) { var node = use.Resolve(); switch (node) { case MethodCall _: // We cannot remove casts to other address spaces in case // of a method invocation. return(false); case PhiValue _: // We are not allowed to remove casts from phi node operands. return(false); case Store _: // We are not allowed to remove casts in the case of alloca // stores if (use.Index != 0) { return(false); } break; case SetArrayElement _: return(false); case SetField setField: // We are not allowed to remove field stores to tuples // with different field types var structureType = setField.StructureType; if (structureType[setField.FieldSpan.Access] != cast.SourceType) { return(false); } break; } } return(true); }
/// <summary cref="IBackendCodeGenerator.GenerateCode(AddressSpaceCast)"/> public void GenerateCode(AddressSpaceCast value) { var sourceType = value.SourceType as AddressSpaceType; var targetAdressRegister = AllocatePlatformRegister( value, out RegisterDescription _); Debug.Assert(value.IsPointerCast, "Invalid pointer access"); var address = LoadPrimitive(value.Value); var toGeneric = value.TargetAddressSpace == MemoryAddressSpace.Generic; var addressSpaceOperation = PTXInstructions.GetAddressSpaceCast(toGeneric); var addressSpaceOperationSuffix = PTXInstructions.GetAddressSpaceCastSuffix(Backend); using var command = BeginCommand(addressSpaceOperation); command.AppendAddressSpace( toGeneric ? sourceType.AddressSpace : value.TargetAddressSpace); command.AppendSuffix(addressSpaceOperationSuffix); command.AppendArgument(targetAdressRegister); command.AppendArgument(address); }
/// <summary cref="IValueVisitor.Visit(AddressSpaceCast)"/> public void Visit(AddressSpaceCast value) { var sourceType = value.SourceType as AddressSpaceType; var targetAdressRegister = AllocatePlatformRegister(value, out RegisterDescription _); PrimitiveRegister address; if (value.IsPointerCast) { address = LoadPrimitive(value.Value); } else { var viewSource = LoadAs <ViewImplementationRegister>(value.Value); address = viewSource.Pointer; // Reuse the existing length register since we don't modify the result var viewTarget = new ViewImplementationRegister( value.Type as ViewType, targetAdressRegister, viewSource.Length); Bind(value, viewTarget); } var toGeneric = value.TargetAddressSpace == MemoryAddressSpace.Generic; var addressSpaceOperation = PTXInstructions.GetAddressSpaceCast(toGeneric); var addressSpaceOperationSuffix = PTXInstructions.GetAddressSpaceCastSuffix(ABI); using (var command = BeginCommand(addressSpaceOperation)) { command.AppendAddressSpace( toGeneric ? sourceType.AddressSpace : value.TargetAddressSpace); command.AppendSuffix(addressSpaceOperationSuffix); command.AppendArgument(targetAdressRegister); command.AppendArgument(address); } }
/// <summary> /// Returns true if the given cast is redundant. /// </summary> /// <param name="cast">The cast to check.</param> /// <returns>True, if the given cast is redundant.</returns> private static bool IsRedundant(AddressSpaceCast cast) => IsRedundantRecursive(cast.TargetAddressSpace, cast);
/// <summary cref="IValueVisitor.Visit(AddressSpaceCast)"/> public void Visit(AddressSpaceCast value) => CodeGenerator.GenerateCode(value);
/// <summary cref="IValueVisitor.Visit(AddressSpaceCast)"/> public void Visit(AddressSpaceCast value) { var targetType = value.TargetType as AddressSpaceType; var source = Load(value.Value); var target = Allocate(value); bool isOperation = CLInstructions.TryGetAddressSpaceCast( value.TargetAddressSpace, out string operation); void GeneratePointerCast(StatementEmitter statement) { if (isOperation) { // There is a specific cast operation statement.AppendCommand(operation); statement.BeginArguments(); statement.Append(source); } else { statement.AppendPointerCast(TypeGenerator[targetType.ElementType]); } statement.Append(source); } if (value.IsPointerCast) { using (var statement = BeginStatement(target)) { GeneratePointerCast(statement); if (isOperation) { statement.EndArguments(); } } } else { var targetView = target as ViewImplementationVariable; Declare(target); // Assign pointer using (var statement = BeginStatement(target, targetView.PointerFieldIndex)) { GeneratePointerCast(statement); statement.AppendField(targetView.PointerFieldIndex); if (isOperation) { statement.EndArguments(); } } // Assign length using (var statement = BeginStatement(target, targetView.LengthFieldIndex)) { statement.Append(source); statement.AppendField(targetView.LengthFieldIndex); } } }