diff options
author | Devang Patel <dpatel@apple.com> | 2009-08-26 05:01:18 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-08-26 05:01:18 +0000 |
commit | 94060421ce73922e71c183fba0fda8bace7d0e2d (patch) | |
tree | 5a87b0b92a0c718d5f87d80b51cc4a6b9251eb63 /lib/Transforms | |
parent | 66d02907de42fa311fb2b512e820277bb1a61e7c (diff) | |
download | external_llvm-94060421ce73922e71c183fba0fda8bace7d0e2d.zip external_llvm-94060421ce73922e71c183fba0fda8bace7d0e2d.tar.gz external_llvm-94060421ce73922e71c183fba0fda8bace7d0e2d.tar.bz2 |
Revert 79977. It causes llvm-gcc bootstrap failures on some platforms.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80073 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/StripSymbols.cpp | 125 | ||||
-rw-r--r-- | lib/Transforms/Utils/CloneFunction.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 6 |
3 files changed, 122 insertions, 11 deletions
diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp index 0bd1696..316b0d7 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -203,56 +203,167 @@ static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { // llvm.dbg.region.end calls, and any globals they point to if now dead. static bool StripDebugInfo(Module &M) { - // Remove all of the calls to the debugger intrinsics, and remove them from - // the module. + SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; + findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); + findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); + + DebugInfoFinder DbgFinder; + DbgFinder.processModule(M); + + // These anchors use LinkOnce linkage so that the optimizer does not + // remove them accidently. Set InternalLinkage for all these debug + // info anchors. + for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), + E = DbgFinder.compile_unit_end(); I != E; ++I) + (*I)->setLinkage(GlobalValue::InternalLinkage); + for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), + E = DbgFinder.global_variable_end(); I != E; ++I) + (*I)->setLinkage(GlobalValue::InternalLinkage); + for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), + E = DbgFinder.subprogram_end(); I != E; ++I) + (*I)->setLinkage(GlobalValue::InternalLinkage); + + + // Delete all dbg variables. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + GlobalVariable *GV = dyn_cast<GlobalVariable>(I); + if (!GV) continue; + if (!GV->use_empty() && llvmUsedValues.count(I) == 0) { + if (GV->getName().startswith("llvm.dbg")) { + GV->replaceAllUsesWith(UndefValue::get(GV->getType())); + } + } + } + Function *FuncStart = M.getFunction("llvm.dbg.func.start"); Function *StopPoint = M.getFunction("llvm.dbg.stoppoint"); Function *RegionStart = M.getFunction("llvm.dbg.region.start"); Function *RegionEnd = M.getFunction("llvm.dbg.region.end"); Function *Declare = M.getFunction("llvm.dbg.declare"); + std::vector<Constant*> DeadConstants; + + // Remove all of the calls to the debugger intrinsics, and remove them from + // the module. if (FuncStart) { while (!FuncStart->use_empty()) { CallInst *CI = cast<CallInst>(FuncStart->use_back()); + Value *Arg = CI->getOperand(1); + assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); + if (Arg->use_empty()) + if (Constant *C = dyn_cast<Constant>(Arg)) + DeadConstants.push_back(C); } FuncStart->eraseFromParent(); } if (StopPoint) { while (!StopPoint->use_empty()) { CallInst *CI = cast<CallInst>(StopPoint->use_back()); + Value *Arg = CI->getOperand(3); + assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); + if (Arg->use_empty()) + if (Constant *C = dyn_cast<Constant>(Arg)) + DeadConstants.push_back(C); } StopPoint->eraseFromParent(); } if (RegionStart) { while (!RegionStart->use_empty()) { CallInst *CI = cast<CallInst>(RegionStart->use_back()); + Value *Arg = CI->getOperand(1); + assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); + if (Arg->use_empty()) + if (Constant *C = dyn_cast<Constant>(Arg)) + DeadConstants.push_back(C); } RegionStart->eraseFromParent(); } if (RegionEnd) { while (!RegionEnd->use_empty()) { CallInst *CI = cast<CallInst>(RegionEnd->use_back()); + Value *Arg = CI->getOperand(1); + assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); + if (Arg->use_empty()) + if (Constant *C = dyn_cast<Constant>(Arg)) + DeadConstants.push_back(C); } RegionEnd->eraseFromParent(); } if (Declare) { while (!Declare->use_empty()) { CallInst *CI = cast<CallInst>(Declare->use_back()); + Value *Arg1 = CI->getOperand(1); + Value *Arg2 = CI->getOperand(2); + assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); CI->eraseFromParent(); + if (Arg1->use_empty()) { + if (Constant *C = dyn_cast<Constant>(Arg1)) + DeadConstants.push_back(C); + else + RecursivelyDeleteTriviallyDeadInstructions(Arg1); + } + if (Arg2->use_empty()) + if (Constant *C = dyn_cast<Constant>(Arg2)) + DeadConstants.push_back(C); } Declare->eraseFromParent(); } - NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv"); - if (NMD) - NMD->eraseFromParent(); + // llvm.dbg.compile_units and llvm.dbg.subprograms are marked as linkonce + // but since we are removing all debug information, make them internal now. + // FIXME: Use private linkage maybe? + if (Constant *C = M.getNamedGlobal("llvm.dbg.compile_units")) + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) + GV->setLinkage(GlobalValue::InternalLinkage); + + if (Constant *C = M.getNamedGlobal("llvm.dbg.subprograms")) + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) + GV->setLinkage(GlobalValue::InternalLinkage); + + if (Constant *C = M.getNamedGlobal("llvm.dbg.global_variables")) + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) + GV->setLinkage(GlobalValue::InternalLinkage); + + // Delete all dbg variables. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + GlobalVariable *GV = dyn_cast<GlobalVariable>(I); + if (!GV) continue; + if (GV->use_empty() && llvmUsedValues.count(I) == 0 + && (!GV->hasSection() + || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0)) + DeadConstants.push_back(GV); + } + + if (DeadConstants.empty()) + return false; - // Remove dead metadata. - M.getContext().RemoveDeadMetadata(); + // Delete any internal globals that were only used by the debugger intrinsics. + while (!DeadConstants.empty()) { + Constant *C = DeadConstants.back(); + DeadConstants.pop_back(); + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { + if (GV->hasLocalLinkage()) + RemoveDeadConstant(GV); + } + else + RemoveDeadConstant(C); + } + + // Remove all llvm.dbg types. + TypeSymbolTable &ST = M.getTypeSymbolTable(); + for (TypeSymbolTable::iterator TI = ST.begin(), TE = ST.end(); TI != TE; ) { + if (!strncmp(TI->first.c_str(), "llvm.dbg.", 9)) + ST.remove(TI++); + else + ++TI; + } + return true; } diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index f66a267..a6df161 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -238,7 +238,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, // Do not clone llvm.dbg.region.end. It will be adjusted by the inliner. if (const DbgFuncStartInst *DFSI = dyn_cast<DbgFuncStartInst>(II)) { if (DbgFnStart == NULL) { - DISubprogram SP(DFSI->getSubprogram()); + DISubprogram SP(cast<GlobalVariable>(DFSI->getSubprogram())); if (SP.describes(BB->getParent())) DbgFnStart = DFSI->getSubprogram(); } diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index 371fd56..c0d10f4 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -207,17 +207,17 @@ static void UpdateCallGraphAfterInlining(CallSite CS, /// to the llvm.dbg.func.start of the function F. Otherwise return NULL. static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) { - MDNode *FnStart = NULL; + GlobalVariable *FnStart = NULL; const DbgRegionEndInst *FnEnd = NULL; for (Function::const_iterator FI = F->begin(), FE =F->end(); FI != FE; ++FI) for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { if (FnStart == NULL) { if (const DbgFuncStartInst *FSI = dyn_cast<DbgFuncStartInst>(BI)) { - DISubprogram SP(FSI->getSubprogram()); + DISubprogram SP(cast<GlobalVariable>(FSI->getSubprogram())); assert (SP.isNull() == false && "Invalid llvm.dbg.func.start"); if (SP.describes(F)) - FnStart = SP.getNode(); + FnStart = SP.getGV(); } } else { if (const DbgRegionEndInst *REI = dyn_cast<DbgRegionEndInst>(BI)) |