Merge pull request #2152 from joelmartinez/mdoc-preserver
[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 static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;
63
64 void
65 mono_llvm_set_unhandled_exception_handler (void)
66 {
67         std::set_terminate (unhandled_exception);
68 }
69
70 class MonoJITMemoryManager : public JITMemoryManager
71 {
72 private:
73         JITMemoryManager *mm;
74
75 public:
76         /* Callbacks installed by mono */
77         AllocCodeMemoryCb *alloc_cb;
78         DlSymCb *dlsym_cb;
79         ExceptionTableCb *exception_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         exception_cb (FrameRegister);
244 }
245
246 #else
247
248 class MonoJITMemoryManager {
249 };
250
251 #endif /* !MONO_CROSS_COMPILE */
252
253 class MonoJITEventListener : public JITEventListener {
254
255 public:
256         FunctionEmittedCb *emitted_cb;
257
258         MonoJITEventListener (FunctionEmittedCb *cb) {
259                 emitted_cb = cb;
260         }
261
262         virtual void NotifyFunctionEmitted(const Function &F,
263                                                                            void *Code, size_t Size,
264                                                                            const EmittedFunctionDetails &Details) {
265                 emitted_cb (wrap (&F), Code, (char*)Code + Size);
266         }
267 };
268
269 class MonoEE {
270 public:
271         ExecutionEngine *EE;
272         MonoJITMemoryManager *mm;
273         MonoJITEventListener *listener;
274         FunctionPassManager *fpm;
275 };
276
277 void
278 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
279 {
280         MonoEE *mono_ee = (MonoEE*)eeref;
281
282         /*
283          * The verifier does some checks on the whole module, leading to quadratic behavior.
284          */
285         //verifyFunction (*(unwrap<Function> (method)));
286         mono_ee->fpm->run (*unwrap<Function> (method));
287 }
288
289 void
290 mono_llvm_dump_value (LLVMValueRef value)
291 {
292         /* Same as LLVMDumpValue (), but print to stdout */
293         fflush (stdout);
294         outs () << (*unwrap<Value> (value));
295 }
296
297 /* Missing overload for building an alloca with an alignment */
298 LLVMValueRef
299 mono_llvm_build_alloca (LLVMBuilderRef builder, LLVMTypeRef Ty, 
300                                                 LLVMValueRef ArraySize,
301                                                 int alignment, const char *Name)
302 {
303         return wrap (unwrap (builder)->Insert (new AllocaInst (unwrap (Ty), unwrap (ArraySize), alignment), Name));
304 }
305
306 LLVMValueRef 
307 mono_llvm_build_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
308                                           const char *Name, gboolean is_volatile, BarrierKind barrier)
309 {
310         LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
311
312         switch (barrier) {
313         case LLVM_BARRIER_NONE:
314                 break;
315         case LLVM_BARRIER_ACQ:
316                 ins->setOrdering(Acquire);
317                 break;
318         case LLVM_BARRIER_SEQ:
319                 ins->setOrdering(SequentiallyConsistent);
320                 break;
321         default:
322                 g_assert_not_reached ();
323                 break;
324         }
325
326         return wrap(ins);
327 }
328
329 LLVMValueRef 
330 mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
331                                                           const char *Name, gboolean is_volatile, int alignment)
332 {
333         LoadInst *ins;
334
335         ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
336         ins->setAlignment (alignment);
337
338         return wrap(ins);
339 }
340
341 LLVMValueRef 
342 mono_llvm_build_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
343                                           gboolean is_volatile, BarrierKind barrier)
344 {
345         StoreInst *ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
346
347         switch (barrier) {
348         case LLVM_BARRIER_NONE:
349                 break;
350         case LLVM_BARRIER_REL:
351                 ins->setOrdering(Release);
352                 break;
353         case LLVM_BARRIER_SEQ:
354                 ins->setOrdering(SequentiallyConsistent);
355                 break;
356         default:
357                 g_assert_not_reached ();
358                 break;
359         }
360
361         return wrap(ins);
362 }
363
364 LLVMValueRef 
365 mono_llvm_build_aligned_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
366                                                            gboolean is_volatile, int alignment)
367 {
368         StoreInst *ins;
369
370         ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
371         ins->setAlignment (alignment);
372
373         return wrap (ins);
374 }
375
376 LLVMValueRef
377 mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef val)
378 {
379         AtomicCmpXchgInst *ins;
380
381         ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent);
382         return wrap (ins);
383 }
384
385 LLVMValueRef
386 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder, AtomicRMWOp op, LLVMValueRef ptr, LLVMValueRef val)
387 {
388         AtomicRMWInst::BinOp aop = AtomicRMWInst::Xchg;
389         AtomicRMWInst *ins;
390
391         switch (op) {
392         case LLVM_ATOMICRMW_OP_XCHG:
393                 aop = AtomicRMWInst::Xchg;
394                 break;
395         case LLVM_ATOMICRMW_OP_ADD:
396                 aop = AtomicRMWInst::Add;
397                 break;
398         default:
399                 g_assert_not_reached ();
400                 break;
401         }
402
403         ins = unwrap (builder)->CreateAtomicRMW (aop, unwrap (ptr), unwrap (val), SequentiallyConsistent);
404         return wrap (ins);
405 }
406
407 LLVMValueRef
408 mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind)
409 {
410         FenceInst *ins;
411         AtomicOrdering ordering;
412
413         g_assert (kind != LLVM_BARRIER_NONE);
414
415         switch (kind) {
416         case LLVM_BARRIER_ACQ:
417                 ordering = Acquire;
418                 break;
419         case LLVM_BARRIER_REL:
420                 ordering = Release;
421                 break;
422         case LLVM_BARRIER_SEQ:
423                 ordering = SequentiallyConsistent;
424                 break;
425         default:
426                 g_assert_not_reached ();
427                 break;
428         }
429
430         ins = unwrap (builder)->CreateFence (ordering);
431         return wrap (ins);
432 }
433
434 void
435 mono_llvm_set_must_tail (LLVMValueRef call_ins)
436 {
437         CallInst *ins = (CallInst*)unwrap (call_ins);
438
439         ins->setTailCallKind (CallInst::TailCallKind::TCK_MustTail);
440 }
441
442 void
443 mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v)
444 {
445         Value *V = ConstantExpr::getTruncOrBitCast (unwrap<Constant> (v), unwrap (var)->getType ());
446         unwrap (var)->replaceAllUsesWith (V);
447 }
448
449 LLVMValueRef
450 mono_llvm_create_constant_data_array (const uint8_t *data, int len)
451 {
452         return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data, len)));
453 }
454
455 void
456 mono_llvm_set_is_constant (LLVMValueRef global_var)
457 {
458         unwrap<GlobalVariable>(global_var)->setConstant (true);
459 }
460
461 void
462 mono_llvm_set_preserveall_cc (LLVMValueRef func)
463 {
464         unwrap<Function>(func)->setCallingConv (CallingConv::PreserveAll);
465 }
466
467 void
468 mono_llvm_set_call_preserveall_cc (LLVMValueRef func)
469 {
470         unwrap<CallInst>(func)->setCallingConv (CallingConv::PreserveAll);
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 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
621   LLVMInitializeX86Target ();
622   LLVMInitializeX86TargetInfo ();
623   LLVMInitializeX86TargetMC ();
624 #elif defined(TARGET_POWERPC)
625   LLVMInitializePowerPCTarget ();
626   LLVMInitializePowerPCTargetInfo ();
627   LLVMInitializePowerPCTargetMC ();
628 #else
629   #error Unsupported mono-llvm target
630 #endif
631
632   PassRegistry &Registry = *PassRegistry::getPassRegistry();
633   initializeCore(Registry);
634   initializeScalarOpts(Registry);
635   initializeAnalysis(Registry);
636   initializeIPA(Registry);
637   initializeTransformUtils(Registry);
638   initializeInstCombine(Registry);
639   initializeTarget(Registry);
640
641   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
642
643   inited = true;
644 }
645
646 MonoEERef
647 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
648 {
649   std::string Error;
650   MonoEE *mono_ee;
651
652   init_llvm ();
653
654   mono_ee = new MonoEE ();
655
656   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
657   mono_mm->alloc_cb = alloc_cb;
658   mono_mm->dlsym_cb = dlsym_cb;
659   mono_mm->exception_cb = exception_cb;
660   mono_ee->mm = mono_mm;
661
662   /*
663    * The Default code model doesn't seem to work on amd64,
664    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
665    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
666    */
667
668   TargetOptions opts;
669   opts.JITExceptionHandling = 1;
670
671   StringRef cpu_name = sys::getHostCPUName ();
672
673   // EngineBuilder no longer has a copy assignment operator (?)
674   std::unique_ptr<Module> Owner(unwrap(MP));
675   EngineBuilder b (std::move(Owner));
676   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
677
678   g_assert (EE);
679   mono_ee->EE = EE;
680
681   MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
682   EE->RegisterJITEventListener (listener);
683   mono_ee->listener = listener;
684
685   FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
686   mono_ee->fpm = fpm;
687
688   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
689
690   if (PassList.size() > 0) {
691           /* Use the passes specified by the env variable */
692           /* Only the passes in force_pass_linking () can be used */
693           for (unsigned i = 0; i < PassList.size(); ++i) {
694                   const PassInfo *PassInf = PassList[i];
695                   Pass *P = 0;
696
697                   if (PassInf->getNormalCtor())
698                           P = PassInf->getNormalCtor()();
699                   fpm->add (P);
700           }
701   } else {
702           /* Use the same passes used by 'opt' by default, without the ipo passes */
703           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";
704           char **args;
705           int i;
706
707           args = g_strsplit (opts, " ", 1000);
708           for (i = 0; args [i]; i++)
709                   ;
710           llvm::cl::ParseCommandLineOptions (i, args, "");
711           g_strfreev (args);
712
713           for (unsigned i = 0; i < PassList.size(); ++i) {
714                   const PassInfo *PassInf = PassList[i];
715                   Pass *P = 0;
716
717                   if (PassInf->getNormalCtor())
718                           P = PassInf->getNormalCtor()();
719                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
720                   fpm->add (P);
721           }
722
723           /*
724           fpm->add(createInstructionCombiningPass());
725           fpm->add(createReassociatePass());
726           fpm->add(createGVNPass());
727           fpm->add(createCFGSimplificationPass());
728           */
729   }
730
731   *ee = wrap (EE);
732
733   return mono_ee;
734 }
735
736 void
737 mono_llvm_dispose_ee (MonoEERef *eeref)
738 {
739         MonoEE *mono_ee = (MonoEE*)eeref;
740
741         delete mono_ee->EE;
742         delete mono_ee->fpm;
743         //delete mono_ee->mm;
744         delete mono_ee->listener;
745         delete mono_ee;
746 }
747
748 #else
749
750 void
751 mono_llvm_set_unhandled_exception_handler (void)
752 {
753 }
754
755 MonoEERef
756 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
757 {
758         g_assert_not_reached ();
759         return NULL;
760 }
761
762 void
763 mono_llvm_dispose_ee (MonoEERef *eeref)
764 {
765         g_assert_not_reached ();
766 }
767
768 /* Not linked in */
769 void
770 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
771                                          void* Addr)
772 {
773         g_assert_not_reached ();
774 }
775
776 void*
777 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
778 {
779         g_assert_not_reached ();
780         return NULL;
781 }
782
783 #endif /* !MONO_CROSS_COMPILE */