public void TestORC() { LLVM.InitializeAllTargets(); LLVM.InitializeAllTargetMCs(); LLVM.InitializeAllTargetInfos(); LLVM.InitializeAllAsmPrinters(); // See http://www.doof.me.uk/2017/05/11/using-orc-with-llvms-c-api/ ModuleRef mod = LLVM.ModuleCreateWithName("LLVMSharpIntro"); TypeRef[] param_types = { LLVM.Int32Type(), LLVM.Int32Type() }; TypeRef ret_type = LLVM.FunctionType(LLVM.Int32Type(), 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); ValueRef tmp = LLVM.BuildAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp"); LLVM.BuildRet(builder, tmp); MyString the_error = new MyString(); LLVM.VerifyModule(mod, VerifierFailureAction.AbortProcessAction, the_error); //LLVM.DisposeMessage(error); TargetRef t2; string tr2 = LLVM.GetDefaultTargetTriple(); var b = LLVM.GetTargetFromTriple(tr2, out t2, the_error); string triple = ""; string cpu = ""; string features = ""; TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, tr2, cpu, features, CodeGenOptLevel.CodeGenLevelDefault, RelocMode.RelocDefault, CodeModel.CodeModelDefault); OrcJITStackRef ojsr = LLVM.OrcCreateInstance(tmr); MyString ms = new MyString(); LLVM.OrcGetMangledSymbol(ojsr, ms, "sum"); IntPtr ctx = IntPtr.Zero; SharedModuleRef smr = LLVM.OrcMakeSharedModule(mod); OrcErrorCode xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh, smr, null, ctx); OrcErrorCode p = LLVM.OrcGetSymbolAddress(ojsr, out IntPtr RetAddr, "sum"); Add addMethod = (Add)Marshal.GetDelegateForFunctionPointer(RetAddr, typeof(Add)); int result = addMethod(10, 10); Console.WriteLine("Result of sum is: " + result); if (result != 20) { throw new Exception("Failed."); } LLVM.DumpModule(mod); LLVM.DisposeBuilder(builder); }
public unsafe static bool TargetMachineEmitToMemoryBuffer(TargetMachineRef T, ModuleRef M, CodeGenFileType codegen, out string ErrorMessage, out MemoryBufferRef OutMemBuf) { bool ret = LLVMPINVOKE.TargetMachineEmitToMemoryBuffer(T.Value, M.Value, (int)codegen, out ErrorMessage, out OutMemBuf.Value); return ret; }
public unsafe static void AddAnalysisPasses(TargetMachineRef T, PassManagerRef PM) { LLVMPINVOKE.AddAnalysisPasses(T.Value, PM.Value); }
public unsafe static void SetTargetMachineAsmVerbosity(TargetMachineRef T, bool VerboseAsm) { LLVMPINVOKE.SetTargetMachineAsmVerbosity(T.Value, VerboseAsm); }
public unsafe static bool TargetMachineEmitToFile(TargetMachineRef T, ModuleRef M, string Filename, CodeGenFileType codegen, out string ErrorMessage) { bool ret = LLVMPINVOKE.TargetMachineEmitToFile(T.Value, M.Value, Filename, (int)codegen, out ErrorMessage); return ret; }
public unsafe static string GetTargetMachineFeatureString(TargetMachineRef T) { string ret = LLVMPINVOKE.GetTargetMachineFeatureString(T.Value); return ret; }
public unsafe static TargetDataRef GetTargetMachineData(TargetMachineRef T) { TargetDataRef ret = new TargetDataRef(LLVMPINVOKE.GetTargetMachineData(T.Value)); return ret; }
public unsafe static void DisposeTargetMachine(TargetMachineRef T) { LLVMPINVOKE.DisposeTargetMachine(T.Value); }
public unsafe static TargetMachineRef CreateTargetMachine(TargetRef T, string Triple, string CPU, string Features, CodeGenOptLevel Level, RelocMode Reloc, CodeModel CodeModel) { TargetMachineRef ret = new TargetMachineRef(LLVMPINVOKE.CreateTargetMachine(T.Value, Triple, CPU, Features, (int)Level, (int)Reloc, (int)CodeModel)); return ret; }
public void TestMultiModules() { LLVM.InitializeAllTargets(); LLVM.InitializeAllTargetMCs(); LLVM.InitializeAllTargetInfos(); LLVM.InitializeAllAsmPrinters(); // First module contains add. ModuleRef mod1 = LLVM.ModuleCreateWithName("LLVMSharpIntro"); TypeRef[] param_types1 = { LLVM.Int32Type(), LLVM.Int32Type() }; TypeRef ret_type1 = LLVM.FunctionType(LLVM.Int32Type(), param_types1, false); ValueRef add = LLVM.AddFunction(mod1, "add", ret_type1); BasicBlockRef entry1 = LLVM.AppendBasicBlock(add, "entry"); BuilderRef builder1 = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder1, entry1); ValueRef tmp1 = LLVM.BuildAdd(builder1, LLVM.GetParam(add, 0), LLVM.GetParam(add, 1), "tmp"); LLVM.BuildRet(builder1, tmp1); MyString the_error = new MyString(); LLVM.VerifyModule(mod1, VerifierFailureAction.PrintMessageAction, the_error); LLVM.DumpModule(mod1); // Second module contains sub. ModuleRef mod2 = LLVM.ModuleCreateWithName("LLVMSharpIntro"); TypeRef[] param_types2 = { LLVM.Int32Type(), LLVM.Int32Type() }; TypeRef ret_type2 = LLVM.FunctionType(LLVM.Int32Type(), param_types2, false); ValueRef sub = LLVM.AddFunction(mod2, "sub", ret_type2); BasicBlockRef entry2 = LLVM.AppendBasicBlock(sub, "entry"); BuilderRef builder2 = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder2, entry2); ValueRef tmp2 = LLVM.BuildSub(builder2, LLVM.GetParam(sub, 0), LLVM.GetParam(sub, 1), "tmp"); LLVM.BuildRet(builder2, tmp2); LLVM.VerifyModule(mod2, VerifierFailureAction.PrintMessageAction, the_error); LLVM.DumpModule(mod2); // Third module contains uses of add and sub. ModuleRef mod3 = LLVM.ModuleCreateWithName("LLVMSharpIntro"); TypeRef[] param_types3 = { }; TypeRef ret_type3 = LLVM.FunctionType(LLVM.Int32Type(), param_types3, false); ValueRef comb = LLVM.AddFunction(mod3, "comb", ret_type3); ValueRef add1 = LLVM.AddFunction(mod3, "add", ret_type1); ValueRef sub2 = LLVM.AddFunction(mod3, "sub", ret_type1); BasicBlockRef entry3 = LLVM.AppendBasicBlock(comb, "entry"); BuilderRef builder3 = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder3, entry3); ValueRef tmpa3 = LLVM.ConstInt(LLVM.Int32Type(), 1, false); ValueRef tmpb3 = LLVM.ConstInt(LLVM.Int32Type(), 2, false); ValueRef tmpc3 = LLVM.ConstInt(LLVM.Int32Type(), 3, false); var tmpd3 = LLVM.BuildCall(builder3, add1, new ValueRef[] { tmpa3, tmpc3 }, ""); var tmpe3 = LLVM.BuildCall(builder3, sub2, new ValueRef[] { tmpd3, tmpb3 }, ""); LLVM.BuildRet(builder3, tmpe3); LLVM.VerifyModule(mod3, VerifierFailureAction.PrintMessageAction, the_error); LLVM.DumpModule(mod3); //LLVM.DisposeMessage(error); TargetRef t2; string tr2 = LLVM.GetDefaultTargetTriple(); var b = LLVM.GetTargetFromTriple(tr2, out t2, the_error); string triple = ""; string cpu = ""; string features = ""; TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, tr2, cpu, features, CodeGenOptLevel.CodeGenLevelDefault, RelocMode.RelocDefault, CodeModel.CodeModelDefault); OrcJITStackRef ojsr = LLVM.OrcCreateInstance(tmr); MyString ms = new MyString(); LLVM.OrcGetMangledSymbol(ojsr, ms, "comb"); IntPtr ctx = IntPtr.Zero; SharedModuleRef smr1 = LLVM.OrcMakeSharedModule(mod1); var xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh1, smr1, null, ctx); SharedModuleRef smr2 = LLVM.OrcMakeSharedModule(mod2); xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh2, smr2, null, ctx); SharedModuleRef smr3 = LLVM.OrcMakeSharedModule(mod3); xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh3, smr3, null, ctx); var p = LLVM.OrcGetSymbolAddress(ojsr, out IntPtr RetAddr, "comb"); Comb combMethod = (Comb)Marshal.GetDelegateForFunctionPointer(RetAddr, typeof(Comb)); int result = combMethod(); Console.WriteLine("Result of comb is: " + result); if (result != 2) { throw new Exception(); } }
/// <summary> /// Compiles an IL assembly to LLVM bytecode. /// </summary> /// <param name="moduleName">The module name.</param> public void Compile(string moduleName) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // Create LLVM module and its context. LLVM.EnablePrettyStackTrace(); mModule = LLVM.ModuleCreateWithName(moduleName); mContext = LLVM.GetModuleContext(mModule); // Targets. LLVM.InitializeAllTargetInfos(); LLVM.InitializeAllTargets(); LLVM.InitializeAllTargetMCs(); LLVM.InitializeAllAsmParsers(); LLVM.InitializeAllAsmPrinters(); string triplet = (Options.Target == "default") ? LLVM.GetDefaultTargetTriple() : Options.Target; MyString error = new MyString(); LLVM.SetTarget(mModule, triplet); TargetRef target; if (LLVM.GetTargetFromTriple(triplet, out target, error)) { throw new InvalidOperationException(error.ToString()); } // Optimizer. mFunctionPassManager = LLVM.CreateFunctionPassManagerForModule(mModule); mPassManager = LLVM.CreatePassManager(); LLVM.InitializeFunctionPassManager(mFunctionPassManager); #if !DEBUG // O0 if (Options.Optimization >= OptimizationLevel.O0) { // Function passes. LLVM.AddPromoteMemoryToRegisterPass(mFunctionPassManager); LLVM.AddConstantPropagationPass(mFunctionPassManager); LLVM.AddReassociatePass(mFunctionPassManager); LLVM.AddInstructionCombiningPass(mFunctionPassManager); // Module passes. LLVM.AddAlwaysInlinerPass(mPassManager); LLVM.AddStripDeadPrototypesPass(mPassManager); LLVM.AddStripSymbolsPass(mPassManager); } // O1 if (Options.Optimization >= OptimizationLevel.O1) { // Function passes. LLVM.AddLowerExpectIntrinsicPass(mFunctionPassManager); LLVM.AddEarlyCSEPass(mFunctionPassManager); LLVM.AddLoopRotatePass(mFunctionPassManager); LLVM.AddLoopUnswitchPass(mFunctionPassManager); LLVM.AddLoopUnrollPass(mFunctionPassManager); LLVM.AddLoopDeletionPass(mFunctionPassManager); LLVM.AddTailCallEliminationPass(mFunctionPassManager); LLVM.AddGVNPass(mFunctionPassManager); LLVM.AddDeadStoreEliminationPass(mFunctionPassManager); LLVM.AddJumpThreadingPass(mFunctionPassManager); LLVM.AddCFGSimplificationPass(mFunctionPassManager); LLVM.AddMemCpyOptPass(mFunctionPassManager); // Module passes. LLVM.AddDeadArgEliminationPass(mPassManager); LLVM.AddAggressiveDCEPass(mFunctionPassManager); } // O2 if (Options.Optimization >= OptimizationLevel.O2) { // Function passes. LLVM.AddLoopVectorizePass(mFunctionPassManager); LLVM.AddSLPVectorizePass(mFunctionPassManager); // Module passes. LLVM.AddFunctionInliningPass(mPassManager); LLVM.AddConstantMergePass(mPassManager); LLVM.AddArgumentPromotionPass(mPassManager); } #endif // Initialize types and runtime. string dataLayout = LLVM.GetDataLayout(Module); TargetData = LLVM.CreateTargetData(dataLayout); TypeHelper.Init(TargetData, this); RuntimeHelper.ImportFunctions(Module); mBuiltinCompiler.Compile(); compileModules(); LLVM.RunPassManager(mPassManager, Module); // Log time. stopWatch.Stop(); Logger.LogDetail("Compilation time: " + stopWatch.Elapsed); // Debug: print LLVM assembly code. #if DEBUG Console.WriteLine(LLVM.PrintModuleToString(mModule)); #endif // Verify and throw exception on error. Console.ForegroundColor = ConsoleColor.DarkGray; if (LLVM.VerifyModule(mModule, VerifierFailureAction.ReturnStatusAction, error)) { Logger.LogError("Compilation of module failed."); Logger.LogInfo(error.ToString()); LLVM.DisposeTargetData(TargetData); return; } else { Logger.LogDetail("Compilation of module succeeded."); } // Output assembly or object file. if (!Options.OutputLLVMIR && !Options.OutputLLVMBitCode) { TargetMachineRef machine = LLVM.CreateTargetMachine(target, triplet, "generic", "", CodeGenOptLevel.CodeGenLevelDefault, RelocMode.RelocDefault, CodeModel.CodeModelDefault); LLVM.SetModuleDataLayout(mModule, LLVM.CreateTargetDataLayout(machine)); CodeGenFileType type = (Options.OutputAssembly) ? CodeGenFileType.AssemblyFile : CodeGenFileType.ObjectFile; if (LLVM.TargetMachineEmitToFile(machine, mModule, Options.OutputFile, type, error)) { throw new InvalidOperationException(error.ToString()); } } // Output LLVM IR code to a file. else if (Options.OutputLLVMIR) { if (LLVM.PrintModuleToFile(mModule, Options.OutputFile, error)) { Logger.LogError("Writing the LLVM code to a file failed."); Logger.LogInfo(error.ToString()); } } // Output LLVM bitcode. else if (Options.OutputLLVMBitCode) { if (LLVM.WriteBitcodeToFile(mModule, Options.OutputFile) != 0) { Logger.LogError("Writing the LLVM code to a file failed."); Logger.LogInfo(error.ToString()); } } // Cleanup. LLVM.DisposeTargetData(TargetData); }
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); }