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