summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-09-20 21:52:33 +0000
committerReid Kleckner <rnk@google.com>2017-09-20 21:52:33 +0000
commit3f547e87b2cdd148c0429ddda48fdeeb111b527d (patch)
tree8eec0bb5535f40c9328bb90dc12844e56c31e8c2 /llvm/lib/Transforms/Utils/Local.cpp
parent047cbee1e77e545c0f1a32b7a1eae113f87deb71 (diff)
downloadbcm5719-llvm-3f547e87b2cdd148c0429ddda48fdeeb111b527d.tar.gz
bcm5719-llvm-3f547e87b2cdd148c0429ddda48fdeeb111b527d.zip
[IR] Add llvm.dbg.addr, a control-dependent version of llvm.dbg.declare
Summary: This implements the design discussed on llvm-dev for better tracking of variables that live in memory through optimizations: http://lists.llvm.org/pipermail/llvm-dev/2017-September/117222.html This is tracked as PR34136 llvm.dbg.addr is intended to be produced and used in almost precisely the same way as llvm.dbg.declare is today, with the exception that it is control-dependent. That means that dbg.addr should always have a position in the instruction stream, and it will allow passes that optimize memory operations on local variables to insert llvm.dbg.value calls to reflect deleted stores. See SourceLevelDebugging.rst for more details. The main drawback to generating DBG_VALUE machine instrs is that they usually cause LLVM to emit a location list for DW_AT_location. The next step will be to teach DwarfDebug.cpp how to recognize more DBG_VALUE ranges as not needing a location list, and possibly start setting DW_AT_start_offset for variables whose lifetimes begin mid-scope. Reviewers: aprantl, dblaikie, probinson Subscribers: eraman, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D37768 llvm-svn: 313825
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp91
1 files changed, 50 insertions, 41 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index c3251e26340..43b07557e09 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1098,12 +1098,13 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
}
/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
-/// that has an associated llvm.dbg.decl intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
StoreInst *SI, DIBuilder &Builder) {
- auto *DIVar = DDI->getVariable();
+ assert(DII->isAddressOfVariable());
+ auto *DIVar = DII->getVariable();
assert(DIVar && "Missing variable");
- auto *DIExpr = DDI->getExpression();
+ auto *DIExpr = DII->getExpression();
Value *DV = SI->getOperand(0);
// If an argument is zero extended then use argument directly. The ZExt
@@ -1114,7 +1115,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))
ExtendedArg = dyn_cast<Argument>(SExt->getOperand(0));
if (ExtendedArg) {
- // If this DDI was already describing only a fragment of a variable, ensure
+ // If this DII was already describing only a fragment of a variable, ensure
// that fragment is appropriately narrowed here.
// But if a fragment wasn't used, describe the value as the original
// argument (rather than the zext or sext) so that it remains described even
@@ -1127,23 +1128,23 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
DIExpr->elements_end() - 3);
Ops.push_back(dwarf::DW_OP_LLVM_fragment);
Ops.push_back(FragmentOffset);
- const DataLayout &DL = DDI->getModule()->getDataLayout();
+ const DataLayout &DL = DII->getModule()->getDataLayout();
Ops.push_back(DL.getTypeSizeInBits(ExtendedArg->getType()));
DIExpr = Builder.createExpression(Ops);
}
DV = ExtendedArg;
}
if (!LdStHasDebugValue(DIVar, DIExpr, SI))
- Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, DDI->getDebugLoc(),
+ Builder.insertDbgValueIntrinsic(DV, DIVar, DIExpr, DII->getDebugLoc(),
SI);
}
/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
-/// that has an associated llvm.dbg.decl intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+/// that has an associated llvm.dbg.declare or llvm.dbg.addr intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
LoadInst *LI, DIBuilder &Builder) {
- auto *DIVar = DDI->getVariable();
- auto *DIExpr = DDI->getExpression();
+ auto *DIVar = DII->getVariable();
+ auto *DIExpr = DII->getExpression();
assert(DIVar && "Missing variable");
if (LdStHasDebugValue(DIVar, DIExpr, LI))
@@ -1154,16 +1155,16 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
// preferable to keep tracking both the loaded value and the original
// address in case the alloca can not be elided.
Instruction *DbgValue = Builder.insertDbgValueIntrinsic(
- LI, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr);
+ LI, DIVar, DIExpr, DII->getDebugLoc(), (Instruction *)nullptr);
DbgValue->insertAfter(LI);
}
-/// Inserts a llvm.dbg.value intrinsic after a phi
-/// that has an associated llvm.dbg.decl intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
+/// llvm.dbg.declare or llvm.dbg.addr intrinsic.
+void llvm::ConvertDebugDeclareToDebugValue(DbgInfoIntrinsic *DII,
PHINode *APN, DIBuilder &Builder) {
- auto *DIVar = DDI->getVariable();
- auto *DIExpr = DDI->getExpression();
+ auto *DIVar = DII->getVariable();
+ auto *DIExpr = DII->getExpression();
assert(DIVar && "Missing variable");
if (PhiHasDebugValue(DIVar, DIExpr, APN))
@@ -1176,7 +1177,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
// insertion point.
// FIXME: Insert dbg.value markers in the successors when appropriate.
if (InsertionPt != BB->end())
- Builder.insertDbgValueIntrinsic(APN, DIVar, DIExpr, DDI->getDebugLoc(),
+ Builder.insertDbgValueIntrinsic(APN, DIVar, DIExpr, DII->getDebugLoc(),
&*InsertionPt);
}
@@ -1231,16 +1232,25 @@ bool llvm::LowerDbgDeclare(Function &F) {
return true;
}
-/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic describing the
-/// alloca 'V', if any.
-DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) {
- if (auto *L = LocalAsMetadata::getIfExists(V))
- if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L))
- for (User *U : MDV->users())
- if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(U))
- return DDI;
+/// Finds all intrinsics declaring local variables as living in the memory that
+/// 'V' points to. This may include a mix of dbg.declare and
+/// dbg.addr intrinsics.
+TinyPtrVector<DbgInfoIntrinsic *> llvm::FindDbgAddrUses(Value *V) {
+ auto *L = LocalAsMetadata::getIfExists(V);
+ if (!L)
+ return {};
+ auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L);
+ if (!MDV)
+ return {};
+
+ TinyPtrVector<DbgInfoIntrinsic *> Declares;
+ for (User *U : MDV->users()) {
+ if (auto *DII = dyn_cast<DbgInfoIntrinsic>(U))
+ if (DII->isAddressOfVariable())
+ Declares.push_back(DII);
+ }
- return nullptr;
+ return Declares;
}
void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {
@@ -1251,23 +1261,22 @@ void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) {
DbgValues.push_back(DVI);
}
-
bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
Instruction *InsertBefore, DIBuilder &Builder,
bool Deref, int Offset) {
- DbgDeclareInst *DDI = FindAllocaDbgDeclare(Address);
- if (!DDI)
- return false;
- DebugLoc Loc = DDI->getDebugLoc();
- auto *DIVar = DDI->getVariable();
- auto *DIExpr = DDI->getExpression();
- assert(DIVar && "Missing variable");
- DIExpr = DIExpression::prepend(DIExpr, Deref, Offset);
- // Insert llvm.dbg.declare immediately after the original alloca, and remove
- // old llvm.dbg.declare.
- Builder.insertDeclare(NewAddress, DIVar, DIExpr, Loc, InsertBefore);
- DDI->eraseFromParent();
- return true;
+ auto DbgAddrs = FindDbgAddrUses(Address);
+ for (DbgInfoIntrinsic *DII : DbgAddrs) {
+ DebugLoc Loc = DII->getDebugLoc();
+ auto *DIVar = DII->getVariable();
+ auto *DIExpr = DII->getExpression();
+ assert(DIVar && "Missing variable");
+ DIExpr = DIExpression::prepend(DIExpr, Deref, Offset);
+ // Insert llvm.dbg.declare immediately after the original alloca, and remove
+ // old llvm.dbg.declare.
+ Builder.insertDeclare(NewAddress, DIVar, DIExpr, Loc, InsertBefore);
+ DII->eraseFromParent();
+ }
+ return !DbgAddrs.empty();
}
bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
OpenPOWER on IntegriCloud