Example #1
0
        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);
        }
Example #2
0
 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;
 }
Example #3
0
 public unsafe static void AddAnalysisPasses(TargetMachineRef T, PassManagerRef PM) {
   LLVMPINVOKE.AddAnalysisPasses(T.Value, PM.Value);
 }
Example #4
0
 public unsafe static void SetTargetMachineAsmVerbosity(TargetMachineRef T, bool VerboseAsm) {
   LLVMPINVOKE.SetTargetMachineAsmVerbosity(T.Value, VerboseAsm);
 }
Example #5
0
 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;
 }
Example #6
0
 public unsafe static string GetTargetMachineFeatureString(TargetMachineRef T) {
   string ret = LLVMPINVOKE.GetTargetMachineFeatureString(T.Value);
   return ret;
 }
Example #7
0
 public unsafe static TargetDataRef GetTargetMachineData(TargetMachineRef T) {
   TargetDataRef ret = new TargetDataRef(LLVMPINVOKE.GetTargetMachineData(T.Value));
   return ret;
 }
Example #8
0
 public unsafe static void DisposeTargetMachine(TargetMachineRef T) {
   LLVMPINVOKE.DisposeTargetMachine(T.Value);
 }
Example #9
0
 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;
 }
Example #10
0
        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();
            }
        }
Example #11
0
        /// <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);
        }
Example #12
0
        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);
        }