Beispiel #1
0
 public unsafe static void AddTargetLibraryInfo(TargetLibraryInfoRef TLI, PassManagerRef PM) {
   LLVMPINVOKE.AddTargetLibraryInfo(TLI.Value, PM.Value);
 }
Beispiel #2
0
 public unsafe static void AddScopedNoAliasAAPass(PassManagerRef PM) {
   LLVMPINVOKE.AddScopedNoAliasAAPass(PM.Value);
 }
Beispiel #3
0
 public unsafe static void AddSLPVectorizePass(PassManagerRef PM) {
   LLVMPINVOKE.AddSLPVectorizePass(PM.Value);
 }
Beispiel #4
0
 public unsafe static void AddVerifierPass(PassManagerRef PM) {
   LLVMPINVOKE.AddVerifierPass(PM.Value);
 }
Beispiel #5
0
 public unsafe static void AddEarlyCSEPass(PassManagerRef PM) {
   LLVMPINVOKE.AddEarlyCSEPass(PM.Value);
 }
Beispiel #6
0
 public unsafe static void AddScalarReplAggregatesPassWithThreshold(PassManagerRef PM, int Threshold) {
   LLVMPINVOKE.AddScalarReplAggregatesPassWithThreshold(PM.Value, Threshold);
 }
Beispiel #7
0
 public unsafe static void AddTailCallEliminationPass(PassManagerRef PM) {
   LLVMPINVOKE.AddTailCallEliminationPass(PM.Value);
 }
Beispiel #8
0
 public unsafe static void AddMergedLoadStoreMotionPass(PassManagerRef PM) {
   LLVMPINVOKE.AddMergedLoadStoreMotionPass(PM.Value);
 }
Beispiel #9
0
 public unsafe static void AddIndVarSimplifyPass(PassManagerRef PM) {
   LLVMPINVOKE.AddIndVarSimplifyPass(PM.Value);
 }
Beispiel #10
0
 public unsafe static void AddDeadStoreEliminationPass(PassManagerRef PM) {
   LLVMPINVOKE.AddDeadStoreEliminationPass(PM.Value);
 }
Beispiel #11
0
 public unsafe static void AddScalarizerPass(PassManagerRef PM) {
   LLVMPINVOKE.AddScalarizerPass(PM.Value);
 }
Beispiel #12
0
 public unsafe static void AddCFGSimplificationPass(PassManagerRef PM) {
   LLVMPINVOKE.AddCFGSimplificationPass(PM.Value);
 }
Beispiel #13
0
 public unsafe static void AddAlignmentFromAssumptionsPass(PassManagerRef PM) {
   LLVMPINVOKE.AddAlignmentFromAssumptionsPass(PM.Value);
 }
Beispiel #14
0
 public unsafe static void AddAggressiveDCEPass(PassManagerRef PM) {
   LLVMPINVOKE.AddAggressiveDCEPass(PM.Value);
 }
Beispiel #15
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);
        }
Beispiel #16
0
 public unsafe static void AddInstructionCombiningPass(PassManagerRef PM) {
   LLVMPINVOKE.AddInstructionCombiningPass(PM.Value);
 }
Beispiel #17
0
 public unsafe static void AddScalarReplAggregatesPassSSA(PassManagerRef PM) {
   LLVMPINVOKE.AddScalarReplAggregatesPassSSA(PM.Value);
 }
Beispiel #18
0
 public unsafe static void AddJumpThreadingPass(PassManagerRef PM) {
   LLVMPINVOKE.AddJumpThreadingPass(PM.Value);
 }
Beispiel #19
0
 public unsafe static void AddSimplifyLibCallsPass(PassManagerRef PM) {
   LLVMPINVOKE.AddSimplifyLibCallsPass(PM.Value);
 }
Beispiel #20
0
 public unsafe static void AddLoopDeletionPass(PassManagerRef PM) {
   LLVMPINVOKE.AddLoopDeletionPass(PM.Value);
 }
Beispiel #21
0
 public unsafe static void AddDemoteMemoryToRegisterPass(PassManagerRef PM) {
   LLVMPINVOKE.AddDemoteMemoryToRegisterPass(PM.Value);
 }
Beispiel #22
0
 public unsafe static void AddLoopUnrollPass(PassManagerRef PM) {
   LLVMPINVOKE.AddLoopUnrollPass(PM.Value);
 }
Beispiel #23
0
 public unsafe static void AddCorrelatedValuePropagationPass(PassManagerRef PM) {
   LLVMPINVOKE.AddCorrelatedValuePropagationPass(PM.Value);
 }
Beispiel #24
0
 public unsafe static void AddMemCpyOptPass(PassManagerRef PM) {
   LLVMPINVOKE.AddMemCpyOptPass(PM.Value);
 }
Beispiel #25
0
 public unsafe static void AddLowerExpectIntrinsicPass(PassManagerRef PM) {
   LLVMPINVOKE.AddLowerExpectIntrinsicPass(PM.Value);
 }
Beispiel #26
0
 public unsafe static void AddPartiallyInlineLibCallsPass(PassManagerRef PM) {
   LLVMPINVOKE.AddPartiallyInlineLibCallsPass(PM.Value);
 }
Beispiel #27
0
 public unsafe static void AddBasicAliasAnalysisPass(PassManagerRef PM) {
   LLVMPINVOKE.AddBasicAliasAnalysisPass(PM.Value);
 }
Beispiel #28
0
 public unsafe static void AddLowerSwitchPass(PassManagerRef PM) {
   LLVMPINVOKE.AddLowerSwitchPass(PM.Value);
 }
Beispiel #29
0
 public unsafe static void AddTargetData(TargetDataRef TD, PassManagerRef PM) {
   LLVMPINVOKE.AddTargetData(TD.Value, PM.Value);
 }
Beispiel #30
0
 public unsafe static void AddReassociatePass(PassManagerRef PM) {
   LLVMPINVOKE.AddReassociatePass(PM.Value);
 }
Beispiel #31
0
 public unsafe static void AddAnalysisPasses(TargetMachineRef T, PassManagerRef PM) {
   LLVMPINVOKE.AddAnalysisPasses(T.Value, PM.Value);
 }
Beispiel #32
0
        public void TestFact()
        {
            ModuleRef Module = LLVM.ModuleCreateWithName("fac_module");

            TypeRef[] fac_args = { LLVM.Int32Type() };
            ValueRef  fac      = LLVM.AddFunction(Module, "fac", LLVM.FunctionType(LLVM.Int32Type(), fac_args, false));

            LLVM.SetFunctionCallConv(fac, (uint)Swigged.LLVM.CallConv.CCallConv);
            ValueRef n = LLVM.GetParam(fac, 0);

            BasicBlockRef entry   = LLVM.AppendBasicBlock(fac, "entry");
            BasicBlockRef iftrue  = LLVM.AppendBasicBlock(fac, "iftrue");
            BasicBlockRef iffalse = LLVM.AppendBasicBlock(fac, "iffalse");
            BasicBlockRef end     = LLVM.AppendBasicBlock(fac, "end");
            BuilderRef    builder = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder, entry);
            ValueRef If = LLVM.BuildICmp(builder, Swigged.LLVM.IntPredicate.IntEQ, n, LLVM.ConstInt(LLVM.Int32Type(), 0, false), "n == 0");

            LLVM.BuildCondBr(builder, If, iftrue, iffalse);

            LLVM.PositionBuilderAtEnd(builder, iftrue);
            ValueRef res_iftrue = LLVM.ConstInt(LLVM.Int32Type(), 1, false);

            LLVM.BuildBr(builder, end);

            LLVM.PositionBuilderAtEnd(builder, iffalse);
            ValueRef n_minus = LLVM.BuildSub(builder, n, LLVM.ConstInt(LLVM.Int32Type(), 1, false), "n - 1");

            ValueRef[] call_fac_args = { n_minus };
            ValueRef   call_fac      = LLVM.BuildCall(builder, fac, call_fac_args, "fac(n - 1)");
            ValueRef   res_iffalse   = LLVM.BuildMul(builder, n, call_fac, "n * fac(n - 1)");

            LLVM.BuildBr(builder, end);

            LLVM.PositionBuilderAtEnd(builder, end);
            ValueRef res = LLVM.BuildPhi(builder, LLVM.Int32Type(), "result");

            ValueRef[]      phi_vals   = { res_iftrue, res_iffalse };
            BasicBlockRef[] phi_blocks = { iftrue, iffalse };
            LLVM.AddIncoming(res, phi_vals, phi_blocks);
            LLVM.BuildRet(builder, res);

            MyString error = new MyString();

            LLVM.VerifyModule(Module, VerifierFailureAction.PrintMessageAction, error);
            if (error.ToString() != "")
            {
                throw new Exception("Failed");
            }

            ExecutionEngineRef engine;
            ModuleProviderRef  provider = LLVM.CreateModuleProviderForExistingModule(Module);

            LLVM.CreateJITCompilerForModule(out engine, Module, 0, error);

            PassManagerRef pass = LLVM.CreatePassManager();

            // LLVM.AddTargetData(LLVM.GetExecutionEngineTargetData(engine), pass);
            LLVM.AddConstantPropagationPass(pass);
            LLVM.AddInstructionCombiningPass(pass);
            LLVM.AddPromoteMemoryToRegisterPass(pass);
            // LLVMAddDemoteMemoryToRegisterPass(pass); // Demotes every possible value to memory
            LLVM.AddGVNPass(pass);
            LLVM.AddCFGSimplificationPass(pass);
            LLVM.RunPassManager(pass, Module);
            LLVM.DumpModule(Module);

            ulong input = 10;

            for (ulong i = 0; i < input; ++i)
            {
                GenericValueRef exec_args                 = LLVM.CreateGenericValueOfInt(LLVM.Int32Type(), input, false);
                GenericValueRef exec_res                  = LLVM.RunFunction(engine, fac, 1, out exec_args);
                var             result_of_function        = LLVM.GenericValueToInt(exec_res, false);
                var             result_of_csharp_function = Factorial(input);
                if (result_of_csharp_function != result_of_function)
                {
                    throw new Exception("Results not the same.");
                }
            }

            LLVM.DisposePassManager(pass);
            LLVM.DisposeBuilder(builder);
            LLVM.DisposeExecutionEngine(engine);
        }