/// Add a def for a variable that is valid for its lifetime.
void addSingleLocVar(DebugVariable Var, DIExpression *Expr, DebugLoc DL,
- Value *V) {
+ RawLocationWrapper R) {
VarLocInfo VarLoc;
VarLoc.VariableID = insertVariable(Var);
VarLoc.Expr = Expr;
VarLoc.DL = DL;
- VarLoc.V = V;
+ VarLoc.Values = R;
SingleLocVars.emplace_back(VarLoc);
}
/// Add a def to the wedge of defs just before /p Before.
void addVarLoc(Instruction *Before, DebugVariable Var, DIExpression *Expr,
- DebugLoc DL, Value *V) {
+ DebugLoc DL, RawLocationWrapper R) {
VarLocInfo VarLoc;
VarLoc.VariableID = insertVariable(Var);
VarLoc.Expr = Expr;
VarLoc.DL = DL;
- VarLoc.V = V;
+ VarLoc.Values = R;
VarLocsBeforeInst[Before].emplace_back(VarLoc);
}
};
auto PrintLoc = [&OS](const VarLocInfo &Loc) {
OS << "DEF Var=[" << (unsigned)Loc.VariableID << "]"
- << " Expr=" << *Loc.Expr << " V=" << *Loc.V << "\n";
+ << " Expr=" << *Loc.Expr << " Values=(";
+ for (auto *Op : Loc.Values.location_ops()) {
+ errs() << Op->getName() << " ";
+ }
+ errs() << ")\n";
};
// Print the single location variables.
/// IDs for memory location base addresses in maps. Use 0 to indicate that
/// there's no memory location.
- UniqueVector<Value *> Bases;
+ UniqueVector<RawLocationWrapper> Bases;
UniqueVector<DebugAggregate> Aggregates;
DenseMap<const BasicBlock *, VarFragMap> LiveIn;
DenseMap<const BasicBlock *, VarFragMap> LiveOut;
/// Return a string for the value that \p BaseID represents.
std::string toString(unsigned BaseID) {
if (BaseID)
- return Bases[BaseID]->getName().str();
+ return Bases[BaseID].getVariableLocationOp(0)->getName().str();
else
return "None";
}
const auto DerefOffsetInBytes = getDerefOffsetInBytes(DIExpr);
const unsigned Base =
DerefOffsetInBytes && *DerefOffsetInBytes * 8 == StartBit
- ? Bases.insert(VarLoc.V)
+ ? Bases.insert(VarLoc.Values)
: 0;
LLVM_DEBUG(dbgs() << "DEF " << DbgVar.getVariable()->getName() << " ["
<< StartBit << ", " << EndBit << "): " << toString(Base)
const DbgVariableIntrinsic *Source, Instruction *After) {
DILocation *DL = Source->getDebugLoc();
- auto Emit = [this, Source, After, DL](Value *Val, DIExpression *Expr) {
+ auto Emit = [this, Source, After, DL](Metadata *Val, DIExpression *Expr) {
assert(Expr);
if (!Val)
- Val = PoisonValue::get(Type::getInt1Ty(Source->getContext()));
+ Val = ValueAsMetadata::get(
+ PoisonValue::get(Type::getInt1Ty(Source->getContext())));
// Find a suitable insert point.
Instruction *InsertBefore = After->getNextNode();
VarLocInfo VarLoc;
VarLoc.VariableID = static_cast<VariableID>(Var);
VarLoc.Expr = Expr;
- VarLoc.V = Val;
+ VarLoc.Values = RawLocationWrapper(Val);
VarLoc.DL = DL;
// Insert it into the map for later.
InsertBeforeMap[InsertBefore].push_back(VarLoc);
// The address-expression has an implicit deref, add it now.
std::tie(Val, Expr) =
walkToAllocaAndPrependOffsetDeref(Layout, Val, Expr);
- Emit(Val, Expr);
+ Emit(ValueAsMetadata::get(Val), Expr);
return;
}
}
/// Get the value component, converting to Undef if it is variadic.
Value *Val =
Source->hasArgList() ? nullptr : Source->getVariableLocationOp(0);
- Emit(Val, Source->getExpression());
+ Emit(ValueAsMetadata::get(Val), Source->getExpression());
return;
}
VarLocInfo VarLoc;
VarLoc.VariableID = static_cast<VariableID>(Var);
VarLoc.Expr = DIE;
- VarLoc.V = const_cast<AllocaInst *>(Info.Base);
+ VarLoc.Values = RawLocationWrapper(
+ ValueAsMetadata::get(const_cast<AllocaInst *>(Info.Base)));
VarLoc.DL = DILoc;
// 3. Insert it into the map for later.
InsertBeforeMap[InsertBefore].push_back(VarLoc);
for (auto &I : BB) {
if (auto *DDI = dyn_cast<DbgDeclareInst>(&I)) {
FnVarLocs->addSingleLocVar(DebugVariable(DDI), DDI->getExpression(),
- DDI->getDebugLoc(), DDI->getAddress());
+ DDI->getDebugLoc(),
+ DDI->getWrappedLocation());
} else if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) {
DebugVariable DV = DebugVariable(DII);
DebugAggregate DA = {DV.getVariable(), DV.getInlinedAt()};
//
// Unless we've already done so, create the single location def now.
if (AlwaysStackHomed.insert(Aggr).second) {
- assert(isa<AllocaInst>(VarLoc.V));
+ assert(!VarLoc.Values.hasArgList() &&
+ isa<AllocaInst>(VarLoc.Values.getVariableLocationOp(0)));
// TODO: When more complex cases are handled VarLoc.Expr should be
// built appropriately rather than always using an empty DIExpression.
// The assert below is a reminder.
assert(Simple);
VarLoc.Expr = DIExpression::get(Fn.getContext(), std::nullopt);
DebugVariable Var = FnVarLocs->getVariable(VarLoc.VariableID);
- FnVarLocs->addSingleLocVar(Var, VarLoc.Expr, VarLoc.DL, VarLoc.V);
+ FnVarLocs->addSingleLocVar(Var, VarLoc.Expr, VarLoc.DL, VarLoc.Values);
InsertedAnyIntrinsics = true;
}
}
if (VarsWithStackSlot->contains(getAggregate(DVI)))
continue;
// Wrapper to get a single value (or undef) from DVI.
- auto GetValue = [DVI]() -> Value * {
+ auto GetValue = [DVI]() -> RawLocationWrapper {
// We can't handle variadic DIExpressions yet so treat those as
// kill locations.
+ Value *V;
if (DVI->isKillLocation() || DVI->getValue() == nullptr ||
DVI->hasArgList())
- return PoisonValue::get(Type::getInt32Ty(DVI->getContext()));
- return DVI->getValue();
+ V = PoisonValue::get(Type::getInt32Ty(DVI->getContext()));
+ else
+ V = DVI->getVariableLocationOp(0);
+ return RawLocationWrapper(ValueAsMetadata::get(V));
};
Instruction *InsertBefore = I.getNextNode();
assert(InsertBefore && "Unexpected: debug intrinsics after a terminator");
removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB,
FunctionVarLocsBuilder &FnVarLocs) {
bool Changed = false;
- DenseMap<DebugVariable, std::pair<Value *, DIExpression *>> VariableMap;
+ DenseMap<DebugVariable, std::pair<RawLocationWrapper, DIExpression *>>
+ VariableMap;
// Scan over the entire block, not just over the instructions mapped by
// FnVarLocs, because wedges in FnVarLocs may only be seperated by debug
// Update the map if we found a new value/expression describing the
// variable, or if the variable wasn't mapped already.
- if (VMI == VariableMap.end() || VMI->second.first != Loc.V ||
+ if (VMI == VariableMap.end() || VMI->second.first != Loc.Values ||
VMI->second.second != Loc.Expr) {
- VariableMap[Key] = {Loc.V, Loc.Expr};
+ VariableMap[Key] = {Loc.Values, Loc.Expr};
NewDefs.push_back(Loc);
continue;
}
// Remove undef entries that are encountered before any non-undef
// intrinsics from the entry block.
- if (isa<UndefValue>(Loc.V) && !HasDefinedBits(Aggr, Var)) {
+ if (Loc.Values.isKillLocation(Loc.Expr) && !HasDefinedBits(Aggr, Var)) {
// Did not insert this Loc, which is the same as removing it.
NumDefsRemoved++;
ChangedThisWedge = true;
It != End; ++It) {
auto *Var = FnVarLocs->getDILocalVariable(It->VariableID);
dropDanglingDebugInfo(Var, It->Expr);
- if (!handleDebugValue(It->V, Var, It->Expr, It->DL, SDNodeOrder,
- /*IsVariadic=*/false))
+ SmallVector<Value *> Values(It->Values.location_ops());
+ if (!handleDebugValue(Values, Var, It->Expr, It->DL, SDNodeOrder,
+ It->Values.hasArgList()))
addDanglingDebugInfo(It, SDNodeOrder);
}
}
}
}
+static bool handleDanglingVariadicDebugInfo(SelectionDAG &DAG,
+ DILocalVariable *Variable,
+ DebugLoc DL, unsigned Order,
+ RawLocationWrapper Values,
+ DIExpression *Expression) {
+ if (!Values.hasArgList())
+ return false;
+ // For variadic dbg_values we will now insert an undef.
+ // FIXME: We can potentially recover these!
+ SmallVector<SDDbgOperand, 2> Locs;
+ for (const Value *V : Values.location_ops()) {
+ auto *Undef = UndefValue::get(V->getType());
+ Locs.push_back(SDDbgOperand::fromConst(Undef));
+ }
+ SDDbgValue *SDV = DAG.getDbgValueList(Variable, Expression, Locs, {},
+ /*IsIndirect=*/false, DL, Order,
+ /*IsVariadic=*/true);
+ DAG.AddDbgValue(SDV, /*isParameter=*/false);
+ return true;
+}
+
void SelectionDAGBuilder::addDanglingDebugInfo(const VarLocInfo *VarLoc,
unsigned Order) {
- DanglingDebugInfoMap[VarLoc->V].emplace_back(VarLoc, Order);
+ if (!handleDanglingVariadicDebugInfo(
+ DAG,
+ const_cast<DILocalVariable *>(DAG.getFunctionVarLocs()
+ ->getVariable(VarLoc->VariableID)
+ .getVariable()),
+ VarLoc->DL, Order, VarLoc->Values, VarLoc->Expr)) {
+ DanglingDebugInfoMap[VarLoc->Values.getVariableLocationOp(0)].emplace_back(
+ VarLoc, Order);
+ }
}
void SelectionDAGBuilder::addDanglingDebugInfo(const DbgValueInst *DI,
unsigned Order) {
// We treat variadic dbg_values differently at this stage.
- if (DI->hasArgList()) {
- // For variadic dbg_values we will now insert an undef.
- // FIXME: We can potentially recover these!
- SmallVector<SDDbgOperand, 2> Locs;
- for (const Value *V : DI->getValues()) {
- auto Undef = UndefValue::get(V->getType());
- Locs.push_back(SDDbgOperand::fromConst(Undef));
- }
- SDDbgValue *SDV = DAG.getDbgValueList(
- DI->getVariable(), DI->getExpression(), Locs, {},
- /*IsIndirect=*/false, DI->getDebugLoc(), Order, /*IsVariadic=*/true);
- DAG.AddDbgValue(SDV, /*isParameter=*/false);
- } else {
+ if (!handleDanglingVariadicDebugInfo(
+ DAG, DI->getVariable(), DI->getDebugLoc(), Order,
+ DI->getWrappedLocation(), DI->getExpression())) {
// TODO: Dangling debug info will eventually either be resolved or produce
// an Undef DBG_VALUE. However in the resolution case, a gap may appear
// between the original dbg.value location and its resolved DBG_VALUE,