Merge pull request #1510 from BrzVlad/fix-file-map
[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, BarrierKind barrier)
322 {
323         LoadInst *ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
324
325         switch (barrier) {
326         case LLVM_BARRIER_NONE:
327                 break;
328         case LLVM_BARRIER_ACQ:
329                 ins->setOrdering(Acquire);
330                 break;
331         case LLVM_BARRIER_SEQ:
332                 ins->setOrdering(SequentiallyConsistent);
333                 break;
334         default:
335                 g_assert_not_reached ();
336                 break;
337         }
338
339         return wrap(ins);
340 }
341
342 LLVMValueRef 
343 mono_llvm_build_aligned_load (LLVMBuilderRef builder, LLVMValueRef PointerVal,
344                                                           const char *Name, gboolean is_volatile, int alignment)
345 {
346         LoadInst *ins;
347
348         ins = unwrap(builder)->CreateLoad(unwrap(PointerVal), is_volatile, Name);
349         ins->setAlignment (alignment);
350
351         return wrap(ins);
352 }
353
354 LLVMValueRef 
355 mono_llvm_build_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
356                                           gboolean is_volatile, BarrierKind barrier)
357 {
358         StoreInst *ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
359
360         switch (barrier) {
361         case LLVM_BARRIER_NONE:
362                 break;
363         case LLVM_BARRIER_REL:
364                 ins->setOrdering(Release);
365                 break;
366         case LLVM_BARRIER_SEQ:
367                 ins->setOrdering(SequentiallyConsistent);
368                 break;
369         default:
370                 g_assert_not_reached ();
371                 break;
372         }
373
374         return wrap(ins);
375 }
376
377 LLVMValueRef 
378 mono_llvm_build_aligned_store (LLVMBuilderRef builder, LLVMValueRef Val, LLVMValueRef PointerVal,
379                                                            gboolean is_volatile, int alignment)
380 {
381         StoreInst *ins;
382
383         ins = unwrap(builder)->CreateStore(unwrap(Val), unwrap(PointerVal), is_volatile);
384         ins->setAlignment (alignment);
385
386         return wrap (ins);
387 }
388
389 LLVMValueRef
390 mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef val)
391 {
392         AtomicCmpXchgInst *ins;
393
394 #if LLVM_API_VERSION >= 1
395         ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent);
396 #else
397         ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent);
398 #endif
399         return wrap (ins);
400 }
401
402 LLVMValueRef
403 mono_llvm_build_atomic_rmw (LLVMBuilderRef builder, AtomicRMWOp op, LLVMValueRef ptr, LLVMValueRef val)
404 {
405         AtomicRMWInst::BinOp aop = AtomicRMWInst::Xchg;
406         AtomicRMWInst *ins;
407
408         switch (op) {
409         case LLVM_ATOMICRMW_OP_XCHG:
410                 aop = AtomicRMWInst::Xchg;
411                 break;
412         case LLVM_ATOMICRMW_OP_ADD:
413                 aop = AtomicRMWInst::Add;
414                 break;
415         default:
416                 g_assert_not_reached ();
417                 break;
418         }
419
420         ins = unwrap (builder)->CreateAtomicRMW (aop, unwrap (ptr), unwrap (val), SequentiallyConsistent);
421         return wrap (ins);
422 }
423
424 LLVMValueRef
425 mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind)
426 {
427         FenceInst *ins;
428         AtomicOrdering ordering;
429
430         g_assert (kind != LLVM_BARRIER_NONE);
431
432         switch (kind) {
433         case LLVM_BARRIER_ACQ:
434                 ordering = Acquire;
435                 break;
436         case LLVM_BARRIER_REL:
437                 ordering = Release;
438                 break;
439         case LLVM_BARRIER_SEQ:
440                 ordering = SequentiallyConsistent;
441                 break;
442         default:
443                 g_assert_not_reached ();
444                 break;
445         }
446
447         ins = unwrap (builder)->CreateFence (ordering);
448         return wrap (ins);
449 }
450
451 void
452 mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v)
453 {
454         Value *V = ConstantExpr::getTruncOrBitCast (unwrap<Constant> (v), unwrap (var)->getType ());
455         unwrap (var)->replaceAllUsesWith (V);
456 }
457
458 static cl::list<const PassInfo*, bool, PassNameParser>
459 PassList(cl::desc("Optimizations available:"));
460
461 static void
462 force_pass_linking (void)
463 {
464         // Make sure the rest is linked in, but never executed
465         if (g_getenv ("FOO") != (char*)-1)
466                 return;
467
468         // This is a subset of the passes in LinkAllPasses.h
469         // The utility passes and the interprocedural passes are commented out
470
471       (void) llvm::createAAEvalPass();
472       (void) llvm::createAggressiveDCEPass();
473       (void) llvm::createAliasAnalysisCounterPass();
474       (void) llvm::createAliasDebugger();
475           /*
476       (void) llvm::createArgumentPromotionPass();
477       (void) llvm::createStructRetPromotionPass();
478           */
479       (void) llvm::createBasicAliasAnalysisPass();
480       (void) llvm::createLibCallAliasAnalysisPass(0);
481       (void) llvm::createScalarEvolutionAliasAnalysisPass();
482       //(void) llvm::createBlockPlacementPass();
483       (void) llvm::createBreakCriticalEdgesPass();
484       (void) llvm::createCFGSimplificationPass();
485           /*
486       (void) llvm::createConstantMergePass();
487       (void) llvm::createConstantPropagationPass();
488           */
489           /*
490       (void) llvm::createDeadArgEliminationPass();
491           */
492       (void) llvm::createDeadCodeEliminationPass();
493       (void) llvm::createDeadInstEliminationPass();
494       (void) llvm::createDeadStoreEliminationPass();
495           /*
496       (void) llvm::createDeadTypeEliminationPass();
497       (void) llvm::createDomOnlyPrinterPass();
498       (void) llvm::createDomPrinterPass();
499       (void) llvm::createDomOnlyViewerPass();
500       (void) llvm::createDomViewerPass();
501       (void) llvm::createEdgeProfilerPass();
502       (void) llvm::createOptimalEdgeProfilerPass();
503       (void) llvm::createFunctionInliningPass();
504       (void) llvm::createAlwaysInlinerPass();
505       (void) llvm::createGlobalDCEPass();
506       (void) llvm::createGlobalOptimizerPass();
507       (void) llvm::createGlobalsModRefPass();
508       (void) llvm::createIPConstantPropagationPass();
509       (void) llvm::createIPSCCPPass();
510           */
511       (void) llvm::createIndVarSimplifyPass();
512       (void) llvm::createInstructionCombiningPass();
513           /*
514       (void) llvm::createInternalizePass(false);
515           */
516       (void) llvm::createLCSSAPass();
517       (void) llvm::createLICMPass();
518       (void) llvm::createLazyValueInfoPass();
519       //(void) llvm::createLoopDependenceAnalysisPass();
520           /*
521       (void) llvm::createLoopExtractorPass();
522           */
523       (void) llvm::createLoopSimplifyPass();
524       (void) llvm::createLoopStrengthReducePass();
525       (void) llvm::createLoopUnrollPass();
526       (void) llvm::createLoopUnswitchPass();
527       (void) llvm::createLoopRotatePass();
528       (void) llvm::createLowerInvokePass();
529           /*
530       (void) llvm::createLowerSetJmpPass();
531           */
532       (void) llvm::createLowerSwitchPass();
533       (void) llvm::createNoAAPass();
534           /*
535       (void) llvm::createNoProfileInfoPass();
536       (void) llvm::createProfileEstimatorPass();
537       (void) llvm::createProfileVerifierPass();
538       (void) llvm::createProfileLoaderPass();
539           */
540       (void) llvm::createPromoteMemoryToRegisterPass();
541       (void) llvm::createDemoteRegisterToMemoryPass();
542           /*
543       (void) llvm::createPruneEHPass();
544       (void) llvm::createPostDomOnlyPrinterPass();
545       (void) llvm::createPostDomPrinterPass();
546       (void) llvm::createPostDomOnlyViewerPass();
547       (void) llvm::createPostDomViewerPass();
548           */
549       (void) llvm::createReassociatePass();
550       (void) llvm::createSCCPPass();
551       (void) llvm::createScalarReplAggregatesPass();
552       //(void) llvm::createSimplifyLibCallsPass();
553           /*
554       (void) llvm::createSingleLoopExtractorPass();
555       (void) llvm::createStripSymbolsPass();
556       (void) llvm::createStripNonDebugSymbolsPass();
557       (void) llvm::createStripDeadDebugInfoPass();
558       (void) llvm::createStripDeadPrototypesPass();
559       (void) llvm::createTailCallEliminationPass();
560       (void) llvm::createTailDuplicationPass();
561       (void) llvm::createJumpThreadingPass();
562           */
563           /*
564       (void) llvm::createUnifyFunctionExitNodesPass();
565           */
566       (void) llvm::createInstCountPass();
567       (void) llvm::createCodeGenPreparePass();
568       (void) llvm::createGVNPass();
569       (void) llvm::createMemCpyOptPass();
570       (void) llvm::createLoopDeletionPass();
571           /*
572       (void) llvm::createPostDomTree();
573       (void) llvm::createPostDomFrontier();
574       (void) llvm::createInstructionNamerPass();
575       (void) llvm::createPartialSpecializationPass();
576       (void) llvm::createFunctionAttrsPass();
577       (void) llvm::createMergeFunctionsPass();
578       (void) llvm::createPrintModulePass(0);
579       (void) llvm::createPrintFunctionPass("", 0);
580       (void) llvm::createDbgInfoPrinterPass();
581       (void) llvm::createModuleDebugInfoPrinterPass();
582       (void) llvm::createPartialInliningPass();
583       (void) llvm::createGEPSplitterPass();
584       (void) llvm::createLintPass();
585           */
586       (void) llvm::createSinkingPass();
587 }
588
589 #ifndef MONO_CROSS_COMPILE
590
591 static gboolean inited;
592
593 static void
594 init_llvm (void)
595 {
596         if (inited)
597                 return;
598
599   force_pass_linking ();
600
601 #ifdef TARGET_ARM
602   LLVMInitializeARMTarget ();
603   LLVMInitializeARMTargetInfo ();
604   LLVMInitializeARMTargetMC ();
605 #else
606   LLVMInitializeX86Target ();
607   LLVMInitializeX86TargetInfo ();
608   LLVMInitializeX86TargetMC ();
609 #endif
610
611   PassRegistry &Registry = *PassRegistry::getPassRegistry();
612   initializeCore(Registry);
613   initializeScalarOpts(Registry);
614   initializeAnalysis(Registry);
615   initializeIPA(Registry);
616   initializeTransformUtils(Registry);
617   initializeInstCombine(Registry);
618   initializeTarget(Registry);
619
620   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
621
622   inited = true;
623 }
624
625 MonoEERef
626 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
627 {
628   std::string Error;
629   MonoEE *mono_ee;
630
631   init_llvm ();
632
633   mono_ee = new MonoEE ();
634
635   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
636   mono_mm->alloc_cb = alloc_cb;
637   mono_mm->dlsym_cb = dlsym_cb;
638   mono_ee->mm = mono_mm;
639
640   /*
641    * The Default code model doesn't seem to work on amd64,
642    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
643    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
644    */
645
646   TargetOptions opts;
647   opts.JITExceptionHandling = 1;
648
649 #if LLVM_API_VERSION >= 2
650   StringRef cpu_name = sys::getHostCPUName ();
651
652   // EngineBuilder no longer has a copy assignment operator (?)
653   std::unique_ptr<Module> Owner(unwrap(MP));
654   EngineBuilder b (std::move(Owner));
655 #ifdef TARGET_AMD64
656   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).setCodeModel (CodeModel::Large).create ();
657 #else
658   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
659 #endif
660
661 #else
662
663   EngineBuilder b (unwrap (MP));
664   EngineBuilder &eb = b;
665   eb = eb.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true);
666 #if LLVM_API_VERSION >= 1
667   StringRef cpu_name = sys::getHostCPUName ();
668   eb = eb.setMCPU (cpu_name);
669 #endif
670 #ifdef TARGET_AMD64
671   eb = eb.setCodeModel (CodeModel::Large);
672 #endif
673
674   ExecutionEngine *EE = eb.create ();
675 #endif
676
677   g_assert (EE);
678   mono_ee->EE = EE;
679
680   EE->InstallExceptionTableRegister (exception_cb);
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 #if LLVM_API_VERSION >= 1
689   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
690 #else
691   fpm->add(new DataLayout(*EE->getDataLayout()));
692 #endif
693
694   if (PassList.size() > 0) {
695           /* Use the passes specified by the env variable */
696           /* Only the passes in force_pass_linking () can be used */
697           for (unsigned i = 0; i < PassList.size(); ++i) {
698                   const PassInfo *PassInf = PassList[i];
699                   Pass *P = 0;
700
701                   if (PassInf->getNormalCtor())
702                           P = PassInf->getNormalCtor()();
703                   fpm->add (P);
704           }
705   } else {
706           /* Use the same passes used by 'opt' by default, without the ipo passes */
707           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";
708           char **args;
709           int i;
710
711           args = g_strsplit (opts, " ", 1000);
712           for (i = 0; args [i]; i++)
713                   ;
714           llvm::cl::ParseCommandLineOptions (i, args, "");
715           g_strfreev (args);
716
717           for (unsigned i = 0; i < PassList.size(); ++i) {
718                   const PassInfo *PassInf = PassList[i];
719                   Pass *P = 0;
720
721                   if (PassInf->getNormalCtor())
722                           P = PassInf->getNormalCtor()();
723                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
724                   fpm->add (P);
725           }
726
727           /*
728           fpm->add(createInstructionCombiningPass());
729           fpm->add(createReassociatePass());
730           fpm->add(createGVNPass());
731           fpm->add(createCFGSimplificationPass());
732           */
733   }
734
735   *ee = wrap (EE);
736
737   return mono_ee;
738 }
739
740 void
741 mono_llvm_dispose_ee (MonoEERef *eeref)
742 {
743         MonoEE *mono_ee = (MonoEE*)eeref;
744
745         delete mono_ee->EE;
746         delete mono_ee->fpm;
747         //delete mono_ee->mm;
748         delete mono_ee->listener;
749         delete mono_ee;
750 }
751
752 #else
753
754 MonoEERef
755 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
756 {
757         g_assert_not_reached ();
758         return NULL;
759 }
760
761 void
762 mono_llvm_dispose_ee (MonoEERef *eeref)
763 {
764         g_assert_not_reached ();
765 }
766
767 /* Not linked in */
768 void
769 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
770                                          void* Addr)
771 {
772         g_assert_not_reached ();
773 }
774
775 void*
776 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
777 {
778         g_assert_not_reached ();
779         return NULL;
780 }
781
782 #endif /* !MONO_CROSS_COMPILE */