2 // jit-llvm.cpp: Support code for using LLVM as a JIT backend
4 // (C) 2009-2011 Novell, Inc.
5 // Copyright 2011-2015 Xamarin, Inc (http://www.xamarin.com)
7 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
9 // Mono's internal header files are not C++ clean, so avoid including them if
15 #include <llvm-c/Core.h>
16 #include <llvm-c/ExecutionEngine.h>
18 #include "mini-llvm-cpp.h"
21 #if defined(MONO_ARCH_LLVM_JIT_SUPPORTED) && !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION > 100
24 * LLVM 3.9 uses the OrcJIT APIs
27 #include <llvm/Support/raw_ostream.h>
28 #include <llvm/Support/Host.h>
29 #include <llvm/Support/TargetSelect.h>
30 #include <llvm/IR/Mangler.h>
31 #include <llvm/ExecutionEngine/ExecutionEngine.h>
32 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
33 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
34 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
35 #if LLVM_API_VERSION >= 500
36 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
37 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
38 #include "llvm/ExecutionEngine/JITSymbol.h"
40 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
46 #include <mono/utils/mono-dl.h>
50 using namespace llvm::orc
;
52 extern cl::opt
<bool> EnableMonoEH
;
53 extern cl::opt
<std::string
> MonoEHFrameSymbol
;
56 mono_llvm_set_unhandled_exception_handler (void)
61 static std::vector
<T
> singletonSet(T t
) {
63 Vec
.push_back(std::move(t
));
70 extern void *memset(void *, int, size_t);
71 void bzero (void *to
, size_t count
) { memset (to
, 0, count
); }
75 static AllocCodeMemoryCb
*alloc_code_mem_cb
;
77 class MonoJitMemoryManager
: public RTDyldMemoryManager
80 ~MonoJitMemoryManager() override
;
82 uint8_t *allocateDataSection(uintptr_t Size
,
85 StringRef SectionName
,
86 bool IsReadOnly
) override
;
88 uint8_t *allocateCodeSection(uintptr_t Size
,
91 StringRef SectionName
) override
;
93 bool finalizeMemory(std::string
*ErrMsg
= nullptr) override
;
96 MonoJitMemoryManager::~MonoJitMemoryManager()
101 MonoJitMemoryManager::allocateDataSection(uintptr_t Size
,
104 StringRef SectionName
,
106 uint8_t *res
= (uint8_t*)malloc (Size
);
108 memset (res
, 0, Size
);
113 MonoJitMemoryManager::allocateCodeSection(uintptr_t Size
,
116 StringRef SectionName
)
118 return alloc_code_mem_cb (NULL
, Size
);
122 MonoJitMemoryManager::finalizeMemory(std::string
*ErrMsg
)
129 /* We use our own trampoline infrastructure instead of the Orc one */
130 #if LLVM_API_VERSION >= 500
131 typedef RTDyldObjectLinkingLayer ObjLayerT
;
132 typedef IRCompileLayer
<ObjLayerT
, SimpleCompiler
> CompileLayerT
;
133 typedef CompileLayerT::ModuleHandleT ModuleHandleT
;
135 typedef ObjectLinkingLayer
<> ObjLayerT
;
136 typedef IRCompileLayer
<ObjLayerT
> CompileLayerT
;
137 typedef CompileLayerT::ModuleSetHandleT ModuleHandleT
;
140 MonoLLVMJIT (TargetMachine
*TM
, MonoJitMemoryManager
*mm
)
141 #if LLVM_API_VERSION >= 500
142 : TM(TM
), ObjectLayer([=] { return std::shared_ptr
<RuntimeDyld::MemoryManager
> (mm
); }),
146 CompileLayer (ObjectLayer
, SimpleCompiler (*TM
)),
150 #if LLVM_API_VERSION >= 500
151 ModuleHandleT
addModule(Function
*F
, std::shared_ptr
<Module
> M
) {
153 ModuleHandleT
addModule(Function
*F
, Module
*M
) {
155 auto Resolver
= createLambdaResolver(
156 [&](const std::string
&Name
) {
157 const char *name
= Name
.c_str ();
158 #if LLVM_API_VERSION >= 500
159 JITSymbolFlags flags
= JITSymbolFlags ();
161 JITSymbolFlags flags
= (JITSymbolFlags
)0;
163 if (!strcmp (name
, "___bzero")) {
164 #if LLVM_API_VERSION >= 500
165 return JITSymbol((uint64_t)(gssize
)(void*)bzero
, flags
);
167 return RuntimeDyld::SymbolInfo((uint64_t)(gssize
)(void*)bzero
, flags
);
174 current
= mono_dl_open (NULL
, 0, NULL
);
177 err
= mono_dl_symbol (current
, name
+ 1, &symbol
);
179 err
= mono_dl_symbol (current
, name
, &symbol
);
180 mono_dl_close (current
);
182 outs () << "R: " << Name
<< "\n";
184 #if LLVM_API_VERSION >= 500
185 return JITSymbol((uint64_t)(gssize
)symbol
, flags
);
187 return RuntimeDyld::SymbolInfo((uint64_t)(gssize
)symbol
, flags
);
190 [](const std::string
&S
) {
191 outs () << "R2: " << S
<< "\n";
196 #if LLVM_API_VERSION >= 500
197 auto m
= CompileLayer
.addModule(M
, std::move(Resolver
));
201 return CompileLayer
.addModuleSet(singletonSet(M
),
202 make_unique
<MonoJitMemoryManager
>(),
203 std::move(Resolver
));
207 std::string
mangle(const std::string
&Name
) {
208 std::string MangledName
;
210 raw_string_ostream
MangledNameStream(MangledName
);
211 Mangler::getNameWithPrefix(MangledNameStream
, Name
,
212 TM
->createDataLayout());
217 std::string
mangle(const GlobalValue
*GV
) {
218 std::string MangledName
;
222 raw_string_ostream
MangledNameStream(MangledName
);
223 Mang
.getNameWithPrefix(MangledNameStream
, GV
, false);
228 gpointer
compile (Function
*F
, int nvars
, LLVMValueRef
*callee_vars
, gpointer
*callee_addrs
, gpointer
*eh_frame
) {
229 F
->getParent ()->setDataLayout (TM
->createDataLayout ());
230 #if LLVM_API_VERSION >= 500
231 // Orc uses a shared_ptr to refer to modules so we have to save them ourselves to keep a ref
232 std::shared_ptr
<Module
> m (F
->getParent ());
233 modules
.push_back (m
);
234 auto ModuleHandle
= addModule (F
, m
);
236 auto ModuleHandle
= addModule (F
, F
->getParent ());
238 auto BodySym
= CompileLayer
.findSymbolIn(ModuleHandle
, mangle (F
), false);
239 auto BodyAddr
= BodySym
.getAddress();
242 for (int i
= 0; i
< nvars
; ++i
) {
243 GlobalVariable
*var
= unwrap
<GlobalVariable
>(callee_vars
[i
]);
245 auto sym
= CompileLayer
.findSymbolIn (ModuleHandle
, mangle (var
->getName ()), true);
246 auto addr
= sym
.getAddress ();
247 #if LLVM_API_VERSION >= 500
248 g_assert ((bool)addr
);
249 callee_addrs
[i
] = (gpointer
)addr
.get ();
252 callee_addrs
[i
] = (gpointer
)addr
;
256 auto ehsym
= CompileLayer
.findSymbolIn(ModuleHandle
, "mono_eh_frame", false);
257 auto ehaddr
= ehsym
.getAddress ();
258 #if LLVM_API_VERSION >= 500
259 g_assert ((bool)ehaddr
);
260 *eh_frame
= (gpointer
)ehaddr
.get ();
261 return (gpointer
)BodyAddr
.get ();
264 *eh_frame
= (gpointer
)ehaddr
;
265 return (gpointer
)BodyAddr
;
271 ObjLayerT ObjectLayer
;
272 CompileLayerT CompileLayer
;
273 std::vector
<std::shared_ptr
<Module
>> modules
;
276 static MonoLLVMJIT
*jit
;
277 static MonoJitMemoryManager
*mono_mm
;
280 mono_llvm_create_ee (LLVMModuleProviderRef MP
, AllocCodeMemoryCb
*alloc_cb
, FunctionEmittedCb
*emitted_cb
, ExceptionTableCb
*exception_cb
, DlSymCb
*dlsym_cb
, LLVMExecutionEngineRef
*ee
)
282 alloc_code_mem_cb
= alloc_cb
;
284 InitializeNativeTarget ();
285 InitializeNativeTargetAsmPrinter();
288 MonoEHFrameSymbol
= "mono_eh_frame";
291 #if defined(TARGET_AMD64) || defined(TARGET_X86)
292 std::vector
<std::string
> attrs
;
293 // FIXME: Autodetect this
294 attrs
.push_back("sse3");
295 attrs
.push_back("sse4.1");
296 EB
.setMAttrs (attrs
);
298 auto TM
= EB
.selectTarget ();
301 mono_mm
= new MonoJitMemoryManager ();
302 jit
= new MonoLLVMJIT (TM
, mono_mm
);
308 * mono_llvm_compile_method:
310 * Compile METHOD to native code. Compute the addresses of the variables in CALLEE_VARS and store them into
311 * CALLEE_ADDRS. Return the EH frame address in EH_FRAME.
314 mono_llvm_compile_method (MonoEERef mono_ee
, LLVMValueRef method
, int nvars
, LLVMValueRef
*callee_vars
, gpointer
*callee_addrs
, gpointer
*eh_frame
)
316 return jit
->compile (unwrap
<Function
> (method
), nvars
, callee_vars
, callee_addrs
, eh_frame
);
320 mono_llvm_dispose_ee (MonoEERef
*eeref
)
325 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE
, LLVMValueRef Global
,
328 g_assert_not_reached ();
332 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE
, LLVMValueRef Global
)
334 g_assert_not_reached ();
338 #elif defined(MONO_ARCH_LLVM_JIT_SUPPORTED) && !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION < 100
342 #include <llvm/Support/raw_ostream.h>
343 #include <llvm/Support/Host.h>
344 #include <llvm/PassManager.h>
345 #include <llvm/ExecutionEngine/ExecutionEngine.h>
346 #include <llvm/ExecutionEngine/JITMemoryManager.h>
347 #include <llvm/ExecutionEngine/JITEventListener.h>
348 #include <llvm/Target/TargetOptions.h>
349 #include <llvm/Target/TargetRegisterInfo.h>
350 #include <llvm/IR/Verifier.h>
351 #include <llvm/Analysis/Passes.h>
352 #include <llvm/Transforms/Scalar.h>
353 #include <llvm/Support/CommandLine.h>
354 #include <llvm/IR/LegacyPassNameParser.h>
355 #include <llvm/Support/PrettyStackTrace.h>
356 #include <llvm/CodeGen/Passes.h>
357 #include <llvm/CodeGen/MachineFunctionPass.h>
358 #include <llvm/CodeGen/MachineFunction.h>
359 #include <llvm/CodeGen/MachineFrameInfo.h>
360 #include <llvm/IR/Function.h>
361 #include <llvm/IR/IRBuilder.h>
362 #include <llvm/IR/Module.h>
364 using namespace llvm
;
366 static void (*unhandled_exception
)() = default_mono_llvm_unhandled_exception
;
369 mono_llvm_set_unhandled_exception_handler (void)
371 std::set_terminate (unhandled_exception
);
374 class MonoJITMemoryManager
: public JITMemoryManager
377 JITMemoryManager
*mm
;
380 /* Callbacks installed by mono */
381 AllocCodeMemoryCb
*alloc_cb
;
383 ExceptionTableCb
*exception_cb
;
385 MonoJITMemoryManager ();
386 ~MonoJITMemoryManager ();
388 void setMemoryWritable (void);
390 void setMemoryExecutable (void);
394 unsigned char *getGOTBase() const {
395 return mm
->getGOTBase ();
398 void setPoisonMemory(bool) {
401 unsigned char *startFunctionBody(const Function
*F
,
402 uintptr_t &ActualSize
);
404 unsigned char *allocateStub(const GlobalValue
* F
, unsigned StubSize
,
407 void endFunctionBody(const Function
*F
, unsigned char *FunctionStart
,
408 unsigned char *FunctionEnd
);
410 unsigned char *allocateSpace(intptr_t Size
, unsigned Alignment
);
412 uint8_t *allocateGlobal(uintptr_t Size
, unsigned Alignment
);
414 void deallocateMemForFunction(const Function
*F
);
416 unsigned char*startExceptionTable(const Function
* F
,
417 uintptr_t &ActualSize
);
419 void endExceptionTable(const Function
*F
, unsigned char *TableStart
,
420 unsigned char *TableEnd
,
421 unsigned char* FrameRegister
);
423 virtual void deallocateFunctionBody(void*) {
426 virtual void deallocateExceptionTable(void*) {
429 virtual uint8_t *allocateCodeSection(uintptr_t Size
, unsigned Alignment
, unsigned SectionID
,
430 StringRef SectionName
) {
436 virtual uint8_t *allocateDataSection(uintptr_t Size
, unsigned Alignment
, unsigned SectionID
,
437 StringRef SectionName
, bool IsReadOnly
) {
443 virtual bool applyPermissions(std::string
*) {
449 virtual bool finalizeMemory(std::string
*ErrMsg
= 0) {
455 virtual void* getPointerToNamedFunction(const std::string
&Name
, bool AbortOnFailure
) {
459 err
= dlsym_cb (Name
.c_str (), &res
);
461 outs () << "Unable to resolve: " << Name
<< ": " << err
<< "\n";
469 MonoJITMemoryManager::MonoJITMemoryManager ()
471 mm
= JITMemoryManager::CreateDefaultMemManager ();
474 MonoJITMemoryManager::~MonoJITMemoryManager ()
480 MonoJITMemoryManager::setMemoryWritable (void)
485 MonoJITMemoryManager::setMemoryExecutable (void)
490 MonoJITMemoryManager::AllocateGOT()
496 MonoJITMemoryManager::startFunctionBody(const Function
*F
,
497 uintptr_t &ActualSize
)
499 // FIXME: This leaks memory
502 return alloc_cb (wrap (F
), ActualSize
);
506 MonoJITMemoryManager::allocateStub(const GlobalValue
* F
, unsigned StubSize
,
509 return alloc_cb (wrap (F
), StubSize
);
513 MonoJITMemoryManager::endFunctionBody(const Function
*F
, unsigned char *FunctionStart
,
514 unsigned char *FunctionEnd
)
519 MonoJITMemoryManager::allocateSpace(intptr_t Size
, unsigned Alignment
)
521 return new unsigned char [Size
];
525 MonoJITMemoryManager::allocateGlobal(uintptr_t Size
, unsigned Alignment
)
527 return new unsigned char [Size
];
531 MonoJITMemoryManager::deallocateMemForFunction(const Function
*F
)
536 MonoJITMemoryManager::startExceptionTable(const Function
* F
,
537 uintptr_t &ActualSize
)
539 return startFunctionBody(F
, ActualSize
);
543 MonoJITMemoryManager::endExceptionTable(const Function
*F
, unsigned char *TableStart
,
544 unsigned char *TableEnd
,
545 unsigned char* FrameRegister
)
547 exception_cb (FrameRegister
);
550 class MonoJITEventListener
: public JITEventListener
{
553 FunctionEmittedCb
*emitted_cb
;
555 MonoJITEventListener (FunctionEmittedCb
*cb
) {
559 virtual void NotifyFunctionEmitted(const Function
&F
,
560 void *Code
, size_t Size
,
561 const EmittedFunctionDetails
&Details
) {
562 emitted_cb (wrap (&F
), Code
, (char*)Code
+ Size
);
569 MonoJITMemoryManager
*mm
;
570 MonoJITEventListener
*listener
;
571 FunctionPassManager
*fpm
;
575 mono_llvm_optimize_method (MonoEERef eeref
, LLVMValueRef method
)
577 MonoEE
*mono_ee
= (MonoEE
*)eeref
;
580 * The verifier does some checks on the whole module, leading to quadratic behavior.
582 //verifyFunction (*(unwrap<Function> (method)));
583 mono_ee
->fpm
->run (*unwrap
<Function
> (method
));
586 static cl::list
<const PassInfo
*, bool, PassNameParser
>
587 PassList(cl::desc("Optimizations available:"));
590 force_pass_linking (void)
592 // Make sure the rest is linked in, but never executed
593 char *foo
= g_getenv ("FOO");
594 gboolean ret
= (foo
!= (char*)-1);
600 // This is a subset of the passes in LinkAllPasses.h
601 // The utility passes and the interprocedural passes are commented out
603 (void) llvm::createAAEvalPass();
604 (void) llvm::createAggressiveDCEPass();
605 (void) llvm::createAliasAnalysisCounterPass();
606 (void) llvm::createAliasDebugger();
608 (void) llvm::createArgumentPromotionPass();
609 (void) llvm::createStructRetPromotionPass();
611 (void) llvm::createBasicAliasAnalysisPass();
612 (void) llvm::createLibCallAliasAnalysisPass(0);
613 (void) llvm::createScalarEvolutionAliasAnalysisPass();
614 //(void) llvm::createBlockPlacementPass();
615 (void) llvm::createBreakCriticalEdgesPass();
616 (void) llvm::createCFGSimplificationPass();
618 (void) llvm::createConstantMergePass();
619 (void) llvm::createConstantPropagationPass();
622 (void) llvm::createDeadArgEliminationPass();
624 (void) llvm::createDeadCodeEliminationPass();
625 (void) llvm::createDeadInstEliminationPass();
626 (void) llvm::createDeadStoreEliminationPass();
628 (void) llvm::createDeadTypeEliminationPass();
629 (void) llvm::createDomOnlyPrinterPass();
630 (void) llvm::createDomPrinterPass();
631 (void) llvm::createDomOnlyViewerPass();
632 (void) llvm::createDomViewerPass();
633 (void) llvm::createEdgeProfilerPass();
634 (void) llvm::createOptimalEdgeProfilerPass();
635 (void) llvm::createFunctionInliningPass();
636 (void) llvm::createAlwaysInlinerPass();
637 (void) llvm::createGlobalDCEPass();
638 (void) llvm::createGlobalOptimizerPass();
639 (void) llvm::createGlobalsModRefPass();
640 (void) llvm::createIPConstantPropagationPass();
641 (void) llvm::createIPSCCPPass();
643 (void) llvm::createIndVarSimplifyPass();
644 (void) llvm::createInstructionCombiningPass();
646 (void) llvm::createInternalizePass(false);
648 (void) llvm::createLCSSAPass();
649 (void) llvm::createLICMPass();
650 (void) llvm::createLazyValueInfoPass();
651 //(void) llvm::createLoopDependenceAnalysisPass();
653 (void) llvm::createLoopExtractorPass();
655 (void) llvm::createLoopSimplifyPass();
656 (void) llvm::createLoopStrengthReducePass();
657 (void) llvm::createLoopUnrollPass();
658 (void) llvm::createLoopUnswitchPass();
659 (void) llvm::createLoopRotatePass();
660 (void) llvm::createLowerInvokePass();
662 (void) llvm::createLowerSetJmpPass();
664 (void) llvm::createLowerSwitchPass();
665 (void) llvm::createNoAAPass();
667 (void) llvm::createNoProfileInfoPass();
668 (void) llvm::createProfileEstimatorPass();
669 (void) llvm::createProfileVerifierPass();
670 (void) llvm::createProfileLoaderPass();
672 (void) llvm::createPromoteMemoryToRegisterPass();
673 (void) llvm::createDemoteRegisterToMemoryPass();
675 (void) llvm::createPruneEHPass();
676 (void) llvm::createPostDomOnlyPrinterPass();
677 (void) llvm::createPostDomPrinterPass();
678 (void) llvm::createPostDomOnlyViewerPass();
679 (void) llvm::createPostDomViewerPass();
681 (void) llvm::createReassociatePass();
682 (void) llvm::createSCCPPass();
683 (void) llvm::createScalarReplAggregatesPass();
684 //(void) llvm::createSimplifyLibCallsPass();
686 (void) llvm::createSingleLoopExtractorPass();
687 (void) llvm::createStripSymbolsPass();
688 (void) llvm::createStripNonDebugSymbolsPass();
689 (void) llvm::createStripDeadDebugInfoPass();
690 (void) llvm::createStripDeadPrototypesPass();
691 (void) llvm::createTailCallEliminationPass();
692 (void) llvm::createTailDuplicationPass();
693 (void) llvm::createJumpThreadingPass();
696 (void) llvm::createUnifyFunctionExitNodesPass();
698 (void) llvm::createInstCountPass();
699 (void) llvm::createCodeGenPreparePass();
700 (void) llvm::createGVNPass();
701 (void) llvm::createMemCpyOptPass();
702 (void) llvm::createLoopDeletionPass();
704 (void) llvm::createPostDomTree();
705 (void) llvm::createPostDomFrontier();
706 (void) llvm::createInstructionNamerPass();
707 (void) llvm::createPartialSpecializationPass();
708 (void) llvm::createFunctionAttrsPass();
709 (void) llvm::createMergeFunctionsPass();
710 (void) llvm::createPrintModulePass(0);
711 (void) llvm::createPrintFunctionPass("", 0);
712 (void) llvm::createDbgInfoPrinterPass();
713 (void) llvm::createModuleDebugInfoPrinterPass();
714 (void) llvm::createPartialInliningPass();
715 (void) llvm::createGEPSplitterPass();
716 (void) llvm::createLintPass();
718 (void) llvm::createSinkingPass();
721 static gboolean inited
;
729 force_pass_linking ();
732 LLVMInitializeARMTarget ();
733 LLVMInitializeARMTargetInfo ();
734 LLVMInitializeARMTargetMC ();
735 #elif defined(TARGET_ARM64)
736 LLVMInitializeAArch64Target ();
737 LLVMInitializeAArch64TargetInfo ();
738 LLVMInitializeAArch64TargetMC ();
739 #elif defined(TARGET_X86) || defined(TARGET_AMD64)
740 LLVMInitializeX86Target ();
741 LLVMInitializeX86TargetInfo ();
742 LLVMInitializeX86TargetMC ();
743 #elif defined(TARGET_POWERPC)
744 LLVMInitializePowerPCTarget ();
745 LLVMInitializePowerPCTargetInfo ();
746 LLVMInitializePowerPCTargetMC ();
748 #error Unsupported mono-llvm target
751 PassRegistry
&Registry
= *PassRegistry::getPassRegistry();
752 initializeCore(Registry
);
753 initializeScalarOpts(Registry
);
754 initializeAnalysis(Registry
);
755 initializeIPA(Registry
);
756 initializeTransformUtils(Registry
);
757 initializeInstCombine(Registry
);
758 initializeTarget(Registry
);
760 llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
766 mono_llvm_create_ee (LLVMModuleProviderRef MP
, AllocCodeMemoryCb
*alloc_cb
, FunctionEmittedCb
*emitted_cb
, ExceptionTableCb
*exception_cb
, DlSymCb
*dlsym_cb
, LLVMExecutionEngineRef
*ee
)
773 mono_ee
= new MonoEE ();
775 MonoJITMemoryManager
*mono_mm
= new MonoJITMemoryManager ();
776 mono_mm
->alloc_cb
= alloc_cb
;
777 mono_mm
->dlsym_cb
= dlsym_cb
;
778 mono_mm
->exception_cb
= exception_cb
;
779 mono_ee
->mm
= mono_mm
;
782 * The Default code model doesn't seem to work on amd64,
783 * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
784 * memset using a normal pcrel code which is in 32bit memory, while memset isn't.
788 opts
.JITExceptionHandling
= 1;
790 StringRef cpu_name
= sys::getHostCPUName ();
792 // EngineBuilder no longer has a copy assignment operator (?)
793 std::unique_ptr
<Module
> Owner(unwrap(MP
));
794 EngineBuilder
b (std::move(Owner
));
795 ExecutionEngine
*EE
= b
.setJITMemoryManager (mono_mm
).setTargetOptions (opts
).setAllocateGVsWithCode (true).setMCPU (cpu_name
).create ();
800 MonoJITEventListener
*listener
= new MonoJITEventListener (emitted_cb
);
801 EE
->RegisterJITEventListener (listener
);
802 mono_ee
->listener
= listener
;
804 FunctionPassManager
*fpm
= new FunctionPassManager (unwrap (MP
));
807 fpm
->add(new DataLayoutPass(*EE
->getDataLayout()));
809 if (PassList
.size() > 0) {
810 /* Use the passes specified by the env variable */
811 /* Only the passes in force_pass_linking () can be used */
812 for (unsigned i
= 0; i
< PassList
.size(); ++i
) {
813 const PassInfo
*PassInf
= PassList
[i
];
816 if (PassInf
->getNormalCtor())
817 P
= PassInf
->getNormalCtor()();
821 /* Use the same passes used by 'opt' by default, without the ipo passes */
822 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";
826 args
= g_strsplit (opts
, " ", 1000);
827 for (i
= 0; args
[i
]; i
++)
829 llvm::cl::ParseCommandLineOptions (i
, args
, "");
832 for (unsigned i
= 0; i
< PassList
.size(); ++i
) {
833 const PassInfo
*PassInf
= PassList
[i
];
836 if (PassInf
->getNormalCtor())
837 P
= PassInf
->getNormalCtor()();
838 g_assert (P
->getPassKind () == llvm::PT_Function
|| P
->getPassKind () == llvm::PT_Loop
);
843 fpm->add(createInstructionCombiningPass());
844 fpm->add(createReassociatePass());
845 fpm->add(createGVNPass());
846 fpm->add(createCFGSimplificationPass());
856 mono_llvm_dispose_ee (MonoEERef
*eeref
)
858 MonoEE
*mono_ee
= (MonoEE
*)eeref
;
862 //delete mono_ee->mm;
863 delete mono_ee
->listener
;
867 #else /* MONO_CROSS_COMPILE */
870 mono_llvm_set_unhandled_exception_handler (void)
875 mono_llvm_create_ee (LLVMModuleProviderRef MP
, AllocCodeMemoryCb
*alloc_cb
, FunctionEmittedCb
*emitted_cb
, ExceptionTableCb
*exception_cb
, DlSymCb
*dlsym_cb
, LLVMExecutionEngineRef
*ee
)
877 g_error ("LLVM JIT not supported on this platform.");
882 mono_llvm_optimize_method (MonoEERef eeref
, LLVMValueRef method
)
884 g_assert_not_reached ();
888 mono_llvm_compile_method (MonoEERef mono_ee
, LLVMValueRef method
, int nvars
, LLVMValueRef
*callee_vars
, gpointer
*callee_addrs
, gpointer
*eh_frame
)
890 g_assert_not_reached ();
895 mono_llvm_dispose_ee (MonoEERef
*eeref
)
897 g_assert_not_reached ();
902 LLVMAddGlobalMapping(LLVMExecutionEngineRef EE
, LLVMValueRef Global
,
905 g_assert_not_reached ();
909 LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE
, LLVMValueRef Global
)
911 g_assert_not_reached ();
915 #endif /* !MONO_CROSS_COMPILE */