}
void SelectionDAGBuilder::addDanglingDebugInfo(const DbgValueInst *DI,
- DebugLoc DL, unsigned Order) {
+ unsigned Order) {
// We treat variadic dbg_values differently at this stage.
if (DI->hasArgList()) {
// For variadic dbg_values we will now insert an undef.
}
SDDbgValue *SDV = DAG.getDbgValueList(
DI->getVariable(), DI->getExpression(), Locs, {},
- /*IsIndirect=*/false, DL, Order, /*IsVariadic=*/true);
+ /*IsIndirect=*/false, DI->getDebugLoc(), Order, /*IsVariadic=*/true);
DAG.AddDbgValue(SDV, /*isParameter=*/false);
} else {
// TODO: Dangling debug info will eventually either be resolved or produce
assert(DI->getNumVariableLocationOps() == 1 &&
"DbgValueInst without an ArgList should have a single location "
"operand.");
- DanglingDebugInfoMap[DI->getValue(0)].emplace_back(DI, DL, Order);
+ DanglingDebugInfoMap[DI->getValue(0)].emplace_back(DI, Order);
}
}
void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,
const DIExpression *Expr) {
auto isMatchingDbgValue = [&](DanglingDebugInfo &DDI) {
- const DbgValueInst *DI = DDI.getDI();
- DIVariable *DanglingVariable = DI->getVariable();
- DIExpression *DanglingExpr = DI->getExpression();
+ DIVariable *DanglingVariable = DDI.getVariable();
+ DIExpression *DanglingExpr = DDI.getExpression();
if (DanglingVariable == Variable && Expr->fragmentsOverlap(DanglingExpr)) {
- LLVM_DEBUG(dbgs() << "Dropping dangling debug info for " << *DI << "\n");
+ LLVM_DEBUG(dbgs() << "Dropping dangling debug info for " << DDI << "\n");
return true;
}
return false;
DanglingDebugInfoVector &DDIV = DanglingDbgInfoIt->second;
for (auto &DDI : DDIV) {
- const DbgValueInst *DI = DDI.getDI();
- assert(!DI->hasArgList() && "Not implemented for variadic dbg_values");
- assert(DI && "Ill-formed DanglingDebugInfo");
- DebugLoc dl = DDI.getdl();
+ DebugLoc DL = DDI.getDebugLoc();
unsigned ValSDNodeOrder = Val.getNode()->getIROrder();
unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();
- DILocalVariable *Variable = DI->getVariable();
- DIExpression *Expr = DI->getExpression();
- assert(Variable->isValidLocationForIntrinsic(dl) &&
+ DILocalVariable *Variable = DDI.getVariable();
+ DIExpression *Expr = DDI.getExpression();
+ assert(Variable->isValidLocationForIntrinsic(DL) &&
"Expected inlined-at fields to agree");
SDDbgValue *SDV;
if (Val.getNode()) {
// in the first place we should not be more successful here). Unless we
// have some test case that prove this to be correct we should avoid
// calling EmitFuncArgumentDbgValue here.
- if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl,
+ if (!EmitFuncArgumentDbgValue(V, Variable, Expr, DL,
FuncArgumentDbgValueKind::Value, Val)) {
- LLVM_DEBUG(dbgs() << "Resolve dangling debug info [order="
- << DbgSDNodeOrder << "] for:\n " << *DI << "\n");
+ LLVM_DEBUG(dbgs() << "Resolve dangling debug info for " << DDI << "\n");
LLVM_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
LLVM_DEBUG(if (ValSDNodeOrder > DbgSDNodeOrder) dbgs()
<< "changing SDNodeOrder from " << DbgSDNodeOrder << " to "
<< ValSDNodeOrder << "\n");
- SDV = getDbgValue(Val, Variable, Expr, dl,
+ SDV = getDbgValue(Val, Variable, Expr, DL,
std::max(DbgSDNodeOrder, ValSDNodeOrder));
DAG.AddDbgValue(SDV, false);
} else
- LLVM_DEBUG(dbgs() << "Resolved dangling debug info for " << *DI
+ LLVM_DEBUG(dbgs() << "Resolved dangling debug info for " << DDI
<< "in EmitFuncArgumentDbgValue\n");
} else {
- LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
- auto Undef = UndefValue::get(DDI.getDI()->getValue(0)->getType());
+ LLVM_DEBUG(dbgs() << "Dropping debug info for " << DDI << "\n");
+ auto Undef = UndefValue::get(V->getType());
auto SDV =
- DAG.getConstantDbgValue(Variable, Expr, Undef, dl, DbgSDNodeOrder);
+ DAG.getConstantDbgValue(Variable, Expr, Undef, DL, DbgSDNodeOrder);
DAG.AddDbgValue(SDV, false);
}
}
// state of `handleDebugValue`, we need know specifically which values were
// invalid, so that we attempt to salvage only those values when processing
// a DIArgList.
- assert(!DDI.getDI()->hasArgList() &&
- "Not implemented for variadic dbg_values");
- Value *V = DDI.getDI()->getValue(0);
- DILocalVariable *Var = DDI.getDI()->getVariable();
- DIExpression *Expr = DDI.getDI()->getExpression();
- DebugLoc DL = DDI.getdl();
+ Value *V = DDI.getVariableLocationOp(0);
+ Value *OrigV = V;
+ DILocalVariable *Var = DDI.getVariable();
+ DIExpression *Expr = DDI.getExpression();
+ DebugLoc DL = DDI.getDebugLoc();
unsigned SDOrder = DDI.getSDNodeOrder();
+
// Currently we consider only dbg.value intrinsics -- we tell the salvager
// that DW_OP_stack_value is desired.
- assert(isa<DbgValueInst>(DDI.getDI()));
bool StackValue = true;
// Can this Value can be encoded without any further work?
// Some kind of simplification occurred: check whether the operand of the
// salvaged debug expression can be encoded in this DAG.
if (handleDebugValue(V, Var, Expr, DL, SDOrder, /*IsVariadic=*/false)) {
- LLVM_DEBUG(dbgs() << "Salvaged debug location info for:\n "
- << *DDI.getDI() << "\nBy stripping back to:\n " << *V);
+ LLVM_DEBUG(
+ dbgs() << "Salvaged debug location info for:\n " << *Var << "\n"
+ << *OrigV << "\nBy stripping back to:\n " << *V << "\n");
return;
}
}
// This was the final opportunity to salvage this debug information, and it
// couldn't be done. Place an undef DBG_VALUE at this location to terminate
// any earlier variable location.
- auto Undef = UndefValue::get(DDI.getDI()->getValue(0)->getType());
- auto SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
+ assert(OrigV && "V shouldn't be null");
+ auto *Undef = UndefValue::get(OrigV->getType());
+ auto *SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
DAG.AddDbgValue(SDV, false);
-
- LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n " << *DDI.getDI()
- << "\n");
- LLVM_DEBUG(dbgs() << " Last seen at:\n " << *DDI.getDI()->getOperand(0)
- << "\n");
+ LLVM_DEBUG(dbgs() << "Dropping debug value info for:\n " << DDI << "\n");
}
bool SelectionDAGBuilder::handleDebugValue(ArrayRef<const Value *> Values,
bool IsVariadic = DI.hasArgList();
if (!handleDebugValue(Values, Variable, Expression, DI.getDebugLoc(),
SDNodeOrder, IsVariadic))
- addDanglingDebugInfo(&DI, DI.getDebugLoc(), SDNodeOrder);
+ addDanglingDebugInfo(&DI, SDNodeOrder);
return;
}
/// Helper type for DanglingDebugInfoMap.
class DanglingDebugInfo {
- const DbgValueInst* DI = nullptr;
- DebugLoc dl;
+ const DbgValueInst *DI = nullptr;
unsigned SDNodeOrder = 0;
public:
DanglingDebugInfo() = default;
- DanglingDebugInfo(const DbgValueInst *di, DebugLoc DL, unsigned SDNO)
- : DI(di), dl(std::move(DL)), SDNodeOrder(SDNO) {}
+ DanglingDebugInfo(const DbgValueInst *DI, unsigned SDNO)
+ : DI(DI), SDNodeOrder(SDNO) {
+ assert(!DI->hasArgList() &&
+ "Dangling variadic debug values not supported yet");
+ }
- const DbgValueInst* getDI() { return DI; }
- DebugLoc getdl() { return dl; }
- unsigned getSDNodeOrder() { return SDNodeOrder; }
+ DILocalVariable *getVariable() const { return DI->getVariable(); }
+ DIExpression *getExpression() const { return DI->getExpression(); }
+ Value *getVariableLocationOp(unsigned Idx) const {
+ assert(Idx == 0 && "Dangling variadic debug values not supported yet");
+ return DI->getVariableLocationOp(Idx);
+ }
+ DebugLoc getDebugLoc() const { return DI->getDebugLoc(); }
+ unsigned getSDNodeOrder() const { return SDNodeOrder; }
+
+ friend raw_ostream &operator<<(raw_ostream &OS,
+ const DanglingDebugInfo &Info) {
+ OS << "DDI(var=" << *Info.getVariable()
+ << ", val= " << *Info.getVariableLocationOp(0)
+ << ", expr=" << *Info.getExpression()
+ << ", order=" << Info.getSDNodeOrder()
+ << ", loc=" << Info.getDebugLoc() << ")";
+ return OS;
+ }
};
/// Helper type for DanglingDebugInfoMap.
SDValue getCopyFromRegs(const Value *V, Type *Ty);
/// Register a dbg_value which relies on a Value which we have not yet seen.
- void addDanglingDebugInfo(const DbgValueInst *DI, DebugLoc DL,
- unsigned Order);
+ void addDanglingDebugInfo(const DbgValueInst *DI, unsigned Order);
/// If we have dangling debug info that describes \p Variable, or an
/// overlapping part of variable considering the \p Expr, then this method