コード例 #1
0
 public SSARewriterContext <TVariable> CreateContext(
     BasicBlock.Builder builder,
     HashSet <Value> converted,
     SSABuilder <TVariable> data) =>
 new SSARewriterContext <TVariable>(
     new RewriterContext(builder, converted),
     data);
コード例 #2
0
 /// <summary>
 /// Specializes as-aligned operations (if any) for debugging purposes (if
 /// enabled). Note that this default implementation does not perform any
 /// operation.
 /// </summary>
 /// <param name="context">The parent IR context.</param>
 /// <param name="methodBuilder">The parent method builder.</param>
 /// <param name="builder">The current block builder.</param>
 /// <param name="asAligned">The current alignment operation.</param>
 protected virtual void Implement(
     IRContext context,
     Method.Builder methodBuilder,
     BasicBlock.Builder builder,
     AsAligned asAligned)
 {
 }
コード例 #3
0
        /// <summary>
        /// Maps internal <see cref="WriteToOutput"/> values to
        /// <see cref="PrintF(string)"/> method calls.
        /// </summary>
        protected override void Implement(
            IRContext context,
            Method.Builder methodBuilder,
            BasicBlock.Builder builder,
            WriteToOutput writeToOutput)
        {
            var location = writeToOutput.Location;

            // Convert to format string constant
            var expressionString = writeToOutput.ToEscapedPrintFExpression();
            var expression       = builder.CreatePrimitiveValue(
                location,
                expressionString);

            // Create a call to the native printf
            var printFMethod = context.Declare(PrintFMethod, out bool _);
            var callBuilder  = builder.CreateCall(location, printFMethod);

            callBuilder.Add(expression);
            foreach (Value argument in writeToOutput.Arguments)
            {
                var converted = WriteToOutput.ConvertToPrintFArgument(
                    builder,
                    location,
                    argument);
                callBuilder.Add(converted);
            }

            // Replace the write node with the call
            callBuilder.Seal();
            builder.Remove(writeToOutput);
        }
コード例 #4
0
 /// <summary>
 /// Keeps the debug assertion operation.
 /// </summary>
 protected override void Implement(
     IRContext context,
     Method.Builder methodBuilder,
     BasicBlock.Builder builder,
     DebugAssertOperation debugAssert)
 {
 }
コード例 #5
0
 /// <summary>
 /// Keeps the IO operation.
 /// </summary>
 protected override void Implement(
     IRContext context,
     Method.Builder methodBuilder,
     BasicBlock.Builder builder,
     WriteToOutput writeToOutput)
 {
 }
コード例 #6
0
ファイル: Block.cs プロジェクト: nguyenvuduc/ILGPU
        /// <summary>
        /// Constructs a new basic block.
        /// </summary>
        /// <param name="codeGenerator">The parent code generator.</param>
        /// <param name="builder">The current basic block builder.</param>
        private Block(CodeGenerator codeGenerator, BasicBlock.Builder builder)
        {
            Debug.Assert(codeGenerator != null, "Invalid code generator");
            Debug.Assert(builder != null, "Invalid builder");

            CodeGenerator = codeGenerator;
            Builder       = builder;
        }
コード例 #7
0
        /// <summary>
        /// Maps internal <see cref="WriteToOutput"/> values to
        /// <see cref="PrintF(string, void*)"/> method calls.
        /// </summary>
        protected override void Implement(
            IRContext context,
            Method.Builder methodBuilder,
            BasicBlock.Builder builder,
            WriteToOutput writeToOutput)
        {
            var location = writeToOutput.Location;

            // Convert to format string constant
            var expressionString = writeToOutput.ToPrintFExpression();
            var expression       = builder.CreatePrimitiveValue(
                location,
                expressionString,
                Encoding.ASCII);

            // Create an argument structure that can be passed via local memory
            var argumentBuilder = builder.CreateDynamicStructure(
                location,
                writeToOutput.Count);

            foreach (Value argument in writeToOutput.Arguments)
            {
                var converted = WriteToOutput.ConvertToPrintFArgument(
                    builder,
                    location,
                    argument);
                argumentBuilder.Add(converted);
            }
            var argumentStructure = argumentBuilder.Seal();

            // Create local alloca to store all data
            var alloca = builder.CreateAlloca(
                location,
                argumentStructure.Type,
                MemoryAddressSpace.Local);

            // Store structure into chunk of local memory
            builder.CreateStore(location, alloca, argumentStructure);

            // Cast alloca to the generic address space to satisfy the requirements of
            // of the printf method
            alloca = builder.CreateAddressSpaceCast(
                location,
                alloca,
                MemoryAddressSpace.Generic);

            // Create a call to the native printf
            var printFMethod = context.Declare(PrintFMethod, out bool _);
            var callBuilder  = builder.CreateCall(location, printFMethod);

            callBuilder.Add(expression);
            callBuilder.Add(alloca);

            // Replace the write node with the call
            callBuilder.Seal();
            builder.Remove(writeToOutput);
        }
コード例 #8
0
 /// <summary>
 /// Lowers a warp shuffle value by constructing a new one.
 /// </summary>
 public ValueReference Lower(
     BasicBlock.Builder builder,
     WarpShuffle source,
     Value newVariable) =>
 builder.CreateShuffle(
     source.Location,
     newVariable,
     source.Origin,
     source.Kind);
コード例 #9
0
ファイル: RewriterContext.cs プロジェクト: killop/ILGPU
        /// <summary>
        /// Constructs a new value processor.
        /// </summary>
        /// <param name="builder">The current builder.</param>
        /// <param name="converted">The set of converted value.</param>
        internal RewriterContext(
            BasicBlock.Builder builder,
            HashSet <Value> converted)
        {
            Debug.Assert(builder != null, "Invalid builder");

            Builder   = builder;
            Converted = converted;
        }
コード例 #10
0
 /// <summary>
 /// Lowers a broadcast value by constructing a new one.
 /// </summary>
 public ValueReference Lower(
     BasicBlock.Builder builder,
     Broadcast source,
     Value newVariable) =>
 builder.CreateBroadcast(
     source.Location,
     newVariable,
     source.Origin,
     source.Kind);
コード例 #11
0
        /// <summary>
        /// Maps internal debug assertions to <see cref="AssertFailed(string, string,
        /// int, string, int)"/> method calls.
        /// </summary>

        protected override void Implement(
            IRContext context,
            Method.Builder methodBuilder,
            BasicBlock.Builder builder,
            DebugAssertOperation debugAssert)
        {
            var location = debugAssert.Location;

            // Create a call to the debug-implementation wrapper while taking the
            // current source location into account
            var nextBlock  = builder.SplitBlock(debugAssert);
            var innerBlock = methodBuilder.CreateBasicBlock(
                location,
                nameof(AssertFailed));

            builder.CreateIfBranch(
                location,
                debugAssert.Condition,
                nextBlock,
                innerBlock);

            // Create a call to the assert implementation
            var innerBuilder = methodBuilder[innerBlock];
            var assertFailed = innerBuilder.CreateCall(
                location,
                context.Declare(AssertFailedMethod, out var _));

            // Move the debug assertion to this block
            var sourceMessage = debugAssert.Message.ResolveAs <StringValue>();
            var message       = innerBuilder.CreatePrimitiveValue(
                location,
                sourceMessage.String,
                sourceMessage.Encoding);

            assertFailed.Add(message);

            // Append source location information
            var debugLocation = debugAssert.GetLocationInfo();

            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, debugLocation.FileName));
            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, debugLocation.Line));
            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, debugLocation.Method));
            assertFailed.Add(
                innerBuilder.CreatePrimitiveValue(location, 1));

            // Finish the actual assertion call and branch
            assertFailed.Seal();
            innerBuilder.CreateBranch(location, nextBlock);

            // Remove the debug assertion value
            debugAssert.Replace(builder.CreateUndefined());
        }
コード例 #12
0
        /// <summary>
        /// Maps internal <see cref="AsAligned"/> values to a debug assertion while
        /// preserving the <see cref="AsAligned"/> value.
        /// </summary>
        protected override void Implement(
            IRContext context,
            Method.Builder methodBuilder,
            BasicBlock.Builder builder,
            AsAligned asAligned)
        {
            // Preserve the asAligned operation
            if (!EnableAssertions)
            {
                return;
            }

            // Check the actual pointer alignment
            var location   = asAligned.Location;
            var comparison = builder.CreateCompare(
                location,
                builder.CreateArithmetic(
                    location,
                    builder.CreatePointerAsIntCast(
                        location,
                        asAligned.Source,
                        IntPointerType.BasicValueType),
                    builder.CreateConvert(
                        location,
                        asAligned.AlignmentInBytes,
                        IntPointerType.BasicValueType),
                    BinaryArithmeticKind.Rem),
                builder.CreatePrimitiveValue(
                    location,
                    IntPointerType.BasicValueType,
                    0L),
                CompareKind.Equal);

            // Create the debug assertion
            Value assert = builder.CreateDebugAssert(
                location,
                comparison,
                builder.CreatePrimitiveValue(
                    location,
                    RuntimeErrorMessages.InvalidlyAssumedPointerOrViewAlignment));

            if (assert is DebugAssertOperation assertOperation)
            {
                Implement(context, methodBuilder, builder, assertOperation);
            }
        }
コード例 #13
0
ファイル: Rewriter.cs プロジェクト: saimarpaka/ILGPU
            public bool Apply(
                BasicBlock.Builder blockBuilder,
                HashSet <Value> converted,
                Value value)
            {
                if (!Rewriter.CanRewrite(Data, value))
                {
                    return(false);
                }
                TContextProvider provider = default;
                var rewriterContext       = provider.CreateContext(
                    blockBuilder,
                    converted,
                    ContextData);

                Rewriter.Apply(rewriterContext, Data, value);
                return(true);
            }
コード例 #14
0
ファイル: RewriterContext.cs プロジェクト: killop/ILGPU
 /// <summary>
 /// Creates a new <see cref="RewriterContext"/>.
 /// </summary>
 public RewriterContext CreateContext(
     BasicBlock.Builder builder,
     HashSet <Value> converted,
     T _) =>
 new RewriterContext(builder, converted);
コード例 #15
0
 /// <summary>
 /// Creates a light-weight rewriter context from the given builder.
 /// </summary>
 /// <param name="builder">The parent builder.</param>
 /// <returns>The created rewriter context.</returns>
 /// <remarks>
 /// Note that this context does not support any of the conversion utilities.
 /// </remarks>
 public static RewriterContext FromBuilder(BasicBlock.Builder builder) =>
 new RewriterContext(builder, null);
コード例 #16
0
ファイル: LowerThreadIntrinsics.cs プロジェクト: linhdh/ILGPU
 /// <summary cref="IValueLowering{T}.Create(BasicBlock.Builder, Value, T)"/>
 public Value Create(
     BasicBlock.Builder builder,
     Value value,
     (Value, BroadcastKind) arguments) =>
コード例 #17
0
ファイル: Block.cs プロジェクト: kingland/ILGPU
 /// <summary>
 /// Constructs a new basic block.
 /// </summary>
 /// <param name="codeGenerator">The parent code generator.</param>
 /// <param name="builder">The current basic block builder.</param>
 private Block(CodeGenerator codeGenerator, BasicBlock.Builder builder)
 {
     CodeGenerator = codeGenerator;
     Builder       = builder;
 }
コード例 #18
0
ファイル: RewriterContext.cs プロジェクト: killop/ILGPU
 /// <summary>
 /// Specializes the build by setting a new block builder.
 /// </summary>
 /// <param name="newBuilder">The new builder to use.</param>
 /// <returns>The specialized rewriter context.</returns>
 public readonly RewriterContext SpecializeBuilder(
     BasicBlock.Builder newBuilder) =>
 new RewriterContext(newBuilder, Converted);
コード例 #19
0
 /// <summary>
 /// Specializes debug output operations (if any). Note that this default
 /// implementation removes the output operations from the current program.
 /// </summary>
 /// <param name="context">The parent IR context.</param>
 /// <param name="methodBuilder">The parent method builder.</param>
 /// <param name="builder">The current block builder.</param>
 /// <param name="debugAssert">The debug assert operation.</param>
 protected virtual void Implement(
     IRContext context,
     Method.Builder methodBuilder,
     BasicBlock.Builder builder,
     DebugAssertOperation debugAssert) =>
 builder.Remove(debugAssert);
コード例 #20
0
 /// <summary>
 /// Specializes IO output operations (if any). Note that this default
 /// implementation removes the output operations from the current program.
 /// </summary>
 /// <param name="context">The parent IR context.</param>
 /// <param name="methodBuilder">The parent method builder.</param>
 /// <param name="builder">The current block builder.</param>
 /// <param name="writeToOutput">The IO output operation.</param>
 protected virtual void Implement(
     IRContext context,
     Method.Builder methodBuilder,
     BasicBlock.Builder builder,
     WriteToOutput writeToOutput) =>
 builder.Remove(writeToOutput);
コード例 #21
0
 /// <summary>
 /// Specializes the build by setting a new block builder.
 /// </summary>
 /// <param name="newBuilder">The new builder to use.</param>
 /// <returns>The specialized rewriter context.</returns>
 public SSARewriterContext <TVariable> SpecializeBuilder(
     BasicBlock.Builder newBuilder) =>
 new SSARewriterContext <TVariable>(
     baseContext.SpecializeBuilder(newBuilder),
     SSABuilder);
コード例 #22
0
        /// <summary>
        /// Specializes an address-space dependent parameter.
        /// </summary>
        /// <param name="methodBuilder">The target method builder.</param>
        /// <param name="builder">The entry block builder.</param>
        /// <param name="typeConverter">The type converter to use.</param>
        /// <param name="parameter">The source parameter.</param>
        /// <returns>True, if the given parameter was specialized.</returns>
        private static bool SpecializeParameter(
            Method.Builder methodBuilder,
            BasicBlock.Builder builder,
            AddressSpaceConverter typeConverter,
            Parameter parameter)
        {
            var converted = typeConverter.ConvertType(
                builder,
                parameter.Type);

            var location    = parameter.Location;
            var targetParam = methodBuilder.AddParameter(converted, parameter.Name);

            if (converted == parameter.Type)
            {
                parameter.Replace(targetParam);
                return(false);
            }

            Value convertedValue;

            if (converted is AddressSpaceType)
            {
                convertedValue = builder.CreateAddressSpaceCast(
                    location,
                    targetParam,
                    (parameter.Type as IAddressSpaceType).AddressSpace);
            }
            else
            {
                var structureType    = parameter.Type.As <StructureType>(location);
                var structureBuilder = builder.CreateStructure(
                    location,
                    structureType);

                var targetType = converted.As <StructureType>(location);
                foreach (var(fieldType, access) in structureType)
                {
                    var field = builder.CreateGetField(
                        location,
                        targetParam,
                        access);
                    if (fieldType == targetType[access])
                    {
                        structureBuilder.Add(field);
                    }
                    else
                    {
                        structureBuilder.Add(
                            builder.CreateAddressSpaceCast(
                                location,
                                field,
                                (fieldType as IAddressSpaceType).AddressSpace));
                    }
                }
                convertedValue = structureBuilder.Seal();
            }

            parameter.Replace(convertedValue);
            return(true);
        }