X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mono%2Fmini%2Fmini-llvm-cpp.cpp;h=cb5ddd33e79032ea2a81781d811f6df9ef68e754;hb=1f5d985270df9390f9cb558656763ea428c14e2c;hp=f11db19bc9620eabc37089ab0ddecd5f7fb1f77d;hpb=6733010353a6024a2b437a6cd5c5c30ae6e99218;p=mono.git diff --git a/mono/mini/mini-llvm-cpp.cpp b/mono/mini/mini-llvm-cpp.cpp index f11db19bc96..cb5ddd33e79 100644 --- a/mono/mini/mini-llvm-cpp.cpp +++ b/mono/mini/mini-llvm-cpp.cpp @@ -25,280 +25,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#if LLVM_API_VERSION >= 1 -#include -#else -#include -#endif -#include -#include -#include -#if LLVM_API_VERSION >= 1 -#include "llvm/IR/LegacyPassNameParser.h" -#else -#include "llvm/Support/PassNameParser.h" -#endif -#include "llvm/Support/PrettyStackTrace.h" -#include -#include -#include -#include #include #include #include -//#include - -#include "llvm-c/Core.h" -#include "llvm-c/ExecutionEngine.h" #include "mini-llvm-cpp.h" -// extern "C" void LLVMInitializeARMTargetInfo(); -// extern "C" void LLVMInitializeARMTarget (); -// extern "C" void LLVMInitializeARMTargetMC (); - using namespace llvm; -#ifndef MONO_CROSS_COMPILE - -class MonoJITMemoryManager : public JITMemoryManager -{ -private: - JITMemoryManager *mm; - -public: - /* Callbacks installed by mono */ - AllocCodeMemoryCb *alloc_cb; - DlSymCb *dlsym_cb; - - MonoJITMemoryManager (); - ~MonoJITMemoryManager (); - - void setMemoryWritable (void); - - void setMemoryExecutable (void); - - void AllocateGOT(); - - unsigned char *getGOTBase() const { - return mm->getGOTBase (); - } - - void setPoisonMemory(bool) { - } - - unsigned char *startFunctionBody(const Function *F, - uintptr_t &ActualSize); - - unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment); - - void endFunctionBody(const Function *F, unsigned char *FunctionStart, - unsigned char *FunctionEnd); - - unsigned char *allocateSpace(intptr_t Size, unsigned Alignment); - - uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment); - - void deallocateMemForFunction(const Function *F); - - unsigned char*startExceptionTable(const Function* F, - uintptr_t &ActualSize); - - void endExceptionTable(const Function *F, unsigned char *TableStart, - unsigned char *TableEnd, - unsigned char* FrameRegister); - - virtual void deallocateFunctionBody(void*) { - } - - virtual void deallocateExceptionTable(void*) { - } - - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, - StringRef SectionName) { - // FIXME: - assert(0); - return NULL; - } - - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, - StringRef SectionName, bool IsReadOnly) { - // FIXME: - assert(0); - return NULL; - } - - virtual bool applyPermissions(std::string*) { - // FIXME: - assert(0); - return false; - } - - virtual bool finalizeMemory(std::string *ErrMsg = 0) { - // FIXME: - assert(0); - return false; - } - - virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) { - void *res; - char *err; - - err = dlsym_cb (Name.c_str (), &res); - if (err) { - outs () << "Unable to resolve: " << Name << ": " << err << "\n"; - assert(0); - return NULL; - } - return res; - } -}; - -MonoJITMemoryManager::MonoJITMemoryManager () -{ - mm = JITMemoryManager::CreateDefaultMemManager (); -} - -MonoJITMemoryManager::~MonoJITMemoryManager () -{ - delete mm; -} - -void -MonoJITMemoryManager::setMemoryWritable (void) -{ -} - -void -MonoJITMemoryManager::setMemoryExecutable (void) -{ -} - -void -MonoJITMemoryManager::AllocateGOT() -{ - mm->AllocateGOT (); -} - -unsigned char * -MonoJITMemoryManager::startFunctionBody(const Function *F, - uintptr_t &ActualSize) -{ - // FIXME: This leaks memory - if (ActualSize == 0) - ActualSize = 128; - return alloc_cb (wrap (F), ActualSize); -} - -unsigned char * -MonoJITMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment) -{ - return alloc_cb (wrap (F), StubSize); -} - -void -MonoJITMemoryManager::endFunctionBody(const Function *F, unsigned char *FunctionStart, - unsigned char *FunctionEnd) -{ -} - -unsigned char * -MonoJITMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) -{ - return new unsigned char [Size]; -} - -uint8_t * -MonoJITMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) -{ - return new unsigned char [Size]; -} - -void -MonoJITMemoryManager::deallocateMemForFunction(const Function *F) -{ -} - -unsigned char* -MonoJITMemoryManager::startExceptionTable(const Function* F, - uintptr_t &ActualSize) -{ - return startFunctionBody(F, ActualSize); -} - -void -MonoJITMemoryManager::endExceptionTable(const Function *F, unsigned char *TableStart, - unsigned char *TableEnd, - unsigned char* FrameRegister) -{ -} - -#else - -class MonoJITMemoryManager { -}; - -#endif /* !MONO_CROSS_COMPILE */ - -class MonoJITEventListener : public JITEventListener { - -public: - FunctionEmittedCb *emitted_cb; - - MonoJITEventListener (FunctionEmittedCb *cb) { - emitted_cb = cb; - } - - virtual void NotifyFunctionEmitted(const Function &F, - void *Code, size_t Size, - const EmittedFunctionDetails &Details) { - /* - * X86TargetMachine::setCodeModelForJIT() sets the code model to Large on amd64, - * which means the JIT will generate calls of the form - * mov reg, - * call *reg - * Our trampoline code can't patch this. Passing CodeModel::Small to createJIT - * doesn't seem to work, we need Default. A discussion is here: - * http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-December/027999.html - * There seems to no way to get the TargeMachine used by an EE either, so we - * install a profiler hook and reset the code model here. - * This should be inside an ifdef, but we can't include our config.h either, - * since its definitions conflict with LLVM's config.h. - * The LLVM mono branch contains a workaround. - */ - emitted_cb (wrap (&F), Code, (char*)Code + Size); - } -}; - -class MonoEE { -public: - ExecutionEngine *EE; - MonoJITMemoryManager *mm; - MonoJITEventListener *listener; - FunctionPassManager *fpm; -}; - -void -mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method) -{ - MonoEE *mono_ee = (MonoEE*)eeref; - - /* - * The verifier does some checks on the whole module, leading to quadratic behavior. - */ - //verifyFunction (*(unwrap (method))); - mono_ee->fpm->run (*unwrap (method)); -} - void mono_llvm_dump_value (LLVMValueRef value) { @@ -391,11 +125,7 @@ mono_llvm_build_cmpxchg (LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef { AtomicCmpXchgInst *ins; -#if LLVM_API_VERSION >= 1 ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent); -#else - ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent); -#endif return wrap (ins); } @@ -449,334 +179,40 @@ mono_llvm_build_fence (LLVMBuilderRef builder, BarrierKind kind) } void -mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v) -{ - Value *V = ConstantExpr::getTruncOrBitCast (unwrap (v), unwrap (var)->getType ()); - unwrap (var)->replaceAllUsesWith (V); -} - -static cl::list -PassList(cl::desc("Optimizations available:")); - -static void -force_pass_linking (void) -{ - // Make sure the rest is linked in, but never executed - if (g_getenv ("FOO") != (char*)-1) - return; - - // This is a subset of the passes in LinkAllPasses.h - // The utility passes and the interprocedural passes are commented out - - (void) llvm::createAAEvalPass(); - (void) llvm::createAggressiveDCEPass(); - (void) llvm::createAliasAnalysisCounterPass(); - (void) llvm::createAliasDebugger(); - /* - (void) llvm::createArgumentPromotionPass(); - (void) llvm::createStructRetPromotionPass(); - */ - (void) llvm::createBasicAliasAnalysisPass(); - (void) llvm::createLibCallAliasAnalysisPass(0); - (void) llvm::createScalarEvolutionAliasAnalysisPass(); - //(void) llvm::createBlockPlacementPass(); - (void) llvm::createBreakCriticalEdgesPass(); - (void) llvm::createCFGSimplificationPass(); - /* - (void) llvm::createConstantMergePass(); - (void) llvm::createConstantPropagationPass(); - */ - /* - (void) llvm::createDeadArgEliminationPass(); - */ - (void) llvm::createDeadCodeEliminationPass(); - (void) llvm::createDeadInstEliminationPass(); - (void) llvm::createDeadStoreEliminationPass(); - /* - (void) llvm::createDeadTypeEliminationPass(); - (void) llvm::createDomOnlyPrinterPass(); - (void) llvm::createDomPrinterPass(); - (void) llvm::createDomOnlyViewerPass(); - (void) llvm::createDomViewerPass(); - (void) llvm::createEdgeProfilerPass(); - (void) llvm::createOptimalEdgeProfilerPass(); - (void) llvm::createFunctionInliningPass(); - (void) llvm::createAlwaysInlinerPass(); - (void) llvm::createGlobalDCEPass(); - (void) llvm::createGlobalOptimizerPass(); - (void) llvm::createGlobalsModRefPass(); - (void) llvm::createIPConstantPropagationPass(); - (void) llvm::createIPSCCPPass(); - */ - (void) llvm::createIndVarSimplifyPass(); - (void) llvm::createInstructionCombiningPass(); - /* - (void) llvm::createInternalizePass(false); - */ - (void) llvm::createLCSSAPass(); - (void) llvm::createLICMPass(); - (void) llvm::createLazyValueInfoPass(); - //(void) llvm::createLoopDependenceAnalysisPass(); - /* - (void) llvm::createLoopExtractorPass(); - */ - (void) llvm::createLoopSimplifyPass(); - (void) llvm::createLoopStrengthReducePass(); - (void) llvm::createLoopUnrollPass(); - (void) llvm::createLoopUnswitchPass(); - (void) llvm::createLoopRotatePass(); - (void) llvm::createLowerInvokePass(); - /* - (void) llvm::createLowerSetJmpPass(); - */ - (void) llvm::createLowerSwitchPass(); - (void) llvm::createNoAAPass(); - /* - (void) llvm::createNoProfileInfoPass(); - (void) llvm::createProfileEstimatorPass(); - (void) llvm::createProfileVerifierPass(); - (void) llvm::createProfileLoaderPass(); - */ - (void) llvm::createPromoteMemoryToRegisterPass(); - (void) llvm::createDemoteRegisterToMemoryPass(); - /* - (void) llvm::createPruneEHPass(); - (void) llvm::createPostDomOnlyPrinterPass(); - (void) llvm::createPostDomPrinterPass(); - (void) llvm::createPostDomOnlyViewerPass(); - (void) llvm::createPostDomViewerPass(); - */ - (void) llvm::createReassociatePass(); - (void) llvm::createSCCPPass(); - (void) llvm::createScalarReplAggregatesPass(); - //(void) llvm::createSimplifyLibCallsPass(); - /* - (void) llvm::createSingleLoopExtractorPass(); - (void) llvm::createStripSymbolsPass(); - (void) llvm::createStripNonDebugSymbolsPass(); - (void) llvm::createStripDeadDebugInfoPass(); - (void) llvm::createStripDeadPrototypesPass(); - (void) llvm::createTailCallEliminationPass(); - (void) llvm::createTailDuplicationPass(); - (void) llvm::createJumpThreadingPass(); - */ - /* - (void) llvm::createUnifyFunctionExitNodesPass(); - */ - (void) llvm::createInstCountPass(); - (void) llvm::createCodeGenPreparePass(); - (void) llvm::createGVNPass(); - (void) llvm::createMemCpyOptPass(); - (void) llvm::createLoopDeletionPass(); - /* - (void) llvm::createPostDomTree(); - (void) llvm::createPostDomFrontier(); - (void) llvm::createInstructionNamerPass(); - (void) llvm::createPartialSpecializationPass(); - (void) llvm::createFunctionAttrsPass(); - (void) llvm::createMergeFunctionsPass(); - (void) llvm::createPrintModulePass(0); - (void) llvm::createPrintFunctionPass("", 0); - (void) llvm::createDbgInfoPrinterPass(); - (void) llvm::createModuleDebugInfoPrinterPass(); - (void) llvm::createPartialInliningPass(); - (void) llvm::createGEPSplitterPass(); - (void) llvm::createLintPass(); - */ - (void) llvm::createSinkingPass(); -} - -#ifndef MONO_CROSS_COMPILE - -static gboolean inited; - -static void -init_llvm (void) +mono_llvm_set_must_tail (LLVMValueRef call_ins) { - if (inited) - return; - - force_pass_linking (); - -#ifdef TARGET_ARM - LLVMInitializeARMTarget (); - LLVMInitializeARMTargetInfo (); - LLVMInitializeARMTargetMC (); -#else - LLVMInitializeX86Target (); - LLVMInitializeX86TargetInfo (); - LLVMInitializeX86TargetMC (); -#endif - - PassRegistry &Registry = *PassRegistry::getPassRegistry(); - initializeCore(Registry); - initializeScalarOpts(Registry); - initializeAnalysis(Registry); - initializeIPA(Registry); - initializeTransformUtils(Registry); - initializeInstCombine(Registry); - initializeTarget(Registry); - - llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", ""); - - inited = true; -} + CallInst *ins = (CallInst*)unwrap (call_ins); -MonoEERef -mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee) -{ - std::string Error; - MonoEE *mono_ee; - - init_llvm (); - - mono_ee = new MonoEE (); - - MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager (); - mono_mm->alloc_cb = alloc_cb; - mono_mm->dlsym_cb = dlsym_cb; - mono_ee->mm = mono_mm; - - /* - * The Default code model doesn't seem to work on amd64, - * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call - * memset using a normal pcrel code which is in 32bit memory, while memset isn't. - */ - - TargetOptions opts; - opts.JITExceptionHandling = 1; - -#if LLVM_API_VERSION >= 2 - StringRef cpu_name = sys::getHostCPUName (); - - // EngineBuilder no longer has a copy assignment operator (?) - std::unique_ptr Owner(unwrap(MP)); - EngineBuilder b (std::move(Owner)); -#ifdef TARGET_AMD64 - ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).setCodeModel (CodeModel::Large).create (); -#else - ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create (); -#endif - -#else - - EngineBuilder b (unwrap (MP)); - EngineBuilder &eb = b; - eb = eb.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true); -#if LLVM_API_VERSION >= 1 - StringRef cpu_name = sys::getHostCPUName (); - eb = eb.setMCPU (cpu_name); -#endif -#ifdef TARGET_AMD64 - eb = eb.setCodeModel (CodeModel::Large); -#endif - - ExecutionEngine *EE = eb.create (); -#endif - - g_assert (EE); - mono_ee->EE = EE; - - EE->InstallExceptionTableRegister (exception_cb); - MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb); - EE->RegisterJITEventListener (listener); - mono_ee->listener = listener; - - FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP)); - mono_ee->fpm = fpm; - -#if LLVM_API_VERSION >= 1 - fpm->add(new DataLayoutPass(*EE->getDataLayout())); -#else - fpm->add(new DataLayout(*EE->getDataLayout())); -#endif - - if (PassList.size() > 0) { - /* Use the passes specified by the env variable */ - /* Only the passes in force_pass_linking () can be used */ - for (unsigned i = 0; i < PassList.size(); ++i) { - const PassInfo *PassInf = PassList[i]; - Pass *P = 0; - - if (PassInf->getNormalCtor()) - P = PassInf->getNormalCtor()(); - fpm->add (P); - } - } else { - /* Use the same passes used by 'opt' by default, without the ipo passes */ - 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"; - char **args; - int i; - - args = g_strsplit (opts, " ", 1000); - for (i = 0; args [i]; i++) - ; - llvm::cl::ParseCommandLineOptions (i, args, ""); - g_strfreev (args); - - for (unsigned i = 0; i < PassList.size(); ++i) { - const PassInfo *PassInf = PassList[i]; - Pass *P = 0; - - if (PassInf->getNormalCtor()) - P = PassInf->getNormalCtor()(); - g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop); - fpm->add (P); - } - - /* - fpm->add(createInstructionCombiningPass()); - fpm->add(createReassociatePass()); - fpm->add(createGVNPass()); - fpm->add(createCFGSimplificationPass()); - */ - } - - *ee = wrap (EE); - - return mono_ee; + ins->setTailCallKind (CallInst::TailCallKind::TCK_MustTail); } void -mono_llvm_dispose_ee (MonoEERef *eeref) +mono_llvm_replace_uses_of (LLVMValueRef var, LLVMValueRef v) { - MonoEE *mono_ee = (MonoEE*)eeref; - - delete mono_ee->EE; - delete mono_ee->fpm; - //delete mono_ee->mm; - delete mono_ee->listener; - delete mono_ee; + Value *V = ConstantExpr::getTruncOrBitCast (unwrap (v), unwrap (var)->getType ()); + unwrap (var)->replaceAllUsesWith (V); } -#else - -MonoEERef -mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee) +LLVMValueRef +mono_llvm_create_constant_data_array (const uint8_t *data, int len) { - g_assert_not_reached (); - return NULL; + return wrap(ConstantDataArray::get (*unwrap(LLVMGetGlobalContext ()), makeArrayRef(data, len))); } void -mono_llvm_dispose_ee (MonoEERef *eeref) +mono_llvm_set_is_constant (LLVMValueRef global_var) { - g_assert_not_reached (); + unwrap(global_var)->setConstant (true); } -/* Not linked in */ void -LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, - void* Addr) +mono_llvm_set_preserveall_cc (LLVMValueRef func) { - g_assert_not_reached (); + unwrap(func)->setCallingConv (CallingConv::PreserveAll); } -void* -LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) +void +mono_llvm_set_call_preserveall_cc (LLVMValueRef func) { - g_assert_not_reached (); - return NULL; + unwrap(func)->setCallingConv (CallingConv::PreserveAll); } - -#endif /* !MONO_CROSS_COMPILE */