diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SROA.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index f578762d2b49..24da26c9f0f2 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -4838,6 +4838,36 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, return NewAI; } +static void insertNewDbgInst(DIBuilder &DIB, DbgDeclareInst *Orig, + AllocaInst *NewAddr, DIExpression *NewFragmentExpr, + Instruction *BeforeInst) { + DIB.insertDeclare(NewAddr, Orig->getVariable(), NewFragmentExpr, + Orig->getDebugLoc(), BeforeInst); +} +static void insertNewDbgInst(DIBuilder &DIB, DbgAssignIntrinsic *Orig, + AllocaInst *NewAddr, DIExpression *NewFragmentExpr, + Instruction *BeforeInst) { + (void)BeforeInst; + if (!NewAddr->hasMetadata(LLVMContext::MD_DIAssignID)) { + NewAddr->setMetadata(LLVMContext::MD_DIAssignID, + DIAssignID::getDistinct(NewAddr->getContext())); + } + auto *NewAssign = DIB.insertDbgAssign( + NewAddr, Orig->getValue(), Orig->getVariable(), NewFragmentExpr, NewAddr, + Orig->getAddressExpression(), Orig->getDebugLoc()); + LLVM_DEBUG(dbgs() << "Created new assign intrinsic: " << *NewAssign << "\n"); + (void)NewAssign; +} +static void insertNewDbgInst(DIBuilder &DIB, DPValue *Orig, AllocaInst *NewAddr, + DIExpression *NewFragmentExpr, + Instruction *BeforeInst) { + (void)DIB; + DPValue *New = new DPValue(ValueAsMetadata::get(NewAddr), Orig->getVariable(), + NewFragmentExpr, Orig->getDebugLoc(), + DPValue::LocationType::Declare); + BeforeInst->getParent()->insertDPValueBefore(New, BeforeInst->getIterator()); +} + /// Walks the slices of an alloca and form partitions based on them, /// rewriting each of their uses. bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { @@ -4939,12 +4969,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { // Migrate debug information from the old alloca to the new alloca(s) // and the individual partitions. - TinyPtrVector<DbgVariableIntrinsic *> DbgVariables; - for (auto *DbgDeclare : FindDbgDeclareUses(&AI)) - DbgVariables.push_back(DbgDeclare); - for (auto *DbgAssign : at::getAssignmentMarkers(&AI)) - DbgVariables.push_back(DbgAssign); - for (DbgVariableIntrinsic *DbgVariable : DbgVariables) { + auto MigrateOne = [&](auto *DbgVariable) { auto *Expr = DbgVariable->getExpression(); DIBuilder DIB(*AI.getModule(), /*AllowUnresolved*/ false); uint64_t AllocaSize = @@ -4997,36 +5022,34 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { // Remove any existing intrinsics on the new alloca describing // the variable fragment. - for (DbgDeclareInst *OldDII : FindDbgDeclareUses(Fragment.Alloca)) { - auto SameVariableFragment = [](const DbgVariableIntrinsic *LHS, - const DbgVariableIntrinsic *RHS) { + SmallVector<DbgDeclareInst *, 1> FragDbgDeclares; + SmallVector<DPValue *, 1> FragDPVs; + findDbgDeclares(FragDbgDeclares, Fragment.Alloca, &FragDPVs); + auto RemoveOne = [DbgVariable](auto *OldDII) { + auto SameVariableFragment = [](const auto *LHS, const auto *RHS) { return LHS->getVariable() == RHS->getVariable() && LHS->getDebugLoc()->getInlinedAt() == RHS->getDebugLoc()->getInlinedAt(); }; if (SameVariableFragment(OldDII, DbgVariable)) OldDII->eraseFromParent(); - } + }; + for_each(FragDbgDeclares, RemoveOne); + for_each(FragDPVs, RemoveOne); - if (auto *DbgAssign = dyn_cast<DbgAssignIntrinsic>(DbgVariable)) { - if (!Fragment.Alloca->hasMetadata(LLVMContext::MD_DIAssignID)) { - Fragment.Alloca->setMetadata( - LLVMContext::MD_DIAssignID, - DIAssignID::getDistinct(AI.getContext())); - } - auto *NewAssign = DIB.insertDbgAssign( - Fragment.Alloca, DbgAssign->getValue(), DbgAssign->getVariable(), - FragmentExpr, Fragment.Alloca, DbgAssign->getAddressExpression(), - DbgAssign->getDebugLoc()); - NewAssign->setDebugLoc(DbgAssign->getDebugLoc()); - LLVM_DEBUG(dbgs() << "Created new assign intrinsic: " << *NewAssign - << "\n"); - } else { - DIB.insertDeclare(Fragment.Alloca, DbgVariable->getVariable(), - FragmentExpr, DbgVariable->getDebugLoc(), &AI); - } + insertNewDbgInst(DIB, DbgVariable, Fragment.Alloca, FragmentExpr, &AI); } - } + }; + + // Migrate debug information from the old alloca to the new alloca(s) + // and the individual partitions. + SmallVector<DbgDeclareInst *, 1> DbgDeclares; + SmallVector<DPValue *, 1> DPValues; + findDbgDeclares(DbgDeclares, &AI, &DPValues); + for_each(DbgDeclares, MigrateOne); + for_each(DPValues, MigrateOne); + for_each(at::getAssignmentMarkers(&AI), MigrateOne); + return Changed; } @@ -5147,7 +5170,12 @@ bool SROA::deleteDeadInstructions( // not be able to find it. if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { DeletedAllocas.insert(AI); - for (DbgDeclareInst *OldDII : FindDbgDeclareUses(AI)) + SmallVector<DbgDeclareInst *, 1> DbgDeclares; + SmallVector<DPValue *, 1> DPValues; + findDbgDeclares(DbgDeclares, AI, &DPValues); + for (DbgDeclareInst *OldDII : DbgDeclares) + OldDII->eraseFromParent(); + for (DPValue *OldDII : DPValues) OldDII->eraseFromParent(); } |