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