internal EmittingContext(LLVMModuleRef pModule, LLVMPassManagerRef pPass, bool pEmitDebug) { CurrentModule = pModule; _passManager = pPass; _context = LLVM.GetGlobalContext(); _deferredStatements = new Stack <List <Syntax.SyntaxNode> >(); Builder = LLVM.CreateBuilder(); _emitDebug = pEmitDebug; Locals = new ScopeCache <LocalDefinition>(); AccessStack = new AccessStack <MemberAccess>(); BreakLocations = new AccessStack <LLVMValueRef>(1); if (_emitDebug) { _debugLocations = new Stack <LLVMMetadataRef>(); _debugInfo = Utils.LlvmPInvokes.LLVMCreateDIBuilder(CurrentModule); _debugFile = Utils.LlvmPInvokes.LLVMDIBuilderCreateFile(_debugInfo, "debug", 5, ".", 1); //Set debug version var version = LLVM.MDNode(new LLVMValueRef[] { GetInt(1), //Error on mismatch LLVM.MDString("Debug Info Version", 18), //Constant string. Cannot change. GetInt(3) }); //Debug version LLVM.AddNamedMetadataOperand(CurrentModule, "llvm.module.flags", version); } }
private void EmitDebugMetadata() { var dwarfVersion = LLVM.MDNode(new[] { LLVM.ConstInt(LLVM.Int32Type(), 2, false), LLVM.MDString("Dwarf Version", 13), LLVM.ConstInt(LLVM.Int32Type(), 4, false) }); var dwarfSchemaVersion = LLVM.MDNode(new[] { LLVM.ConstInt(LLVM.Int32Type(), 2, false), LLVM.MDString("Debug Info Version", 18), LLVM.ConstInt(LLVM.Int32Type(), 3, false) }); LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", dwarfVersion); LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", dwarfSchemaVersion); LLVM.DIBuilderFinalize(DIBuilder); }
public CodeGenerator(string targetPlatform, string dataLayout, int optimisation, string moduleName) { TargetPlatform = targetPlatform; DataLayout = dataLayout; OptimisationLevel = optimisation; if (optimisation != -1) { LLVMPassManagerBuilderRef passManagerBuilderRef = LLVM.PassManagerBuilderCreate(); LLVM.PassManagerBuilderSetOptLevel(passManagerBuilderRef, (uint)optimisation); PassManager = LLVM.CreatePassManager(); LLVM.PassManagerBuilderPopulateModulePassManager(passManagerBuilderRef, PassManager.Value); } Module = LLVM.ModuleCreateWithName(moduleName); Context = LLVM.GetModuleContext(Module); Builder = LLVM.CreateBuilder(); LLVM.SetTarget(Module, TargetPlatform); LLVM.SetDataLayout(Module, dataLayout); LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", LLVM.MDNode(new[] { LLVM.ConstInt(LLVM.Int32Type(), 2, false), LLVM.MDString("Dwarf Version", (uint)"Dwarf Version".Length), LLVM.ConstInt(LLVM.Int32Type(), 4, false) })); LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", LLVM.MDNode(new[] { LLVM.ConstInt(LLVM.Int32Type(), 2, false), LLVM.MDString("Debug Info Version", (uint)"Debug Info Version".Length), LLVM.ConstInt(LLVM.Int32Type(), 3, false) })); _globals = new Dictionary <string, LLVMValueRef>(); _structCache = new Dictionary <string, LLVMTypeRef>(); _functionCache = new Dictionary <string, LLVMValueRef>(); }
public void TestPTX() { LLVM.InitializeAllTargets(); LLVM.InitializeAllTargetMCs(); LLVM.InitializeAllTargetInfos(); LLVM.InitializeAllAsmPrinters(); ModuleRef mod = LLVM.ModuleCreateWithName("llvmptx"); var pt = LLVM.PointerType(LLVM.Int64Type(), 1); TypeRef[] param_types = { pt }; TypeRef ret_type = LLVM.FunctionType(LLVM.VoidType(), param_types, false); ValueRef sum = LLVM.AddFunction(mod, "sum", ret_type); BasicBlockRef entry = LLVM.AppendBasicBlock(sum, "entry"); BuilderRef builder = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder, entry); var v = LLVM.BuildLoad(builder, LLVM.GetParam(sum, 0), ""); ValueRef tmp = LLVM.BuildAdd(builder, v, LLVM.ConstInt(LLVM.Int64Type(), 1, false), "tmp"); LLVM.BuildStore(builder, tmp, LLVM.GetParam(sum, 0)); LLVM.BuildRetVoid(builder); MyString the_error = new MyString(); LLVM.VerifyModule(mod, VerifierFailureAction.PrintMessageAction, the_error); string triple = "nvptx64-nvidia-cuda"; TargetRef t2; var b = LLVM.GetTargetFromTriple(triple, out t2, the_error); string cpu = ""; string features = ""; TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, triple, cpu, features, CodeGenOptLevel.CodeGenLevelDefault, RelocMode.RelocDefault, CodeModel.CodeModelKernel); ContextRef context_ref = LLVM.ContextCreate(); ValueRef kernelMd = LLVM.MDNodeInContext(context_ref, new ValueRef[3] { sum, LLVM.MDStringInContext(context_ref, "kernel", 6), LLVM.ConstInt(LLVM.Int32TypeInContext(context_ref), 1, false) }); LLVM.AddNamedMetadataOperand(mod, "nvvm.annotations", kernelMd); var y1 = LLVM.TargetMachineEmitToMemoryBuffer( tmr, mod, Swigged.LLVM.CodeGenFileType.AssemblyFile, the_error, out MemoryBufferRef buffer); string ptx = null; try { ptx = LLVM.GetBufferStart(buffer); uint length = LLVM.GetBufferSize(buffer); // Output the PTX assembly code. We can run this using the CUDA Driver API System.Console.WriteLine(ptx); } finally { LLVM.DisposeMemoryBuffer(buffer); } // RUN THE MF. Int64[] h_C = new Int64[100]; CudaContext ctx = new CudaContext(CudaContext.GetMaxGflopsDeviceId()); CudaKernel kernel = ctx.LoadKernelPTX(Encoding.ASCII.GetBytes(ptx), "sum"); var d_C = new CudaDeviceVariable <Int64>(100); int N = 1; int threadsPerBlock = 256; kernel.BlockDimensions = threadsPerBlock; kernel.GridDimensions = (N + threadsPerBlock - 1) / threadsPerBlock; kernel.Run(d_C.DevicePointer); h_C = d_C; System.Console.WriteLine("Result " + h_C[0]); if (h_C[0] != 1) { throw new Exception("Failed."); } LLVM.DumpModule(mod); LLVM.DisposeBuilder(builder); }
private static async Task <CudaModule> CompileAsync( IMethod method, IEnumerable <ITypeMember> memberRoots, IEnumerable <IType> typeRoots, int threadIdParamIndex, ClrAssembly assembly, CudaContext context) { // Figure out which members we need to compile. var desc = await CreateContentDescriptionAsync(method, memberRoots, typeRoots, assembly); // Compile those members to LLVM IR. Use an Itanium name mangling scheme. var mangler = new ItaniumMangler(assembly.Resolver.TypeEnvironment); var moduleBuilder = LlvmBackend.Compile(desc, assembly.Resolver.TypeEnvironment); var module = moduleBuilder.Module; // Generate type metadata for all type roots. foreach (var type in typeRoots) { moduleBuilder.Metadata.GetMetadata(type, moduleBuilder); } // Get the compiled kernel function. var kernelFuncName = mangler.Mangle(method, true); var kernelFunc = LLVM.GetNamedFunction(module, kernelFuncName); if (threadIdParamIndex >= 0) { // If we have a thread ID parameter, then we need to generate a thunk // kernel function that calls our actual kernel function. This thunk's // responsibility is to determine the thread ID of the kernel. var thunkKernelName = "kernel"; var thunkTargetType = kernelFunc.TypeOf().GetElementType(); var thunkParamTypes = new List <LLVMTypeRef>(thunkTargetType.GetParamTypes()); if (threadIdParamIndex < thunkParamTypes.Count) { thunkParamTypes.RemoveAt(threadIdParamIndex); } var thunkKernel = LLVM.AddFunction( module, thunkKernelName, LLVM.FunctionType( thunkTargetType.GetReturnType(), thunkParamTypes.ToArray(), thunkTargetType.IsFunctionVarArg)); using (var builder = new IRBuilder(moduleBuilder.Context)) { builder.PositionBuilderAtEnd(thunkKernel.AppendBasicBlock("entry")); var args = new List <LLVMValueRef>(thunkKernel.GetParams()); args.Insert(threadIdParamIndex, ComputeUniqueThreadId(builder, module)); var call = builder.CreateCall(kernelFunc, args.ToArray(), ""); if (call.TypeOf().TypeKind == LLVMTypeKind.LLVMVoidTypeKind) { builder.CreateRetVoid(); } else { builder.CreateRet(call); } } kernelFuncName = thunkKernelName; kernelFunc = thunkKernel; } // Mark the compiled kernel as a kernel symbol. LLVM.AddNamedMetadataOperand( module, "nvvm.annotations", LLVM.MDNode(new LLVMValueRef[] { kernelFunc, MDString("kernel"), LLVM.ConstInt(LLVM.Int32TypeInContext(LLVM.GetModuleContext(module)), 1, false) })); // LLVM.DumpModule(module); // Compile that LLVM IR down to PTX. LLVMTargetMachineRef machine; var ptx = CompileToPtx(module, context.GetDeviceComputeCapability(), out machine); // Console.WriteLine(System.Text.Encoding.UTF8.GetString(ptx)); // Load the PTX kernel. return(new CudaModule(assembly, moduleBuilder, machine, context.LoadModulePTX(ptx), kernelFuncName, context)); }