X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-llvm-cpp.cpp;h=e3219686ae2cf5beb7eb8ea5adb7fc9987e51d86;hb=58e8a9f85176c9607e605b888ef45db01a0f6997;hp=927d32f78f3a704022da9bf2e6270bb8f03f4a95;hpb=c050b0aeccbc1c78c75e0528e6e30c49a84db82c;p=mono.git diff --git a/mono/mini/mini-llvm-cpp.cpp b/mono/mini/mini-llvm-cpp.cpp index 927d32f78f3..e3219686ae2 100644 --- a/mono/mini/mini-llvm-cpp.cpp +++ b/mono/mini/mini-llvm-cpp.cpp @@ -3,6 +3,7 @@ // // (C) 2009-2011 Novell, Inc. // Copyright 2011 Xamarin, Inc (http://www.xamarin.com) +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // // @@ -25,276 +26,15 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include - -#include -#include +#include #include "mini-llvm-cpp.h" -// extern "C" void LLVMInitializeARMTargetInfo(); -// extern "C" void LLVMInitializeARMTarget (); -// extern "C" void LLVMInitializeARMTargetMC (); - using namespace llvm; -#ifndef MONO_CROSS_COMPILE - -void -mono_llvm_cpp_throw_exception (void) -{ - gint32 *ex = NULL; - - /* The generated code catches an int32* */ - throw ex; -} - -static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception; - -void -mono_llvm_set_unhandled_exception_handler (void) -{ - std::set_terminate (unhandled_exception); -} - -class MonoJITMemoryManager : public JITMemoryManager -{ -private: - JITMemoryManager *mm; - -public: - /* Callbacks installed by mono */ - AllocCodeMemoryCb *alloc_cb; - DlSymCb *dlsym_cb; - ExceptionTableCb *exception_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) -{ - exception_cb (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) { - 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) { @@ -479,319 +219,61 @@ mono_llvm_set_call_preserveall_cc (LLVMValueRef func) unwrap(func)->setCallingConv (CallingConv::PreserveAll); } -static cl::list -PassList(cl::desc("Optimizations available:")); +#if LLVM_API_VERSION > 100 -static void -force_pass_linking (void) +void* +mono_llvm_create_di_builder (LLVMModuleRef module) { - // 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(); + return new DIBuilder (*unwrap(module)); } -#ifndef MONO_CROSS_COMPILE - -static gboolean inited; - -static void -init_llvm (void) +void* +mono_llvm_di_create_compile_unit (void *di_builder, const char *cu_name, const char *dir, const char *producer) { - if (inited) - return; - - force_pass_linking (); - -#ifdef TARGET_ARM - LLVMInitializeARMTarget (); - LLVMInitializeARMTargetInfo (); - LLVMInitializeARMTargetMC (); -#elif defined(TARGET_X86) - LLVMInitializeX86Target (); - LLVMInitializeX86TargetInfo (); - LLVMInitializeX86TargetMC (); -#elif defined(TARGET_POWERPC) - LLVMInitializePowerPCTarget (); - LLVMInitializePowerPCTargetInfo (); - LLVMInitializePowerPCTargetMC (); -#else - #error Unsupported mono-llvm target -#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; -} + DIBuilder *builder = (DIBuilder*)di_builder; -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_mm->exception_cb = exception_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; - - StringRef cpu_name = sys::getHostCPUName (); - - // EngineBuilder no longer has a copy assignment operator (?) - std::unique_ptr Owner(unwrap(MP)); - EngineBuilder b (std::move(Owner)); - ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create (); - - g_assert (EE); - mono_ee->EE = EE; - - MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb); - EE->RegisterJITEventListener (listener); - mono_ee->listener = listener; - - FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP)); - mono_ee->fpm = fpm; - - fpm->add(new DataLayoutPass(*EE->getDataLayout())); - - 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; + return builder->createCompileUnit (dwarf::DW_LANG_C99, cu_name, dir, producer, true, "", 0); } -void -mono_llvm_dispose_ee (MonoEERef *eeref) +void* +mono_llvm_di_create_function (void *di_builder, void *cu, const char *name, const char *mangled_name, const char *dir, const char *file, int line) { - MonoEE *mono_ee = (MonoEE*)eeref; + DIBuilder *builder = (DIBuilder*)di_builder; + DIFile *di_file; + DISubroutineType *type; - delete mono_ee->EE; - delete mono_ee->fpm; - //delete mono_ee->mm; - delete mono_ee->listener; - delete mono_ee; + // FIXME: Share DIFile + di_file = builder->createFile (file, dir); + type = builder->createSubroutineType (builder->getOrCreateTypeArray (ArrayRef ())); + return builder->createFunction (di_file, name, mangled_name, di_file, line, type, true, true, 0); } -#else - -void -mono_llvm_cpp_throw_exception (void) +void* +mono_llvm_di_create_file (void *di_builder, const char *dir, const char *file) { -} + DIBuilder *builder = (DIBuilder*)di_builder; -void -mono_llvm_set_unhandled_exception_handler (void) -{ + return builder->createFile (file, dir); } -MonoEERef -mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee) +void* +mono_llvm_di_create_location (void *di_builder, void *scope, int row, int column) { - g_assert_not_reached (); - return NULL; + return DILocation::get (*unwrap(LLVMGetGlobalContext ()), row, column, (Metadata*)scope); } void -mono_llvm_dispose_ee (MonoEERef *eeref) +mono_llvm_di_set_location (LLVMBuilderRef builder, void *loc_md) { - g_assert_not_reached (); + unwrap(builder)->SetCurrentDebugLocation ((DILocation*)loc_md); } -/* Not linked in */ void -LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, - void* Addr) +mono_llvm_di_builder_finalize (void *di_builder) { - g_assert_not_reached (); -} + DIBuilder *builder = (DIBuilder*)di_builder; -void* -LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) -{ - g_assert_not_reached (); - return NULL; + builder->finalize (); } -#endif /* !MONO_CROSS_COMPILE */ +#endif /* #if LLVM_API_VERSION > 100 */