diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 87 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 6 |
6 files changed, 77 insertions, 58 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 3fac7220727..0e8a83cbe18 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1107,7 +1107,7 @@ void CodeViewDebug::calculateRanges( auto J = std::next(I); const DIExpression *DIExpr = DVInst->getDebugExpression(); while (J != E && - !fragmentsOverlap(DIExpr, J->first->getDebugExpression())) + !DIExpr->fragmentsOverlap(J->first->getDebugExpression())) ++J; if (J != E) End = getLabelBeforeInsn(J->first); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 2e5c2244793..edf66e93058 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -123,29 +123,6 @@ MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) { return LabelsAfterInsn.lookup(MI); } -int DebugHandlerBase::fragmentCmp(const DIExpression *P1, - const DIExpression *P2) { - auto Fragment1 = *P1->getFragmentInfo(); - auto Fragment2 = *P2->getFragmentInfo(); - unsigned l1 = Fragment1.OffsetInBits; - unsigned l2 = Fragment2.OffsetInBits; - unsigned r1 = l1 + Fragment1.SizeInBits; - unsigned r2 = l2 + Fragment2.SizeInBits; - if (r1 <= l2) - return -1; - else if (r2 <= l1) - return 1; - else - return 0; -} - -bool DebugHandlerBase::fragmentsOverlap(const DIExpression *P1, - const DIExpression *P2) { - if (!P1->isFragment() || !P2->isFragment()) - return true; - return fragmentCmp(P1, P2) == 0; -} - /// If this type is derived from a base type then return base type size. uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) { DIType *Ty = TyRef.resolve(); @@ -232,8 +209,8 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) { const DIExpression *Fragment = I->first->getDebugExpression(); if (std::all_of(Ranges.begin(), I, [&](DbgValueHistoryMap::InstrRange Pred) { - return !fragmentsOverlap( - Fragment, Pred.first->getDebugExpression()); + return !Fragment->fragmentsOverlap( + Pred.first->getDebugExpression()); })) LabelsBeforeInsn[I->first] = Asm->getFunctionBegin(); else diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h index 245d70038de..1ccefe32be7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h @@ -122,14 +122,6 @@ public: /// Return Label immediately following the instruction. MCSymbol *getLabelAfterInsn(const MachineInstr *MI); - /// Determine the relative position of the fragments described by P1 and P2. - /// Returns -1 if P1 is entirely before P2, 0 if P1 and P2 overlap, 1 if P1 is - /// entirely after P2. - static int fragmentCmp(const DIExpression *P1, const DIExpression *P2); - - /// Determine whether two variable fragments overlap. - static bool fragmentsOverlap(const DIExpression *P1, const DIExpression *P2); - /// If this type is derived from a base type then return base type size. static uint64_t getBaseTypeSize(const DITypeRef TyRef); }; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 2caf9c9ed27..a1e9a01e72b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -919,8 +919,7 @@ bool DebugLocEntry::MergeValues(const DebugLocEntry &Next) { // sorted. for (unsigned i = 0, j = 0; i < Values.size(); ++i) { for (; j < Next.Values.size(); ++j) { - int res = DebugHandlerBase::fragmentCmp( - cast<DIExpression>(Values[i].Expression), + int res = cast<DIExpression>(Values[i].Expression)->fragmentCmp( cast<DIExpression>(Next.Values[j].Expression)); if (res == 0) // The two expressions overlap, we can't merge. return false; @@ -983,7 +982,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, // If this fragment overlaps with any open ranges, truncate them. const DIExpression *DIExpr = Begin->getDebugExpression(); auto Last = remove_if(OpenRanges, [&](DebugLocEntry::Value R) { - return fragmentsOverlap(DIExpr, R.getExpression()); + return DIExpr->fragmentsOverlap(R.getExpression()); }); OpenRanges.erase(Last, OpenRanges.end()); 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. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 9e7c2bc6821..3d58a040e2a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -671,6 +671,12 @@ public: /// emit CopyFromReg of the specified type Ty. Return empty SDValue() otherwise. SDValue getCopyFromRegs(const Value *V, Type *Ty); + /// If we have dangling debug info that describes \p Variable, or an + /// overlapping part of variable considering the \p Expr, then this method + /// weill drop that debug info as it isn't valid any longer. + void dropDanglingDebugInfo(const DILocalVariable *Variable, + const DIExpression *Expr); + // resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V, // generate the debug data structures now that we've seen its definition. void resolveDanglingDebugInfo(const Value *V, SDValue Val); |