diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index f05f0be27f5..df6b101b405 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "SelectionDAGBuilder.h" +#include "SDNodeDbgValue.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" @@ -1077,29 +1078,64 @@ 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 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()) { - const DbgValueInst *DI = DDI.getDI(); - DebugLoc dl = DDI.getdl(); - 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)) { - SDV = getDbgValue(Val, Variable, Expr, dl, DbgSDNodeOrder); - DAG.AddDbgValue(SDV, Val.getNode(), false); - } + 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); } else - DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n"); - DanglingDebugInfoMap[V] = DanglingDebugInfo(); - } + DEBUG(dbgs() << "Resolved dangling debug info for " << *DI + << "in EmitFuncArgumentDbgValue\n"); + } else + DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n"); + DanglingDebugInfoMap[V] = DanglingDebugInfo(); } /// getCopyFromRegs - If there was virtual register allocated for the value V @@ -5178,6 +5214,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { const DbgInfoIntrinsic &DI = cast<DbgInfoIntrinsic>(I); DILocalVariable *Variable = DI.getVariable(); DIExpression *Expression = DI.getExpression(); + dropDanglingDebugInfo(Variable, Expression); assert(Variable && "Missing variable"); // Check if address has undef value. @@ -5209,10 +5246,11 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { // DBG_VALUE instructions. llvm.dbg.declare is handled as a frame index in // the MachineFunction variable table. if (FI != std::numeric_limits<int>::max()) { - if (Intrinsic == Intrinsic::dbg_addr) - DAG.AddDbgValue(DAG.getFrameIndexDbgValue(Variable, Expression, FI, dl, - SDNodeOrder), - getRoot().getNode(), isParameter); + if (Intrinsic == Intrinsic::dbg_addr) { + SDDbgValue *SDV = DAG.getFrameIndexDbgValue(Variable, Expression, + FI, dl, SDNodeOrder); + DAG.AddDbgValue(SDV, getRoot().getNode(), isParameter); + } return nullptr; } @@ -5256,6 +5294,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { DILocalVariable *Variable = DI.getVariable(); DIExpression *Expression = DI.getExpression(); + dropDanglingDebugInfo(Variable, Expression); const Value *V = DI.getValue(); if (!V) return nullptr; @@ -5280,6 +5319,12 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { return nullptr; } + // TODO: When we get here we will either drop the dbg.value completely, or + // we try to move it forward by letting it dangle for awhile. So we should + // probably add an extra DbgValue to the DAG here, with a reference to + // "noreg", to indicate that we have lost the debug location for the + // variable. + if (!V->use_empty() ) { // Do not call getValue(V) yet, as we don't want to generate code. // Remember it for later. |

