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