summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
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/CodeGen
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/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index fb32487ac42..a98be560860 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5109,37 +5109,48 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
DAG.setRoot(CallResult.second);
return nullptr;
}
+ case Intrinsic::dbg_addr:
case Intrinsic::dbg_declare: {
- const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
+ const DbgInfoIntrinsic &DI = cast<DbgInfoIntrinsic>(I);
DILocalVariable *Variable = DI.getVariable();
DIExpression *Expression = DI.getExpression();
- const Value *Address = DI.getAddress();
assert(Variable && "Missing variable");
- if (!Address) {
- DEBUG(dbgs() << "Dropping debug info for " << DI << "\n");
- return nullptr;
- }
// Check if address has undef value.
- if (isa<UndefValue>(Address) ||
+ const Value *Address = DI.getVariableLocation();
+ if (!Address || isa<UndefValue>(Address) ||
(Address->use_empty() && !isa<Argument>(Address))) {
DEBUG(dbgs() << "Dropping debug info for " << DI << "\n");
return nullptr;
}
- // Static allocas are handled more efficiently in the variable frame index
- // side table.
+ bool isParameter = Variable->isParameter() || isa<Argument>(Address);
+
+ // Check if this variable can be described by a frame index, typically
+ // either as a static alloca or a byval parameter.
+ int FI = INT_MAX;
if (const auto *AI =
- dyn_cast<AllocaInst>(Address->stripInBoundsConstantOffsets()))
- if (AI->isStaticAlloca() && FuncInfo.StaticAllocaMap.count(AI))
- return nullptr;
+ dyn_cast<AllocaInst>(Address->stripInBoundsConstantOffsets())) {
+ if (AI->isStaticAlloca()) {
+ auto I = FuncInfo.StaticAllocaMap.find(AI);
+ if (I != FuncInfo.StaticAllocaMap.end())
+ FI = I->second;
+ }
+ } else if (const auto *Arg = dyn_cast<Argument>(
+ Address->stripInBoundsConstantOffsets())) {
+ FI = FuncInfo.getArgumentFrameIndex(Arg);
+ }
- // Byval arguments with frame indices were already handled after argument
- // lowering and before isel.
- if (const auto *Arg =
- dyn_cast<Argument>(Address->stripInBoundsConstantOffsets()))
- if (FuncInfo.getArgumentFrameIndex(Arg) != INT_MAX)
- return nullptr;
+ // llvm.dbg.addr is control dependent and always generates indirect
+ // DBG_VALUE instructions. llvm.dbg.declare is handled as a frame index in
+ // the MachineFunction variable table.
+ if (FI != INT_MAX) {
+ if (Intrinsic == Intrinsic::dbg_addr)
+ DAG.AddDbgValue(DAG.getFrameIndexDbgValue(Variable, Expression, FI, dl,
+ SDNodeOrder),
+ getRoot().getNode(), isParameter);
+ return nullptr;
+ }
SDValue &N = NodeMap[Address];
if (!N.getNode() && isa<Argument>(Address))
@@ -5150,7 +5161,6 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
Address = BCI->getOperand(0);
// Parameters are handled specially.
- bool isParameter = Variable->isParameter() || isa<Argument>(Address);
auto FINode = dyn_cast<FrameIndexSDNode>(N.getNode());
if (isParameter && FINode) {
// Byval parameter. We have a frame index at this point.
OpenPOWER on IntegriCloud