summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-10-24 22:55:12 +0000
committerAdrian Prantl <aprantl@apple.com>2017-10-24 22:55:12 +0000
commit2eb7cbf987f21b4d573af41d11b327d7257d4fe2 (patch)
tree537cf866e3bace697e9ed5da8173e15c44aaa7c8 /llvm/lib/CodeGen/SelectionDAG
parent4f00a71af56e9707711dd44d92f4a9216808076f (diff)
downloadbcm5719-llvm-2eb7cbf987f21b4d573af41d11b327d7257d4fe2.tar.gz
bcm5719-llvm-2eb7cbf987f21b4d573af41d11b327d7257d4fe2.zip
Implement salavageDebugInfo functionality for SelectionDAG.
Similar to how llvm::salvagDebugInfo hooks into InstCombine, this adds a hook that can be invoked before an SDNode that is associated with an SDDbgValue is erased to capture the effect of the deleted node in a DIExpression. The motivating example is an SDDebugValue attached to an ADD operation that gets folded into a LOAD+OFFSET operation. rdar://problem/32121503 llvm-svn: 316525
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp34
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp1
2 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index f712862f184..dd5e1e5a3ee 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6978,6 +6978,40 @@ SDDbgValue *SelectionDAG::getFrameIndexDbgValue(DIVariable *Var,
return new (DbgInfo->getAlloc()) SDDbgValue(Var, Expr, FI, DL, O);
}
+void SelectionDAG::salvageDebugInfo(SDNode &N) {
+ if (!N.getHasDebugValue())
+ return;
+ for (auto DV : GetDbgValues(&N)) {
+ if (DV->isInvalidated())
+ continue;
+ switch (N.getOpcode()) {
+ default:
+ break;
+ case ISD::ADD:
+ SDValue N0 = N.getOperand(0);
+ SDValue N1 = N.getOperand(1);
+ if (!isConstantIntBuildVectorOrConstantInt(N0) &&
+ isConstantIntBuildVectorOrConstantInt(N1)) {
+ uint64_t Offset = N.getConstantOperandVal(1);
+ // Rewrite an ADD constant node into a DIExpression. Since we are
+ // performing arithmetic to compute the variable's *value* in the
+ // DIExpression, we need to mark the expression with a
+ // DW_OP_stack_value.
+ auto *DIExpr = DV->getExpression();
+ DIExpr = DIExpression::prepend(DIExpr, DIExpression::NoDeref, Offset,
+ DIExpression::WithStackValue);
+ SDDbgValue *Clone =
+ getDbgValue(DV->getVariable(), DIExpr, N0.getNode(), N0.getResNo(),
+ DV->isIndirect(), DV->getDebugLoc(), DV->getOrder());
+ DV->setIsInvalidated();
+ AddDbgValue(Clone, N0.getNode(), false);
+ DEBUG(dbgs() << "SALVAGE: Rewriting"; N0.getNode()->dumprFull(this);
+ dbgs() << " into " << *DIExpr << '\n');
+ }
+ }
+ }
+}
+
namespace {
/// RAUWUpdateListener - Helper for ReplaceAllUsesWith - When the node
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 5311ef437e9..4c4d196427e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3550,6 +3550,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
"NodeToMatch was removed partway through selection");
SelectionDAG::DAGNodeDeletedListener NDL(*CurDAG, [&](SDNode *N,
SDNode *E) {
+ CurDAG->salvageDebugInfo(*N);
auto &Chain = ChainNodesMatched;
assert((!E || !is_contained(Chain, N)) &&
"Chain node replaced during MorphNode");
OpenPOWER on IntegriCloud