diff --git a/llvm/include/llvm/CodeGen/AssignmentTrackingAnalysis.h b/llvm/include/llvm/CodeGen/AssignmentTrackingAnalysis.h --- a/llvm/include/llvm/CodeGen/AssignmentTrackingAnalysis.h +++ b/llvm/include/llvm/CodeGen/AssignmentTrackingAnalysis.h @@ -3,6 +3,7 @@ #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/Pass.h" namespace llvm { @@ -21,7 +22,7 @@ llvm::VariableID VariableID; DIExpression *Expr = nullptr; DebugLoc DL; - Value *V = nullptr; // TODO: Needs to be value_s_ for variadic expressions. + RawLocationWrapper Values = RawLocationWrapper(); }; /// Data structure describing the variable locations in a function. Used as the diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp --- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp +++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp @@ -105,23 +105,23 @@ /// 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); } }; @@ -148,7 +148,11 @@ 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. @@ -317,7 +321,7 @@ /// IDs for memory location base addresses in maps. Use 0 to indicate that /// there's no memory location. - UniqueVector Bases; + UniqueVector Bases; UniqueVector Aggregates; DenseMap LiveIn; DenseMap LiveOut; @@ -370,7 +374,7 @@ /// 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"; } @@ -603,7 +607,7 @@ 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) @@ -1244,10 +1248,11 @@ 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(); @@ -1257,7 +1262,7 @@ VarLocInfo VarLoc; VarLoc.VariableID = static_cast(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); @@ -1286,7 +1291,7 @@ // 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; } } @@ -1295,7 +1300,7 @@ /// 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; } @@ -1373,7 +1378,8 @@ VarLocInfo VarLoc; VarLoc.VariableID = static_cast(Var); VarLoc.Expr = DIE; - VarLoc.V = const_cast(Info.Base); + VarLoc.Values = RawLocationWrapper( + ValueAsMetadata::get(const_cast(Info.Base))); VarLoc.DL = DILoc; // 3. Insert it into the map for later. InsertBeforeMap[InsertBefore].push_back(VarLoc); @@ -1856,7 +1862,8 @@ for (auto &I : BB) { if (auto *DDI = dyn_cast(&I)) { FnVarLocs->addSingleLocVar(DebugVariable(DDI), DDI->getExpression(), - DDI->getDebugLoc(), DDI->getAddress()); + DDI->getDebugLoc(), + DDI->getWrappedLocation()); } else if (auto *DII = dyn_cast(&I)) { DebugVariable DV = DebugVariable(DII); DebugAggregate DA = {DV.getVariable(), DV.getInlinedAt()}; @@ -2068,14 +2075,15 @@ // // Unless we've already done so, create the single location def now. if (AlwaysStackHomed.insert(Aggr).second) { - assert(isa(VarLoc.V)); + assert(!VarLoc.Values.hasArgList() && + isa(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; } } @@ -2119,13 +2127,16 @@ 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"); @@ -2213,7 +2224,8 @@ removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB, FunctionVarLocsBuilder &FnVarLocs) { bool Changed = false; - DenseMap> VariableMap; + DenseMap> + VariableMap; // Scan over the entire block, not just over the instructions mapped by // FnVarLocs, because wedges in FnVarLocs may only be seperated by debug @@ -2238,9 +2250,9 @@ // 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; } @@ -2320,7 +2332,7 @@ // Remove undef entries that are encountered before any non-undef // intrinsics from the entry block. - if (isa(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; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -131,7 +131,7 @@ Value *getVariableLocationOp(unsigned Idx) const { assert(Idx == 0 && "Dangling variadic debug values not supported yet"); if (Info.is()) - return Info.get()->V; + return Info.get()->Values.getVariableLocationOp(Idx); return Info.get()->getVariableLocationOp(Idx); } DebugLoc getDebugLoc() const { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1145,8 +1145,9 @@ 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 Values(It->Values.location_ops()); + if (!handleDebugValue(Values, Var, It->Expr, It->DL, SDNodeOrder, + It->Values.hasArgList())) addDanglingDebugInfo(It, SDNodeOrder); } } @@ -1206,27 +1207,46 @@ } } +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 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(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 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, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1368,9 +1368,11 @@ FunctionVarLocs const *FnVarLocs) { for (auto It = FnVarLocs->single_locs_begin(), End = FnVarLocs->single_locs_end(); - It != End; ++It) - processDbgDeclare(FuncInfo, It->V, It->Expr, + It != End; ++It) { + assert(!It->Values.hasArgList() && "Single loc variadic ops not supported"); + processDbgDeclare(FuncInfo, It->Values.getVariableLocationOp(0), It->Expr, FnVarLocs->getDILocalVariable(It->VariableID), It->DL); + } } void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {