/// <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); }
/// <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); }