summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp95
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h5
-rw-r--r--llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll24
3 files changed, 59 insertions, 65 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 5de9566785b..2a6f958c3bc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1080,62 +1080,59 @@ void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) {
void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,
const DIExpression *Expr) {
- SmallVector<const Value *, 4> ToRemove;
- for (auto &DMI : DanglingDebugInfoMap) {
- DanglingDebugInfo &DDI = DMI.second;
- if (DDI.getDI()) {
- const DbgValueInst *DI = DDI.getDI();
- DIVariable *DanglingVariable = DI->getVariable();
- DIExpression *DanglingExpr = DI->getExpression();
- if (DanglingVariable == Variable &&
- Expr->fragmentsOverlap(DanglingExpr)) {
- DEBUG(dbgs() << "Dropping dangling debug info for " << *DI << "\n");
- ToRemove.push_back(DMI.first);
+ for (auto &DDIMI : DanglingDebugInfoMap)
+ for (auto &DDI : DDIMI.second)
+ if (DDI.getDI()) {
+ const DbgValueInst *DI = DDI.getDI();
+ DIVariable *DanglingVariable = DI->getVariable();
+ DIExpression *DanglingExpr = DI->getExpression();
+ if (DanglingVariable == Variable &&
+ Expr->fragmentsOverlap(DanglingExpr)) {
+ DEBUG(dbgs() << "Dropping dangling debug info for " << *DI << "\n");
+ DDI = DanglingDebugInfo();
+ }
}
- }
- }
-
- for (auto V : ToRemove)
- DanglingDebugInfoMap[V] = DanglingDebugInfo();
}
// resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V,
// generate the debug data structures now that we've seen its definition.
void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
SDValue Val) {
- DanglingDebugInfo &DDI = DanglingDebugInfoMap[V];
- if (!DDI.getDI())
- return;
- const DbgValueInst *DI = DDI.getDI();
- DebugLoc dl = DDI.getdl();
- unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
- unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
- DILocalVariable *Variable = DI->getVariable();
- DIExpression *Expr = DI->getExpression();
- assert(Variable->isValidLocationForIntrinsic(dl) &&
- "Expected inlined-at fields to agree");
- SDDbgValue *SDV;
- if (Val.getNode()) {
- if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, false, Val)) {
- DEBUG(dbgs() << "Resolve dangling debug info [order=" << DbgSDNodeOrder
- << "] for:\n " << *DI << "\n");
- DEBUG(dbgs() << " By mapping to:\n "; Val.dump());
- // Increase the SDNodeOrder for the DbgValue here to make sure it is
- // inserted after the definition of Val when emitting the instructions
- // after ISel. An alternative could be to teach
- // ScheduleDAGSDNodes::EmitSchedule to delay the insertion properly.
- DEBUG(if (ValSDNodeOrder > DbgSDNodeOrder)
- dbgs() << "changing SDNodeOrder from " << DbgSDNodeOrder
- << " to " << ValSDNodeOrder << "\n");
- SDV = getDbgValue(Val, Variable, Expr, dl,
- std::max(DbgSDNodeOrder, ValSDNodeOrder));
- DAG.AddDbgValue(SDV, Val.getNode(), false);
+ DanglingDebugInfoVector &DDIV = DanglingDebugInfoMap[V];
+ for (auto &DDI : DDIV) {
+ if (!DDI.getDI())
+ continue;
+ const DbgValueInst *DI = DDI.getDI();
+ DebugLoc dl = DDI.getdl();
+ unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
+ unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
+ DILocalVariable *Variable = DI->getVariable();
+ DIExpression *Expr = DI->getExpression();
+ assert(Variable->isValidLocationForIntrinsic(dl) &&
+ "Expected inlined-at fields to agree");
+ SDDbgValue *SDV;
+ if (Val.getNode()) {
+ if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, false, Val)) {
+ DEBUG(dbgs() << "Resolve dangling debug info [order=" << DbgSDNodeOrder
+ << "] for:\n " << *DI << "\n");
+ DEBUG(dbgs() << " By mapping to:\n "; Val.dump());
+ // Increase the SDNodeOrder for the DbgValue here to make sure it is
+ // inserted after the definition of Val when emitting the instructions
+ // after ISel. An alternative could be to teach
+ // ScheduleDAGSDNodes::EmitSchedule to delay the insertion properly.
+ DEBUG(if (ValSDNodeOrder > DbgSDNodeOrder)
+ dbgs() << "changing SDNodeOrder from " << DbgSDNodeOrder
+ << " to " << ValSDNodeOrder << "\n");
+ SDV = getDbgValue(Val, Variable, Expr, dl,
+ std::max(DbgSDNodeOrder, ValSDNodeOrder));
+ DAG.AddDbgValue(SDV, Val.getNode(), false);
+ } else
+ DEBUG(dbgs() << "Resolved dangling debug info for " << *DI
+ << "in EmitFuncArgumentDbgValue\n");
} else
- DEBUG(dbgs() << "Resolved dangling debug info for " << *DI
- << "in EmitFuncArgumentDbgValue\n");
- } else
- DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
- DanglingDebugInfoMap[V] = DanglingDebugInfo();
+ DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
+ }
+ DanglingDebugInfoMap[V].clear();
}
/// getCopyFromRegs - If there was virtual register allocated for the value V
@@ -5330,7 +5327,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
// Do not call getValue(V) yet, as we don't want to generate code.
// Remember it for later.
DanglingDebugInfo DDI(&DI, dl, SDNodeOrder);
- DanglingDebugInfoMap[V] = DDI;
+ DanglingDebugInfoMap[V].push_back(DDI);
return nullptr;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 3d58a040e2a..94f7d5821ad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -116,9 +116,12 @@ class SelectionDAGBuilder {
unsigned getSDNodeOrder() { return SDNodeOrder; }
};
+ /// DanglingDebugInfoVector - Helper type for DanglingDebugInfoMap.
+ typedef std::vector<DanglingDebugInfo> DanglingDebugInfoVector;
+
/// DanglingDebugInfoMap - Keeps track of dbg_values for which we have not
/// yet seen the referent. We defer handling these until we do see it.
- DenseMap<const Value*, DanglingDebugInfo> DanglingDebugInfoMap;
+ DenseMap<const Value*, DanglingDebugInfoVector> DanglingDebugInfoMap;
public:
/// PendingLoads - Loads are not emitted to the program immediately. We bunch
diff --git a/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll b/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
index a8ef9565718..0a75f74a5b3 100644
--- a/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
+++ b/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
@@ -50,8 +50,8 @@
; CHECK: ![[BAR3:.*]] = !DILocalVariable(name: "foo3"
; CHECK: ![[FOO4:.*]] = !DILocalVariable(name: "foo4"
; CHECK: ![[BAR4:.*]] = !DILocalVariable(name: "bar4"
-; CHECK: ![[FOO5:.*]] = !DILocalVariable(name: "bar5"
-; CHECK: ![[BAR5:.*]] = !DILocalVariable(name: "foo5"
+; CHECK: ![[BAR5:.*]] = !DILocalVariable(name: "bar5"
+; CHECK: ![[FOO5:.*]] = !DILocalVariable(name: "foo5"
source_filename = "sdag-dangling-dbgvalue.c"
@@ -74,13 +74,11 @@ entry1:
ret i32 ptrtoint (%struct.SS* @S to i32), !dbg !25
}
-; Verify that the def comes before the debug-use for bar2.
-; TODO: Currently dbg.value for foo2 is dropped. Seems to be a bug. The
-; SelectionDAGBuilder should support several dangling dbg.value for the
-; same value.
+; Verify that the def comes before the debug-use for foo2 and bar2.
define i32 @test2() local_unnamed_addr #0 !dbg !26 {
; CHECK-LABEL: bb.0.entry2
; CHECK-NEXT: [[REG2:%[0-9]+]]:gr64 =
+; CHECK-NEXT: DBG_VALUE debug-use [[REG2]], debug-use $noreg, ![[FOO2]], !DIExpression()
; CHECK-NEXT: DBG_VALUE debug-use [[REG2]], debug-use $noreg, ![[BAR2]], !DIExpression()
entry2:
call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !28, metadata !DIExpression()), !dbg !30
@@ -88,13 +86,11 @@ entry2:
ret i32 add (i32 ptrtoint (%struct.SS* @S to i32), i32 ptrtoint (%struct.SS* @S to i32)), !dbg !32
}
-; Verify that the def comes before the debug-use for foo3.
-; TODO: Currently dbg.value for bar3 is dropped. Seems to be a bug. The
-; SelectionDAGBuilder should support several dangling dbg.value for the
-; same value.
+; Verify that the def comes before the debug-use for foo3 and bar3.
define i32 @test3() local_unnamed_addr #0 !dbg !33 {
; CHECK-LABEL: bb.0.entry3
; CHECK-NEXT: [[REG3:%[0-9]+]]:gr64 =
+; CHECK-NEXT: DBG_VALUE debug-use [[REG3]], debug-use $noreg, ![[BAR3]], !DIExpression()
; CHECK-NEXT: DBG_VALUE debug-use [[REG3]], debug-use $noreg, ![[FOO3]], !DIExpression()
entry3:
call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !36, metadata !DIExpression()), !dbg !38
@@ -118,15 +114,13 @@ entry4:
}
; Verify that we do not get a DBG_VALUE that maps foo5 to @S here.
-; TODO: At the moment we do not get any DBG_VALUE at all here. If
-; SelectionDAGBuilder should support several dangling dbg.value for the
-; same value it would be possible to at least get a DBG_VALUE for
-; bar5.
; TODO: foo5 is set to null, and it is not really used. Just like in test1 it
; can be discussed if there should be a DBG_VALUE for foo5 here.
define i32 @test5() local_unnamed_addr #0 !dbg !47 {
; CHECK-LABEL: bb.0.entry5:
-; CHECK-NOT: DBG_VALUE
+; CHECK-NEXT: [[REG5:%[0-9]+]]:gr64 =
+; CHECK-NEXT: DBG_VALUE debug-use [[REG5]], debug-use $noreg, ![[BAR5]], !DIExpression()
+; CHECK-NOT: DBG_VALUE debug-use [[REG5]], debug-use $noreg, ![[FOO5]], !DIExpression()
; CHECK: RET
entry5:
call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !49, metadata !DIExpression()), !dbg !51
OpenPOWER on IntegriCloud