diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -24,6 +24,7 @@ #define LLVM_IR_INTRINSICINST_H #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/FPEnv.h" #include "llvm/IR/Function.h" @@ -123,10 +124,77 @@ /// This is the common base class for debug info intrinsics for variables. class DbgVariableIntrinsic : public DbgInfoIntrinsic { public: - /// Get the location corresponding to the variable referenced by the debug + // Iterator for ValueAsMetadata that internally uses direct pointer iteration + // over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the + // ValueAsMetadata . + class location_op_iterator + : public iterator_facade_base { + PointerUnion I; + + public: + location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {} + location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {} + + location_op_iterator &operator=(const location_op_iterator &R) { + I = R.I; + return *this; + } + bool operator==(const location_op_iterator &RHS) const { + return I == RHS.I; + } + const Value *operator*() const { + ValueAsMetadata *VAM = I.is() + ? I.get() + : *I.get(); + return VAM->getValue(); + }; + Value *operator*() { + ValueAsMetadata *VAM = I.is() + ? I.get() + : *I.get(); + return VAM->getValue(); + } + location_op_iterator &operator++() { + if (I.is()) + I = I.get() + 1; + else + I = I.get() + 1; + return *this; + } + location_op_iterator &operator--() { + if (I.is()) + I = I.get() - 1; + else + I = I.get() - 1; + return *this; + } + }; + + /// Get the locations corresponding to the variable referenced by the debug /// info intrinsic. Depending on the intrinsic, this could be the /// variable's value or its address. - Value *getVariableLocation(bool AllowNullOp = true) const; + iterator_range location_ops() const; + + Value *getVariableLocationOp(unsigned OpIdx) const; + + void replaceVariableLocationOp(Value *OldValue, Value *NewValue); + + void setVariable(DILocalVariable *NewVar) { + setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar)); + } + + void setExpression(DIExpression *NewExpr) { + setArgOperand(2, MetadataAsValue::get(NewExpr->getContext(), NewExpr)); + } + + unsigned getNumVariableLocationOps() const { + if (hasArgList()) + return cast(getRawLocation())->getArgs().size(); + return 1; + } + + bool hasArgList() const { return isa(getRawLocation()); } /// Does this describe the address of a local variable. True for dbg.addr /// and dbg.declare, but not dbg.value, which describes its value. @@ -134,6 +202,24 @@ return getIntrinsicID() != Intrinsic::dbg_value; } + void setUndef() { + // TODO: When/if we remove duplicate values from DIArgLists, we don't need + // this set anymore. + SmallPtrSet RemovedValues; + for (Value *OldValue : location_ops()) { + if (!RemovedValues.insert(OldValue).second) + continue; + Value *Undef = UndefValue::get(OldValue->getType()); + replaceVariableLocationOp(OldValue, Undef); + } + } + + bool isUndef() const { + return (getNumVariableLocationOps() == 0 && + !getExpression()->isComplex()) || + any_of(location_ops(), [](Value *V) { return isa(V); }); + } + DILocalVariable *getVariable() const { return cast(getRawVariable()); } @@ -142,6 +228,10 @@ return cast(getRawExpression()); } + Metadata *getRawLocation() const { + return cast(getArgOperand(0))->getMetadata(); + } + Metadata *getRawVariable() const { return cast(getArgOperand(1))->getMetadata(); } @@ -170,12 +260,21 @@ return isa(V) && classof(cast(V)); } /// @} +private: + void setArgOperand(unsigned i, Value *v) { + DbgInfoIntrinsic::setArgOperand(i, v); + } + void setOperand(unsigned i, Value *v) { DbgInfoIntrinsic::setOperand(i, v); } }; /// This represents the llvm.dbg.declare instruction. class DbgDeclareInst : public DbgVariableIntrinsic { public: - Value *getAddress() const { return getVariableLocation(); } + Value *getAddress() const { + assert(getNumVariableLocationOps() == 1 && + "dbg.declare must have exactly 1 location operand."); + return getVariableLocationOp(0); + } /// \name Casting methods /// @{ @@ -191,7 +290,11 @@ /// This represents the llvm.dbg.addr instruction. class DbgAddrIntrinsic : public DbgVariableIntrinsic { public: - Value *getAddress() const { return getVariableLocation(); } + Value *getAddress() const { + assert(getNumVariableLocationOps() == 1 && + "dbg.addr must have exactly 1 location operand."); + return getVariableLocationOp(0); + } /// \name Casting methods /// @{ @@ -206,8 +309,13 @@ /// This represents the llvm.dbg.value instruction. class DbgValueInst : public DbgVariableIntrinsic { public: - Value *getValue() const { - return getVariableLocation(/* AllowNullOp = */ false); + // The default argument should only be used in ISel, and the default option + // should be removed once ISel support for multiple location ops is complete. + Value *getValue(unsigned OpIdx = 0) const { + return getVariableLocationOp(OpIdx); + } + iterator_range getValues() const { + return location_ops(); } /// \name Casting methods diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -550,8 +550,7 @@ SmallVector Ops; Ops.append(std::next(DIExpr->elements_begin()), DIExpr->elements_end()); - auto *E = DIExpression::get(Context, Ops); - DDI->setOperand(2, MetadataAsValue::get(Context, E)); + DDI->setExpression(DIExpression::get(Context, Ops)); } } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -2807,11 +2807,8 @@ // including the debug uses. Since we are undoing the replacements, // the original debug uses must also be reinstated to maintain the // correctness and utility of debug value instructions. - for (auto *DVI: DbgValues) { - LLVMContext &Ctx = Inst->getType()->getContext(); - auto *MV = MetadataAsValue::get(Ctx, ValueAsMetadata::get(Inst)); - DVI->setOperand(0, MV); - } + for (auto *DVI : DbgValues) + DVI->replaceVariableLocationOp(DVI->getVariableLocationOp(0), Inst); } }; @@ -7733,7 +7730,7 @@ DbgValueInst &DVI = *cast(I); // Does this dbg.value refer to a sunk address calculation? - Value *Location = DVI.getVariableLocation(); + Value *Location = DVI.getVariableLocationOp(0); WeakTrackingVH SunkAddrVH = SunkAddrs[Location]; Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; if (SunkAddr) { @@ -7741,8 +7738,7 @@ // opportunity to be accurately lowered. This update may change the type of // pointer being referred to; however this makes no difference to debugging // information, and we can't generate bitcasts that may affect codegen. - DVI.setOperand(0, MetadataAsValue::get(DVI.getContext(), - ValueAsMetadata::get(SunkAddr))); + DVI.replaceVariableLocationOp(Location, SunkAddr); return true; } return false; 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 @@ -1191,8 +1191,7 @@ << "in EmitFuncArgumentDbgValue\n"); } else { LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n"); - auto Undef = - UndefValue::get(DDI.getDI()->getVariableLocation()->getType()); + auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType()); auto SDV = DAG.getConstantDbgValue(Variable, Expr, Undef, dl, DbgSDNodeOrder); DAG.AddDbgValue(SDV, nullptr, false); @@ -1246,7 +1245,7 @@ // 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()->getVariableLocation()->getType()); + auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType()); auto SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder); DAG.AddDbgValue(SDV, nullptr, false); @@ -5867,7 +5866,7 @@ LLVM_DEBUG(dbgs() << "SelectionDAG visiting debug intrinsic: " << DI << "\n"); // Check if address has undef value. - const Value *Address = DI.getVariableLocation(); + const Value *Address = DI.getVariableLocationOp(0); if (!Address || isa(Address) || (Address->use_empty() && !isa(Address))) { LLVM_DEBUG(dbgs() << "Dropping debug info for " << DI diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -712,6 +712,12 @@ return false; // Constant wasn't dead } + // If C is only used by metadata, it should not be preserved but should have + // its uses replaced. + if (C->isUsedByMetadata()) { + const_cast(C)->replaceAllUsesWith( + UndefValue::get(C->getType())); + } const_cast(C)->destroyConstant(); return true; } diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp --- a/llvm/lib/IR/IntrinsicInst.cpp +++ b/llvm/lib/IR/IntrinsicInst.cpp @@ -38,18 +38,65 @@ /// intrinsics for variables. /// -Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const { - Value *Op = getArgOperand(0); - if (AllowNullOp && !Op) +iterator_range +DbgVariableIntrinsic::location_ops() const { + auto *MD = getRawLocation(); + assert(MD && "First operand of DbgVariableIntrinsic should be non-null."); + + // If operand is ValueAsMetadata, return a range over just that operand. + if (auto *VAM = dyn_cast(MD)) { + return {location_op_iterator(VAM), location_op_iterator(VAM + 1)}; + } + // If operand is DIArgList, return a range over its args. + if (auto *AL = dyn_cast(MD)) + return {location_op_iterator(AL->args_begin()), + location_op_iterator(AL->args_end())}; + // Operand must be an empty metadata tuple, so return empty iterator. + return {location_op_iterator(static_cast(nullptr)), + location_op_iterator(static_cast(nullptr))}; +} + +Value *DbgVariableIntrinsic::getVariableLocationOp(unsigned OpIdx) const { + auto *MD = getRawLocation(); + assert(MD && "First operand of DbgVariableIntrinsic should be non-null."); + if (auto *AL = dyn_cast(MD)) + return AL->getArgs()[OpIdx]->getValue(); + if (isa(MD)) return nullptr; + assert( + isa(MD) && + "Attempted to get location operand from DbgVariableIntrinsic with none."); + auto *V = cast(MD); + assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " + "single location operand."); + return V->getValue(); +} - auto *MD = cast(Op)->getMetadata(); - if (auto *V = dyn_cast(MD)) - return V->getValue(); +static ValueAsMetadata *getAsMetadata(Value *V) { + return isa(V) ? dyn_cast( + cast(V)->getMetadata()) + : ValueAsMetadata::get(V); +} - // When the value goes to null, it gets replaced by an empty MDNode. - assert(!cast(MD)->getNumOperands() && "Expected an empty MDNode"); - return nullptr; +void DbgVariableIntrinsic::replaceVariableLocationOp(Value *OldValue, + Value *NewValue) { + assert(NewValue && "Values must be non-null"); + auto Locations = location_ops(); + auto OldIt = find(Locations, OldValue); + assert(OldIt != Locations.end() && "OldValue must be a current location"); + if (!hasArgList()) { + Value *NewOperand = isa(NewValue) + ? NewValue + : MetadataAsValue::get( + getContext(), ValueAsMetadata::get(NewValue)); + return setArgOperand(0, NewOperand); + } + SmallVector MDs; + ValueAsMetadata *NewOperand = getAsMetadata(NewValue); + for (auto *VMD : Locations) + MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD)); + setArgOperand( + 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); } Optional DbgVariableIntrinsic::getFragmentSizeInBits() const { diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -5332,7 +5332,7 @@ } void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic &DII) { - auto *MD = cast(DII.getArgOperand(0))->getMetadata(); + auto *MD = DII.getRawLocation(); AssertDI(isa(MD) || isa(MD) || (isa(MD) && !cast(MD)->getNumOperands()), "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); diff --git a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp --- a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp +++ b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp @@ -284,6 +284,7 @@ class AArch64StackTagging : public FunctionPass { struct AllocaInfo { AllocaInst *AI; + TrackingVH OldAI; // Track through RAUW to replace debug uses. SmallVector LifetimeStart; SmallVector LifetimeEnd; SmallVector DbgVariableIntrinsics; @@ -557,12 +558,13 @@ Instruction *I = &*IT; if (auto *AI = dyn_cast(I)) { Allocas[AI].AI = AI; + Allocas[AI].OldAI = AI; continue; } if (auto *DVI = dyn_cast(I)) { if (auto *AI = - dyn_cast_or_null(DVI->getVariableLocation())) { + dyn_cast_or_null(DVI->getVariableLocationOp(0))) { Allocas[AI].DbgVariableIntrinsics.push_back(DVI); } continue; @@ -705,9 +707,7 @@ // Fixup debug intrinsics to point to the new alloca. for (auto DVI : Info.DbgVariableIntrinsics) - DVI->setArgOperand( - 0, - MetadataAsValue::get(F->getContext(), LocalAsMetadata::get(Info.AI))); + DVI->replaceVariableLocationOp(Info.OldAI, Info.AI); } // If we have instrumented at least one alloca, all unrecognized lifetime diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3548,9 +3548,8 @@ return false; if (isa(I)) - DII->setOperand( - 0, MetadataAsValue::get(I->getContext(), - ValueAsMetadata::get(I->getOperand(0)))); + DII->replaceVariableLocationOp(DII->getVariableLocationOp(0), + I->getOperand(0)); return true; }; diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -1151,9 +1151,10 @@ // to put it at the beginning of the expression. SmallVector NewOps = {dwarf::DW_OP_LLVM_tag_offset, RetagMask(N)}; - DDI->setArgOperand( - 2, MetadataAsValue::get(*C, DIExpression::prependOpcodes( - DDI->getExpression(), NewOps))); + auto Locations = DDI->location_ops(); + unsigned LocNo = std::distance(Locations.begin(), find(Locations, AI)); + DDI->setExpression( + DIExpression::appendOpsToArg(DDI->getExpression(), NewOps, LocNo)); } size_t Size = getAllocaSizeInBytes(*AI); @@ -1217,7 +1218,7 @@ if (auto *DDI = dyn_cast(&Inst)) if (auto *Alloca = - dyn_cast_or_null(DDI->getVariableLocation())) + dyn_cast_or_null(DDI->getVariableLocationOp(0))) AllocaDbgMap[Alloca].push_back(DDI); if (InstrumentLandingPads && isa(Inst)) @@ -1298,10 +1299,9 @@ for (auto &Inst : BB) if (auto *DVI = dyn_cast(&Inst)) if (auto *AI = - dyn_cast_or_null(DVI->getVariableLocation())) + dyn_cast_or_null(DVI->getVariableLocationOp(0))) if (auto *NewAI = AllocaToPaddedAllocaMap.lookup(AI)) - DVI->setArgOperand( - 0, MetadataAsValue::get(*C, LocalAsMetadata::get(NewAI))); + DVI->replaceVariableLocationOp(AI, NewAI); for (auto &P : AllocaToPaddedAllocaMap) P.first->eraseFromParent(); } diff --git a/llvm/lib/Transforms/Scalar/ADCE.cpp b/llvm/lib/Transforms/Scalar/ADCE.cpp --- a/llvm/lib/Transforms/Scalar/ADCE.cpp +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp @@ -521,7 +521,7 @@ // If intrinsic is pointing at a live SSA value, there may be an // earlier optimization bug: if we know the location of the variable, // why isn't the scope of the location alive? - if (Value *V = DII->getVariableLocation()) + if (Value *V = DII->getVariableLocationOp(0)) if (Instruction *II = dyn_cast(V)) if (isLive(II)) dbgs() << "Dropping debug info for " << *DII << "\n"; diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -5774,7 +5774,8 @@ } using EqualValues = SmallVector, 4>; -using EqualValuesMap = DenseMap; +using EqualValuesMap = + DenseMap, EqualValues>; static void DbgGatherEqualValues(Loop *L, ScalarEvolution &SE, EqualValuesMap &DbgValueToEqualSet) { @@ -5783,48 +5784,51 @@ auto DVI = dyn_cast(&I); if (!DVI) continue; - auto V = DVI->getVariableLocation(); - if (!V || !SE.isSCEVable(V->getType())) - continue; - auto DbgValueSCEV = SE.getSCEV(V); - EqualValues EqSet; - for (PHINode &Phi : L->getHeader()->phis()) { - if (V->getType() != Phi.getType()) + for (auto V : DVI->location_ops()) { + if (!V || !SE.isSCEVable(V->getType())) continue; - if (!SE.isSCEVable(Phi.getType())) + if (DbgValueToEqualSet.count({DVI, V})) continue; - auto PhiSCEV = SE.getSCEV(&Phi); - Optional Offset = - SE.computeConstantDifference(DbgValueSCEV, PhiSCEV); - if (Offset && Offset->getMinSignedBits() <= 64) - EqSet.emplace_back(std::make_tuple( - &Phi, Offset.getValue().getSExtValue(), DVI->getExpression())); + auto DbgValueSCEV = SE.getSCEV(V); + EqualValues EqSet; + for (PHINode &Phi : L->getHeader()->phis()) { + if (V->getType() != Phi.getType()) + continue; + if (!SE.isSCEVable(Phi.getType())) + continue; + auto PhiSCEV = SE.getSCEV(&Phi); + Optional Offset = + SE.computeConstantDifference(DbgValueSCEV, PhiSCEV); + if (Offset && Offset->getMinSignedBits() <= 64) + EqSet.emplace_back(std::make_tuple( + &Phi, Offset.getValue().getSExtValue(), DVI->getExpression())); + } + DbgValueToEqualSet[{DVI, V}] = std::move(EqSet); } - DbgValueToEqualSet[DVI] = std::move(EqSet); } } } static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet) { for (auto A : DbgValueToEqualSet) { - auto DVI = A.first; + auto DVI = A.first.first; + auto V = A.first.second; // Only update those that are now undef. - if (!isa_and_nonnull(DVI->getVariableLocation())) + if (!isa_and_nonnull(V)) continue; for (auto EV : A.second) { - auto V = std::get(EV); - if (!V) + auto EVHandle = std::get(EV); + if (!EVHandle) continue; auto DbgDIExpr = std::get(EV); auto Offset = std::get(EV); - auto &Ctx = DVI->getContext(); - DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V))); + DVI->replaceVariableLocationOp(V, EVHandle); if (Offset) { SmallVector Ops; DIExpression::appendOffset(Ops, Offset); - DbgDIExpr = DIExpression::prependOpcodes(DbgDIExpr, Ops, true); + DbgDIExpr = DIExpression::appendOpsToArg(DbgDIExpr, Ops, 0); } - DVI->setOperand(2, MetadataAsValue::get(Ctx, DbgDIExpr)); + DVI->setExpression(DbgDIExpr); break; } } diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp @@ -266,7 +266,7 @@ // Debug variable has special operand to check it's not hoisted. if (const auto *DVI = dyn_cast(U)) { if (const auto *I = - dyn_cast_or_null(DVI->getVariableLocation())) + dyn_cast_or_null(DVI->getVariableLocationOp(0))) if (NotHoisted.count(I) == 0) return true; return false; diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1516,7 +1516,7 @@ // If the location isn't a constant or an instruction, delete the // intrinsic. auto *DVI = cast(DII); - Value *Location = DVI->getVariableLocation(); + Value *Location = DVI->getVariableLocationOp(0); if (!Location || (!isa(Location) && !isa(Location))) { DebugIntrinsicsToDelete.push_back(DVI); @@ -1539,7 +1539,7 @@ NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(), OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero, OldVar->getAlignInBits()); - DVI->setArgOperand(1, MetadataAsValue::get(Ctx, NewVar)); + DVI->setVariable(cast(NewVar)); } for (auto *DII : DebugIntrinsicsToDelete) DII->eraseFromParent(); diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp --- a/llvm/lib/Transforms/Utils/LCSSA.cpp +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp @@ -236,7 +236,6 @@ llvm::findDbgValues(DbgValues, I); // Update pre-existing debug value uses that reside outside the loop. - auto &Ctx = I->getContext(); for (auto DVI : DbgValues) { BasicBlock *UserBB = DVI->getParent(); if (InstBB == UserBB || L->contains(UserBB)) @@ -247,7 +246,7 @@ Value *V = AddedPHIs.size() == 1 ? AddedPHIs[0] : SSAUpdate.FindValueForBlock(UserBB); if (V) - DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V))); + DVI->replaceVariableLocationOp(I, V); } // SSAUpdater might have inserted phi-nodes inside other loops. We'll need diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -562,8 +562,7 @@ findDbgUsers(DbgUsers, I); for (auto *DII : DbgUsers) { Value *Undef = UndefValue::get(I->getType()); - DII->setOperand(0, MetadataAsValue::get(DII->getContext(), - ValueAsMetadata::get(Undef))); + DII->replaceVariableLocationOp(I, Undef); } return !DbgUsers.empty(); } @@ -1359,7 +1358,7 @@ // VLA). Try to use the size of the alloca that the dbg intrinsic describes // intead. if (DII->isAddressOfVariable()) - if (auto *AI = dyn_cast_or_null(DII->getVariableLocation())) + if (auto *AI = dyn_cast_or_null(DII->getVariableLocationOp(0))) if (Optional FragmentSize = AI->getAllocationSizeInBits(DL)) { assert(ValueSize.isScalable() == FragmentSize->isScalable() && "Both sizes should agree on the scalable flag."); @@ -1567,7 +1566,8 @@ ValueToValueMapTy DbgValueMap; for (auto &I : *BB) { if (auto DbgII = dyn_cast(&I)) { - if (auto *Loc = dyn_cast_or_null(DbgII->getVariableLocation())) + if (auto *Loc = + dyn_cast_or_null(DbgII->getVariableLocationOp(0))) DbgValueMap.insert({Loc, DbgII}); } } @@ -1577,19 +1577,18 @@ // Then iterate through the new PHIs and look to see if they use one of the // previously mapped PHIs. If so, insert a new dbg.value intrinsic that will // propagate the info through the new PHI. - LLVMContext &C = BB->getContext(); for (auto PHI : InsertedPHIs) { BasicBlock *Parent = PHI->getParent(); // Avoid inserting an intrinsic into an EH block. if (Parent->getFirstNonPHI()->isEHPad()) continue; - auto PhiMAV = MetadataAsValue::get(C, ValueAsMetadata::get(PHI)); for (auto VI : PHI->operand_values()) { auto V = DbgValueMap.find(VI); if (V != DbgValueMap.end()) { auto *DbgII = cast(V->second); - Instruction *NewDbgII = DbgII->clone(); - NewDbgII->setOperand(0, PhiMAV); + DbgVariableIntrinsic *NewDbgII = + cast(DbgII->clone()); + NewDbgII->replaceVariableLocationOp(VI, PHI); auto InsertionPt = Parent->getFirstInsertionPt(); assert(InsertionPt != Parent->end() && "Ill-formed basic block"); NewDbgII->insertBefore(&*InsertionPt); @@ -1723,9 +1722,7 @@ void llvm::salvageDebugInfoForDbgValues( Instruction &I, ArrayRef DbgUsers) { - auto &Ctx = I.getContext(); bool Salvaged = false; - auto wrapMD = [&](Value *V) { return wrapValueInMetadata(Ctx, V); }; for (auto *DII : DbgUsers) { // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because they @@ -1741,8 +1738,8 @@ if (!DIExpr) break; - DII->setOperand(0, wrapMD(I.getOperand(0))); - DII->setOperand(2, MetadataAsValue::get(Ctx, DIExpr)); + DII->replaceVariableLocationOp(&I, I.getOperand(0)); + DII->setExpression(DIExpr); LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n'); Salvaged = true; } @@ -1752,8 +1749,7 @@ for (auto *DII : DbgUsers) { Value *Undef = UndefValue::get(I.getType()); - DII->setOperand(0, MetadataAsValue::get(DII->getContext(), - ValueAsMetadata::get(Undef))); + DII->replaceVariableLocationOp(&I, Undef); } } @@ -1897,13 +1893,12 @@ if (UndefOrSalvage.count(DII)) continue; - LLVMContext &Ctx = DII->getContext(); DbgValReplacement DVR = RewriteExpr(*DII); if (!DVR) continue; - DII->setOperand(0, wrapValueInMetadata(Ctx, &To)); - DII->setOperand(2, MetadataAsValue::get(Ctx, *DVR)); + DII->replaceVariableLocationOp(&From, &To); + DII->setExpression(*DVR); LLVM_DEBUG(dbgs() << "REWRITE: " << *DII << '\n'); Changed = true; } diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -176,9 +176,7 @@ NewVal = SSA.GetValueInMiddleOfBlock(UserBB); else NewVal = UndefValue::get(OrigHeaderVal->getType()); - DbgValue->setOperand(0, - MetadataAsValue::get(OrigHeaderVal->getContext(), - ValueAsMetadata::get(NewVal))); + DbgValue->replaceVariableLocationOp(OrigHeaderVal, NewVal); } } } @@ -382,7 +380,8 @@ using DbgIntrinsicHash = std::pair, DIExpression *>; auto makeHash = [](DbgVariableIntrinsic *D) -> DbgIntrinsicHash { - return {{D->getVariableLocation(), D->getVariable()}, D->getExpression()}; + return {{D->getVariableLocationOp(0), D->getVariable()}, + D->getExpression()}; }; SmallDenseSet DbgIntrinsics; for (auto I = std::next(OrigPreheader->rbegin()), E = OrigPreheader->rend(); diff --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp b/llvm/unittests/Transforms/Utils/LocalTest.cpp --- a/llvm/unittests/Transforms/Utils/LocalTest.cpp +++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp @@ -758,13 +758,14 @@ EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT)); auto *ADbgVal = cast(A.getNextNode()); - EXPECT_EQ(ConstantInt::get(A.getType(), 0), ADbgVal->getVariableLocation()); + EXPECT_EQ(ConstantInt::get(A.getType(), 0), + ADbgVal->getVariableLocationOp(0)); // Introduce a use-before-def. Check that the dbg.values for %f become undef. EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT)); auto *FDbgVal = cast(F_.getNextNode()); - EXPECT_TRUE(isa(FDbgVal->getVariableLocation())); + EXPECT_TRUE(isa(FDbgVal->getVariableLocationOp(0))); SmallVector FDbgVals; findDbgValues(FDbgVals, &F_);