diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index df146458b4e6f..bb79d2568fca0 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -36,7 +36,6 @@ class BasicBlock; class BranchInst; class CallBase; class CallInst; -class DbgVariableIntrinsic; class DIBuilder; class DomTreeUpdater; class Function; @@ -275,36 +274,23 @@ LLVM_ABI CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr); LLVM_ABI void InsertDebugValueAtStoreLoc(DbgVariableRecord *DVR, StoreInst *SI, DIBuilder &Builder); -/// Creates and inserts an llvm.dbg.value intrinsic before a store -/// that has an associated llvm.dbg.value intrinsic. -LLVM_ABI void InsertDebugValueAtStoreLoc(DbgVariableIntrinsic *DII, - StoreInst *SI, DIBuilder &Builder); - -/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value -/// that has an associated llvm.dbg.declare intrinsic. -LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, - StoreInst *SI, - DIBuilder &Builder); +/// Inserts a dbg.value record before a store to an alloca'd value +/// that has an associated dbg.declare record. LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, StoreInst *SI, DIBuilder &Builder); -/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value -/// that has an associated llvm.dbg.declare intrinsic. -LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, - LoadInst *LI, DIBuilder &Builder); +/// Inserts a dbg.value record before a load of an alloca'd value +/// that has an associated dbg.declare record. LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, LoadInst *LI, DIBuilder &Builder); -/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated -/// llvm.dbg.declare intrinsic. -LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, - PHINode *LI, DIBuilder &Builder); +/// Inserts a dbg.value record after a phi that has an associated +/// llvm.dbg.declare record. LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, PHINode *LI, DIBuilder &Builder); -/// Lowers llvm.dbg.declare intrinsics into appropriate set of -/// llvm.dbg.value intrinsics. +/// Lowers dbg.declare records into appropriate set of dbg.value records. LLVM_ABI bool LowerDbgDeclare(Function &F); /// Propagate dbg.value intrinsics through the newly inserted PHIs. @@ -312,7 +298,7 @@ LLVM_ABI void insertDebugValuesForPHIs(BasicBlock *BB, SmallVectorImpl &InsertedPHIs); -/// Replaces llvm.dbg.declare instruction when the address it +/// Replaces dbg.declare record when the address it /// describes is replaced with a new value. If Deref is true, an /// additional DW_OP_deref is prepended to the expression. If Offset /// is non-zero, a constant displacement is added to the expression @@ -321,10 +307,10 @@ LLVM_ABI bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset); -/// Replaces multiple llvm.dbg.value instructions when the alloca it describes +/// Replaces multiple dbg.value records when the alloca it describes /// is replaced with a new value. If Offset is non-zero, a constant displacement /// is added to the expression (after the mandatory Deref). Offset can be -/// negative. New llvm.dbg.value instructions are inserted at the locations of +/// negative. New dbg.value records are inserted at the locations of /// the instructions they replace. LLVM_ABI void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, int Offset = 0); diff --git a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h index 8b7daf616b110..f288bdfb84f49 100644 --- a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h +++ b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h @@ -23,7 +23,6 @@ namespace llvm { class DominatorTree; -class DbgVariableIntrinsic; class IntrinsicInst; class PostDominatorTree; class AllocaInst; @@ -53,8 +52,6 @@ struct AllocaInfo { AllocaInst *AI; SmallVector LifetimeStart; SmallVector LifetimeEnd; - SmallVector DbgVariableIntrinsics; - // Non-intrinsic records of variable locations. SmallVector DbgVariableRecords; }; diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index b587d76465803..d62667454b728 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3644,9 +3644,6 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) { ConstantInt::get(Type::getInt1Ty(C->getContext()), C->isFalseWhenEqual())); } else if (auto *SI = dyn_cast(I)) { - for (auto *DVI : DVIs) - if (DVI->isAddressOfVariable()) - ConvertDebugDeclareToDebugValue(DVI, SI, *DIB); for (auto *DVR : DVRs) if (DVR->isAddressOfVariable()) ConvertDebugDeclareToDebugValue(DVR, SI, *DIB); diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 70b4552190a4e..23256cf2acbd2 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -315,18 +315,11 @@ calculateFragment(DILocalVariable *Variable, return UseFrag; } -static DebugVariable getAggregateVariable(DbgVariableIntrinsic *DVI) { - return DebugVariable(DVI->getVariable(), std::nullopt, - DVI->getDebugLoc().getInlinedAt()); -} static DebugVariable getAggregateVariable(DbgVariableRecord *DVR) { return DebugVariable(DVR->getVariable(), std::nullopt, DVR->getDebugLoc().getInlinedAt()); } -/// Helpers for handling new and old debug info modes in migrateDebugInfo. -/// These overloads unwrap a DbgInstPtr {Instruction* | DbgRecord*} union based -/// on the \p Unused parameter type. DbgVariableRecord *UnwrapDbgInstPtr(DbgInstPtr P, DbgVariableRecord *Unused) { (void)Unused; return static_cast(cast(P)); @@ -376,9 +369,6 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit, /// Map of aggregate variables to their fragment associated with OldAlloca. DenseMap> BaseFragments; - for (auto *DAI : at::getAssignmentMarkers(OldAlloca)) - BaseFragments[getAggregateVariable(DAI)] = - DAI->getExpression()->getFragmentInfo(); for (auto *DVR : at::getDVRAssignmentMarkers(OldAlloca)) BaseFragments[getAggregateVariable(DVR)] = DVR->getExpression()->getFragmentInfo(); @@ -391,7 +381,7 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit, DIBuilder DIB(*OldInst->getModule(), /*AllowUnresolved*/ false); assert(OldAlloca->isStaticAlloca()); - auto MigrateDbgAssign = [&](auto *DbgAssign) { + auto MigrateDbgAssign = [&](DbgVariableRecord *DbgAssign) { LLVM_DEBUG(dbgs() << " existing dbg.assign is: " << *DbgAssign << "\n"); auto *Expr = DbgAssign->getExpression(); @@ -486,7 +476,6 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit, LLVM_DEBUG(dbgs() << "Created new assign: " << *NewAssign << "\n"); }; - for_each(MarkerRange, MigrateDbgAssign); for_each(DVRAssignMarkerRange, MigrateDbgAssign); } @@ -5119,36 +5108,13 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, } // There isn't a shared interface to get the "address" parts out of a -// dbg.declare and dbg.assign, so provide some wrappers now for -// both debug intrinsics and records. -const Value *getAddress(const DbgVariableIntrinsic *DVI) { - if (const auto *DAI = dyn_cast(DVI)) - return DAI->getAddress(); - return cast(DVI)->getAddress(); -} - -const Value *getAddress(const DbgVariableRecord *DVR) { - return DVR->getAddress(); -} - -bool isKillAddress(const DbgVariableIntrinsic *DVI) { - if (const auto *DAI = dyn_cast(DVI)) - return DAI->isKillAddress(); - return cast(DVI)->isKillLocation(); -} - +// dbg.declare and dbg.assign, so provide some wrappers. bool isKillAddress(const DbgVariableRecord *DVR) { if (DVR->getType() == DbgVariableRecord::LocationType::Assign) return DVR->isKillAddress(); return DVR->isKillLocation(); } -const DIExpression *getAddressExpression(const DbgVariableIntrinsic *DVI) { - if (const auto *DAI = dyn_cast(DVI)) - return DAI->getAddressExpression(); - return cast(DVI)->getExpression(); -} - const DIExpression *getAddressExpression(const DbgVariableRecord *DVR) { if (DVR->getType() == DbgVariableRecord::LocationType::Assign) return DVR->getAddressExpression(); @@ -5236,66 +5202,6 @@ static DIExpression *createOrReplaceFragment(const DIExpression *Expr, return DIExpression::get(Expr->getContext(), Ops); } -/// Insert a new dbg.declare. -/// \p Orig Original to copy debug loc and variable from. -/// \p NewAddr Location's new base address. -/// \p NewAddrExpr New expression to apply to address. -/// \p BeforeInst Insert position. -/// \p NewFragment New fragment (absolute, non-relative). -/// \p BitExtractAdjustment Offset to apply to any extract_bits op. -static void -insertNewDbgInst(DIBuilder &DIB, DbgDeclareInst *Orig, AllocaInst *NewAddr, - DIExpression *NewAddrExpr, Instruction *BeforeInst, - std::optional NewFragment, - int64_t BitExtractAdjustment) { - if (NewFragment) - NewAddrExpr = createOrReplaceFragment(NewAddrExpr, *NewFragment, - BitExtractAdjustment); - if (!NewAddrExpr) - return; - - DIB.insertDeclare(NewAddr, Orig->getVariable(), NewAddrExpr, - Orig->getDebugLoc(), BeforeInst->getIterator()); -} - -/// Insert a new dbg.assign. -/// \p Orig Original to copy debug loc, variable, value and value expression -/// from. -/// \p NewAddr Location's new base address. -/// \p NewAddrExpr New expression to apply to address. -/// \p BeforeInst Insert position. -/// \p NewFragment New fragment (absolute, non-relative). -/// \p BitExtractAdjustment Offset to apply to any extract_bits op. -static void -insertNewDbgInst(DIBuilder &DIB, DbgAssignIntrinsic *Orig, AllocaInst *NewAddr, - DIExpression *NewAddrExpr, Instruction *BeforeInst, - std::optional NewFragment, - int64_t BitExtractAdjustment) { - // DIBuilder::insertDbgAssign will insert the #dbg_assign after NewAddr. - (void)BeforeInst; - - // A dbg.assign puts fragment info in the value expression only. The address - // expression has already been built: NewAddrExpr. - DIExpression *NewFragmentExpr = Orig->getExpression(); - if (NewFragment) - NewFragmentExpr = createOrReplaceFragment(NewFragmentExpr, *NewFragment, - BitExtractAdjustment); - if (!NewFragmentExpr) - return; - - // Apply a DIAssignID to the store if it doesn't already have it. - if (!NewAddr->hasMetadata(LLVMContext::MD_DIAssignID)) { - NewAddr->setMetadata(LLVMContext::MD_DIAssignID, - DIAssignID::getDistinct(NewAddr->getContext())); - } - - Instruction *NewAssign = cast(DIB.insertDbgAssign( - NewAddr, Orig->getValue(), Orig->getVariable(), NewFragmentExpr, NewAddr, - NewAddrExpr, Orig->getDebugLoc())); - LLVM_DEBUG(dbgs() << "Created new assign intrinsic: " << *NewAssign << "\n"); - (void)NewAssign; -} - /// Insert a new DbgRecord. /// \p Orig Original to copy record type, debug loc and variable from, and /// additionally value and value expression for dbg_assign records. @@ -5457,12 +5363,12 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { // Migrate debug information from the old alloca to the new alloca(s) // and the individual partitions. - auto MigrateOne = [&](auto *DbgVariable) { + auto MigrateOne = [&](DbgVariableRecord *DbgVariable) { // Can't overlap with undef memory. if (isKillAddress(DbgVariable)) return; - const Value *DbgPtr = getAddress(DbgVariable); + const Value *DbgPtr = DbgVariable->getAddress(); DIExpression::FragmentInfo VarFrag = DbgVariable->getFragmentOrEntireVariable(); // Get the address expression constant offset if one exists and the ops @@ -5543,7 +5449,6 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { if (SameVariableFragment(OldDII, DbgVariable)) OldDII->eraseFromParent(); }; - for_each(findDbgDeclares(Fragment.Alloca), RemoveOne); for_each(findDVRDeclares(Fragment.Alloca), RemoveOne); for_each(findDVRValues(Fragment.Alloca), RemoveOne); insertNewDbgInst(DIB, DbgVariable, Fragment.Alloca, NewExpr, &AI, @@ -5553,10 +5458,8 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { // Migrate debug information from the old alloca to the new alloca(s) // and the individual partitions. - for_each(findDbgDeclares(&AI), MigrateOne); for_each(findDVRDeclares(&AI), MigrateOne); for_each(findDVRValues(&AI), MigrateOne); - for_each(at::getAssignmentMarkers(&AI), MigrateOne); for_each(at::getDVRAssignmentMarkers(&AI), MigrateOne); return Changed; @@ -5777,8 +5680,6 @@ bool SROA::deleteDeadInstructions( // not be able to find it. if (AllocaInst *AI = dyn_cast(I)) { DeletedAllocas.insert(AI); - for (DbgDeclareInst *OldDII : findDbgDeclares(AI)) - OldDII->eraseFromParent(); for (DbgVariableRecord *OldDII : findDVRDeclares(AI)) OldDII->eraseFromParent(); } diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index fccb73a36b182..b187208bc238c 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -576,9 +576,8 @@ void PruningFunctionCloner::CloneBlock( } // Eagerly remap operands to the newly cloned instruction, except for PHI - // nodes for which we defer processing until we update the CFG. Also defer - // debug intrinsic processing because they may contain use-before-defs. - if (!isa(NewInst) && !isa(NewInst)) { + // nodes for which we defer processing until we update the CFG. + if (!isa(NewInst)) { RemapInstruction(NewInst, VMap, ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges); @@ -733,15 +732,6 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, StartingInst = &StartingBB->front(); } - // Collect debug intrinsics for remapping later. - SmallVector DbgIntrinsics; - for (const auto &BB : *OldFunc) { - for (const auto &I : BB) { - if (const auto *DVI = dyn_cast(&I)) - DbgIntrinsics.push_back(DVI); - } - } - // Clone the entry block, and anything recursively reachable from it. std::vector CloneWorklist; PFC.CloneBlock(StartingBB, StartingInst->getIterator(), CloneWorklist); @@ -899,21 +889,11 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, // Restore attributes. NewFunc->setAttributes(Attrs); - // Remap debug intrinsic operands now that all values have been mapped. - // Doing this now (late) preserves use-before-defs in debug intrinsics. If + // Remap debug records operands now that all values have been mapped. + // Doing this now (late) preserves use-before-defs in debug records. If // we didn't do this, ValueAsMetadata(use-before-def) operands would be // replaced by empty metadata. This would signal later cleanup passes to - // remove the debug intrinsics, potentially causing incorrect locations. - for (const auto *DVI : DbgIntrinsics) { - if (DbgVariableIntrinsic *NewDVI = - cast_or_null(VMap.lookup(DVI))) - RemapInstruction(NewDVI, VMap, - ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges, - TypeMapper, Materializer); - } - - // Do the same for DbgVariableRecords, touching all the instructions in the - // cloned range of blocks. + // remove the debug records, potentially causing incorrect locations. Function::iterator Begin = cast(VMap[StartingBB])->getIterator(); for (BasicBlock &BB : make_range(Begin, NewFunc->end())) { for (Instruction &I : BB) { diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index ccdaca9b0e91c..72bc09431e9cb 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -428,10 +428,6 @@ bool llvm::wouldInstructionBeTriviallyDead(const Instruction *I, if (I->isEHPad()) return false; - // We don't want debug info removed by anything this general. - if (isa(I)) - return false; - if (const DbgLabelInst *DLI = dyn_cast(I)) { if (DLI->getLabel()) return false; @@ -1632,33 +1628,6 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar, /// describes an alloca'd variable, so we need to use the alloc size of the /// value when doing the comparison. E.g. an i1 value will be identified as /// covering an n-bit fragment, if the store size of i1 is at least n bits. -static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) { - const DataLayout &DL = DII->getDataLayout(); - TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy); - if (std::optional FragmentSize = - DII->getExpression()->getActiveBits(DII->getVariable())) - return TypeSize::isKnownGE(ValueSize, TypeSize::getFixed(*FragmentSize)); - - // We can't always calculate the size of the DI variable (e.g. if it is a - // VLA). Try to use the size of the alloca that the dbg intrinsic describes - // instead. - if (DII->isAddressOfVariable()) { - // DII should have exactly 1 location when it is an address. - assert(DII->getNumVariableLocationOps() == 1 && - "address of variable must have exactly 1 location operand."); - if (auto *AI = - dyn_cast_or_null(DII->getVariableLocationOp(0))) { - if (std::optional FragmentSize = - AI->getAllocationSizeInBits(DL)) { - return TypeSize::isKnownGE(ValueSize, *FragmentSize); - } - } - } - // Could not determine size of variable. Conservatively return false. - return false; -} -// RemoveDIs: duplicate implementation of the above, using DbgVariableRecords, -// the replacement for dbg.values. static bool valueCoversEntireFragment(Type *ValTy, DbgVariableRecord *DVR) { const DataLayout &DL = DVR->getModule()->getDataLayout(); TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy); @@ -1703,98 +1672,12 @@ static void insertDbgValueOrDbgVariableRecordAfter( insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, NextIt); } -/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value -/// that has an associated llvm.dbg.declare intrinsic. -void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, - StoreInst *SI, DIBuilder &Builder) { - assert(DII->isAddressOfVariable() || isa(DII)); - auto *DIVar = DII->getVariable(); - assert(DIVar && "Missing variable"); - auto *DIExpr = DII->getExpression(); - Value *DV = SI->getValueOperand(); - - DebugLoc NewLoc = getDebugValueLoc(DII); - - // If the alloca describes the variable itself, i.e. the expression in the - // dbg.declare doesn't start with a dereference, we can perform the - // conversion if the value covers the entire fragment of DII. - // If the alloca describes the *address* of DIVar, i.e. DIExpr is - // *just* a DW_OP_deref, we use DV as is for the dbg.value. - // We conservatively ignore other dereferences, because the following two are - // not equivalent: - // dbg.declare(alloca, ..., !Expr(deref, plus_uconstant, 2)) - // dbg.value(DV, ..., !Expr(deref, plus_uconstant, 2)) - // The former is adding 2 to the address of the variable, whereas the latter - // is adding 2 to the value of the variable. As such, we insist on just a - // deref expression. - bool CanConvert = - DIExpr->isDeref() || (!DIExpr->startsWithDeref() && - valueCoversEntireFragment(DV->getType(), DII)); - if (CanConvert) { - insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, - SI->getIterator()); - return; - } - - // FIXME: If storing to a part of the variable described by the dbg.declare, - // then we want to insert a dbg.value for the corresponding fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " << *DII - << '\n'); - // For now, when there is a store to parts of the variable (but we do not - // know which part) we insert an dbg.value intrinsic to indicate that we - // know nothing about the variable's content. - DV = PoisonValue::get(DV->getType()); - insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, - SI->getIterator()); -} - static DIExpression *dropInitialDeref(const DIExpression *DIExpr) { int NumEltDropped = DIExpr->getElements()[0] == dwarf::DW_OP_LLVM_arg ? 3 : 1; return DIExpression::get(DIExpr->getContext(), DIExpr->getElements().drop_front(NumEltDropped)); } -void llvm::InsertDebugValueAtStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI, - DIBuilder &Builder) { - auto *DIVar = DII->getVariable(); - assert(DIVar && "Missing variable"); - auto *DIExpr = DII->getExpression(); - DIExpr = dropInitialDeref(DIExpr); - Value *DV = SI->getValueOperand(); - - DebugLoc NewLoc = getDebugValueLoc(DII); - - insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, - SI->getIterator()); -} - -/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value -/// that has an associated llvm.dbg.declare intrinsic. -void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, - LoadInst *LI, DIBuilder &Builder) { - auto *DIVar = DII->getVariable(); - auto *DIExpr = DII->getExpression(); - assert(DIVar && "Missing variable"); - - if (!valueCoversEntireFragment(LI->getType(), DII)) { - // FIXME: If only referring to a part of the variable described by the - // dbg.declare, then we want to insert a dbg.value for the corresponding - // fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " - << *DII << '\n'); - return; - } - - DebugLoc NewLoc = getDebugValueLoc(DII); - - // We are now tracking the loaded value instead of the address. In the - // future if multi-location support is added to the IR, it might be - // preferable to keep tracking both the loaded value and the original - // address in case the alloca can not be elided. - insertDbgValueOrDbgVariableRecordAfter(Builder, LI, DIVar, DIExpr, NewLoc, - LI); -} - void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, StoreInst *SI, DIBuilder &Builder) { assert(DVR->isAddressOfVariable() || DVR->isDbgAssign()); @@ -1855,40 +1738,6 @@ void llvm::InsertDebugValueAtStoreLoc(DbgVariableRecord *DVR, StoreInst *SI, SI->getIterator()); } -/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated -/// llvm.dbg.declare intrinsic. -void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, - PHINode *APN, DIBuilder &Builder) { - auto *DIVar = DII->getVariable(); - auto *DIExpr = DII->getExpression(); - assert(DIVar && "Missing variable"); - - if (PhiHasDebugValue(DIVar, DIExpr, APN)) - return; - - if (!valueCoversEntireFragment(APN->getType(), DII)) { - // FIXME: If only referring to a part of the variable described by the - // dbg.declare, then we want to insert a dbg.value for the corresponding - // fragment. - LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " - << *DII << '\n'); - return; - } - - BasicBlock *BB = APN->getParent(); - auto InsertionPt = BB->getFirstInsertionPt(); - - DebugLoc NewLoc = getDebugValueLoc(DII); - - // The block may be a catchswitch block, which does not have a valid - // insertion point. - // FIXME: Insert dbg.value markers in the successors when appropriate. - if (InsertionPt != BB->end()) { - insertDbgValueOrDbgVariableRecord(Builder, APN, DIVar, DIExpr, NewLoc, - InsertionPt); - } -} - void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, LoadInst *LI, DIBuilder &Builder) { auto *DIVar = DVR->getVariable(); @@ -1981,7 +1830,7 @@ bool llvm::LowerDbgDeclare(Function &F) { if (Dbgs.empty() && DVRs.empty()) return Changed; - auto LowerOne = [&](auto *DDI) { + auto LowerOne = [&](DbgVariableRecord *DDI) { AllocaInst *AI = dyn_cast_or_null(DDI->getVariableLocationOp(0)); // If this is an alloca for a scalar variable, insert a dbg.value @@ -2036,7 +1885,6 @@ bool llvm::LowerDbgDeclare(Function &F) { Changed = true; }; - for_each(Dbgs, LowerOne); for_each(DVRs, LowerOne); if (Changed) @@ -2046,12 +1894,9 @@ bool llvm::LowerDbgDeclare(Function &F) { return Changed; } -// RemoveDIs: re-implementation of insertDebugValuesForPHIs, but which pulls the -// debug-info out of the block's DbgVariableRecords rather than dbg.value -// intrinsics. -static void -insertDbgVariableRecordsForPHIs(BasicBlock *BB, - SmallVectorImpl &InsertedPHIs) { +/// Propagate dbg.value records through the newly inserted PHIs. +void llvm::insertDebugValuesForPHIs(BasicBlock *BB, + SmallVectorImpl &InsertedPHIs) { assert(BB && "No BasicBlock to clone DbgVariableRecord(s) from."); if (InsertedPHIs.size() == 0) return; @@ -2113,76 +1958,12 @@ insertDbgVariableRecordsForPHIs(BasicBlock *BB, } } -/// Propagate dbg.value intrinsics through the newly inserted PHIs. -void llvm::insertDebugValuesForPHIs(BasicBlock *BB, - SmallVectorImpl &InsertedPHIs) { - assert(BB && "No BasicBlock to clone dbg.value(s) from."); - if (InsertedPHIs.size() == 0) - return; - - insertDbgVariableRecordsForPHIs(BB, InsertedPHIs); - - // Map existing PHI nodes to their dbg.values. - ValueToValueMapTy DbgValueMap; - for (auto &I : *BB) { - if (auto DbgII = dyn_cast(&I)) { - for (Value *V : DbgII->location_ops()) - if (auto *Loc = dyn_cast_or_null(V)) - DbgValueMap.insert({Loc, DbgII}); - } - } - if (DbgValueMap.size() == 0) - return; - - // Map a pair of the destination BB and old dbg.value to the new dbg.value, - // so that if a dbg.value is being rewritten to use more than one of the - // inserted PHIs in the same destination BB, we can update the same dbg.value - // with all the new PHIs instead of creating one copy for each. - MapVector, - DbgVariableIntrinsic *> - NewDbgValueMap; - // Then iterate through the new PHIs and look to see if they use one of the - // previously mapped PHIs. If so, create a new dbg.value intrinsic that will - // propagate the info through the new PHI. If we use more than one new PHI in - // a single destination BB with the same old dbg.value, merge the updates so - // that we get a single new dbg.value with all the new PHIs. - for (auto *PHI : InsertedPHIs) { - BasicBlock *Parent = PHI->getParent(); - // Avoid inserting an intrinsic into an EH block. - if (Parent->getFirstNonPHIIt()->isEHPad()) - continue; - for (auto *VI : PHI->operand_values()) { - auto V = DbgValueMap.find(VI); - if (V != DbgValueMap.end()) { - auto *DbgII = cast(V->second); - auto [NewDI, Inserted] = NewDbgValueMap.try_emplace({Parent, DbgII}); - if (Inserted) - NewDI->second = cast(DbgII->clone()); - DbgVariableIntrinsic *NewDbgII = NewDI->second; - // If PHI contains VI as an operand more than once, we may - // replaced it in NewDbgII; confirm that it is present. - if (is_contained(NewDbgII->location_ops(), VI)) - NewDbgII->replaceVariableLocationOp(VI, PHI); - } - } - } - // Insert thew new dbg.values into their destination blocks. - for (auto DI : NewDbgValueMap) { - BasicBlock *Parent = DI.first.first; - auto *NewDbgII = DI.second; - auto InsertionPt = Parent->getFirstInsertionPt(); - assert(InsertionPt != Parent->end() && "Ill-formed basic block"); - NewDbgII->insertBefore(InsertionPt); - } -} - bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder, uint8_t DIExprFlags, int Offset) { - TinyPtrVector DbgDeclares = findDbgDeclares(Address); TinyPtrVector DVRDeclares = findDVRDeclares(Address); - auto ReplaceOne = [&](auto *DII) { + auto ReplaceOne = [&](DbgVariableRecord *DII) { assert(DII->getVariable() && "Missing variable"); auto *DIExpr = DII->getExpression(); DIExpr = DIExpression::prepend(DIExpr, DIExprFlags, Offset); @@ -2190,10 +1971,9 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, DII->replaceVariableLocationOp(Address, NewAddress); }; - for_each(DbgDeclares, ReplaceOne); for_each(DVRDeclares, ReplaceOne); - return !DbgDeclares.empty() || !DVRDeclares.empty(); + return !DVRDeclares.empty(); } static void updateOneDbgValueForAlloca(const DebugLoc &Loc, @@ -2645,7 +2425,6 @@ using DbgValReplacement = std::optional; /// changes are made. static bool rewriteDebugUsers( Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT, - function_ref RewriteExpr, function_ref RewriteDVRExpr) { // Find debug users of From. SmallVector Users; @@ -2654,43 +2433,32 @@ static bool rewriteDebugUsers( if (Users.empty() && DPUsers.empty()) return false; + // Ignore intrinsic-users: they are no longer supported and should never + // appear. + assert(Users.empty()); + // Prevent use-before-def of To. bool Changed = false; - SmallPtrSet UndefOrSalvage; SmallPtrSet UndefOrSalvageDVR; if (isa(&To)) { bool DomPointAfterFrom = From.getNextNode() == &DomPoint; - for (auto *DII : Users) { - // It's common to see a debug user between From and DomPoint. Move it - // after DomPoint to preserve the variable update without any reordering. - if (DomPointAfterFrom && DII->getNextNode() == &DomPoint) { - LLVM_DEBUG(dbgs() << "MOVE: " << *DII << '\n'); - DII->moveAfter(&DomPoint); - Changed = true; - - // Users which otherwise aren't dominated by the replacement value must - // be salvaged or deleted. - } else if (!DT.dominates(&DomPoint, DII)) { - UndefOrSalvage.insert(DII); - } - } - // DbgVariableRecord implementation of the above. for (auto *DVR : DPUsers) { Instruction *MarkedInstr = DVR->getMarker()->MarkedInstr; Instruction *NextNonDebug = MarkedInstr; - // The next instruction might still be a dbg.declare, skip over it. - if (isa(NextNonDebug)) - NextNonDebug = NextNonDebug->getNextNode(); + // It's common to see a debug user between From and DomPoint. Move it + // after DomPoint to preserve the variable update without any reordering. if (DomPointAfterFrom && NextNonDebug == &DomPoint) { LLVM_DEBUG(dbgs() << "MOVE: " << *DVR << '\n'); DVR->removeFromParent(); - // Ensure there's a marker. DomPoint.getParent()->insertDbgRecordAfter(DVR, &DomPoint); Changed = true; + + // Users which otherwise aren't dominated by the replacement value must + // be salvaged or deleted. } else if (!DT.dominates(&DomPoint, MarkedInstr)) { UndefOrSalvageDVR.insert(DVR); } @@ -2698,19 +2466,6 @@ static bool rewriteDebugUsers( } // Update debug users without use-before-def risk. - for (auto *DII : Users) { - if (UndefOrSalvage.count(DII)) - continue; - - DbgValReplacement DVRepl = RewriteExpr(*DII); - if (!DVRepl) - continue; - - DII->replaceVariableLocationOp(&From, &To); - DII->setExpression(*DVRepl); - LLVM_DEBUG(dbgs() << "REWRITE: " << *DII << '\n'); - Changed = true; - } for (auto *DVR : DPUsers) { if (UndefOrSalvageDVR.count(DVR)) continue; @@ -2725,7 +2480,7 @@ static bool rewriteDebugUsers( Changed = true; } - if (!UndefOrSalvage.empty() || !UndefOrSalvageDVR.empty()) { + if (!UndefOrSalvageDVR.empty()) { // Try to salvage the remaining debug users. salvageDebugInfo(From); Changed = true; @@ -2770,9 +2525,6 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, Type *FromTy = From.getType(); Type *ToTy = To.getType(); - auto Identity = [&](DbgVariableIntrinsic &DII) -> DbgValReplacement { - return DII.getExpression(); - }; auto IdentityDVR = [&](DbgVariableRecord &DVR) -> DbgValReplacement { return DVR.getExpression(); }; @@ -2781,7 +2533,7 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, Module &M = *From.getModule(); const DataLayout &DL = M.getDataLayout(); if (isBitCastSemanticsPreserving(DL, FromTy, ToTy)) - return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDVR); + return rewriteDebugUsers(From, To, DomPoint, DT, IdentityDVR); // Handle integer-to-integer widening and narrowing. // FIXME: Use DW_OP_convert when it's available everywhere. @@ -2793,24 +2545,10 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, // When the width of the result grows, assume that a debugger will only // access the low `FromBits` bits when inspecting the source variable. if (FromBits < ToBits) - return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDVR); + return rewriteDebugUsers(From, To, DomPoint, DT, IdentityDVR); // The width of the result has shrunk. Use sign/zero extension to describe // the source variable's high bits. - auto SignOrZeroExt = [&](DbgVariableIntrinsic &DII) -> DbgValReplacement { - DILocalVariable *Var = DII.getVariable(); - - // Without knowing signedness, sign/zero extension isn't possible. - auto Signedness = Var->getSignedness(); - if (!Signedness) - return std::nullopt; - - bool Signed = *Signedness == DIBasicType::Signedness::Signed; - return DIExpression::appendExt(DII.getExpression(), ToBits, FromBits, - Signed); - }; - // RemoveDIs: duplicate implementation working on DbgVariableRecords rather - // than on dbg.value intrinsics. auto SignOrZeroExtDVR = [&](DbgVariableRecord &DVR) -> DbgValReplacement { DILocalVariable *Var = DVR.getVariable(); @@ -2823,8 +2561,7 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To, return DIExpression::appendExt(DVR.getExpression(), ToBits, FromBits, Signed); }; - return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt, - SignOrZeroExtDVR); + return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExtDVR); } // TODO: Floating-point conversions, vectors. @@ -3800,10 +3537,6 @@ void llvm::remapDebugVariable(ValueToValueMapTy &Mapping, Instruction *Inst) { if (I != Mapping.end()) DA->setAddress(I->second); }; - if (auto DVI = dyn_cast(Inst)) - RemapDebugOperands(DVI, DVI->location_ops()); - if (auto DAI = dyn_cast(Inst)) - RemapAssignAddress(DAI); for (DbgVariableRecord &DVR : filterDbgVars(Inst->getDbgRecordRange())) { RemapDebugOperands(&DVR, DVR.location_ops()); if (DVR.isDbgAssign()) diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp index 511c15555fa83..6226596017980 100644 --- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp +++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp @@ -168,22 +168,6 @@ void StackInfoBuilder::visit(OptimizationRemarkEmitter &ORE, Info.AllocasToInstrument[AI].LifetimeEnd.push_back(II); return; } - if (auto *DVI = dyn_cast(&Inst)) { - auto AddIfInteresting = [&](Value *V) { - if (auto *AI = dyn_cast_or_null(V)) { - if (getAllocaInterestingness(*AI) != - AllocaInterestingness::kInteresting) - return; - AllocaInfo &AInfo = Info.AllocasToInstrument[AI]; - auto &DVIVec = AInfo.DbgVariableIntrinsics; - if (DVIVec.empty() || DVIVec.back() != DVI) - DVIVec.push_back(DVI); - } - }; - for_each(DVI->location_ops(), AddIfInteresting); - if (auto *DAI = dyn_cast(DVI)) - AddIfInteresting(DAI->getAddress()); - } Instruction *ExitUntag = getUntagLocationIfFunctionExit(Inst); if (ExitUntag) @@ -297,19 +281,12 @@ Value *getAndroidSlotPtr(IRBuilder<> &IRB, int Slot) { IRB.CreateCall(ThreadPointerFunc), 8 * Slot); } -static DbgAssignIntrinsic *DynCastToDbgAssign(DbgVariableIntrinsic *DVI) { - return dyn_cast(DVI); -} - static DbgVariableRecord *DynCastToDbgAssign(DbgVariableRecord *DVR) { return DVR->isDbgAssign() ? DVR : nullptr; } void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag) { - // Helper utility for adding DW_OP_LLVM_tag_offset to debug-info records, - // abstracted over whether they're intrinsic-stored or DbgVariableRecord - // stored. - auto AnnotateDbgRecord = [&](auto *DPtr) { + auto AnnotateDbgRecord = [&](DbgVariableRecord *DPtr) { // Prepend "tag_offset, N" to the dwarf expression. // Tag offset logically applies to the alloca pointer, and it makes sense // to put it at the beginning of the expression. @@ -325,7 +302,6 @@ void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag) { } }; - llvm::for_each(Info.DbgVariableIntrinsics, AnnotateDbgRecord); llvm::for_each(Info.DbgVariableRecords, AnnotateDbgRecord); } diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index 46808a818cb26..ccd7ee360e014 100644 --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -115,29 +115,17 @@ static void createDebugValue(DIBuilder &DIB, Value *NewValue, DbgVariableRecord::createDbgVariableRecord(NewValue, Variable, Expression, DI, *InsertBefore); } -static void createDebugValue(DIBuilder &DIB, Value *NewValue, - DILocalVariable *Variable, - DIExpression *Expression, const DILocation *DI, - Instruction *InsertBefore) { - DIB.insertDbgValueIntrinsic(NewValue, Variable, Expression, DI, - InsertBefore->getIterator()); -} /// Helper for updating assignment tracking debug info when promoting allocas. class AssignmentTrackingInfo { /// DbgAssignIntrinsics linked to the alloca with at most one per variable /// fragment. (i.e. not be a comprehensive set if there are multiple /// dbg.assigns for one variable fragment). - SmallVector DbgAssigns; SmallVector DVRAssigns; public: void init(AllocaInst *AI) { SmallSet Vars; - for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(AI)) { - if (Vars.insert(DebugVariable(DAI)).second) - DbgAssigns.push_back(DAI); - } for (DbgVariableRecord *DVR : at::getDVRAssignmentMarkers(AI)) { if (Vars.insert(DebugVariable(DVR)).second) DVRAssigns.push_back(DVR); @@ -148,11 +136,10 @@ class AssignmentTrackingInfo { /// \p ToDelete that stores to this alloca. void updateForDeletedStore( StoreInst *ToDelete, DIBuilder &DIB, - SmallSet *DbgAssignsToDelete, SmallSet *DVRAssignsToDelete) const { // There's nothing to do if the alloca doesn't have any variables using // assignment tracking. - if (DbgAssigns.empty() && DVRAssigns.empty()) + if (DVRAssigns.empty()) return; // Insert a dbg.value where the linked dbg.assign is and remember to delete @@ -169,25 +156,22 @@ class AssignmentTrackingInfo { DbgAssign->getExpression(), DbgAssign->getDebugLoc(), DbgAssign); }; - for (auto *Assign : at::getAssignmentMarkers(ToDelete)) - InsertValueForAssign(Assign, DbgAssignsToDelete); for (auto *Assign : at::getDVRAssignmentMarkers(ToDelete)) InsertValueForAssign(Assign, DVRAssignsToDelete); // It's possible for variables using assignment tracking to have no - // dbg.assign linked to this store. These are variables in DbgAssigns that + // dbg.assign linked to this store. These are variables in DVRAssigns that // are missing from VarHasDbgAssignForStore. Since there isn't a dbg.assign // to mark the assignment - and the store is going to be deleted - insert a // dbg.value to do that now. An untracked store may be either one that // cannot be represented using assignment tracking (non-const offset or // size) or one that is trackable but has had its DIAssignID attachment // dropped accidentally. - auto ConvertUnlinkedAssignToValue = [&](auto *Assign) { + auto ConvertUnlinkedAssignToValue = [&](DbgVariableRecord *Assign) { if (VarHasDbgAssignForStore.contains(DebugVariableAggregate(Assign))) return; ConvertDebugDeclareToDebugValue(Assign, ToDelete, DIB); }; - for_each(DbgAssigns, ConvertUnlinkedAssignToValue); for_each(DVRAssigns, ConvertUnlinkedAssignToValue); } @@ -197,17 +181,12 @@ class AssignmentTrackingInfo { // Regardless of the position of dbg.assigns relative to stores, the // incoming values into a new PHI should be the same for the (imaginary) // debug-phi. - for (auto *DAI : DbgAssigns) - ConvertDebugDeclareToDebugValue(DAI, NewPhi, DIB); for (auto *DVR : DVRAssigns) ConvertDebugDeclareToDebugValue(DVR, NewPhi, DIB); } - void clear() { - DbgAssigns.clear(); - DVRAssigns.clear(); - } - bool empty() { return DbgAssigns.empty() && DVRAssigns.empty(); } + void clear() { DVRAssigns.clear(); } + bool empty() { return DVRAssigns.empty(); } }; struct AllocaInfo { @@ -412,7 +391,6 @@ struct PromoteMem2Reg { SmallVector AllocaATInfo; /// A set of dbg.assigns to delete because they've been demoted to /// dbg.values. Call cleanUpDbgAssigns to delete them. - SmallSet DbgAssignsToDelete; SmallSet DVRAssignsToDelete; /// The set of basic blocks the renamer has already visited. @@ -467,9 +445,6 @@ struct PromoteMem2Reg { /// Delete dbg.assigns that have been demoted to dbg.values. void cleanUpDbgAssigns() { - for (auto *DAI : DbgAssignsToDelete) - DAI->eraseFromParent(); - DbgAssignsToDelete.clear(); for (auto *DVR : DVRAssignsToDelete) DVR->eraseFromParent(); DVRAssignsToDelete.clear(); @@ -571,7 +546,6 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC, - SmallSet *DbgAssignsToDelete, SmallSet *DVRAssignsToDelete) { StoreInst *OnlyStore = Info.OnlyStore; Value *ReplVal = OnlyStore->getOperand(0); @@ -637,27 +611,23 @@ rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false); // Update assignment tracking info for the store we're going to delete. - Info.AssignmentTracking.updateForDeletedStore( - Info.OnlyStore, DIB, DbgAssignsToDelete, DVRAssignsToDelete); + Info.AssignmentTracking.updateForDeletedStore(Info.OnlyStore, DIB, + DVRAssignsToDelete); // Record debuginfo for the store and remove the declaration's // debuginfo. - auto ConvertDebugInfoForStore = [&](auto &Container) { - for (auto *DbgItem : Container) { - if (DbgItem->isAddressOfVariable()) { - ConvertDebugDeclareToDebugValue(DbgItem, Info.OnlyStore, DIB); - DbgItem->eraseFromParent(); - } else if (DbgItem->isValueOfVariable() && - DbgItem->getExpression()->startsWithDeref()) { - InsertDebugValueAtStoreLoc(DbgItem, Info.OnlyStore, DIB); - DbgItem->eraseFromParent(); - } else if (DbgItem->getExpression()->startsWithDeref()) { - DbgItem->eraseFromParent(); - } + for (DbgVariableRecord *DbgItem : Info.DPUsers) { + if (DbgItem->isAddressOfVariable()) { + ConvertDebugDeclareToDebugValue(DbgItem, Info.OnlyStore, DIB); + DbgItem->eraseFromParent(); + } else if (DbgItem->isValueOfVariable() && + DbgItem->getExpression()->startsWithDeref()) { + InsertDebugValueAtStoreLoc(DbgItem, Info.OnlyStore, DIB); + DbgItem->eraseFromParent(); + } else if (DbgItem->getExpression()->startsWithDeref()) { + DbgItem->eraseFromParent(); } - }; - ConvertDebugInfoForStore(Info.DbgUsers); - ConvertDebugInfoForStore(Info.DPUsers); + } // Remove dbg.assigns linked to the alloca as these are now redundant. at::deleteAssignmentMarkers(AI); @@ -690,7 +660,6 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, LargeBlockInfo &LBI, const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC, - SmallSet *DbgAssignsToDelete, SmallSet *DVRAssignsToDelete) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not @@ -755,18 +724,13 @@ promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, while (!AI->use_empty()) { StoreInst *SI = cast(AI->user_back()); // Update assignment tracking info for the store we're going to delete. - Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DbgAssignsToDelete, - DVRAssignsToDelete); + Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DVRAssignsToDelete); // Record debuginfo for the store before removing it. - auto DbgUpdateForStore = [&](auto &Container) { - for (auto *DbgItem : Container) { - if (DbgItem->isAddressOfVariable()) { - ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB); - } + for (DbgVariableRecord *DbgItem : Info.DPUsers) { + if (DbgItem->isAddressOfVariable()) { + ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB); } - }; - DbgUpdateForStore(Info.DbgUsers); - DbgUpdateForStore(Info.DPUsers); + } SI->eraseFromParent(); LBI.deleteValue(SI); @@ -830,7 +794,7 @@ void PromoteMem2Reg::run() { // it that are directly dominated by the definition with the value stored. if (Info.DefiningBlocks.size() == 1) { if (rewriteSingleStoreAlloca(AI, Info, LBI, SQ.DL, DT, AC, - &DbgAssignsToDelete, &DVRAssignsToDelete)) { + &DVRAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); ++NumSingleStore; @@ -842,7 +806,7 @@ void PromoteMem2Reg::run() { // linear sweep over the block to eliminate it. if (Info.OnlyUsedInOneBlock && promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, AC, - &DbgAssignsToDelete, &DVRAssignsToDelete)) { + &DVRAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); continue; @@ -1182,13 +1146,9 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) { // The currently active variable for this block is now the PHI. IncomingVals.set(AllocaNo, APN); AllocaATInfo[AllocaNo].updateForNewPhi(APN, DIB); - auto ConvertDbgDeclares = [&](auto &Container) { - for (auto *DbgItem : Container) - if (DbgItem->isAddressOfVariable()) - ConvertDebugDeclareToDebugValue(DbgItem, APN, DIB); - }; - ConvertDbgDeclares(AllocaDbgUsers[AllocaNo]); - ConvertDbgDeclares(AllocaDPUsers[AllocaNo]); + for (DbgVariableRecord *DbgItem : AllocaDPUsers[AllocaNo]) + if (DbgItem->isAddressOfVariable()) + ConvertDebugDeclareToDebugValue(DbgItem, APN, DIB); // Get the next phi node. ++PNI; @@ -1242,15 +1202,11 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) { // Record debuginfo for the store before removing it. IncomingLocs.set(AllocaNo, SI->getDebugLoc()); - AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, &DbgAssignsToDelete, + AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, &DVRAssignsToDelete); - auto ConvertDbgDeclares = [&](auto &Container) { - for (auto *DbgItem : Container) - if (DbgItem->isAddressOfVariable()) - ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB); - }; - ConvertDbgDeclares(AllocaDbgUsers[ai->second]); - ConvertDbgDeclares(AllocaDPUsers[ai->second]); + for (DbgVariableRecord *DbgItem : AllocaDPUsers[ai->second]) + if (DbgItem->isAddressOfVariable()) + ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB); SI->eraseFromParent(); } }