[mono-config] fix copying of prefix during replacement
[mono.git] / mono / mini / llvm-jit.cpp
1 //
2 // jit-llvm.cpp: Support code for using LLVM as a JIT backend
3 //
4 // (C) 2009-2011 Novell, Inc.
5 // Copyright 2011-2015 Xamarin, Inc (http://www.xamarin.com)
6 //
7
8 //
9 // Mono's internal header files are not C++ clean, so avoid including them if 
10 // possible
11 //
12
13 #include "config.h"
14
15 #include <llvm-c/Core.h>
16 #include <llvm-c/ExecutionEngine.h>
17
18 #include "mini-llvm-cpp.h"
19 #include "llvm-jit.h"
20
21 #if !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION > 100
22
23 /*
24  * LLVM 3.9 uses the OrcJIT APIs
25  */
26
27 #include <llvm/Support/raw_ostream.h>
28 #include <llvm/Support/Host.h>
29 #include <llvm/Support/TargetSelect.h>
30 #include <llvm/ExecutionEngine/ExecutionEngine.h>
31 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
32 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
33 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
34 #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
35 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
36 #include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
37
38 using namespace llvm;
39 using namespace llvm::orc;
40
41 void
42 mono_llvm_set_unhandled_exception_handler (void)
43 {
44 }
45
46 static gboolean inited;
47
48 static void
49 init_llvm (void)
50 {
51         if (inited)
52                 return;
53
54         InitializeNativeTarget ();
55         InitializeNativeTargetAsmPrinter();
56 }
57
58 MonoEERef
59 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
60 {
61         init_llvm ();
62
63         return NULL;
64 }
65
66 void
67 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
68 {
69         g_assert_not_reached ();
70 }
71
72 void
73 mono_llvm_dispose_ee (MonoEERef *eeref)
74 {
75 }
76
77 void
78 LLVMAddGlobalMapping (LLVMExecutionEngineRef EE, LLVMValueRef Global,
79                                           void* Addr)
80 {
81 }
82
83 void*
84 LLVMGetPointerToGlobal (LLVMExecutionEngineRef EE, LLVMValueRef Global)
85 {
86         g_assert_not_reached ();
87         return NULL;
88 }
89
90 #elif !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION < 100
91
92 #include <stdint.h>
93
94 #include <llvm/Support/raw_ostream.h>
95 #include <llvm/Support/Host.h>
96 #include <llvm/PassManager.h>
97 #include <llvm/ExecutionEngine/ExecutionEngine.h>
98 #include <llvm/ExecutionEngine/JITMemoryManager.h>
99 #include <llvm/ExecutionEngine/JITEventListener.h>
100 #include <llvm/Target/TargetOptions.h>
101 #include <llvm/Target/TargetRegisterInfo.h>
102 #include <llvm/IR/Verifier.h>
103 #include <llvm/Analysis/Passes.h>
104 #include <llvm/Transforms/Scalar.h>
105 #include <llvm/Support/CommandLine.h>
106 #include <llvm/IR/LegacyPassNameParser.h>
107 #include <llvm/Support/PrettyStackTrace.h>
108 #include <llvm/CodeGen/Passes.h>
109 #include <llvm/CodeGen/MachineFunctionPass.h>
110 #include <llvm/CodeGen/MachineFunction.h>
111 #include <llvm/CodeGen/MachineFrameInfo.h>
112 #include <llvm/IR/Function.h>
113 #include <llvm/IR/IRBuilder.h>
114 #include <llvm/IR/Module.h>
115
116 using namespace llvm;
117
118 static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;
119
120 void
121 mono_llvm_set_unhandled_exception_handler (void)
122 {
123         std::set_terminate (unhandled_exception);
124 }
125
126 class MonoJITMemoryManager : public JITMemoryManager
127 {
128 private:
129         JITMemoryManager *mm;
130
131 public:
132         /* Callbacks installed by mono */
133         AllocCodeMemoryCb *alloc_cb;
134         DlSymCb *dlsym_cb;
135         ExceptionTableCb *exception_cb;
136
137         MonoJITMemoryManager ();
138         ~MonoJITMemoryManager ();
139
140         void setMemoryWritable (void);
141
142         void setMemoryExecutable (void);
143
144         void AllocateGOT();
145
146     unsigned char *getGOTBase() const {
147                 return mm->getGOTBase ();
148     }
149
150         void setPoisonMemory(bool) {
151         }
152
153         unsigned char *startFunctionBody(const Function *F, 
154                                                                          uintptr_t &ActualSize);
155   
156         unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
157                                                                  unsigned Alignment);
158   
159         void endFunctionBody(const Function *F, unsigned char *FunctionStart,
160                                                  unsigned char *FunctionEnd);
161
162         unsigned char *allocateSpace(intptr_t Size, unsigned Alignment);
163
164         uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
165   
166         void deallocateMemForFunction(const Function *F);
167   
168         unsigned char*startExceptionTable(const Function* F,
169                                                                           uintptr_t &ActualSize);
170   
171         void endExceptionTable(const Function *F, unsigned char *TableStart,
172                                                    unsigned char *TableEnd, 
173                                                    unsigned char* FrameRegister);
174
175         virtual void deallocateFunctionBody(void*) {
176         }
177
178         virtual void deallocateExceptionTable(void*) {
179         }
180
181         virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
182                                                                                  StringRef SectionName) {
183                 // FIXME:
184                 assert(0);
185                 return NULL;
186         }
187
188         virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
189                                                                                  StringRef SectionName, bool IsReadOnly) {
190                 // FIXME:
191                 assert(0);
192                 return NULL;
193         }
194
195         virtual bool applyPermissions(std::string*) {
196                 // FIXME:
197                 assert(0);
198                 return false;
199         }
200
201         virtual bool finalizeMemory(std::string *ErrMsg = 0) {
202                 // FIXME:
203                 assert(0);
204                 return false;
205         }
206
207         virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
208                 void *res;
209                 char *err;
210
211                 err = dlsym_cb (Name.c_str (), &res);
212                 if (err) {
213                         outs () << "Unable to resolve: " << Name << ": " << err << "\n";
214                         assert(0);
215                         return NULL;
216                 }
217                 return res;
218         }
219 };
220
221 MonoJITMemoryManager::MonoJITMemoryManager ()
222 {
223         mm = JITMemoryManager::CreateDefaultMemManager ();
224 }
225
226 MonoJITMemoryManager::~MonoJITMemoryManager ()
227 {
228         delete mm;
229 }
230
231 void
232 MonoJITMemoryManager::setMemoryWritable (void)
233 {
234 }
235
236 void
237 MonoJITMemoryManager::setMemoryExecutable (void)
238 {
239 }
240
241 void
242 MonoJITMemoryManager::AllocateGOT()
243 {
244         mm->AllocateGOT ();
245 }
246
247 unsigned char *
248 MonoJITMemoryManager::startFunctionBody(const Function *F, 
249                                         uintptr_t &ActualSize)
250 {
251         // FIXME: This leaks memory
252         if (ActualSize == 0)
253                 ActualSize = 128;
254         return alloc_cb (wrap (F), ActualSize);
255 }
256   
257 unsigned char *
258 MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
259                            unsigned Alignment)
260 {
261         return alloc_cb (wrap (F), StubSize);
262 }
263   
264 void
265 MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart,
266                                   unsigned char *FunctionEnd)
267 {
268 }
269
270 unsigned char *
271 MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
272 {
273         return new unsigned char [Size];
274 }
275
276 uint8_t *
277 MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
278 {
279         return new unsigned char [Size];
280 }
281
282 void
283 MonoJITMemoryManager::deallocateMemForFunction(const Function *F)
284 {
285 }
286   
287 unsigned char*
288 MonoJITMemoryManager::startExceptionTable(const Function* F,
289                                           uintptr_t &ActualSize)
290 {
291         return startFunctionBody(F, ActualSize);
292 }
293   
294 void
295 MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart,
296                                         unsigned char *TableEnd, 
297                                         unsigned char* FrameRegister)
298 {
299         exception_cb (FrameRegister);
300 }
301
302 class MonoJITEventListener : public JITEventListener {
303
304 public:
305         FunctionEmittedCb *emitted_cb;
306
307         MonoJITEventListener (FunctionEmittedCb *cb) {
308                 emitted_cb = cb;
309         }
310
311         virtual void NotifyFunctionEmitted(const Function &F,
312                                                                            void *Code, size_t Size,
313                                                                            const EmittedFunctionDetails &Details) {
314                 emitted_cb (wrap (&F), Code, (char*)Code + Size);
315         }
316 };
317
318 class MonoEE {
319 public:
320         ExecutionEngine *EE;
321         MonoJITMemoryManager *mm;
322         MonoJITEventListener *listener;
323         FunctionPassManager *fpm;
324 };
325
326 void
327 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
328 {
329         MonoEE *mono_ee = (MonoEE*)eeref;
330
331         /*
332          * The verifier does some checks on the whole module, leading to quadratic behavior.
333          */
334         //verifyFunction (*(unwrap<Function> (method)));
335         mono_ee->fpm->run (*unwrap<Function> (method));
336 }
337
338 static cl::list<const PassInfo*, bool, PassNameParser>
339 PassList(cl::desc("Optimizations available:"));
340
341 static void
342 force_pass_linking (void)
343 {
344         // Make sure the rest is linked in, but never executed
345         if (g_getenv ("FOO") != (char*)-1)
346                 return;
347
348         // This is a subset of the passes in LinkAllPasses.h
349         // The utility passes and the interprocedural passes are commented out
350
351       (void) llvm::createAAEvalPass();
352       (void) llvm::createAggressiveDCEPass();
353       (void) llvm::createAliasAnalysisCounterPass();
354       (void) llvm::createAliasDebugger();
355           /*
356       (void) llvm::createArgumentPromotionPass();
357       (void) llvm::createStructRetPromotionPass();
358           */
359       (void) llvm::createBasicAliasAnalysisPass();
360       (void) llvm::createLibCallAliasAnalysisPass(0);
361       (void) llvm::createScalarEvolutionAliasAnalysisPass();
362       //(void) llvm::createBlockPlacementPass();
363       (void) llvm::createBreakCriticalEdgesPass();
364       (void) llvm::createCFGSimplificationPass();
365           /*
366       (void) llvm::createConstantMergePass();
367       (void) llvm::createConstantPropagationPass();
368           */
369           /*
370       (void) llvm::createDeadArgEliminationPass();
371           */
372       (void) llvm::createDeadCodeEliminationPass();
373       (void) llvm::createDeadInstEliminationPass();
374       (void) llvm::createDeadStoreEliminationPass();
375           /*
376       (void) llvm::createDeadTypeEliminationPass();
377       (void) llvm::createDomOnlyPrinterPass();
378       (void) llvm::createDomPrinterPass();
379       (void) llvm::createDomOnlyViewerPass();
380       (void) llvm::createDomViewerPass();
381       (void) llvm::createEdgeProfilerPass();
382       (void) llvm::createOptimalEdgeProfilerPass();
383       (void) llvm::createFunctionInliningPass();
384       (void) llvm::createAlwaysInlinerPass();
385       (void) llvm::createGlobalDCEPass();
386       (void) llvm::createGlobalOptimizerPass();
387       (void) llvm::createGlobalsModRefPass();
388       (void) llvm::createIPConstantPropagationPass();
389       (void) llvm::createIPSCCPPass();
390           */
391       (void) llvm::createIndVarSimplifyPass();
392       (void) llvm::createInstructionCombiningPass();
393           /*
394       (void) llvm::createInternalizePass(false);
395           */
396       (void) llvm::createLCSSAPass();
397       (void) llvm::createLICMPass();
398       (void) llvm::createLazyValueInfoPass();
399       //(void) llvm::createLoopDependenceAnalysisPass();
400           /*
401       (void) llvm::createLoopExtractorPass();
402           */
403       (void) llvm::createLoopSimplifyPass();
404       (void) llvm::createLoopStrengthReducePass();
405       (void) llvm::createLoopUnrollPass();
406       (void) llvm::createLoopUnswitchPass();
407       (void) llvm::createLoopRotatePass();
408       (void) llvm::createLowerInvokePass();
409           /*
410       (void) llvm::createLowerSetJmpPass();
411           */
412       (void) llvm::createLowerSwitchPass();
413       (void) llvm::createNoAAPass();
414           /*
415       (void) llvm::createNoProfileInfoPass();
416       (void) llvm::createProfileEstimatorPass();
417       (void) llvm::createProfileVerifierPass();
418       (void) llvm::createProfileLoaderPass();
419           */
420       (void) llvm::createPromoteMemoryToRegisterPass();
421       (void) llvm::createDemoteRegisterToMemoryPass();
422           /*
423       (void) llvm::createPruneEHPass();
424       (void) llvm::createPostDomOnlyPrinterPass();
425       (void) llvm::createPostDomPrinterPass();
426       (void) llvm::createPostDomOnlyViewerPass();
427       (void) llvm::createPostDomViewerPass();
428           */
429       (void) llvm::createReassociatePass();
430       (void) llvm::createSCCPPass();
431       (void) llvm::createScalarReplAggregatesPass();
432       //(void) llvm::createSimplifyLibCallsPass();
433           /*
434       (void) llvm::createSingleLoopExtractorPass();
435       (void) llvm::createStripSymbolsPass();
436       (void) llvm::createStripNonDebugSymbolsPass();
437       (void) llvm::createStripDeadDebugInfoPass();
438       (void) llvm::createStripDeadPrototypesPass();
439       (void) llvm::createTailCallEliminationPass();
440       (void) llvm::createTailDuplicationPass();
441       (void) llvm::createJumpThreadingPass();
442           */
443           /*
444       (void) llvm::createUnifyFunctionExitNodesPass();
445           */
446       (void) llvm::createInstCountPass();
447       (void) llvm::createCodeGenPreparePass();
448       (void) llvm::createGVNPass();
449       (void) llvm::createMemCpyOptPass();
450       (void) llvm::createLoopDeletionPass();
451           /*
452       (void) llvm::createPostDomTree();
453       (void) llvm::createPostDomFrontier();
454       (void) llvm::createInstructionNamerPass();
455       (void) llvm::createPartialSpecializationPass();
456       (void) llvm::createFunctionAttrsPass();
457       (void) llvm::createMergeFunctionsPass();
458       (void) llvm::createPrintModulePass(0);
459       (void) llvm::createPrintFunctionPass("", 0);
460       (void) llvm::createDbgInfoPrinterPass();
461       (void) llvm::createModuleDebugInfoPrinterPass();
462       (void) llvm::createPartialInliningPass();
463       (void) llvm::createGEPSplitterPass();
464       (void) llvm::createLintPass();
465           */
466       (void) llvm::createSinkingPass();
467 }
468
469 static gboolean inited;
470
471 static void
472 init_llvm (void)
473 {
474         if (inited)
475                 return;
476
477   force_pass_linking ();
478
479 #ifdef TARGET_ARM
480   LLVMInitializeARMTarget ();
481   LLVMInitializeARMTargetInfo ();
482   LLVMInitializeARMTargetMC ();
483 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
484   LLVMInitializeX86Target ();
485   LLVMInitializeX86TargetInfo ();
486   LLVMInitializeX86TargetMC ();
487 #elif defined(TARGET_POWERPC)
488   LLVMInitializePowerPCTarget ();
489   LLVMInitializePowerPCTargetInfo ();
490   LLVMInitializePowerPCTargetMC ();
491 #else
492   #error Unsupported mono-llvm target
493 #endif
494
495   PassRegistry &Registry = *PassRegistry::getPassRegistry();
496   initializeCore(Registry);
497   initializeScalarOpts(Registry);
498   initializeAnalysis(Registry);
499   initializeIPA(Registry);
500   initializeTransformUtils(Registry);
501   initializeInstCombine(Registry);
502   initializeTarget(Registry);
503
504   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
505
506   inited = true;
507 }
508
509 MonoEERef
510 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
511 {
512   std::string Error;
513   MonoEE *mono_ee;
514
515   init_llvm ();
516
517   mono_ee = new MonoEE ();
518
519   MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
520   mono_mm->alloc_cb = alloc_cb;
521   mono_mm->dlsym_cb = dlsym_cb;
522   mono_mm->exception_cb = exception_cb;
523   mono_ee->mm = mono_mm;
524
525   /*
526    * The Default code model doesn't seem to work on amd64,
527    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
528    * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
529    */
530
531   TargetOptions opts;
532   opts.JITExceptionHandling = 1;
533
534   StringRef cpu_name = sys::getHostCPUName ();
535
536   // EngineBuilder no longer has a copy assignment operator (?)
537   std::unique_ptr<Module> Owner(unwrap(MP));
538   EngineBuilder b (std::move(Owner));
539   ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
540
541   g_assert (EE);
542   mono_ee->EE = EE;
543
544   MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
545   EE->RegisterJITEventListener (listener);
546   mono_ee->listener = listener;
547
548   FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
549   mono_ee->fpm = fpm;
550
551   fpm->add(new DataLayoutPass(*EE->getDataLayout()));
552
553   if (PassList.size() > 0) {
554           /* Use the passes specified by the env variable */
555           /* Only the passes in force_pass_linking () can be used */
556           for (unsigned i = 0; i < PassList.size(); ++i) {
557                   const PassInfo *PassInf = PassList[i];
558                   Pass *P = 0;
559
560                   if (PassInf->getNormalCtor())
561                           P = PassInf->getNormalCtor()();
562                   fpm->add (P);
563           }
564   } else {
565           /* Use the same passes used by 'opt' by default, without the ipo passes */
566           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";
567           char **args;
568           int i;
569
570           args = g_strsplit (opts, " ", 1000);
571           for (i = 0; args [i]; i++)
572                   ;
573           llvm::cl::ParseCommandLineOptions (i, args, "");
574           g_strfreev (args);
575
576           for (unsigned i = 0; i < PassList.size(); ++i) {
577                   const PassInfo *PassInf = PassList[i];
578                   Pass *P = 0;
579
580                   if (PassInf->getNormalCtor())
581                           P = PassInf->getNormalCtor()();
582                   g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
583                   fpm->add (P);
584           }
585
586           /*
587           fpm->add(createInstructionCombiningPass());
588           fpm->add(createReassociatePass());
589           fpm->add(createGVNPass());
590           fpm->add(createCFGSimplificationPass());
591           */
592   }
593
594   *ee = wrap (EE);
595
596   return mono_ee;
597 }
598
599 void
600 mono_llvm_dispose_ee (MonoEERef *eeref)
601 {
602         MonoEE *mono_ee = (MonoEE*)eeref;
603
604         delete mono_ee->EE;
605         delete mono_ee->fpm;
606         //delete mono_ee->mm;
607         delete mono_ee->listener;
608         delete mono_ee;
609 }
610
611 #else /* MONO_CROSS_COMPILE */
612
613 void
614 mono_llvm_set_unhandled_exception_handler (void)
615 {
616 }
617
618 MonoEERef
619 mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
620 {
621         g_assert_not_reached ();
622         return NULL;
623 }
624
625 void
626 mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
627 {
628         g_assert_not_reached ();
629 }
630
631 void
632 mono_llvm_dispose_ee (MonoEERef *eeref)
633 {
634         g_assert_not_reached ();
635 }
636
637 /* Not linked in */
638 void
639 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
640                                          void* Addr)
641 {
642         g_assert_not_reached ();
643 }
644
645 void*
646 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
647 {
648         g_assert_not_reached ();
649         return NULL;
650 }
651
652 #endif /* !MONO_CROSS_COMPILE */