Esempio n. 1
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);
        }
Esempio n. 2
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);
        }