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