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