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