[ci] Bump timeout in ms-test-suite
[mono-project.git] / mono / mini / llvm-jit.cpp
blob2011fddafaf2b67bb34877c797008a9705e0fc4e
1 //
2 // jit-llvm.cpp: Support code for using LLVM as a JIT backend
3 //
4 // (C) 2009-2011 Novell, Inc.
5 // Copyright 2011-2015 Xamarin, Inc (http://www.xamarin.com)
6 //
7 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
8 //
9 // Mono's internal header files are not C++ clean, so avoid including them if
10 // possible
13 #include "config.h"
15 #include <llvm-c/Core.h>
16 #include <llvm-c/ExecutionEngine.h>
18 #include "mini-llvm-cpp.h"
19 #include "llvm-jit.h"
21 #if !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION > 100
24 * LLVM 3.9 uses the OrcJIT APIs
27 #include <llvm/Support/raw_ostream.h>
28 #include <llvm/Support/Host.h>
29 #include <llvm/Support/TargetSelect.h>
30 #include <llvm/ExecutionEngine/ExecutionEngine.h>
31 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
32 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
33 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
34 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
35 #include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
37 #include <cstdlib>
39 extern "C" {
40 #include <mono/utils/mono-dl.h>
43 using namespace llvm;
44 using namespace llvm::orc;
46 extern cl::opt<bool> EnableMonoEH;
47 extern cl::opt<std::string> MonoEHFrameSymbol;
49 void
50 mono_llvm_set_unhandled_exception_handler (void)
54 template <typename T>
55 static std::vector<T> singletonSet(T t) {
56 std::vector<T> Vec;
57 Vec.push_back(std::move(t));
58 return Vec;
61 #ifdef __MINGW32__
63 #include <stddef.h>
64 extern void *memset(void *, int, size_t);
65 void bzero (void *to, size_t count) { memset (to, 0, count); }
67 #endif
69 static AllocCodeMemoryCb *alloc_code_mem_cb;
71 class MonoJitMemoryManager : public RTDyldMemoryManager
73 public:
74 ~MonoJitMemoryManager() override;
76 uint8_t *allocateDataSection(uintptr_t Size,
77 unsigned Alignment,
78 unsigned SectionID,
79 StringRef SectionName,
80 bool IsReadOnly) override;
82 uint8_t *allocateCodeSection(uintptr_t Size,
83 unsigned Alignment,
84 unsigned SectionID,
85 StringRef SectionName) override;
87 bool finalizeMemory(std::string *ErrMsg = nullptr) override;
90 MonoJitMemoryManager::~MonoJitMemoryManager()
94 uint8_t *
95 MonoJitMemoryManager::allocateDataSection(uintptr_t Size,
96 unsigned Alignment,
97 unsigned SectionID,
98 StringRef SectionName,
99 bool IsReadOnly) {
100 uint8_t *res = (uint8_t*)malloc (Size);
101 assert (res);
102 memset (res, 0, Size);
103 return res;
106 uint8_t *
107 MonoJitMemoryManager::allocateCodeSection(uintptr_t Size,
108 unsigned Alignment,
109 unsigned SectionID,
110 StringRef SectionName)
112 return alloc_code_mem_cb (NULL, Size);
115 bool
116 MonoJitMemoryManager::finalizeMemory(std::string *ErrMsg)
118 return false;
121 class MonoLLVMJIT {
122 public:
123 /* We use our own trampoline infrastructure instead of the Orc one */
124 typedef ObjectLinkingLayer<> ObjLayerT;
125 typedef IRCompileLayer<ObjLayerT> CompileLayerT;
126 typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
128 MonoLLVMJIT (TargetMachine *TM)
129 : TM(TM),
130 CompileLayer (ObjectLayer, SimpleCompiler (*TM)) {
133 ModuleHandleT addModule(Module *M) {
134 auto Resolver = createLambdaResolver(
135 [&](const std::string &Name) {
136 const char *name = Name.c_str ();
137 if (!strcmp (name, "___bzero"))
138 return RuntimeDyld::SymbolInfo((uint64_t)(gssize)(void*)bzero, (JITSymbolFlags)0);
140 MonoDl *current;
141 char *err;
142 void *symbol;
143 current = mono_dl_open (NULL, 0, NULL);
144 g_assert (current);
145 if (name [0] == '_')
146 err = mono_dl_symbol (current, name + 1, &symbol);
147 else
148 err = mono_dl_symbol (current, name, &symbol);
149 mono_dl_close (current);
150 if (!symbol)
151 outs () << "R: " << Name << "\n";
152 assert (symbol);
153 return RuntimeDyld::SymbolInfo((uint64_t)(gssize)symbol, (JITSymbolFlags)0);
155 [](const std::string &S) {
156 outs () << "R2: " << S << "\n";
157 assert (0);
158 return nullptr;
159 } );
161 return CompileLayer.addModuleSet(singletonSet(M),
162 make_unique<MonoJitMemoryManager>(),
163 std::move(Resolver));
166 std::string mangle(const std::string &Name) {
167 std::string MangledName;
169 raw_string_ostream MangledNameStream(MangledName);
170 Mangler::getNameWithPrefix(MangledNameStream, Name,
171 TM->createDataLayout());
173 return MangledName;
176 std::string mangle(const GlobalValue *GV) {
177 std::string MangledName;
179 Mangler Mang;
181 raw_string_ostream MangledNameStream(MangledName);
182 Mang.getNameWithPrefix(MangledNameStream, GV, false);
184 return MangledName;
187 gpointer compile (Function *F, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame) {
188 F->getParent ()->setDataLayout (TM->createDataLayout ());
189 auto ModuleHandle = addModule (F->getParent ());
191 auto BodySym = CompileLayer.findSymbolIn(ModuleHandle, mangle (F), false);
192 auto BodyAddr = BodySym.getAddress();
193 assert (BodyAddr);
195 for (int i = 0; i < nvars; ++i) {
196 GlobalVariable *var = unwrap<GlobalVariable>(callee_vars [i]);
198 auto sym = CompileLayer.findSymbolIn (ModuleHandle, mangle (var->getName ()), true);
199 auto addr = sym.getAddress ();
200 g_assert (addr);
201 callee_addrs [i] = (gpointer)addr;
204 auto ehsym = CompileLayer.findSymbolIn(ModuleHandle, "mono_eh_frame", false);
205 auto ehaddr = ehsym.getAddress ();
206 g_assert (ehaddr);
207 *eh_frame = (gpointer)ehaddr;
209 return (gpointer)BodyAddr;
212 private:
213 TargetMachine *TM;
214 ObjLayerT ObjectLayer;
215 CompileLayerT CompileLayer;
218 static MonoLLVMJIT *jit;
220 MonoEERef
221 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
223 alloc_code_mem_cb = alloc_cb;
225 InitializeNativeTarget ();
226 InitializeNativeTargetAsmPrinter();
228 EnableMonoEH = true;
229 MonoEHFrameSymbol = "mono_eh_frame";
231 EngineBuilder EB;
232 #if defined(TARGET_AMD64) || defined(TARGET_X86)
233 std::vector<std::string> attrs;
234 // FIXME: Autodetect this
235 attrs.push_back("sse3");
236 attrs.push_back("sse4.1");
237 EB.setMAttrs (attrs);
238 #endif
239 auto TM = EB.selectTarget ();
240 assert (TM);
242 jit = new MonoLLVMJIT (TM);
244 return NULL;
248 * mono_llvm_compile_method:
250 * Compile METHOD to native code. Compute the addresses of the variables in CALLEE_VARS and store them into
251 * CALLEE_ADDRS. Return the EH frame address in EH_FRAME.
253 gpointer
254 mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
256 return jit->compile (unwrap<Function> (method), nvars, callee_vars, callee_addrs, eh_frame);
259 void
260 mono_llvm_dispose_ee (MonoEERef *eeref)
264 void
265 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
266 void* Addr)
268 g_assert_not_reached ();
271 void*
272 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
274 g_assert_not_reached ();
275 return NULL;
278 #elif !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION < 100
280 #include <stdint.h>
282 #include <llvm/Support/raw_ostream.h>
283 #include <llvm/Support/Host.h>
284 #include <llvm/PassManager.h>
285 #include <llvm/ExecutionEngine/ExecutionEngine.h>
286 #include <llvm/ExecutionEngine/JITMemoryManager.h>
287 #include <llvm/ExecutionEngine/JITEventListener.h>
288 #include <llvm/Target/TargetOptions.h>
289 #include <llvm/Target/TargetRegisterInfo.h>
290 #include <llvm/IR/Verifier.h>
291 #include <llvm/Analysis/Passes.h>
292 #include <llvm/Transforms/Scalar.h>
293 #include <llvm/Support/CommandLine.h>
294 #include <llvm/IR/LegacyPassNameParser.h>
295 #include <llvm/Support/PrettyStackTrace.h>
296 #include <llvm/CodeGen/Passes.h>
297 #include <llvm/CodeGen/MachineFunctionPass.h>
298 #include <llvm/CodeGen/MachineFunction.h>
299 #include <llvm/CodeGen/MachineFrameInfo.h>
300 #include <llvm/IR/Function.h>
301 #include <llvm/IR/IRBuilder.h>
302 #include <llvm/IR/Module.h>
304 using namespace llvm;
306 static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;
308 void
309 mono_llvm_set_unhandled_exception_handler (void)
311 std::set_terminate (unhandled_exception);
314 class MonoJITMemoryManager : public JITMemoryManager
316 private:
317 JITMemoryManager *mm;
319 public:
320 /* Callbacks installed by mono */
321 AllocCodeMemoryCb *alloc_cb;
322 DlSymCb *dlsym_cb;
323 ExceptionTableCb *exception_cb;
325 MonoJITMemoryManager ();
326 ~MonoJITMemoryManager ();
328 void setMemoryWritable (void);
330 void setMemoryExecutable (void);
332 void AllocateGOT();
334 unsigned char *getGOTBase() const {
335 return mm->getGOTBase ();
338 void setPoisonMemory(bool) {
341 unsigned char *startFunctionBody(const Function *F,
342 uintptr_t &ActualSize);
344 unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
345 unsigned Alignment);
347 void endFunctionBody(const Function *F, unsigned char *FunctionStart,
348 unsigned char *FunctionEnd);
350 unsigned char *allocateSpace(intptr_t Size, unsigned Alignment);
352 uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
354 void deallocateMemForFunction(const Function *F);
356 unsigned char*startExceptionTable(const Function* F,
357 uintptr_t &ActualSize);
359 void endExceptionTable(const Function *F, unsigned char *TableStart,
360 unsigned char *TableEnd,
361 unsigned char* FrameRegister);
363 virtual void deallocateFunctionBody(void*) {
366 virtual void deallocateExceptionTable(void*) {
369 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
370 StringRef SectionName) {
371 // FIXME:
372 assert(0);
373 return NULL;
376 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
377 StringRef SectionName, bool IsReadOnly) {
378 // FIXME:
379 assert(0);
380 return NULL;
383 virtual bool applyPermissions(std::string*) {
384 // FIXME:
385 assert(0);
386 return false;
389 virtual bool finalizeMemory(std::string *ErrMsg = 0) {
390 // FIXME:
391 assert(0);
392 return false;
395 virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
396 void *res;
397 char *err;
399 err = dlsym_cb (Name.c_str (), &res);
400 if (err) {
401 outs () << "Unable to resolve: " << Name << ": " << err << "\n";
402 assert(0);
403 return NULL;
405 return res;
409 MonoJITMemoryManager::MonoJITMemoryManager ()
411 mm = JITMemoryManager::CreateDefaultMemManager ();
414 MonoJITMemoryManager::~MonoJITMemoryManager ()
416 delete mm;
419 void
420 MonoJITMemoryManager::setMemoryWritable (void)
424 void
425 MonoJITMemoryManager::setMemoryExecutable (void)
429 void
430 MonoJITMemoryManager::AllocateGOT()
432 mm->AllocateGOT ();
435 unsigned char *
436 MonoJITMemoryManager::startFunctionBody(const Function *F,
437 uintptr_t &ActualSize)
439 // FIXME: This leaks memory
440 if (ActualSize == 0)
441 ActualSize = 128;
442 return alloc_cb (wrap (F), ActualSize);
445 unsigned char *
446 MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
447 unsigned Alignment)
449 return alloc_cb (wrap (F), StubSize);
452 void
453 MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart,
454 unsigned char *FunctionEnd)
458 unsigned char *
459 MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
461 return new unsigned char [Size];
464 uint8_t *
465 MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
467 return new unsigned char [Size];
470 void
471 MonoJITMemoryManager::deallocateMemForFunction(const Function *F)
475 unsigned char*
476 MonoJITMemoryManager::startExceptionTable(const Function* F,
477 uintptr_t &ActualSize)
479 return startFunctionBody(F, ActualSize);
482 void
483 MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart,
484 unsigned char *TableEnd,
485 unsigned char* FrameRegister)
487 exception_cb (FrameRegister);
490 class MonoJITEventListener : public JITEventListener {
492 public:
493 FunctionEmittedCb *emitted_cb;
495 MonoJITEventListener (FunctionEmittedCb *cb) {
496 emitted_cb = cb;
499 virtual void NotifyFunctionEmitted(const Function &F,
500 void *Code, size_t Size,
501 const EmittedFunctionDetails &Details) {
502 emitted_cb (wrap (&F), Code, (char*)Code + Size);
506 class MonoEE {
507 public:
508 ExecutionEngine *EE;
509 MonoJITMemoryManager *mm;
510 MonoJITEventListener *listener;
511 FunctionPassManager *fpm;
514 void
515 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
517 MonoEE *mono_ee = (MonoEE*)eeref;
520 * The verifier does some checks on the whole module, leading to quadratic behavior.
522 //verifyFunction (*(unwrap<Function> (method)));
523 mono_ee->fpm->run (*unwrap<Function> (method));
526 static cl::list<const PassInfo*, bool, PassNameParser>
527 PassList(cl::desc("Optimizations available:"));
529 static void
530 force_pass_linking (void)
532 // Make sure the rest is linked in, but never executed
533 if (g_getenv ("FOO") != (char*)-1)
534 return;
536 // This is a subset of the passes in LinkAllPasses.h
537 // The utility passes and the interprocedural passes are commented out
539 (void) llvm::createAAEvalPass();
540 (void) llvm::createAggressiveDCEPass();
541 (void) llvm::createAliasAnalysisCounterPass();
542 (void) llvm::createAliasDebugger();
544 (void) llvm::createArgumentPromotionPass();
545 (void) llvm::createStructRetPromotionPass();
547 (void) llvm::createBasicAliasAnalysisPass();
548 (void) llvm::createLibCallAliasAnalysisPass(0);
549 (void) llvm::createScalarEvolutionAliasAnalysisPass();
550 //(void) llvm::createBlockPlacementPass();
551 (void) llvm::createBreakCriticalEdgesPass();
552 (void) llvm::createCFGSimplificationPass();
554 (void) llvm::createConstantMergePass();
555 (void) llvm::createConstantPropagationPass();
558 (void) llvm::createDeadArgEliminationPass();
560 (void) llvm::createDeadCodeEliminationPass();
561 (void) llvm::createDeadInstEliminationPass();
562 (void) llvm::createDeadStoreEliminationPass();
564 (void) llvm::createDeadTypeEliminationPass();
565 (void) llvm::createDomOnlyPrinterPass();
566 (void) llvm::createDomPrinterPass();
567 (void) llvm::createDomOnlyViewerPass();
568 (void) llvm::createDomViewerPass();
569 (void) llvm::createEdgeProfilerPass();
570 (void) llvm::createOptimalEdgeProfilerPass();
571 (void) llvm::createFunctionInliningPass();
572 (void) llvm::createAlwaysInlinerPass();
573 (void) llvm::createGlobalDCEPass();
574 (void) llvm::createGlobalOptimizerPass();
575 (void) llvm::createGlobalsModRefPass();
576 (void) llvm::createIPConstantPropagationPass();
577 (void) llvm::createIPSCCPPass();
579 (void) llvm::createIndVarSimplifyPass();
580 (void) llvm::createInstructionCombiningPass();
582 (void) llvm::createInternalizePass(false);
584 (void) llvm::createLCSSAPass();
585 (void) llvm::createLICMPass();
586 (void) llvm::createLazyValueInfoPass();
587 //(void) llvm::createLoopDependenceAnalysisPass();
589 (void) llvm::createLoopExtractorPass();
591 (void) llvm::createLoopSimplifyPass();
592 (void) llvm::createLoopStrengthReducePass();
593 (void) llvm::createLoopUnrollPass();
594 (void) llvm::createLoopUnswitchPass();
595 (void) llvm::createLoopRotatePass();
596 (void) llvm::createLowerInvokePass();
598 (void) llvm::createLowerSetJmpPass();
600 (void) llvm::createLowerSwitchPass();
601 (void) llvm::createNoAAPass();
603 (void) llvm::createNoProfileInfoPass();
604 (void) llvm::createProfileEstimatorPass();
605 (void) llvm::createProfileVerifierPass();
606 (void) llvm::createProfileLoaderPass();
608 (void) llvm::createPromoteMemoryToRegisterPass();
609 (void) llvm::createDemoteRegisterToMemoryPass();
611 (void) llvm::createPruneEHPass();
612 (void) llvm::createPostDomOnlyPrinterPass();
613 (void) llvm::createPostDomPrinterPass();
614 (void) llvm::createPostDomOnlyViewerPass();
615 (void) llvm::createPostDomViewerPass();
617 (void) llvm::createReassociatePass();
618 (void) llvm::createSCCPPass();
619 (void) llvm::createScalarReplAggregatesPass();
620 //(void) llvm::createSimplifyLibCallsPass();
622 (void) llvm::createSingleLoopExtractorPass();
623 (void) llvm::createStripSymbolsPass();
624 (void) llvm::createStripNonDebugSymbolsPass();
625 (void) llvm::createStripDeadDebugInfoPass();
626 (void) llvm::createStripDeadPrototypesPass();
627 (void) llvm::createTailCallEliminationPass();
628 (void) llvm::createTailDuplicationPass();
629 (void) llvm::createJumpThreadingPass();
632 (void) llvm::createUnifyFunctionExitNodesPass();
634 (void) llvm::createInstCountPass();
635 (void) llvm::createCodeGenPreparePass();
636 (void) llvm::createGVNPass();
637 (void) llvm::createMemCpyOptPass();
638 (void) llvm::createLoopDeletionPass();
640 (void) llvm::createPostDomTree();
641 (void) llvm::createPostDomFrontier();
642 (void) llvm::createInstructionNamerPass();
643 (void) llvm::createPartialSpecializationPass();
644 (void) llvm::createFunctionAttrsPass();
645 (void) llvm::createMergeFunctionsPass();
646 (void) llvm::createPrintModulePass(0);
647 (void) llvm::createPrintFunctionPass("", 0);
648 (void) llvm::createDbgInfoPrinterPass();
649 (void) llvm::createModuleDebugInfoPrinterPass();
650 (void) llvm::createPartialInliningPass();
651 (void) llvm::createGEPSplitterPass();
652 (void) llvm::createLintPass();
654 (void) llvm::createSinkingPass();
657 static gboolean inited;
659 static void
660 init_llvm (void)
662 if (inited)
663 return;
665 force_pass_linking ();
667 #ifdef TARGET_ARM
668 LLVMInitializeARMTarget ();
669 LLVMInitializeARMTargetInfo ();
670 LLVMInitializeARMTargetMC ();
671 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
672 LLVMInitializeX86Target ();
673 LLVMInitializeX86TargetInfo ();
674 LLVMInitializeX86TargetMC ();
675 #elif defined(TARGET_POWERPC)
676 LLVMInitializePowerPCTarget ();
677 LLVMInitializePowerPCTargetInfo ();
678 LLVMInitializePowerPCTargetMC ();
679 #else
680 #error Unsupported mono-llvm target
681 #endif
683 PassRegistry &Registry = *PassRegistry::getPassRegistry();
684 initializeCore(Registry);
685 initializeScalarOpts(Registry);
686 initializeAnalysis(Registry);
687 initializeIPA(Registry);
688 initializeTransformUtils(Registry);
689 initializeInstCombine(Registry);
690 initializeTarget(Registry);
692 llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
694 inited = true;
697 MonoEERef
698 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
700 std::string Error;
701 MonoEE *mono_ee;
703 init_llvm ();
705 mono_ee = new MonoEE ();
707 MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
708 mono_mm->alloc_cb = alloc_cb;
709 mono_mm->dlsym_cb = dlsym_cb;
710 mono_mm->exception_cb = exception_cb;
711 mono_ee->mm = mono_mm;
714 * The Default code model doesn't seem to work on amd64,
715 * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
716 * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
719 TargetOptions opts;
720 opts.JITExceptionHandling = 1;
722 StringRef cpu_name = sys::getHostCPUName ();
724 // EngineBuilder no longer has a copy assignment operator (?)
725 std::unique_ptr<Module> Owner(unwrap(MP));
726 EngineBuilder b (std::move(Owner));
727 ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
729 g_assert (EE);
730 mono_ee->EE = EE;
732 MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
733 EE->RegisterJITEventListener (listener);
734 mono_ee->listener = listener;
736 FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
737 mono_ee->fpm = fpm;
739 fpm->add(new DataLayoutPass(*EE->getDataLayout()));
741 if (PassList.size() > 0) {
742 /* Use the passes specified by the env variable */
743 /* Only the passes in force_pass_linking () can be used */
744 for (unsigned i = 0; i < PassList.size(); ++i) {
745 const PassInfo *PassInf = PassList[i];
746 Pass *P = 0;
748 if (PassInf->getNormalCtor())
749 P = PassInf->getNormalCtor()();
750 fpm->add (P);
752 } else {
753 /* Use the same passes used by 'opt' by default, without the ipo passes */
754 const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg";
755 char **args;
756 int i;
758 args = g_strsplit (opts, " ", 1000);
759 for (i = 0; args [i]; i++)
761 llvm::cl::ParseCommandLineOptions (i, args, "");
762 g_strfreev (args);
764 for (unsigned i = 0; i < PassList.size(); ++i) {
765 const PassInfo *PassInf = PassList[i];
766 Pass *P = 0;
768 if (PassInf->getNormalCtor())
769 P = PassInf->getNormalCtor()();
770 g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
771 fpm->add (P);
775 fpm->add(createInstructionCombiningPass());
776 fpm->add(createReassociatePass());
777 fpm->add(createGVNPass());
778 fpm->add(createCFGSimplificationPass());
782 *ee = wrap (EE);
784 return mono_ee;
787 void
788 mono_llvm_dispose_ee (MonoEERef *eeref)
790 MonoEE *mono_ee = (MonoEE*)eeref;
792 delete mono_ee->EE;
793 delete mono_ee->fpm;
794 //delete mono_ee->mm;
795 delete mono_ee->listener;
796 delete mono_ee;
799 #else /* MONO_CROSS_COMPILE */
801 void
802 mono_llvm_set_unhandled_exception_handler (void)
806 MonoEERef
807 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
809 g_assert_not_reached ();
810 return NULL;
813 void
814 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
816 g_assert_not_reached ();
819 gpointer
820 mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
822 g_assert_not_reached ();
823 return NULL;
826 void
827 mono_llvm_dispose_ee (MonoEERef *eeref)
829 g_assert_not_reached ();
832 /* Not linked in */
833 void
834 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
835 void* Addr)
837 g_assert_not_reached ();
840 void*
841 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
843 g_assert_not_reached ();
844 return NULL;
847 #endif /* !MONO_CROSS_COMPILE */