Merge remote-tracking branch 'origin/bitcode-premerge'
[mono.git] / mono / mini / mini-llvm-cpp.cpp
1 //
2 // mini-llvm-cpp.cpp: C++ support classes for the mono LLVM integration
3 //
4 // (C) 2009-2011 Novell, Inc.
5 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
6 //
7
8 //
9 // We need to override some stuff in LLVM, but this cannot be done using the C
10 // interface, so we have to use some C++ code here.
11 // The things which we override are:
12 // - the default JIT code manager used by LLVM doesn't allocate memory using
13 //   MAP_32BIT, we require it.
14 // - add some callbacks so we can obtain the size of methods and their exception
15 //   tables.
16 //
17
18 //
19 // Mono's internal header files are not C++ clean, so avoid including them if 
20 // possible
21 //
22
23 #include "config.h"
24
25 #include <stdint.h>
26
27 #include <llvm/Support/raw_ostream.h>
28 #include <llvm/Support/Host.h>
29 #include <llvm/PassManager.h>
30 #include <llvm/ExecutionEngine/ExecutionEngine.h>
31 #include <llvm/ExecutionEngine/JITMemoryManager.h>
32 #include <llvm/ExecutionEngine/JITEventListener.h>
33 #include <llvm/Target/TargetOptions.h>
34 #include <llvm/Target/TargetRegisterInfo.h>
35 #include <llvm/IR/Verifier.h>
36 #include <llvm/Analysis/Passes.h>
37 #include <llvm/Transforms/Scalar.h>
38 #include <llvm/Support/CommandLine.h>
39 #include "llvm/IR/LegacyPassNameParser.h"
40 #include "llvm/Support/PrettyStackTrace.h"
41 #include <llvm/CodeGen/Passes.h>
42 #include <llvm/CodeGen/MachineFunctionPass.h>
43 #include <llvm/CodeGen/MachineFunction.h>
44 #include <llvm/CodeGen/MachineFrameInfo.h>
45 #include <llvm/IR/Function.h>
46 #include <llvm/IR/IRBuilder.h>
47 #include <llvm/IR/Module.h>
48
49 #include "llvm-c/Core.h"
50 #include "llvm-c/ExecutionEngine.h"
51
52 #include "mini-llvm-cpp.h"
53
54 // extern "C" void LLVMInitializeARMTargetInfo();
55 // extern "C" void LLVMInitializeARMTarget ();
56 // extern "C" void LLVMInitializeARMTargetMC ();
57
58 using namespace llvm;
59
60 #ifndef MONO_CROSS_COMPILE
61
62 void
63 mono_llvm_cpp_throw_exception (void)
64 {
65         gint32 *ex = NULL;
66
67         /* The generated code catches an int32* */
68         throw ex;
69 }
70
71 static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;
72
73 void
74 mono_llvm_set_unhandled_exception_handler (void)
75 {
76         std::set_terminate (unhandled_exception);
77 }
78
79 class MonoJITMemoryManager : public JITMemoryManager
80 {
81 private:
82         JITMemoryManager *mm;
83
84 public:
85         /* Callbacks installed by mono */
86         AllocCodeMemoryCb *alloc_cb;
87         DlSymCb *dlsym_cb;
88         ExceptionTableCb *exception_cb;
89
90         MonoJITMemoryManager ();
91         ~MonoJITMemoryManager ();
92
93         void setMemoryWritable (void);
94
95         void setMemoryExecutable (void);
96
97         void AllocateGOT();
98
99     unsigned char *getGOTBase() const {
100                 return mm->getGOTBase ();
101     }
102
103         void setPoisonMemory(bool) {
104         }
105
106         unsigned char *startFunctionBody(const Function *F, 
107                                                                          uintptr_t &ActualSize);
108   
109         unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
110                                                                  unsigned Alignment);
111   
112         void endFunctionBody(const Function *F, unsigned char *FunctionStart,
113                                                  unsigned char *FunctionEnd);
114
115         unsigned char *allocateSpace(intptr_t Size, unsigned Alignment);
116
117         uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
118   
119         void deallocateMemForFunction(const Function *F);
120   
121         unsigned char*startExceptionTable(const Function* F,
122                                                                           uintptr_t &ActualSize);
123   
124         void endExceptionTable(const Function *F, unsigned char *TableStart,
125                                                    unsigned char *TableEnd, 
126                                                    unsigned char* FrameRegister);
127
128         virtual void deallocateFunctionBody(void*) {
129         }
130
131         virtual void deallocateExceptionTable(void*) {
132         }
133
134         virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
135                                                                                  StringRef SectionName) {
136                 // FIXME:
137                 assert(0);
138                 return NULL;
139         }
140
141         virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
142                                                                                  StringRef SectionName, bool IsReadOnly) {
143                 // FIXME:
144                 assert(0);
145                 return NULL;
146         }
147
148         virtual bool applyPermissions(std::string*) {
149                 // FIXME:
150                 assert(0);
151                 return false;
152         }
153
154         virtual bool finalizeMemory(std::string *ErrMsg = 0) {
155                 // FIXME:
156                 assert(0);
157                 return false;
158         }
159
160         virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
161                 void *res;
162                 char *err;
163
164                 err = dlsym_cb (Name.c_str (), &res);
165                 if (err) {
166                         outs () << "Unable to resolve: " << Name << ": " << err << "\n";
167                         assert(0);
168                         return NULL;
169                 }
170                 return res;
171         }
172 };
173
174 MonoJITMemoryManager::MonoJITMemoryManager ()
175 {
176         mm = JITMemoryManager::CreateDefaultMemManager ();
177 }
178
179 MonoJITMemoryManager::~MonoJITMemoryManager ()
180 {
181         delete mm;
182 }
183
184 void
185 MonoJITMemoryManager::setMemoryWritable (void)
186 {
187 }
188
189 void
190 MonoJITMemoryManager::setMemoryExecutable (void)
191 {
192 }
193
194 void
195 MonoJITMemoryManager::AllocateGOT()
196 {
197         mm->AllocateGOT ();
198 }
199
200 unsigned char *
201 MonoJITMemoryManager::startFunctionBody(const Function *F, 
202                                         uintptr_t &ActualSize)
203 {
204         // FIXME: This leaks memory
205         if (ActualSize == 0)
206                 ActualSize = 128;
207         return alloc_cb (wrap (F), ActualSize);
208 }
209   
210 unsigned char *
211 MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
212                            unsigned Alignment)
213 {
214         return alloc_cb (wrap (F), StubSize);
215 }
216   
217 void
218 MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart,
219                                   unsigned char *FunctionEnd)
220 {
221 }
222
223 unsigned char *
224 MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
225 {
226         return new unsigned char [Size];
227 }
228
229 uint8_t *
230 MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
231 {
232         return new unsigned char [Size];
233 }
234
235 void
236 MonoJITMemoryManager::deallocateMemForFunction(const Function *F)
237 {
238 }
239   
240 unsigned char*
241 MonoJITMemoryManager::startExceptionTable(const Function* F,
242                                           uintptr_t &ActualSize)
243 {
244         return startFunctionBody(F, ActualSize);
245 }
246   
247 void
248 MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart,
249                                         unsigned char *TableEnd, 
250                                         unsigned char* FrameRegister)
251 {
252         exception_cb (FrameRegister);
253 }
254
255 #else
256
257 class MonoJITMemoryManager {
258 };
259
260 #endif /* !MONO_CROSS_COMPILE */
261
262 class MonoJITEventListener : public JITEventListener {
263
264 public:
265         FunctionEmittedCb *emitted_cb;
266
267         MonoJITEventListener (FunctionEmittedCb *cb) {
268                 emitted_cb = cb;
269         }
270
271         virtual void NotifyFunctionEmitted(const Function &F,
272                                                                            void *Code, size_t Size,
273                                                                            const EmittedFunctionDetails &Details) {
274                 emitted_cb (wrap (&F), Code, (char*)Code + Size);
275         }
276 };
277
278 class MonoEE {
279 public:
280         ExecutionEngine *EE;
281         MonoJITMemoryManager *mm;
282         MonoJITEventListener *listener;
283         FunctionPassManager *fpm;
284 };
285
286 void
287 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
288 {
289         MonoEE *mono_ee = (MonoEE*)eeref;
290
291         /*
292          * The verifier does some checks on the whole module, leading to quadratic behavior.
293          */
294         //verifyFunction (*(unwrap<Function> (method)));
295         mono_ee->fpm->run (*unwrap<Function> (method));
296 }
297
298 void
299 mono_llvm_dump_value (LLVMValueRef value)
300 {
301         /* Same as LLVMDumpValue (), but print to stdout */
302         fflush (stdout);
303         outs () << (*unwrap<Value> (value));
304 }
305
306 /* Missing overload for building an alloca with an alignment */
307 LLVMValueRef
308 mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty, 
309                                                 LLVMValueRef ArraySize,
310                                                 int alignment, const char *Name)
311 {
312         return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), unwrap (ArraySize), alignment), Name));
313 }
314
315 LLVMValueRef 
316 mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
317                                           const char *Name, gboolean is_volatile, BarrierKind barrier)
318 {
319         LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
320
321         switch (barrier) {
322         case LLVM_BARRIER_NONE:
323                 break;
324         case LLVM_BARRIER_ACQ:
325                 ins->setOrdering(Acquire);
326                 break;
327         case LLVM_BARRIER_SEQ:
328                 ins->setOrdering(SequentiallyConsistent);
329                 break;
330         default:
331                 g_assert_not_reached ();
332                 break;
333         }
334
335         return wrap(ins);
336 }
337
338 LLVMValueRef 
339 mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
340                                                           const char *Name, gboolean is_volatile, int alignment)
341 {
342         LoadInst *ins;
343
344         ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
345         ins->setAlignment (alignment);
346
347         return wrap(ins);
348 }
349
350 LLVMValueRef 
351 mono_llvm_build_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
352                                           gboolean is_volatile, BarrierKind barrier)
353 {
354         StoreInst *ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
355
356         switch (barrier) {
357         case LLVM_BARRIER_NONE:
358                 break;
359         case LLVM_BARRIER_REL:
360                 ins->setOrdering(Release);
361                 break;
362         case LLVM_BARRIER_SEQ:
363                 ins->setOrdering(SequentiallyConsistent);
364                 break;
365         default:
366                 g_assert_not_reached ();
367                 break;
368         }
369
370         return wrap(ins);
371 }
372
373 LLVMValueRef 
374 mono_llvm_build_aligned_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
375                                                            gboolean is_volatile, int alignment)
376 {
377         StoreInst *ins;
378
379         ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
380         ins->setAlignment (alignment);
381
382         return wrap (ins);
383 }
384
385 LLVMValueRef
386 mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef val)
387 {
388         AtomicCmpXchgInst *ins;
389
390         ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent);
391         return wrap (ins);
392 }
393
394 LLVMValueRef
395 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder, AtomicRMWOp op, LLVMValueRef ptr, LLVMValueRef val)
396 {
397         AtomicRMWInst::BinOp aop = AtomicRMWInst::Xchg;
398         AtomicRMWInst *ins;
399
400         switch (op) {
401         case LLVM_ATOMICRMW_OP_XCHG:
402                 aop = AtomicRMWInst::Xchg;
403                 break;
404         case LLVM_ATOMICRMW_OP_ADD:
405                 aop = AtomicRMWInst::Add;
406                 break;
407         default:
408                 g_assert_not_reached ();
409                 break;
410         }
411
412         ins = unwrap (builder)->CreateAtomicRMW (aop, unwrap (ptr), unwrap (val), SequentiallyConsistent);
413         return wrap (ins);
414 }
415
416 LLVMValueRef
417 mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind)
418 {
419         FenceInst *ins;
420         AtomicOrdering ordering;
421
422         g_assert (kind != LLVM_BARRIER_NONE);
423
424         switch (kind) {
425         case LLVM_BARRIER_ACQ:
426                 ordering = Acquire;
427                 break;
428         case LLVM_BARRIER_REL:
429                 ordering = Release;
430                 break;
431         case LLVM_BARRIER_SEQ:
432                 ordering = SequentiallyConsistent;
433                 break;
434         default:
435                 g_assert_not_reached ();
436                 break;
437         }
438
439         ins = unwrap (builder)->CreateFence (ordering);
440         return wrap (ins);
441 }
442
443 void
444 mono_llvm_set_must_tail (LLVMValueRef call_ins)
445 {
446         CallInst *ins = (CallInst*)unwrap (call_ins);
447
448         ins->setTailCallKind (CallInst::TailCallKind::TCK_MustTail);
449 }
450
451 void
452 mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v)
453 {
454         Value *V = ConstantExpr::getTruncOrBitCast (unwrap<Constant> (v), unwrap (var)->getType ());
455         unwrap (var)->replaceAllUsesWith (V);
456 }
457
458 LLVMValueRef
459 mono_llvm_create_constant_data_array (const uint8_t *data, int len)
460 {
461         return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data, len)));
462 }
463
464 void
465 mono_llvm_set_is_constant (LLVMValueRef global_var)
466 {
467         unwrap<GlobalVariable>(global_var)->setConstant (true);
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 #ifndef MONO_CROSS_COMPILE
602
603 static gboolean inited;
604
605 static void
606 init_llvm (void)
607 {
608         if (inited)
609                 return;
610
611   force_pass_linking ();
612
613 #ifdef TARGET_ARM
614   LLVMInitializeARMTarget ();
615   LLVMInitializeARMTargetInfo ();
616   LLVMInitializeARMTargetMC ();
617 #else
618   LLVMInitializeX86Target ();
619   LLVMInitializeX86TargetInfo ();
620   LLVMInitializeX86TargetMC ();
621 #endif
622
623   PassRegistry &Registry = *PassRegistry::getPassRegistry();
624   initializeCore(Registry);
625   initializeScalarOpts(Registry);
626   initializeAnalysis(Registry);
627   initializeIPA(Registry);
628   initializeTransformUtils(Registry);
629   initializeInstCombine(Registry);
630   initializeTarget(Registry);
631
632   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
633
634   inited = true;
635 }
636
637 MonoEERef
638 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
639 {
640   std::string Error;
641   MonoEE *mono_ee;
642
643   init_llvm ();
644
645   mono_ee = new MonoEE ();
646
647   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
648   mono_mm->alloc_cb = alloc_cb;
649   mono_mm->dlsym_cb = dlsym_cb;
650   mono_mm->exception_cb = exception_cb;
651   mono_ee->mm = mono_mm;
652
653   /*
654    * The Default code model doesn't seem to work on amd64,
655    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
656    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
657    */
658
659   TargetOptions opts;
660   opts.JITExceptionHandling = 1;
661
662   StringRef cpu_name = sys::getHostCPUName ();
663
664   // EngineBuilder no longer has a copy assignment operator (?)
665   std::unique_ptr<Module> Owner(unwrap(MP));
666   EngineBuilder b (std::move(Owner));
667   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
668
669   g_assert (EE);
670   mono_ee->EE = EE;
671
672   MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
673   EE->RegisterJITEventListener (listener);
674   mono_ee->listener = listener;
675
676   FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
677   mono_ee->fpm = fpm;
678
679   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
680
681   if (PassList.size() > 0) {
682           /* Use the passes specified by the env variable */
683           /* Only the passes in force_pass_linking () can be used */
684           for (unsigned i = 0; i < PassList.size(); ++i) {
685                   const PassInfo *PassInf = PassList[i];
686                   Pass *P = 0;
687
688                   if (PassInf->getNormalCtor())
689                           P = PassInf->getNormalCtor()();
690                   fpm->add (P);
691           }
692   } else {
693           /* Use the same passes used by 'opt' by default, without the ipo passes */
694           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";
695           char **args;
696           int i;
697
698           args = g_strsplit (opts, " ", 1000);
699           for (i = 0; args [i]; i++)
700                   ;
701           llvm::cl::ParseCommandLineOptions (i, args, "");
702           g_strfreev (args);
703
704           for (unsigned i = 0; i < PassList.size(); ++i) {
705                   const PassInfo *PassInf = PassList[i];
706                   Pass *P = 0;
707
708                   if (PassInf->getNormalCtor())
709                           P = PassInf->getNormalCtor()();
710                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
711                   fpm->add (P);
712           }
713
714           /*
715           fpm->add(createInstructionCombiningPass());
716           fpm->add(createReassociatePass());
717           fpm->add(createGVNPass());
718           fpm->add(createCFGSimplificationPass());
719           */
720   }
721
722   *ee = wrap (EE);
723
724   return mono_ee;
725 }
726
727 void
728 mono_llvm_dispose_ee (MonoEERef *eeref)
729 {
730         MonoEE *mono_ee = (MonoEE*)eeref;
731
732         delete mono_ee->EE;
733         delete mono_ee->fpm;
734         //delete mono_ee->mm;
735         delete mono_ee->listener;
736         delete mono_ee;
737 }
738
739 #else
740
741 MonoEERef
742 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
743 {
744         g_assert_not_reached ();
745         return NULL;
746 }
747
748 void
749 mono_llvm_dispose_ee (MonoEERef *eeref)
750 {
751         g_assert_not_reached ();
752 }
753
754 /* Not linked in */
755 void
756 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
757                                          void* Addr)
758 {
759         g_assert_not_reached ();
760 }
761
762 void*
763 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
764 {
765         g_assert_not_reached ();
766         return NULL;
767 }
768
769
770 #endif /* !MONO_CROSS_COMPILE */