コード例 #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
 public void Visit(AddressSpaceCast value)
 {
     if (Get <AddressSpaceCast>().TargetAddressSpace != value.TargetAddressSpace)
     {
         Fail();
     }
 }
コード例 #3
0
        /// <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();
                }
            }
        }
コード例 #4
0
ファイル: SSAConstruction.cs プロジェクト: adamreeve/ILGPU
        /// <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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        /// <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);
                }
            }
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
        /// <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);
            }
        }
コード例 #12
0
 /// <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);
コード例 #13
0
 /// <summary cref="IValueVisitor.Visit(AddressSpaceCast)"/>
 public void Visit(AddressSpaceCast value) =>
 CodeGenerator.GenerateCode(value);
コード例 #14
0
        /// <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);
                }
            }
        }