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" @@ -126,7 +127,26 @@ /// Get the location 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; + SmallVector getVariableLocationOps(bool AllowNullOp = true) const; + Value *getVariableLocationOp(unsigned OpIdx, bool AllowNullOp = true) 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 +154,20 @@ return getIntrinsicID() != Intrinsic::dbg_value; } + void setUndef() { + for (Value *OldValue : getVariableLocationOps()) { + Value *Undef = UndefValue::get(OldValue->getType()); + replaceVariableLocationOp(OldValue, Undef); + } + } + + bool isUndef() const { + return (getNumVariableLocationOps() == 0 && + !getExpression()->isComplex()) || + any_of(getVariableLocationOps(), + [](Value *V) { return isa(V); }); + } + DILocalVariable *getVariable() const { return cast(getRawVariable()); } @@ -142,6 +176,10 @@ return cast(getRawExpression()); } + Metadata *getRawLocation() const { + return cast(getArgOperand(0))->getMetadata(); + } + Metadata *getRawVariable() const { return cast(getArgOperand(1))->getMetadata(); } @@ -170,12 +208,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 +238,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 +257,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, /* AllowNullOp = */ false); + } + SmallVector getValues() const { + return getVariableLocationOps(/* AllowNullOp = */ false); } /// \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 @@ -2797,11 +2797,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); } }; @@ -7731,7 +7728,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) { @@ -7739,8 +7736,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); @@ -5827,7 +5826,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 @@ -681,6 +681,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,12 +38,47 @@ /// intrinsics for variables. /// -Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const { +SmallVector +DbgVariableIntrinsic::getVariableLocationOps(bool AllowNullOp) const { + SmallVector Result; Value *Op = getArgOperand(0); - if (AllowNullOp && !Op) + if (AllowNullOp && !Op) { + Result.push_back(nullptr); + return Result; + } + + auto *MD = cast(Op)->getMetadata(); + if (auto *V = dyn_cast(MD)) { + Result.push_back(V->getValue()); + return Result; + } + if (auto *AL = dyn_cast(MD)) { + for (auto *V : AL->getArgs()) + Result.push_back(V->getValue()); + return Result; + } + + // When the value goes to null, it gets replaced by an empty MDNode. + assert(!cast(MD)->getNumOperands() && "Expected an empty MDNode"); + Result.push_back(nullptr); + return Result; +} + +Value *DbgVariableIntrinsic::getVariableLocationOp(unsigned OpIdx, + bool AllowNullOp) const { + Value *Op = getArgOperand(0); + if (AllowNullOp && !Op) { return nullptr; + } auto *MD = cast(Op)->getMetadata(); + if (auto *AL = dyn_cast(MD)) { + if (auto *VMD = AL->getArgs()[OpIdx]) + return VMD->getValue(); + return nullptr; + } + assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " + "single location operand."); if (auto *V = dyn_cast(MD)) return V->getValue(); @@ -52,6 +87,32 @@ return nullptr; } +static ValueAsMetadata *getAsMetadata(Value *V) { + return isa(V) ? dyn_cast( + cast(V)->getMetadata()) + : ValueAsMetadata::get(V); +} + +void DbgVariableIntrinsic::replaceVariableLocationOp(Value *OldValue, + Value *NewValue) { + auto Locations = getVariableLocationOps(); + 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 { if (auto Fragment = getExpression()->getFragmentInfo()) return Fragment->SizeInBits; 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 @@ -5267,7 +5267,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 @@ -279,6 +279,7 @@ class AArch64StackTagging : public FunctionPass { struct AllocaInfo { AllocaInst *AI; + TrackingVH OldAI; // Track through RAUW to replace debug uses. SmallVector LifetimeStart; SmallVector LifetimeEnd; SmallVector DbgVariableIntrinsics; @@ -551,12 +552,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; @@ -699,9 +701,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 @@ -3520,9 +3520,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 @@ -1128,9 +1128,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->getVariableLocationOps(); + unsigned LocNo = std::distance(Locations.begin(), find(Locations, AI)); + DDI->setExpression( + DIExpression::appendOpsToArg(DDI->getExpression(), NewOps, LocNo)); } size_t Size = getAllocaSizeInBytes(*AI); @@ -1194,7 +1195,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)) @@ -1275,10 +1276,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/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp @@ -259,7 +259,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 @@ -1473,7 +1473,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); @@ -1496,7 +1496,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 @@ -234,7 +234,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 @@ -555,8 +555,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(); } @@ -1375,7 +1374,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 (auto FragmentSize = AI->getAllocationSizeInBits(DL)) return ValueSize >= *FragmentSize; // Could not determine size of variable. Conservatively return false. @@ -1580,7 +1579,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}); } } @@ -1590,19 +1590,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); @@ -1736,9 +1735,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 @@ -1754,8 +1751,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; } @@ -1765,8 +1762,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); } } @@ -1910,13 +1906,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 @@ -177,9 +177,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); } } } @@ -383,7 +381,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_);