Merge pull request #1936 from esdrubal/DotNetRelativeOrAbsolute
[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 //#include <llvm/LinkAllPasses.h>
49
50 #include "llvm-c/Core.h"
51 #include "llvm-c/ExecutionEngine.h"
52
53 #include "mini-llvm-cpp.h"
54
55 // extern "C" void LLVMInitializeARMTargetInfo();
56 // extern "C" void LLVMInitializeARMTarget ();
57 // extern "C" void LLVMInitializeARMTargetMC ();
58
59 using namespace llvm;
60
61 #ifndef MONO_CROSS_COMPILE
62
63 class MonoJITMemoryManager : public JITMemoryManager
64 {
65 private:
66         JITMemoryManager *mm;
67
68 public:
69         /* Callbacks installed by mono */
70         AllocCodeMemoryCb *alloc_cb;
71         DlSymCb *dlsym_cb;
72         ExceptionTableCb *exception_cb;
73
74         MonoJITMemoryManager ();
75         ~MonoJITMemoryManager ();
76
77         void setMemoryWritable (void);
78
79         void setMemoryExecutable (void);
80
81         void AllocateGOT();
82
83     unsigned char *getGOTBase() const {
84                 return mm->getGOTBase ();
85     }
86
87         void setPoisonMemory(bool) {
88         }
89
90         unsigned char *startFunctionBody(const Function *F, 
91                                                                          uintptr_t &ActualSize);
92   
93         unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
94                                                                  unsigned Alignment);
95   
96         void endFunctionBody(const Function *F, unsigned char *FunctionStart,
97                                                  unsigned char *FunctionEnd);
98
99         unsigned char *allocateSpace(intptr_t Size, unsigned Alignment);
100
101         uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
102   
103         void deallocateMemForFunction(const Function *F);
104   
105         unsigned char*startExceptionTable(const Function* F,
106                                                                           uintptr_t &ActualSize);
107   
108         void endExceptionTable(const Function *F, unsigned char *TableStart,
109                                                    unsigned char *TableEnd, 
110                                                    unsigned char* FrameRegister);
111
112         virtual void deallocateFunctionBody(void*) {
113         }
114
115         virtual void deallocateExceptionTable(void*) {
116         }
117
118         virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
119                                                                                  StringRef SectionName) {
120                 // FIXME:
121                 assert(0);
122                 return NULL;
123         }
124
125         virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
126                                                                                  StringRef SectionName, bool IsReadOnly) {
127                 // FIXME:
128                 assert(0);
129                 return NULL;
130         }
131
132         virtual bool applyPermissions(std::string*) {
133                 // FIXME:
134                 assert(0);
135                 return false;
136         }
137
138         virtual bool finalizeMemory(std::string *ErrMsg = 0) {
139                 // FIXME:
140                 assert(0);
141                 return false;
142         }
143
144         virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
145                 void *res;
146                 char *err;
147
148                 err = dlsym_cb (Name.c_str (), &res);
149                 if (err) {
150                         outs () << "Unable to resolve: " << Name << ": " << err << "\n";
151                         assert(0);
152                         return NULL;
153                 }
154                 return res;
155         }
156 };
157
158 MonoJITMemoryManager::MonoJITMemoryManager ()
159 {
160         mm = JITMemoryManager::CreateDefaultMemManager ();
161 }
162
163 MonoJITMemoryManager::~MonoJITMemoryManager ()
164 {
165         delete mm;
166 }
167
168 void
169 MonoJITMemoryManager::setMemoryWritable (void)
170 {
171 }
172
173 void
174 MonoJITMemoryManager::setMemoryExecutable (void)
175 {
176 }
177
178 void
179 MonoJITMemoryManager::AllocateGOT()
180 {
181         mm->AllocateGOT ();
182 }
183
184 unsigned char *
185 MonoJITMemoryManager::startFunctionBody(const Function *F, 
186                                         uintptr_t &ActualSize)
187 {
188         // FIXME: This leaks memory
189         if (ActualSize == 0)
190                 ActualSize = 128;
191         return alloc_cb (wrap (F), ActualSize);
192 }
193   
194 unsigned char *
195 MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
196                            unsigned Alignment)
197 {
198         return alloc_cb (wrap (F), StubSize);
199 }
200   
201 void
202 MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart,
203                                   unsigned char *FunctionEnd)
204 {
205 }
206
207 unsigned char *
208 MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
209 {
210         return new unsigned char [Size];
211 }
212
213 uint8_t *
214 MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
215 {
216         return new unsigned char [Size];
217 }
218
219 void
220 MonoJITMemoryManager::deallocateMemForFunction(const Function *F)
221 {
222 }
223   
224 unsigned char*
225 MonoJITMemoryManager::startExceptionTable(const Function* F,
226                                           uintptr_t &ActualSize)
227 {
228         return startFunctionBody(F, ActualSize);
229 }
230   
231 void
232 MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart,
233                                         unsigned char *TableEnd, 
234                                         unsigned char* FrameRegister)
235 {
236         exception_cb (FrameRegister);
237 }
238
239 #else
240
241 class MonoJITMemoryManager {
242 };
243
244 #endif /* !MONO_CROSS_COMPILE */
245
246 class MonoJITEventListener : public JITEventListener {
247
248 public:
249         FunctionEmittedCb *emitted_cb;
250
251         MonoJITEventListener (FunctionEmittedCb *cb) {
252                 emitted_cb = cb;
253         }
254
255         virtual void NotifyFunctionEmitted(const Function &F,
256                                                                            void *Code, size_t Size,
257                                                                            const EmittedFunctionDetails &Details) {
258                 emitted_cb (wrap (&F), Code, (char*)Code + Size);
259         }
260 };
261
262 class MonoEE {
263 public:
264         ExecutionEngine *EE;
265         MonoJITMemoryManager *mm;
266         MonoJITEventListener *listener;
267         FunctionPassManager *fpm;
268 };
269
270 void
271 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
272 {
273         MonoEE *mono_ee = (MonoEE*)eeref;
274
275         /*
276          * The verifier does some checks on the whole module, leading to quadratic behavior.
277          */
278         //verifyFunction (*(unwrap<Function> (method)));
279         mono_ee->fpm->run (*unwrap<Function> (method));
280 }
281
282 void
283 mono_llvm_dump_value (LLVMValueRef value)
284 {
285         /* Same as LLVMDumpValue (), but print to stdout */
286         fflush (stdout);
287         outs () << (*unwrap<Value> (value));
288 }
289
290 /* Missing overload for building an alloca with an alignment */
291 LLVMValueRef
292 mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty, 
293                                                 LLVMValueRef ArraySize,
294                                                 int alignment, const char *Name)
295 {
296         return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), unwrap (ArraySize), alignment), Name));
297 }
298
299 LLVMValueRef 
300 mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
301                                           const char *Name, gboolean is_volatile, BarrierKind barrier)
302 {
303         LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
304
305         switch (barrier) {
306         case LLVM_BARRIER_NONE:
307                 break;
308         case LLVM_BARRIER_ACQ:
309                 ins->setOrdering(Acquire);
310                 break;
311         case LLVM_BARRIER_SEQ:
312                 ins->setOrdering(SequentiallyConsistent);
313                 break;
314         default:
315                 g_assert_not_reached ();
316                 break;
317         }
318
319         return wrap(ins);
320 }
321
322 LLVMValueRef 
323 mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
324                                                           const char *Name, gboolean is_volatile, int alignment)
325 {
326         LoadInst *ins;
327
328         ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
329         ins->setAlignment (alignment);
330
331         return wrap(ins);
332 }
333
334 LLVMValueRef 
335 mono_llvm_build_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
336                                           gboolean is_volatile, BarrierKind barrier)
337 {
338         StoreInst *ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
339
340         switch (barrier) {
341         case LLVM_BARRIER_NONE:
342                 break;
343         case LLVM_BARRIER_REL:
344                 ins->setOrdering(Release);
345                 break;
346         case LLVM_BARRIER_SEQ:
347                 ins->setOrdering(SequentiallyConsistent);
348                 break;
349         default:
350                 g_assert_not_reached ();
351                 break;
352         }
353
354         return wrap(ins);
355 }
356
357 LLVMValueRef 
358 mono_llvm_build_aligned_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
359                                                            gboolean is_volatile, int alignment)
360 {
361         StoreInst *ins;
362
363         ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
364         ins->setAlignment (alignment);
365
366         return wrap (ins);
367 }
368
369 LLVMValueRef
370 mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef val)
371 {
372         AtomicCmpXchgInst *ins;
373
374         ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent);
375         return wrap (ins);
376 }
377
378 LLVMValueRef
379 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder, AtomicRMWOp op, LLVMValueRef ptr, LLVMValueRef val)
380 {
381         AtomicRMWInst::BinOp aop = AtomicRMWInst::Xchg;
382         AtomicRMWInst *ins;
383
384         switch (op) {
385         case LLVM_ATOMICRMW_OP_XCHG:
386                 aop = AtomicRMWInst::Xchg;
387                 break;
388         case LLVM_ATOMICRMW_OP_ADD:
389                 aop = AtomicRMWInst::Add;
390                 break;
391         default:
392                 g_assert_not_reached ();
393                 break;
394         }
395
396         ins = unwrap (builder)->CreateAtomicRMW (aop, unwrap (ptr), unwrap (val), SequentiallyConsistent);
397         return wrap (ins);
398 }
399
400 LLVMValueRef
401 mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind)
402 {
403         FenceInst *ins;
404         AtomicOrdering ordering;
405
406         g_assert (kind != LLVM_BARRIER_NONE);
407
408         switch (kind) {
409         case LLVM_BARRIER_ACQ:
410                 ordering = Acquire;
411                 break;
412         case LLVM_BARRIER_REL:
413                 ordering = Release;
414                 break;
415         case LLVM_BARRIER_SEQ:
416                 ordering = SequentiallyConsistent;
417                 break;
418         default:
419                 g_assert_not_reached ();
420                 break;
421         }
422
423         ins = unwrap (builder)->CreateFence (ordering);
424         return wrap (ins);
425 }
426
427 void
428 mono_llvm_set_must_tail (LLVMValueRef call_ins)
429 {
430         CallInst *ins = (CallInst*)unwrap (call_ins);
431
432         ins->setTailCallKind (CallInst::TailCallKind::TCK_MustTail);
433 }
434
435 void
436 mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v)
437 {
438         Value *V = ConstantExpr::getTruncOrBitCast (unwrap<Constant> (v), unwrap (var)->getType ());
439         unwrap (var)->replaceAllUsesWith (V);
440 }
441
442 LLVMValueRef
443 mono_llvm_create_constant_data_array (const uint8_t *data, int len)
444 {
445         return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data, len)));
446 }
447
448 void
449 mono_llvm_set_is_constant (LLVMValueRef global_var)
450 {
451         unwrap<GlobalVariable>(global_var)->setConstant (true);
452 }
453
454 static cl::list<const PassInfo*, bool, PassNameParser>
455 PassList(cl::desc("Optimizations available:"));
456
457 static void
458 force_pass_linking (void)
459 {
460         // Make sure the rest is linked in, but never executed
461         if (g_getenv ("FOO") != (char*)-1)
462                 return;
463
464         // This is a subset of the passes in LinkAllPasses.h
465         // The utility passes and the interprocedural passes are commented out
466
467       (void) llvm::createAAEvalPass();
468       (void) llvm::createAggressiveDCEPass();
469       (void) llvm::createAliasAnalysisCounterPass();
470       (void) llvm::createAliasDebugger();
471           /*
472       (void) llvm::createArgumentPromotionPass();
473       (void) llvm::createStructRetPromotionPass();
474           */
475       (void) llvm::createBasicAliasAnalysisPass();
476       (void) llvm::createLibCallAliasAnalysisPass(0);
477       (void) llvm::createScalarEvolutionAliasAnalysisPass();
478       //(void) llvm::createBlockPlacementPass();
479       (void) llvm::createBreakCriticalEdgesPass();
480       (void) llvm::createCFGSimplificationPass();
481           /*
482       (void) llvm::createConstantMergePass();
483       (void) llvm::createConstantPropagationPass();
484           */
485           /*
486       (void) llvm::createDeadArgEliminationPass();
487           */
488       (void) llvm::createDeadCodeEliminationPass();
489       (void) llvm::createDeadInstEliminationPass();
490       (void) llvm::createDeadStoreEliminationPass();
491           /*
492       (void) llvm::createDeadTypeEliminationPass();
493       (void) llvm::createDomOnlyPrinterPass();
494       (void) llvm::createDomPrinterPass();
495       (void) llvm::createDomOnlyViewerPass();
496       (void) llvm::createDomViewerPass();
497       (void) llvm::createEdgeProfilerPass();
498       (void) llvm::createOptimalEdgeProfilerPass();
499       (void) llvm::createFunctionInliningPass();
500       (void) llvm::createAlwaysInlinerPass();
501       (void) llvm::createGlobalDCEPass();
502       (void) llvm::createGlobalOptimizerPass();
503       (void) llvm::createGlobalsModRefPass();
504       (void) llvm::createIPConstantPropagationPass();
505       (void) llvm::createIPSCCPPass();
506           */
507       (void) llvm::createIndVarSimplifyPass();
508       (void) llvm::createInstructionCombiningPass();
509           /*
510       (void) llvm::createInternalizePass(false);
511           */
512       (void) llvm::createLCSSAPass();
513       (void) llvm::createLICMPass();
514       (void) llvm::createLazyValueInfoPass();
515       //(void) llvm::createLoopDependenceAnalysisPass();
516           /*
517       (void) llvm::createLoopExtractorPass();
518           */
519       (void) llvm::createLoopSimplifyPass();
520       (void) llvm::createLoopStrengthReducePass();
521       (void) llvm::createLoopUnrollPass();
522       (void) llvm::createLoopUnswitchPass();
523       (void) llvm::createLoopRotatePass();
524       (void) llvm::createLowerInvokePass();
525           /*
526       (void) llvm::createLowerSetJmpPass();
527           */
528       (void) llvm::createLowerSwitchPass();
529       (void) llvm::createNoAAPass();
530           /*
531       (void) llvm::createNoProfileInfoPass();
532       (void) llvm::createProfileEstimatorPass();
533       (void) llvm::createProfileVerifierPass();
534       (void) llvm::createProfileLoaderPass();
535           */
536       (void) llvm::createPromoteMemoryToRegisterPass();
537       (void) llvm::createDemoteRegisterToMemoryPass();
538           /*
539       (void) llvm::createPruneEHPass();
540       (void) llvm::createPostDomOnlyPrinterPass();
541       (void) llvm::createPostDomPrinterPass();
542       (void) llvm::createPostDomOnlyViewerPass();
543       (void) llvm::createPostDomViewerPass();
544           */
545       (void) llvm::createReassociatePass();
546       (void) llvm::createSCCPPass();
547       (void) llvm::createScalarReplAggregatesPass();
548       //(void) llvm::createSimplifyLibCallsPass();
549           /*
550       (void) llvm::createSingleLoopExtractorPass();
551       (void) llvm::createStripSymbolsPass();
552       (void) llvm::createStripNonDebugSymbolsPass();
553       (void) llvm::createStripDeadDebugInfoPass();
554       (void) llvm::createStripDeadPrototypesPass();
555       (void) llvm::createTailCallEliminationPass();
556       (void) llvm::createTailDuplicationPass();
557       (void) llvm::createJumpThreadingPass();
558           */
559           /*
560       (void) llvm::createUnifyFunctionExitNodesPass();
561           */
562       (void) llvm::createInstCountPass();
563       (void) llvm::createCodeGenPreparePass();
564       (void) llvm::createGVNPass();
565       (void) llvm::createMemCpyOptPass();
566       (void) llvm::createLoopDeletionPass();
567           /*
568       (void) llvm::createPostDomTree();
569       (void) llvm::createPostDomFrontier();
570       (void) llvm::createInstructionNamerPass();
571       (void) llvm::createPartialSpecializationPass();
572       (void) llvm::createFunctionAttrsPass();
573       (void) llvm::createMergeFunctionsPass();
574       (void) llvm::createPrintModulePass(0);
575       (void) llvm::createPrintFunctionPass("", 0);
576       (void) llvm::createDbgInfoPrinterPass();
577       (void) llvm::createModuleDebugInfoPrinterPass();
578       (void) llvm::createPartialInliningPass();
579       (void) llvm::createGEPSplitterPass();
580       (void) llvm::createLintPass();
581           */
582       (void) llvm::createSinkingPass();
583 }
584
585 #ifndef MONO_CROSS_COMPILE
586
587 static gboolean inited;
588
589 static void
590 init_llvm (void)
591 {
592         if (inited)
593                 return;
594
595   force_pass_linking ();
596
597 #ifdef TARGET_ARM
598   LLVMInitializeARMTarget ();
599   LLVMInitializeARMTargetInfo ();
600   LLVMInitializeARMTargetMC ();
601 #else
602   LLVMInitializeX86Target ();
603   LLVMInitializeX86TargetInfo ();
604   LLVMInitializeX86TargetMC ();
605 #endif
606
607   PassRegistry &Registry = *PassRegistry::getPassRegistry();
608   initializeCore(Registry);
609   initializeScalarOpts(Registry);
610   initializeAnalysis(Registry);
611   initializeIPA(Registry);
612   initializeTransformUtils(Registry);
613   initializeInstCombine(Registry);
614   initializeTarget(Registry);
615
616   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
617
618   inited = true;
619 }
620
621 MonoEERef
622 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
623 {
624   std::string Error;
625   MonoEE *mono_ee;
626
627   init_llvm ();
628
629   mono_ee = new MonoEE ();
630
631   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
632   mono_mm->alloc_cb = alloc_cb;
633   mono_mm->dlsym_cb = dlsym_cb;
634   mono_mm->exception_cb = exception_cb;
635   mono_ee->mm = mono_mm;
636
637   /*
638    * The Default code model doesn't seem to work on amd64,
639    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
640    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
641    */
642
643   TargetOptions opts;
644   opts.JITExceptionHandling = 1;
645
646   StringRef cpu_name = sys::getHostCPUName ();
647
648   // EngineBuilder no longer has a copy assignment operator (?)
649   std::unique_ptr<Module> Owner(unwrap(MP));
650   EngineBuilder b (std::move(Owner));
651   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
652
653   g_assert (EE);
654   mono_ee->EE = EE;
655
656   MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
657   EE->RegisterJITEventListener (listener);
658   mono_ee->listener = listener;
659
660   FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
661   mono_ee->fpm = fpm;
662
663   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
664
665   if (PassList.size() > 0) {
666           /* Use the passes specified by the env variable */
667           /* Only the passes in force_pass_linking () can be used */
668           for (unsigned i = 0; i < PassList.size(); ++i) {
669                   const PassInfo *PassInf = PassList[i];
670                   Pass *P = 0;
671
672                   if (PassInf->getNormalCtor())
673                           P = PassInf->getNormalCtor()();
674                   fpm->add (P);
675           }
676   } else {
677           /* Use the same passes used by 'opt' by default, without the ipo passes */
678           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";
679           char **args;
680           int i;
681
682           args = g_strsplit (opts, " ", 1000);
683           for (i = 0; args [i]; i++)
684                   ;
685           llvm::cl::ParseCommandLineOptions (i, args, "");
686           g_strfreev (args);
687
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                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
695                   fpm->add (P);
696           }
697
698           /*
699           fpm->add(createInstructionCombiningPass());
700           fpm->add(createReassociatePass());
701           fpm->add(createGVNPass());
702           fpm->add(createCFGSimplificationPass());
703           */
704   }
705
706   *ee = wrap (EE);
707
708   return mono_ee;
709 }
710
711 void
712 mono_llvm_dispose_ee (MonoEERef *eeref)
713 {
714         MonoEE *mono_ee = (MonoEE*)eeref;
715
716         delete mono_ee->EE;
717         delete mono_ee->fpm;
718         //delete mono_ee->mm;
719         delete mono_ee->listener;
720         delete mono_ee;
721 }
722
723 #else
724
725 MonoEERef
726 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
727 {
728         g_assert_not_reached ();
729         return NULL;
730 }
731
732 void
733 mono_llvm_dispose_ee (MonoEERef *eeref)
734 {
735         g_assert_not_reached ();
736 }
737
738 /* Not linked in */
739 void
740 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
741                                          void* Addr)
742 {
743         g_assert_not_reached ();
744 }
745
746 void*
747 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
748 {
749         g_assert_not_reached ();
750         return NULL;
751 }
752
753 #endif /* !MONO_CROSS_COMPILE */