Revert "[llvm] Add support for building with more recent versions of the mono llvm...
[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 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
36
37 #include <cstdlib>
38
39 extern "C" {
40 #include <mono/utils/mono-dl.h>
41 }
42
43 using namespace llvm;
44 using namespace llvm::orc;
45
46 extern cl::opt<bool> EnableMonoEH;
47 extern cl::opt<std::string> MonoEHFrameSymbol;
48
49 void
50 mono_llvm_set_unhandled_exception_handler (void)
51 {
52 }
53
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;
59 }
60
61 #ifdef __MINGW32__
62
63 #include <stddef.h>
64 extern void *memset(void *, int, size_t);
65 void bzero (void *to, size_t count) { memset (to, 0, count); }
66
67 #endif
68
69 static AllocCodeMemoryCb *alloc_code_mem_cb;
70
71 class MonoJitMemoryManager : public RTDyldMemoryManager
72 {
73 public:
74         ~MonoJitMemoryManager() override;
75
76         uint8_t *allocateDataSection(uintptr_t Size,
77                                                                  unsigned Alignment,
78                                                                  unsigned SectionID,
79                                                                  StringRef SectionName,
80                                                                  bool IsReadOnly) override;
81
82         uint8_t *allocateCodeSection(uintptr_t Size,
83                                                                  unsigned Alignment,
84                                                                  unsigned SectionID,
85                                                                  StringRef SectionName) override;
86
87         bool finalizeMemory(std::string *ErrMsg = nullptr) override;
88 };
89
90 MonoJitMemoryManager::~MonoJitMemoryManager()
91 {
92 }
93
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;
104 }
105
106 uint8_t *
107 MonoJitMemoryManager::allocateCodeSection(uintptr_t Size,
108                                                                                   unsigned Alignment,
109                                                                                   unsigned SectionID,
110                                                                                   StringRef SectionName)
111 {
112         return alloc_code_mem_cb (NULL, Size);
113 }
114
115 bool
116 MonoJitMemoryManager::finalizeMemory(std::string *ErrMsg)
117 {
118         return false;
119 }
120
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;
127
128         MonoLLVMJIT (TargetMachine *TM)
129                 : TM(TM),
130                   CompileLayer (ObjectLayer, SimpleCompiler (*TM)) {
131         }
132
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);
139
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);
154                       },
155                       [](const std::string &S) {
156                                                   outs () << "R2: " << S << "\n";
157                                                   assert (0);
158                                                   return nullptr;
159                                           } );
160
161                 return CompileLayer.addModuleSet(singletonSet(M),
162                                                                                   make_unique<MonoJitMemoryManager>(),
163                                                                                   std::move(Resolver));
164         }
165
166         std::string mangle(const std::string &Name) {
167                 std::string MangledName;
168                 {
169                         raw_string_ostream MangledNameStream(MangledName);
170                         Mangler::getNameWithPrefix(MangledNameStream, Name,
171                                                                            TM->createDataLayout());
172                 }
173                 return MangledName;
174         }
175
176         std::string mangle(const GlobalValue *GV) {
177                 std::string MangledName;
178                 {
179                         Mangler Mang;
180
181                         raw_string_ostream MangledNameStream(MangledName);
182                         Mang.getNameWithPrefix(MangledNameStream, GV, false);
183                 }
184                 return MangledName;
185         }
186
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 ());
190
191                 auto BodySym = CompileLayer.findSymbolIn(ModuleHandle, mangle (F), false);
192                 auto BodyAddr = BodySym.getAddress();
193                 assert (BodyAddr);
194
195                 for (int i = 0; i < nvars; ++i) {
196                         GlobalVariable *var = unwrap<GlobalVariable>(callee_vars [i]);
197
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;
202                 }
203
204                 auto ehsym = CompileLayer.findSymbolIn(ModuleHandle, "mono_eh_frame", false);
205                 auto ehaddr = ehsym.getAddress ();
206                 g_assert (ehaddr);
207                 *eh_frame = (gpointer)ehaddr;
208
209                 return (gpointer)BodyAddr;
210         }
211
212 private:
213         TargetMachine *TM;
214         ObjLayerT ObjectLayer;
215         CompileLayerT CompileLayer;
216 };
217
218 static MonoLLVMJIT *jit;
219
220 MonoEERef
221 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
222 {
223         alloc_code_mem_cb = alloc_cb;
224
225         InitializeNativeTarget ();
226         InitializeNativeTargetAsmPrinter();
227
228         EnableMonoEH = true;
229         MonoEHFrameSymbol = "mono_eh_frame";
230
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);
241
242         jit = new MonoLLVMJIT (TM);
243
244         return NULL;
245 }
246
247 /*
248  * mono_llvm_compile_method:
249  *
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.
252  */
253 gpointer
254 mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
255 {
256         return jit->compile (unwrap<Function> (method), nvars, callee_vars, callee_addrs, eh_frame);
257 }
258
259 void
260 mono_llvm_dispose_ee (MonoEERef *eeref)
261 {
262 }
263
264 void
265 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
266                                          void* Addr)
267 {
268         g_assert_not_reached ();
269 }
270
271 void*
272 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
273 {
274         g_assert_not_reached ();
275         return NULL;
276 }
277
278 #elif !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION < 100
279
280 #include <stdint.h>
281
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>
303
304 using namespace llvm;
305
306 static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;
307
308 void
309 mono_llvm_set_unhandled_exception_handler (void)
310 {
311         std::set_terminate (unhandled_exception);
312 }
313
314 class MonoJITMemoryManager : public JITMemoryManager
315 {
316 private:
317         JITMemoryManager *mm;
318
319 public:
320         /* Callbacks installed by mono */
321         AllocCodeMemoryCb *alloc_cb;
322         DlSymCb *dlsym_cb;
323         ExceptionTableCb *exception_cb;
324
325         MonoJITMemoryManager ();
326         ~MonoJITMemoryManager ();
327
328         void setMemoryWritable (void);
329
330         void setMemoryExecutable (void);
331
332         void AllocateGOT();
333
334     unsigned char *getGOTBase() const {
335                 return mm->getGOTBase ();
336     }
337
338         void setPoisonMemory(bool) {
339         }
340
341         unsigned char *startFunctionBody(const Function *F, 
342                                                                          uintptr_t &ActualSize);
343   
344         unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
345                                                                  unsigned Alignment);
346   
347         void endFunctionBody(const Function *F, unsigned char *FunctionStart,
348                                                  unsigned char *FunctionEnd);
349
350         unsigned char *allocateSpace(intptr_t Size, unsigned Alignment);
351
352         uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
353   
354         void deallocateMemForFunction(const Function *F);
355   
356         unsigned char*startExceptionTable(const Function* F,
357                                                                           uintptr_t &ActualSize);
358   
359         void endExceptionTable(const Function *F, unsigned char *TableStart,
360                                                    unsigned char *TableEnd, 
361                                                    unsigned char* FrameRegister);
362
363         virtual void deallocateFunctionBody(void*) {
364         }
365
366         virtual void deallocateExceptionTable(void*) {
367         }
368
369         virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
370                                                                                  StringRef SectionName) {
371                 // FIXME:
372                 assert(0);
373                 return NULL;
374         }
375
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;
381         }
382
383         virtual bool applyPermissions(std::string*) {
384                 // FIXME:
385                 assert(0);
386                 return false;
387         }
388
389         virtual bool finalizeMemory(std::string *ErrMsg = 0) {
390                 // FIXME:
391                 assert(0);
392                 return false;
393         }
394
395         virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
396                 void *res;
397                 char *err;
398
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;
404                 }
405                 return res;
406         }
407 };
408
409 MonoJITMemoryManager::MonoJITMemoryManager ()
410 {
411         mm = JITMemoryManager::CreateDefaultMemManager ();
412 }
413
414 MonoJITMemoryManager::~MonoJITMemoryManager ()
415 {
416         delete mm;
417 }
418
419 void
420 MonoJITMemoryManager::setMemoryWritable (void)
421 {
422 }
423
424 void
425 MonoJITMemoryManager::setMemoryExecutable (void)
426 {
427 }
428
429 void
430 MonoJITMemoryManager::AllocateGOT()
431 {
432         mm->AllocateGOT ();
433 }
434
435 unsigned char *
436 MonoJITMemoryManager::startFunctionBody(const Function *F, 
437                                         uintptr_t &ActualSize)
438 {
439         // FIXME: This leaks memory
440         if (ActualSize == 0)
441                 ActualSize = 128;
442         return alloc_cb (wrap (F), ActualSize);
443 }
444   
445 unsigned char *
446 MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
447                            unsigned Alignment)
448 {
449         return alloc_cb (wrap (F), StubSize);
450 }
451   
452 void
453 MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart,
454                                   unsigned char *FunctionEnd)
455 {
456 }
457
458 unsigned char *
459 MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
460 {
461         return new unsigned char [Size];
462 }
463
464 uint8_t *
465 MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
466 {
467         return new unsigned char [Size];
468 }
469
470 void
471 MonoJITMemoryManager::deallocateMemForFunction(const Function *F)
472 {
473 }
474   
475 unsigned char*
476 MonoJITMemoryManager::startExceptionTable(const Function* F,
477                                           uintptr_t &ActualSize)
478 {
479         return startFunctionBody(F, ActualSize);
480 }
481   
482 void
483 MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart,
484                                         unsigned char *TableEnd, 
485                                         unsigned char* FrameRegister)
486 {
487         exception_cb (FrameRegister);
488 }
489
490 class MonoJITEventListener : public JITEventListener {
491
492 public:
493         FunctionEmittedCb *emitted_cb;
494
495         MonoJITEventListener (FunctionEmittedCb *cb) {
496                 emitted_cb = cb;
497         }
498
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);
503         }
504 };
505
506 class MonoEE {
507 public:
508         ExecutionEngine *EE;
509         MonoJITMemoryManager *mm;
510         MonoJITEventListener *listener;
511         FunctionPassManager *fpm;
512 };
513
514 void
515 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
516 {
517         MonoEE *mono_ee = (MonoEE*)eeref;
518
519         /*
520          * The verifier does some checks on the whole module, leading to quadratic behavior.
521          */
522         //verifyFunction (*(unwrap<Function> (method)));
523         mono_ee->fpm->run (*unwrap<Function> (method));
524 }
525
526 static cl::list<const PassInfo*, bool, PassNameParser>
527 PassList(cl::desc("Optimizations available:"));
528
529 static void
530 force_pass_linking (void)
531 {
532         // Make sure the rest is linked in, but never executed
533         char *foo = g_getenv ("FOO");
534         gboolean ret = (foo != (char*)-1);
535         g_free (foo);
536
537         if (ret) 
538                 return;
539
540         // This is a subset of the passes in LinkAllPasses.h
541         // The utility passes and the interprocedural passes are commented out
542
543       (void) llvm::createAAEvalPass();
544       (void) llvm::createAggressiveDCEPass();
545       (void) llvm::createAliasAnalysisCounterPass();
546       (void) llvm::createAliasDebugger();
547           /*
548       (void) llvm::createArgumentPromotionPass();
549       (void) llvm::createStructRetPromotionPass();
550           */
551       (void) llvm::createBasicAliasAnalysisPass();
552       (void) llvm::createLibCallAliasAnalysisPass(0);
553       (void) llvm::createScalarEvolutionAliasAnalysisPass();
554       //(void) llvm::createBlockPlacementPass();
555       (void) llvm::createBreakCriticalEdgesPass();
556       (void) llvm::createCFGSimplificationPass();
557           /*
558       (void) llvm::createConstantMergePass();
559       (void) llvm::createConstantPropagationPass();
560           */
561           /*
562       (void) llvm::createDeadArgEliminationPass();
563           */
564       (void) llvm::createDeadCodeEliminationPass();
565       (void) llvm::createDeadInstEliminationPass();
566       (void) llvm::createDeadStoreEliminationPass();
567           /*
568       (void) llvm::createDeadTypeEliminationPass();
569       (void) llvm::createDomOnlyPrinterPass();
570       (void) llvm::createDomPrinterPass();
571       (void) llvm::createDomOnlyViewerPass();
572       (void) llvm::createDomViewerPass();
573       (void) llvm::createEdgeProfilerPass();
574       (void) llvm::createOptimalEdgeProfilerPass();
575       (void) llvm::createFunctionInliningPass();
576       (void) llvm::createAlwaysInlinerPass();
577       (void) llvm::createGlobalDCEPass();
578       (void) llvm::createGlobalOptimizerPass();
579       (void) llvm::createGlobalsModRefPass();
580       (void) llvm::createIPConstantPropagationPass();
581       (void) llvm::createIPSCCPPass();
582           */
583       (void) llvm::createIndVarSimplifyPass();
584       (void) llvm::createInstructionCombiningPass();
585           /*
586       (void) llvm::createInternalizePass(false);
587           */
588       (void) llvm::createLCSSAPass();
589       (void) llvm::createLICMPass();
590       (void) llvm::createLazyValueInfoPass();
591       //(void) llvm::createLoopDependenceAnalysisPass();
592           /*
593       (void) llvm::createLoopExtractorPass();
594           */
595       (void) llvm::createLoopSimplifyPass();
596       (void) llvm::createLoopStrengthReducePass();
597       (void) llvm::createLoopUnrollPass();
598       (void) llvm::createLoopUnswitchPass();
599       (void) llvm::createLoopRotatePass();
600       (void) llvm::createLowerInvokePass();
601           /*
602       (void) llvm::createLowerSetJmpPass();
603           */
604       (void) llvm::createLowerSwitchPass();
605       (void) llvm::createNoAAPass();
606           /*
607       (void) llvm::createNoProfileInfoPass();
608       (void) llvm::createProfileEstimatorPass();
609       (void) llvm::createProfileVerifierPass();
610       (void) llvm::createProfileLoaderPass();
611           */
612       (void) llvm::createPromoteMemoryToRegisterPass();
613       (void) llvm::createDemoteRegisterToMemoryPass();
614           /*
615       (void) llvm::createPruneEHPass();
616       (void) llvm::createPostDomOnlyPrinterPass();
617       (void) llvm::createPostDomPrinterPass();
618       (void) llvm::createPostDomOnlyViewerPass();
619       (void) llvm::createPostDomViewerPass();
620           */
621       (void) llvm::createReassociatePass();
622       (void) llvm::createSCCPPass();
623       (void) llvm::createScalarReplAggregatesPass();
624       //(void) llvm::createSimplifyLibCallsPass();
625           /*
626       (void) llvm::createSingleLoopExtractorPass();
627       (void) llvm::createStripSymbolsPass();
628       (void) llvm::createStripNonDebugSymbolsPass();
629       (void) llvm::createStripDeadDebugInfoPass();
630       (void) llvm::createStripDeadPrototypesPass();
631       (void) llvm::createTailCallEliminationPass();
632       (void) llvm::createTailDuplicationPass();
633       (void) llvm::createJumpThreadingPass();
634           */
635           /*
636       (void) llvm::createUnifyFunctionExitNodesPass();
637           */
638       (void) llvm::createInstCountPass();
639       (void) llvm::createCodeGenPreparePass();
640       (void) llvm::createGVNPass();
641       (void) llvm::createMemCpyOptPass();
642       (void) llvm::createLoopDeletionPass();
643           /*
644       (void) llvm::createPostDomTree();
645       (void) llvm::createPostDomFrontier();
646       (void) llvm::createInstructionNamerPass();
647       (void) llvm::createPartialSpecializationPass();
648       (void) llvm::createFunctionAttrsPass();
649       (void) llvm::createMergeFunctionsPass();
650       (void) llvm::createPrintModulePass(0);
651       (void) llvm::createPrintFunctionPass("", 0);
652       (void) llvm::createDbgInfoPrinterPass();
653       (void) llvm::createModuleDebugInfoPrinterPass();
654       (void) llvm::createPartialInliningPass();
655       (void) llvm::createGEPSplitterPass();
656       (void) llvm::createLintPass();
657           */
658       (void) llvm::createSinkingPass();
659 }
660
661 static gboolean inited;
662
663 static void
664 init_llvm (void)
665 {
666         if (inited)
667                 return;
668
669   force_pass_linking ();
670
671 #ifdef TARGET_ARM
672   LLVMInitializeARMTarget ();
673   LLVMInitializeARMTargetInfo ();
674   LLVMInitializeARMTargetMC ();
675 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
676   LLVMInitializeX86Target ();
677   LLVMInitializeX86TargetInfo ();
678   LLVMInitializeX86TargetMC ();
679 #elif defined(TARGET_POWERPC)
680   LLVMInitializePowerPCTarget ();
681   LLVMInitializePowerPCTargetInfo ();
682   LLVMInitializePowerPCTargetMC ();
683 #else
684   #error Unsupported mono-llvm target
685 #endif
686
687   PassRegistry &Registry = *PassRegistry::getPassRegistry();
688   initializeCore(Registry);
689   initializeScalarOpts(Registry);
690   initializeAnalysis(Registry);
691   initializeIPA(Registry);
692   initializeTransformUtils(Registry);
693   initializeInstCombine(Registry);
694   initializeTarget(Registry);
695
696   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
697
698   inited = true;
699 }
700
701 MonoEERef
702 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
703 {
704   std::string Error;
705   MonoEE *mono_ee;
706
707   init_llvm ();
708
709   mono_ee = new MonoEE ();
710
711   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
712   mono_mm->alloc_cb = alloc_cb;
713   mono_mm->dlsym_cb = dlsym_cb;
714   mono_mm->exception_cb = exception_cb;
715   mono_ee->mm = mono_mm;
716
717   /*
718    * The Default code model doesn't seem to work on amd64,
719    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
720    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
721    */
722
723   TargetOptions opts;
724   opts.JITExceptionHandling = 1;
725
726   StringRef cpu_name = sys::getHostCPUName ();
727
728   // EngineBuilder no longer has a copy assignment operator (?)
729   std::unique_ptr<Module> Owner(unwrap(MP));
730   EngineBuilder b (std::move(Owner));
731   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
732
733   g_assert (EE);
734   mono_ee->EE = EE;
735
736   MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
737   EE->RegisterJITEventListener (listener);
738   mono_ee->listener = listener;
739
740   FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
741   mono_ee->fpm = fpm;
742
743   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
744
745   if (PassList.size() > 0) {
746           /* Use the passes specified by the env variable */
747           /* Only the passes in force_pass_linking () can be used */
748           for (unsigned i = 0; i < PassList.size(); ++i) {
749                   const PassInfo *PassInf = PassList[i];
750                   Pass *P = 0;
751
752                   if (PassInf->getNormalCtor())
753                           P = PassInf->getNormalCtor()();
754                   fpm->add (P);
755           }
756   } else {
757           /* Use the same passes used by 'opt' by default, without the ipo passes */
758           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";
759           char **args;
760           int i;
761
762           args = g_strsplit (opts, " ", 1000);
763           for (i = 0; args [i]; i++)
764                   ;
765           llvm::cl::ParseCommandLineOptions (i, args, "");
766           g_strfreev (args);
767
768           for (unsigned i = 0; i < PassList.size(); ++i) {
769                   const PassInfo *PassInf = PassList[i];
770                   Pass *P = 0;
771
772                   if (PassInf->getNormalCtor())
773                           P = PassInf->getNormalCtor()();
774                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
775                   fpm->add (P);
776           }
777
778           /*
779           fpm->add(createInstructionCombiningPass());
780           fpm->add(createReassociatePass());
781           fpm->add(createGVNPass());
782           fpm->add(createCFGSimplificationPass());
783           */
784   }
785
786   *ee = wrap (EE);
787
788   return mono_ee;
789 }
790
791 void
792 mono_llvm_dispose_ee (MonoEERef *eeref)
793 {
794         MonoEE *mono_ee = (MonoEE*)eeref;
795
796         delete mono_ee->EE;
797         delete mono_ee->fpm;
798         //delete mono_ee->mm;
799         delete mono_ee->listener;
800         delete mono_ee;
801 }
802
803 #else /* MONO_CROSS_COMPILE */
804
805 void
806 mono_llvm_set_unhandled_exception_handler (void)
807 {
808 }
809
810 MonoEERef
811 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
812 {
813         g_assert_not_reached ();
814         return NULL;
815 }
816
817 void
818 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
819 {
820         g_assert_not_reached ();
821 }
822
823 gpointer
824 mono_llvm_compile_method (MonoEERef mono_ee, LLVMValueRef method, int nvars, LLVMValueRef *callee_vars, gpointer *callee_addrs, gpointer *eh_frame)
825 {
826         g_assert_not_reached ();
827         return NULL;
828 }
829
830 void
831 mono_llvm_dispose_ee (MonoEERef *eeref)
832 {
833         g_assert_not_reached ();
834 }
835
836 /* Not linked in */
837 void
838 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
839                                          void* Addr)
840 {
841         g_assert_not_reached ();
842 }
843
844 void*
845 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
846 {
847         g_assert_not_reached ();
848         return NULL;
849 }
850
851 #endif /* !MONO_CROSS_COMPILE */