Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / llvm-jit.cpp
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
11 //
12
13 #include "config.h"
14
15 #include <llvm-c/Core.h>
16 #include <llvm-c/ExecutionEngine.h>
17
18 #include "mini-llvm-cpp.h"
19 #include "llvm-jit.h"
20
21 #if !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION > 100
22
23 /*
24  * LLVM 3.9 uses the OrcJIT APIs
25  */
26
27 #include <llvm/Support/raw_ostream.h>
28 #include <llvm/Support/Host.h>
29 #include <llvm/Support/TargetSelect.h>
30 #include <llvm/IR/Mangler.h>
31 #include <llvm/ExecutionEngine/ExecutionEngine.h>
32 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
33 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
34 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
35 #if LLVM_API_VERSION >= 500
36 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
37 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
38 #include "llvm/ExecutionEngine/JITSymbol.h"
39 #else
40 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
41 #endif
42
43 #include <cstdlib>
44
45 extern "C" {
46 #include <mono/utils/mono-dl.h>
47 }
48
49 using namespace llvm;
50 using namespace llvm::orc;
51
52 extern cl::opt<bool> EnableMonoEH;
53 extern cl::opt<std::string> MonoEHFrameSymbol;
54
55 void
56 mono_llvm_set_unhandled_exception_handler (void)
57 {
58 }
59
60 template <typename T>
61 static std::vector<T> singletonSet(T t) {
62   std::vector<T> Vec;
63   Vec.push_back(std::move(t));
64   return Vec;
65 }
66
67 #ifdef __MINGW32__
68
69 #include <stddef.h>
70 extern void *memset(void *, int, size_t);
71 void bzero (void *to, size_t count) { memset (to, 0, count); }
72
73 #endif
74
75 static AllocCodeMemoryCb *alloc_code_mem_cb;
76
77 class MonoJitMemoryManager : public RTDyldMemoryManager
78 {
79 public:
80         ~MonoJitMemoryManager() override;
81
82         uint8_t *allocateDataSection(uintptr_t Size,
83                                                                  unsigned Alignment,
84                                                                  unsigned SectionID,
85                                                                  StringRef SectionName,
86                                                                  bool IsReadOnly) override;
87
88         uint8_t *allocateCodeSection(uintptr_t Size,
89                                                                  unsigned Alignment,
90                                                                  unsigned SectionID,
91                                                                  StringRef SectionName) override;
92
93         bool finalizeMemory(std::string *ErrMsg = nullptr) override;
94 };
95
96 MonoJitMemoryManager::~MonoJitMemoryManager()
97 {
98 }
99
100 uint8_t *
101 MonoJitMemoryManager::allocateDataSection(uintptr_t Size,
102                                                                                   unsigned Alignment,
103                                                                                   unsigned SectionID,
104                                                                                   StringRef SectionName,
105                                                                                   bool IsReadOnly) {
106         uint8_t *res = (uint8_t*)malloc (Size);
107         assert (res);
108         memset (res, 0, Size);
109         return res;
110 }
111
112 uint8_t *
113 MonoJitMemoryManager::allocateCodeSection(uintptr_t Size,
114                                                                                   unsigned Alignment,
115                                                                                   unsigned SectionID,
116                                                                                   StringRef SectionName)
117 {
118         return alloc_code_mem_cb (NULL, Size);
119 }
120
121 bool
122 MonoJitMemoryManager::finalizeMemory(std::string *ErrMsg)
123 {
124         return false;
125 }
126
127 class MonoLLVMJIT {
128 public:
129         /* We use our own trampoline infrastructure instead of the Orc one */
130 #if LLVM_API_VERSION >= 500
131         typedef RTDyldObjectLinkingLayer ObjLayerT;
132         typedef IRCompileLayer<ObjLayerT, SimpleCompiler> CompileLayerT;
133         typedef CompileLayerT::ModuleHandleT ModuleHandleT;
134 #else
135         typedef ObjectLinkingLayer<> ObjLayerT;
136         typedef IRCompileLayer<ObjLayerT> CompileLayerT;
137         typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
138 #endif
139
140         MonoLLVMJIT (TargetMachine *TM, MonoJitMemoryManager *mm)
141 #if LLVM_API_VERSION >= 500
142                 : TM(TM), ObjectLayer([=] { return std::shared_ptr<RuntimeDyld::MemoryManager> (mm); }),
143 #else
144                 : TM(TM),
145 #endif
146                   CompileLayer (ObjectLayer, SimpleCompiler (*TM)),
147                   modules() {
148         }
149
150 #if LLVM_API_VERSION >= 500
151         ModuleHandleT addModule(Function *F, std::shared_ptr<Module> M) {
152 #else
153         ModuleHandleT addModule(Function *F, Module *M) {
154 #endif
155                 auto Resolver = createLambdaResolver(
156                       [&](const std::string &Name) {
157                                                   const char *name = Name.c_str ();
158 #if LLVM_API_VERSION >= 500
159                                                   JITSymbolFlags flags = JITSymbolFlags ();
160 #else
161                                                   JITSymbolFlags flags = (JITSymbolFlags)0;
162 #endif
163                                                   if (!strcmp (name, "___bzero")) {
164 #if LLVM_API_VERSION >= 500
165                                                           return JITSymbol((uint64_t)(gssize)(void*)bzero, flags);
166 #else
167                                                           return RuntimeDyld::SymbolInfo((uint64_t)(gssize)(void*)bzero, flags);
168 #endif
169                                                   }
170
171                                                   MonoDl *current;
172                                                   char *err;
173                                                   void *symbol;
174                                                   current = mono_dl_open (NULL, 0, NULL);
175                                                   g_assert (current);
176                                                   if (name [0] == '_')
177                                                           err = mono_dl_symbol (current, name + 1, &symbol);
178                                                   else
179                                                           err = mono_dl_symbol (current, name, &symbol);
180                                                   mono_dl_close (current);
181                                                   if (!symbol)
182                                                           outs () << "R: " << Name << "\n";
183                                                   assert (symbol);
184 #if LLVM_API_VERSION >= 500
185                                                   return JITSymbol((uint64_t)(gssize)symbol, flags);
186 #else
187                                                   return RuntimeDyld::SymbolInfo((uint64_t)(gssize)symbol, flags);
188 #endif
189                       },
190                       [](const std::string &S) {
191                                                   outs () << "R2: " << S << "\n";
192                                                   assert (0);
193                                                   return nullptr;
194                                           } );
195
196 #if LLVM_API_VERSION >= 500
197                 ModuleHandleT m = CompileLayer.addModule(M,
198                                                                                                  std::move(Resolver));
199                 return m;
200 #else
201                 return CompileLayer.addModuleSet(singletonSet(M),
202                                                                                   make_unique<MonoJitMemoryManager>(),
203                                                                                   std::move(Resolver));
204 #endif
205         }
206
207         std::string mangle(const std::string &Name) {
208                 std::string MangledName;
209                 {
210                         raw_string_ostream MangledNameStream(MangledName);
211                         Mangler::getNameWithPrefix(MangledNameStream, Name,
212                                                                            TM->createDataLayout());
213                 }
214                 return MangledName;
215         }
216
217         std::string mangle(const GlobalValue *GV) {
218                 std::string MangledName;
219                 {
220                         Mangler Mang;
221
222                         raw_string_ostream MangledNameStream(MangledName);
223                         Mang.getNameWithPrefix(MangledNameStream, GV, false);
224                 }
225                 return MangledName;
226         }
227
228         gpointer compile (Function *F, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame) {
229                 F->getParent ()->setDataLayout (TM->createDataLayout ());
230 #if LLVM_API_VERSION >= 500
231                 // Orc uses a shared_ptr to refer to modules so we have to save them ourselves to keep a ref
232                 std::shared_ptr<Module> m (F->getParent ());
233                 modules.push_back (m);
234                 auto ModuleHandle = addModule (F, m);
235 #else
236                 auto ModuleHandle = addModule (F, F->getParent ());
237 #endif
238                 auto BodySym = CompileLayer.findSymbolIn(ModuleHandle, mangle (F), false);
239                 auto BodyAddr = BodySym.getAddress();
240                 assert (BodyAddr);
241
242                 for (int i = 0; i < nvars; ++i) {
243                         GlobalVariable *var = unwrap<GlobalVariable>(callee_vars [i]);
244
245                         auto sym = CompileLayer.findSymbolIn (ModuleHandle, mangle (var->getName ()), true);
246                         auto addr = sym.getAddress ();
247                         g_assert (addr);
248                         callee_addrs [i] = (gpointer)addr;
249                 }
250
251                 auto ehsym = CompileLayer.findSymbolIn(ModuleHandle, "mono_eh_frame", false);
252                 auto ehaddr = ehsym.getAddress ();
253                 g_assert (ehaddr);
254                 *eh_frame = (gpointer)ehaddr;
255
256                 return (gpointer)BodyAddr;
257         }
258
259 private:
260         TargetMachine *TM;
261         ObjLayerT ObjectLayer;
262         CompileLayerT CompileLayer;
263         std::vector<std::shared_ptr<Module>> modules;
264 };
265
266 static MonoLLVMJIT *jit;
267 static MonoJitMemoryManager *mono_mm;
268
269 MonoEERef
270 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
271 {
272         alloc_code_mem_cb = alloc_cb;
273
274         InitializeNativeTarget ();
275         InitializeNativeTargetAsmPrinter();
276
277         EnableMonoEH = true;
278         MonoEHFrameSymbol = "mono_eh_frame";
279
280         EngineBuilder EB;
281 #if defined(TARGET_AMD64) || defined(TARGET_X86)
282         std::vector<std::string> attrs;
283         // FIXME: Autodetect this
284         attrs.push_back("sse3");
285         attrs.push_back("sse4.1");
286         EB.setMAttrs (attrs);
287 #endif
288         auto TM = EB.selectTarget ();
289         assert (TM);
290
291         mono_mm = new MonoJitMemoryManager ();
292         jit = new MonoLLVMJIT (TM, mono_mm);
293
294         return NULL;
295 }
296
297 /*
298  * mono_llvm_compile_method:
299  *
300  *   Compile METHOD to native code. Compute the addresses of the variables in CALLEE_VARS and store them into
301  * CALLEE_ADDRS. Return the EH frame address in EH_FRAME.
302  */
303 gpointer
304 mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
305 {
306         return jit->compile (unwrap<Function> (method), nvars, callee_vars, callee_addrs, eh_frame);
307 }
308
309 void
310 mono_llvm_dispose_ee (MonoEERef *eeref)
311 {
312 }
313
314 void
315 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
316                                          void* Addr)
317 {
318         g_assert_not_reached ();
319 }
320
321 void*
322 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
323 {
324         g_assert_not_reached ();
325         return NULL;
326 }
327
328 #elif !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION < 100
329
330 #include <stdint.h>
331
332 #include <llvm/Support/raw_ostream.h>
333 #include <llvm/Support/Host.h>
334 #include <llvm/PassManager.h>
335 #include <llvm/ExecutionEngine/ExecutionEngine.h>
336 #include <llvm/ExecutionEngine/JITMemoryManager.h>
337 #include <llvm/ExecutionEngine/JITEventListener.h>
338 #include <llvm/Target/TargetOptions.h>
339 #include <llvm/Target/TargetRegisterInfo.h>
340 #include <llvm/IR/Verifier.h>
341 #include <llvm/Analysis/Passes.h>
342 #include <llvm/Transforms/Scalar.h>
343 #include <llvm/Support/CommandLine.h>
344 #include <llvm/IR/LegacyPassNameParser.h>
345 #include <llvm/Support/PrettyStackTrace.h>
346 #include <llvm/CodeGen/Passes.h>
347 #include <llvm/CodeGen/MachineFunctionPass.h>
348 #include <llvm/CodeGen/MachineFunction.h>
349 #include <llvm/CodeGen/MachineFrameInfo.h>
350 #include <llvm/IR/Function.h>
351 #include <llvm/IR/IRBuilder.h>
352 #include <llvm/IR/Module.h>
353
354 using namespace llvm;
355
356 static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;
357
358 void
359 mono_llvm_set_unhandled_exception_handler (void)
360 {
361         std::set_terminate (unhandled_exception);
362 }
363
364 class MonoJITMemoryManager : public JITMemoryManager
365 {
366 private:
367         JITMemoryManager *mm;
368
369 public:
370         /* Callbacks installed by mono */
371         AllocCodeMemoryCb *alloc_cb;
372         DlSymCb *dlsym_cb;
373         ExceptionTableCb *exception_cb;
374
375         MonoJITMemoryManager ();
376         ~MonoJITMemoryManager ();
377
378         void setMemoryWritable (void);
379
380         void setMemoryExecutable (void);
381
382         void AllocateGOT();
383
384     unsigned char *getGOTBase() const {
385                 return mm->getGOTBase ();
386     }
387
388         void setPoisonMemory(bool) {
389         }
390
391         unsigned char *startFunctionBody(const Function *F, 
392                                                                          uintptr_t &ActualSize);
393   
394         unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
395                                                                  unsigned Alignment);
396   
397         void endFunctionBody(const Function *F, unsigned char *FunctionStart,
398                                                  unsigned char *FunctionEnd);
399
400         unsigned char *allocateSpace(intptr_t Size, unsigned Alignment);
401
402         uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
403   
404         void deallocateMemForFunction(const Function *F);
405   
406         unsigned char*startExceptionTable(const Function* F,
407                                                                           uintptr_t &ActualSize);
408   
409         void endExceptionTable(const Function *F, unsigned char *TableStart,
410                                                    unsigned char *TableEnd, 
411                                                    unsigned char* FrameRegister);
412
413         virtual void deallocateFunctionBody(void*) {
414         }
415
416         virtual void deallocateExceptionTable(void*) {
417         }
418
419         virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
420                                                                                  StringRef SectionName) {
421                 // FIXME:
422                 assert(0);
423                 return NULL;
424         }
425
426         virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
427                                                                                  StringRef SectionName, bool IsReadOnly) {
428                 // FIXME:
429                 assert(0);
430                 return NULL;
431         }
432
433         virtual bool applyPermissions(std::string*) {
434                 // FIXME:
435                 assert(0);
436                 return false;
437         }
438
439         virtual bool finalizeMemory(std::string *ErrMsg = 0) {
440                 // FIXME:
441                 assert(0);
442                 return false;
443         }
444
445         virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
446                 void *res;
447                 char *err;
448
449                 err = dlsym_cb (Name.c_str (), &res);
450                 if (err) {
451                         outs () << "Unable to resolve: " << Name << ": " << err << "\n";
452                         assert(0);
453                         return NULL;
454                 }
455                 return res;
456         }
457 };
458
459 MonoJITMemoryManager::MonoJITMemoryManager ()
460 {
461         mm = JITMemoryManager::CreateDefaultMemManager ();
462 }
463
464 MonoJITMemoryManager::~MonoJITMemoryManager ()
465 {
466         delete mm;
467 }
468
469 void
470 MonoJITMemoryManager::setMemoryWritable (void)
471 {
472 }
473
474 void
475 MonoJITMemoryManager::setMemoryExecutable (void)
476 {
477 }
478
479 void
480 MonoJITMemoryManager::AllocateGOT()
481 {
482         mm->AllocateGOT ();
483 }
484
485 unsigned char *
486 MonoJITMemoryManager::startFunctionBody(const Function *F, 
487                                         uintptr_t &ActualSize)
488 {
489         // FIXME: This leaks memory
490         if (ActualSize == 0)
491                 ActualSize = 128;
492         return alloc_cb (wrap (F), ActualSize);
493 }
494   
495 unsigned char *
496 MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
497                            unsigned Alignment)
498 {
499         return alloc_cb (wrap (F), StubSize);
500 }
501   
502 void
503 MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart,
504                                   unsigned char *FunctionEnd)
505 {
506 }
507
508 unsigned char *
509 MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
510 {
511         return new unsigned char [Size];
512 }
513
514 uint8_t *
515 MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
516 {
517         return new unsigned char [Size];
518 }
519
520 void
521 MonoJITMemoryManager::deallocateMemForFunction(const Function *F)
522 {
523 }
524   
525 unsigned char*
526 MonoJITMemoryManager::startExceptionTable(const Function* F,
527                                           uintptr_t &ActualSize)
528 {
529         return startFunctionBody(F, ActualSize);
530 }
531   
532 void
533 MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart,
534                                         unsigned char *TableEnd, 
535                                         unsigned char* FrameRegister)
536 {
537         exception_cb (FrameRegister);
538 }
539
540 class MonoJITEventListener : public JITEventListener {
541
542 public:
543         FunctionEmittedCb *emitted_cb;
544
545         MonoJITEventListener (FunctionEmittedCb *cb) {
546                 emitted_cb = cb;
547         }
548
549         virtual void NotifyFunctionEmitted(const Function &F,
550                                                                            void *Code, size_t Size,
551                                                                            const EmittedFunctionDetails &Details) {
552                 emitted_cb (wrap (&F), Code, (char*)Code + Size);
553         }
554 };
555
556 class MonoEE {
557 public:
558         ExecutionEngine *EE;
559         MonoJITMemoryManager *mm;
560         MonoJITEventListener *listener;
561         FunctionPassManager *fpm;
562 };
563
564 void
565 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
566 {
567         MonoEE *mono_ee = (MonoEE*)eeref;
568
569         /*
570          * The verifier does some checks on the whole module, leading to quadratic behavior.
571          */
572         //verifyFunction (*(unwrap<Function> (method)));
573         mono_ee->fpm->run (*unwrap<Function> (method));
574 }
575
576 static cl::list<const PassInfo*, bool, PassNameParser>
577 PassList(cl::desc("Optimizations available:"));
578
579 static void
580 force_pass_linking (void)
581 {
582         // Make sure the rest is linked in, but never executed
583         char *foo = g_getenv ("FOO");
584         gboolean ret = (foo != (char*)-1);
585         g_free (foo);
586
587         if (ret) 
588                 return;
589
590         // This is a subset of the passes in LinkAllPasses.h
591         // The utility passes and the interprocedural passes are commented out
592
593       (void) llvm::createAAEvalPass();
594       (void) llvm::createAggressiveDCEPass();
595       (void) llvm::createAliasAnalysisCounterPass();
596       (void) llvm::createAliasDebugger();
597           /*
598       (void) llvm::createArgumentPromotionPass();
599       (void) llvm::createStructRetPromotionPass();
600           */
601       (void) llvm::createBasicAliasAnalysisPass();
602       (void) llvm::createLibCallAliasAnalysisPass(0);
603       (void) llvm::createScalarEvolutionAliasAnalysisPass();
604       //(void) llvm::createBlockPlacementPass();
605       (void) llvm::createBreakCriticalEdgesPass();
606       (void) llvm::createCFGSimplificationPass();
607           /*
608       (void) llvm::createConstantMergePass();
609       (void) llvm::createConstantPropagationPass();
610           */
611           /*
612       (void) llvm::createDeadArgEliminationPass();
613           */
614       (void) llvm::createDeadCodeEliminationPass();
615       (void) llvm::createDeadInstEliminationPass();
616       (void) llvm::createDeadStoreEliminationPass();
617           /*
618       (void) llvm::createDeadTypeEliminationPass();
619       (void) llvm::createDomOnlyPrinterPass();
620       (void) llvm::createDomPrinterPass();
621       (void) llvm::createDomOnlyViewerPass();
622       (void) llvm::createDomViewerPass();
623       (void) llvm::createEdgeProfilerPass();
624       (void) llvm::createOptimalEdgeProfilerPass();
625       (void) llvm::createFunctionInliningPass();
626       (void) llvm::createAlwaysInlinerPass();
627       (void) llvm::createGlobalDCEPass();
628       (void) llvm::createGlobalOptimizerPass();
629       (void) llvm::createGlobalsModRefPass();
630       (void) llvm::createIPConstantPropagationPass();
631       (void) llvm::createIPSCCPPass();
632           */
633       (void) llvm::createIndVarSimplifyPass();
634       (void) llvm::createInstructionCombiningPass();
635           /*
636       (void) llvm::createInternalizePass(false);
637           */
638       (void) llvm::createLCSSAPass();
639       (void) llvm::createLICMPass();
640       (void) llvm::createLazyValueInfoPass();
641       //(void) llvm::createLoopDependenceAnalysisPass();
642           /*
643       (void) llvm::createLoopExtractorPass();
644           */
645       (void) llvm::createLoopSimplifyPass();
646       (void) llvm::createLoopStrengthReducePass();
647       (void) llvm::createLoopUnrollPass();
648       (void) llvm::createLoopUnswitchPass();
649       (void) llvm::createLoopRotatePass();
650       (void) llvm::createLowerInvokePass();
651           /*
652       (void) llvm::createLowerSetJmpPass();
653           */
654       (void) llvm::createLowerSwitchPass();
655       (void) llvm::createNoAAPass();
656           /*
657       (void) llvm::createNoProfileInfoPass();
658       (void) llvm::createProfileEstimatorPass();
659       (void) llvm::createProfileVerifierPass();
660       (void) llvm::createProfileLoaderPass();
661           */
662       (void) llvm::createPromoteMemoryToRegisterPass();
663       (void) llvm::createDemoteRegisterToMemoryPass();
664           /*
665       (void) llvm::createPruneEHPass();
666       (void) llvm::createPostDomOnlyPrinterPass();
667       (void) llvm::createPostDomPrinterPass();
668       (void) llvm::createPostDomOnlyViewerPass();
669       (void) llvm::createPostDomViewerPass();
670           */
671       (void) llvm::createReassociatePass();
672       (void) llvm::createSCCPPass();
673       (void) llvm::createScalarReplAggregatesPass();
674       //(void) llvm::createSimplifyLibCallsPass();
675           /*
676       (void) llvm::createSingleLoopExtractorPass();
677       (void) llvm::createStripSymbolsPass();
678       (void) llvm::createStripNonDebugSymbolsPass();
679       (void) llvm::createStripDeadDebugInfoPass();
680       (void) llvm::createStripDeadPrototypesPass();
681       (void) llvm::createTailCallEliminationPass();
682       (void) llvm::createTailDuplicationPass();
683       (void) llvm::createJumpThreadingPass();
684           */
685           /*
686       (void) llvm::createUnifyFunctionExitNodesPass();
687           */
688       (void) llvm::createInstCountPass();
689       (void) llvm::createCodeGenPreparePass();
690       (void) llvm::createGVNPass();
691       (void) llvm::createMemCpyOptPass();
692       (void) llvm::createLoopDeletionPass();
693           /*
694       (void) llvm::createPostDomTree();
695       (void) llvm::createPostDomFrontier();
696       (void) llvm::createInstructionNamerPass();
697       (void) llvm::createPartialSpecializationPass();
698       (void) llvm::createFunctionAttrsPass();
699       (void) llvm::createMergeFunctionsPass();
700       (void) llvm::createPrintModulePass(0);
701       (void) llvm::createPrintFunctionPass("", 0);
702       (void) llvm::createDbgInfoPrinterPass();
703       (void) llvm::createModuleDebugInfoPrinterPass();
704       (void) llvm::createPartialInliningPass();
705       (void) llvm::createGEPSplitterPass();
706       (void) llvm::createLintPass();
707           */
708       (void) llvm::createSinkingPass();
709 }
710
711 static gboolean inited;
712
713 static void
714 init_llvm (void)
715 {
716         if (inited)
717                 return;
718
719   force_pass_linking ();
720
721 #ifdef TARGET_ARM
722   LLVMInitializeARMTarget ();
723   LLVMInitializeARMTargetInfo ();
724   LLVMInitializeARMTargetMC ();
725 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
726   LLVMInitializeX86Target ();
727   LLVMInitializeX86TargetInfo ();
728   LLVMInitializeX86TargetMC ();
729 #elif defined(TARGET_POWERPC)
730   LLVMInitializePowerPCTarget ();
731   LLVMInitializePowerPCTargetInfo ();
732   LLVMInitializePowerPCTargetMC ();
733 #else
734   #error Unsupported mono-llvm target
735 #endif
736
737   PassRegistry &Registry = *PassRegistry::getPassRegistry();
738   initializeCore(Registry);
739   initializeScalarOpts(Registry);
740   initializeAnalysis(Registry);
741   initializeIPA(Registry);
742   initializeTransformUtils(Registry);
743   initializeInstCombine(Registry);
744   initializeTarget(Registry);
745
746   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
747
748   inited = true;
749 }
750
751 MonoEERef
752 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
753 {
754   std::string Error;
755   MonoEE *mono_ee;
756
757   init_llvm ();
758
759   mono_ee = new MonoEE ();
760
761   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
762   mono_mm->alloc_cb = alloc_cb;
763   mono_mm->dlsym_cb = dlsym_cb;
764   mono_mm->exception_cb = exception_cb;
765   mono_ee->mm = mono_mm;
766
767   /*
768    * The Default code model doesn't seem to work on amd64,
769    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
770    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
771    */
772
773   TargetOptions opts;
774   opts.JITExceptionHandling = 1;
775
776   StringRef cpu_name = sys::getHostCPUName ();
777
778   // EngineBuilder no longer has a copy assignment operator (?)
779   std::unique_ptr<Module> Owner(unwrap(MP));
780   EngineBuilder b (std::move(Owner));
781   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
782
783   g_assert (EE);
784   mono_ee->EE = EE;
785
786   MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
787   EE->RegisterJITEventListener (listener);
788   mono_ee->listener = listener;
789
790   FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
791   mono_ee->fpm = fpm;
792
793   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
794
795   if (PassList.size() > 0) {
796           /* Use the passes specified by the env variable */
797           /* Only the passes in force_pass_linking () can be used */
798           for (unsigned i = 0; i < PassList.size(); ++i) {
799                   const PassInfo *PassInf = PassList[i];
800                   Pass *P = 0;
801
802                   if (PassInf->getNormalCtor())
803                           P = PassInf->getNormalCtor()();
804                   fpm->add (P);
805           }
806   } else {
807           /* Use the same passes used by 'opt' by default, without the ipo passes */
808           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";
809           char **args;
810           int i;
811
812           args = g_strsplit (opts, " ", 1000);
813           for (i = 0; args [i]; i++)
814                   ;
815           llvm::cl::ParseCommandLineOptions (i, args, "");
816           g_strfreev (args);
817
818           for (unsigned i = 0; i < PassList.size(); ++i) {
819                   const PassInfo *PassInf = PassList[i];
820                   Pass *P = 0;
821
822                   if (PassInf->getNormalCtor())
823                           P = PassInf->getNormalCtor()();
824                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
825                   fpm->add (P);
826           }
827
828           /*
829           fpm->add(createInstructionCombiningPass());
830           fpm->add(createReassociatePass());
831           fpm->add(createGVNPass());
832           fpm->add(createCFGSimplificationPass());
833           */
834   }
835
836   *ee = wrap (EE);
837
838   return mono_ee;
839 }
840
841 void
842 mono_llvm_dispose_ee (MonoEERef *eeref)
843 {
844         MonoEE *mono_ee = (MonoEE*)eeref;
845
846         delete mono_ee->EE;
847         delete mono_ee->fpm;
848         //delete mono_ee->mm;
849         delete mono_ee->listener;
850         delete mono_ee;
851 }
852
853 #else /* MONO_CROSS_COMPILE */
854
855 void
856 mono_llvm_set_unhandled_exception_handler (void)
857 {
858 }
859
860 MonoEERef
861 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
862 {
863         g_assert_not_reached ();
864         return NULL;
865 }
866
867 void
868 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
869 {
870         g_assert_not_reached ();
871 }
872
873 gpointer
874 mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
875 {
876         g_assert_not_reached ();
877         return NULL;
878 }
879
880 void
881 mono_llvm_dispose_ee (MonoEERef *eeref)
882 {
883         g_assert_not_reached ();
884 }
885
886 /* Not linked in */
887 void
888 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
889                                          void* Addr)
890 {
891         g_assert_not_reached ();
892 }
893
894 void*
895 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
896 {
897         g_assert_not_reached ();
898         return NULL;
899 }
900
901 #endif /* !MONO_CROSS_COMPILE */