diff --git a/CMakeLists.txt b/CMakeLists.txt index a9952fc3..c770561a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ set(PROGRAM_PREFIX CACHE STRING "prepended to ldc binary name") set(PROGRAM_SUFFIX CACHE STRING "appended to ldc binary name") option(USE_BOEHM_GC "use the Boehm garbage collector internally") option(GENERATE_OFFTI "generate complete ClassInfo.offTi arrays") +option(USE_METADATA "use metadata and related custom optimization passes") if(D_VERSION EQUAL 1) set(DMDFE_PATH dmd) @@ -208,6 +209,10 @@ if(GENERATE_OFFTI) add_definitions(-DGENERATE_OFFTI) endif(GENERATE_OFFTI) +if(USE_METADATA) + add_definitions(-DUSE_METADATA) +endif(USE_METADATA) + if(CMAKE_MINOR_VERSION LESS 6) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin CACHE PATH "output dir for built executables") set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "output dir for built libraries") diff --git a/gen/main.cpp b/gen/main.cpp index dc52ac22..84478800 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -941,12 +941,13 @@ LDC_TARGETS std::string errormsg; for (int i = 0; i < llvmModules.size(); i++) { +#if USE_METADATA //FIXME: workaround for llvm metadata bug: // the LinkInModule call asserts with metadata unstripped llvm::ModulePass* stripMD = createStripMetaData(); stripMD->runOnModule(*llvmModules[i]); delete stripMD; - +#endif // USE_METADATA if(linker.LinkInModule(llvmModules[i], &errormsg)) error("%s", errormsg.c_str()); delete llvmModules[i]; diff --git a/gen/metadata.h b/gen/metadata.h index aba4c65c..a9525ed2 100644 --- a/gen/metadata.h +++ b/gen/metadata.h @@ -1,3 +1,5 @@ +#if USE_METADATA + #ifndef LDC_GEN_METADATA_H #define LDC_GEN_METADATA_H @@ -46,3 +48,5 @@ enum ClassDataFields { }; #endif + +#endif // USE_METADATA diff --git a/gen/optimizer.cpp b/gen/optimizer.cpp index a15c4121..4b1d98ec 100644 --- a/gen/optimizer.cpp +++ b/gen/optimizer.cpp @@ -160,8 +160,10 @@ static void addPassesForOptLevel(PassManager& pm) { if (!disableSimplifyRuntimeCalls) addPass(pm, createSimplifyDRuntimeCalls()); +#if USE_METADATA if (!disableGCToStack) addPass(pm, createGarbageCollect2Stack()); +#endif // USE_METADATA } // Run some clean-up passes addPass(pm, createInstructionCombiningPass()); @@ -221,6 +223,7 @@ static void addPassesForOptLevel(PassManager& pm) { bool ldc_optimize_module(llvm::Module* m) { if (!optimize()) { +#if USE_METADATA if (!disableStripMetaData) { // This one always needs to run if metadata is generated, because // the code generator will assert if it's not used. @@ -228,6 +231,7 @@ bool ldc_optimize_module(llvm::Module* m) stripMD->runOnModule(*m); delete stripMD; } +#endif return false; } @@ -266,11 +270,13 @@ bool ldc_optimize_module(llvm::Module* m) if (optimize) addPassesForOptLevel(pm); +#if USE_METADATA if (!disableStripMetaData) { // This one is purposely not disabled by disableLangSpecificPasses // because the code generator will assert if it's not used. addPass(pm, createStripMetaData()); } +#endif // USE_METADATA pm.run(*m); return true; diff --git a/gen/passes/GarbageCollect2Stack.cpp b/gen/passes/GarbageCollect2Stack.cpp index 2cbe834a..c990d920 100644 --- a/gen/passes/GarbageCollect2Stack.cpp +++ b/gen/passes/GarbageCollect2Stack.cpp @@ -1,3 +1,5 @@ +#if USE_METADATA + //===- GarbageCollect2Stack - Optimize calls to the D garbage collector ---===// // // The LLVM D Compiler @@ -642,3 +644,5 @@ bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) { // All uses examined - not captured or live across original allocation. return true; } + +#endif // USE_METADATA diff --git a/gen/passes/Passes.h b/gen/passes/Passes.h index 29e9df21..f0695191 100644 --- a/gen/passes/Passes.h +++ b/gen/passes/Passes.h @@ -10,8 +10,10 @@ namespace llvm { // Performs simplifications on runtime calls. llvm::FunctionPass* createSimplifyDRuntimeCalls(); +#if USE_METADATA llvm::FunctionPass* createGarbageCollect2Stack(); llvm::ModulePass* createStripMetaData(); +#endif // USE_METADATA llvm::ModulePass* createStripExternalsPass(); diff --git a/gen/passes/StripMetaData.cpp b/gen/passes/StripMetaData.cpp index f6b95f61..b2402429 100644 --- a/gen/passes/StripMetaData.cpp +++ b/gen/passes/StripMetaData.cpp @@ -1,3 +1,5 @@ +#if USE_METADATA + //===- StripMetaData - Strips D-specific metadata -------------------------===// // // The LLVM D Compiler @@ -75,3 +77,5 @@ bool StripMetaData::runOnModule(Module &M) { } return Changed; } + +#endif // USE_METADATA diff --git a/gen/typinf.cpp b/gen/typinf.cpp index e29d520d..b88fec6a 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -302,6 +302,7 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid) tid->ir.irGlobal = irg; +#if USE_METADATA // don't do this for void or llvm will crash if (tid->tinfo->ty != Tvoid) { // Add some metadata for use by optimization passes. @@ -321,6 +322,7 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid) llvm::NamedMDNode::Create(metaname, &metadata, 1, gIR->module); } } +#endif // USE_METADATA DtoDeclareTypeInfo(tid); } diff --git a/ir/irclass.cpp b/ir/irclass.cpp index c310b18d..edb73c65 100644 --- a/ir/irclass.cpp +++ b/ir/irclass.cpp @@ -71,6 +71,7 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol() classInfo = new llvm::GlobalVariable( *gIR->module, tc->getPA().get(), false, _linkage, NULL, initname); +#if USE_METADATA // Generate some metadata on this ClassInfo if it's for a class. ClassDeclaration* classdecl = aggrdecl->isClassDeclaration(); if (classdecl && !aggrdecl->isInterfaceDeclaration()) { @@ -90,6 +91,7 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol() std::string metaname = CD_PREFIX + initname; llvm::NamedMDNode::Create(metaname, &metadata, 1, gIR->module); } +#endif // USE_METADATA return classInfo; }