summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-10-09 08:13:15 +0000
committerAlexey Samsonov <samsonov@google.com>2012-10-09 08:13:15 +0000
commite97a3a4b4fccbe6283b616af93ab0117d3a7fee9 (patch)
treeafe233298f0be8fd15476c640cc05e3c131a0c85 /lib/Transforms/IPO
parent6765834754cbb3cb0f15b4b15e98c5e73fa50066 (diff)
downloadllvm-e97a3a4b4fccbe6283b616af93ab0117d3a7fee9.tar.gz
llvm-e97a3a4b4fccbe6283b616af93ab0117d3a7fee9.tar.bz2
llvm-e97a3a4b4fccbe6283b616af93ab0117d3a7fee9.tar.xz
Fix PR14016.
DeadArgumentElimination pass can replace one LLVM function with another, invalidating a pointer stored in debug info metadata entry for this function. To fix this, we collect debug info descriptors for functions before running a DeadArgumentElimination pass and "patch" pointers in metadata nodes if we replace a function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 13ff465c53..29053a09e0 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -21,7 +21,9 @@
#include "llvm/Transforms/IPO.h"
#include "llvm/CallingConv.h"
#include "llvm/Constant.h"
+#include "llvm/DebugInfo.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/DIBuilder.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
@@ -121,6 +123,15 @@ namespace {
typedef SmallVector<RetOrArg, 5> UseVector;
+ // Map each LLVM function to corresponding metadata with debug info. If
+ // the function is replaced with another one, we should patch the pointer
+ // to LLVM function in metadata.
+ // As the code generation for module is finished (and DIBuilder is
+ // finalized) we assume that subprogram descriptors won't be changed, and
+ // they are stored in map for short duration anyway.
+ typedef std::map<Function*, DISubprogram> FunctionDIMap;
+ FunctionDIMap FunctionDIs;
+
protected:
// DAH uses this to specify a different ID.
explicit DAE(char &ID) : ModulePass(ID) {}
@@ -141,6 +152,7 @@ namespace {
unsigned RetValNum = 0);
Liveness SurveyUses(const Value *V, UseVector &MaybeLiveUses);
+ void CollectFunctionDIs(Module &M);
void SurveyFunction(const Function &F);
void MarkValue(const RetOrArg &RA, Liveness L,
const UseVector &MaybeLiveUses);
@@ -180,6 +192,31 @@ INITIALIZE_PASS(DAH, "deadarghaX0r",
ModulePass *llvm::createDeadArgEliminationPass() { return new DAE(); }
ModulePass *llvm::createDeadArgHackingPass() { return new DAH(); }
+/// CollectFunctionDIs - Map each function in the module to its debug info
+/// descriptor.
+void DAE::CollectFunctionDIs(Module &M) {
+ FunctionDIs.clear();
+
+ for (Module::named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end(); I != E; ++I) {
+ NamedMDNode &NMD = *I;
+ for (unsigned i = 0, n = NMD.getNumOperands(); i < n; ++i) {
+ MDNode *Node = NMD.getOperand(i);
+ if (DIDescriptor(Node).isCompileUnit()) {
+ DICompileUnit CU(Node);
+ const DIArray &SPs = CU.getSubprograms();
+ for (unsigned i = 0, n = SPs.getNumElements(); i < n; ++i) {
+ DISubprogram SP(SPs.getElement(i));
+ if (SP.Verify()) {
+ if (Function *F = SP.getFunction())
+ FunctionDIs[F] = SP;
+ }
+ }
+ }
+ }
+ }
+}
+
/// DeleteDeadVarargs - If this is an function that takes a ... list, and if
/// llvm.vastart is never called, the varargs list is dead for the function.
bool DAE::DeleteDeadVarargs(Function &Fn) {
@@ -284,6 +321,11 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
I2->takeName(I);
}
+ // Patch the pointer to LLVM function in debug info descriptor.
+ FunctionDIMap::iterator DI = FunctionDIs.find(&Fn);
+ if (DI != FunctionDIs.end())
+ DI->second.replaceFunction(NF);
+
// Finally, nuke the old function.
Fn.eraseFromParent();
return true;
@@ -952,6 +994,11 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
BB->getInstList().erase(RI);
}
+ // Patch the pointer to LLVM function in debug info descriptor.
+ FunctionDIMap::iterator DI = FunctionDIs.find(F);
+ if (DI != FunctionDIs.end())
+ DI->second.replaceFunction(NF);
+
// Now that the old function is dead, delete it.
F->eraseFromParent();
@@ -961,6 +1008,9 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
bool DAE::runOnModule(Module &M) {
bool Changed = false;
+ // Collect debug info descriptors for functions.
+ CollectFunctionDIs(M);
+
// First pass: Do a simple check to see if any functions can have their "..."
// removed. We can do this if they never call va_start. This loop cannot be
// fused with the next loop, because deleting a function invalidates