Update llvm-jit.cpp
authorEgor Bogatov <egorbo@gmail.com>
Fri, 16 Aug 2019 21:25:19 +0000 (00:25 +0300)
committerEgor Bogatov <egorbo@gmail.com>
Fri, 16 Aug 2019 21:25:19 +0000 (00:25 +0300)
Commit migrated from https://github.com/mono/mono/commit/6847508d2a0a161cfe11f7376d0d914d3d80c720

src/mono/mono/mini/llvm-jit.cpp

index 45e0e63..9702353 100644 (file)
@@ -24,6 +24,7 @@
 #include <llvm/Support/Host.h>
 #include <llvm/Support/TargetSelect.h>
 #include <llvm/IR/Mangler.h>
+#include "llvm/IR/LegacyPassNameParser.h"
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
@@ -31,6 +32,7 @@
 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Transforms/Scalar.h"
 
 #include <cstdlib>
 
@@ -237,13 +239,19 @@ init_mono_llvm_jit ()
 }
 
 static MonoLLVMJIT *
-make_mono_llvm_jit (TargetMachine *target_machine)
+make_mono_llvm_jit (TargetMachine *target_machine, LLVMModuleProviderRef mp)
 {
        return new MonoLLVMJIT{target_machine};
 }
 
 #elif LLVM_API_VERSION > 600
 
+// The OptimizationList is automatically populated with registered Passes by the
+// PassNameParser.
+//
+static cl::list<const PassInfo*, bool, PassNameParser>
+PassList(cl::desc("Optimizations available:"));
+
 class MonoLLVMJIT {
 public:
        /* We use our own trampoline infrastructure instead of the Orc one */
@@ -251,10 +259,62 @@ public:
        typedef IRCompileLayer<ObjLayerT, SimpleCompiler> CompileLayerT;
        typedef CompileLayerT::ModuleHandleT ModuleHandleT;
 
-       MonoLLVMJIT (TargetMachine *TM, MonoJitMemoryManager *mm)
+       MonoLLVMJIT (TargetMachine *TM, MonoJitMemoryManager *mm, LLVMModuleProviderRef mp)
                : TM(TM), ObjectLayer([=] { return std::shared_ptr<RuntimeDyld::MemoryManager> (mm); }),
                  CompileLayer (ObjectLayer, SimpleCompiler (*TM)),
-                 modules() {
+                 modules(),
+                 fpm (unwrap (mp)) {
+               initPassManager ();
+       }
+
+       void initPassManager () {
+               // Initialize passes (copied from https://github.com/mono/llvm/blob/release_60/tools/opt/opt.cpp#L379)
+               PassRegistry &registry = *PassRegistry::getPassRegistry();
+               initializeCore(registry);
+               //initializeCoroutines(registry);
+               initializeScalarOpts(registry);
+               //initializeObjCARCOpts(registry);
+               //initializeVectorization(registry);
+               //initializeIPO(registry);
+               initializeAnalysis(registry);
+               initializeTransformUtils(registry);
+               initializeInstCombine(registry);
+               //initializeInstrumentation(registry);
+               initializeTarget(registry);
+               //initializeExpandMemCmpPassPass(registry);
+               //initializeScalarizeMaskedMemIntrinPass(registry);
+               //initializeCodeGenPreparePass(registry);
+               //initializeAtomicExpandPass(registry);
+               //initializeRewriteSymbolsLegacyPassPass(registry);
+               //initializeWinEHPreparePass(registry);
+               //initializeDwarfEHPreparePass(registry);
+               //initializeSafeStackLegacyPassPass(registry);
+               //initializeSjLjEHPreparePass(registry);
+               //initializePreISelIntrinsicLoweringLegacyPassPass(registry);
+               //initializeGlobalMergePass(registry);
+               //initializeIndirectBrExpandPassPass(registry);
+               //initializeInterleavedAccessPass(registry);
+               //initializeEntryExitInstrumenterPass(registry);
+               //initializePostInlineEntryExitInstrumenterPass(registry);
+               //initializeUnreachableBlockElimLegacyPassPass(registry);
+               //initializeExpandReductionsPass(registry);
+               //initializeWriteBitcodePassPass(registry);
+
+               // FIXME: find optimal mono specific order of passes, see https://llvm.org/docs/Frontend/PerformanceTips.html#pass-ordering
+               const char *opts = "opt -simplifycfg -sroa -instcombine -early-cse-memssa -instcombine -gvn";
+               char **args = g_strsplit (opts, " ", -1);
+               llvm::cl::ParseCommandLineOptions (g_strv_length (args), args, "");
+
+               for (int i = 0; i < PassList.size(); i++) {
+                       Pass *pass = PassList[i]->getNormalCtor()();
+                       if (pass->getPassKind () == llvm::PT_Function || pass->getPassKind () == llvm::PT_Loop) {
+                               fpm.add (pass);
+                       } else {
+                               printf("Opt pass is not supported: %s\n", args[i + 1]);
+                       }
+               }
+               g_strfreev (args);
+               fpm.doInitialization();
        }
 
        ModuleHandleT addModule(Function *F, std::shared_ptr<Module> M) {
@@ -314,6 +374,7 @@ public:
 
        gpointer compile (Function *F, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame) {
                F->getParent ()->setDataLayout (TM->createDataLayout ());
+               fpm.run(*F);
                // Orc uses a shared_ptr to refer to modules so we have to save them ourselves to keep a ref
                std::shared_ptr<Module> m (F->getParent ());
                modules.push_back (m);
@@ -343,6 +404,7 @@ private:
        ObjLayerT ObjectLayer;
        CompileLayerT CompileLayer;
        std::vector<std::shared_ptr<Module>> modules;
+       legacy::FunctionPassManager fpm;
 };
 
 static MonoJitMemoryManager *mono_mm;
@@ -354,9 +416,9 @@ init_mono_llvm_jit ()
 }
 
 static MonoLLVMJIT *
-make_mono_llvm_jit (TargetMachine *target_machine)
+make_mono_llvm_jit (TargetMachine *target_machine, LLVMModuleProviderRef mp)
 {
-       return new MonoLLVMJIT(target_machine, mono_mm);
+       return new MonoLLVMJIT(target_machine, mono_mm, mp);
 }
 
 #endif
@@ -386,7 +448,7 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
        assert (TM);
 
        init_mono_llvm_jit ();
-       jit = make_mono_llvm_jit (TM);
+       jit = make_mono_llvm_jit (TM, MP);
 
        return NULL;
 }