diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 104 |
1 files changed, 82 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 446149f..066826b 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -411,7 +411,7 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I, return true; } if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) { - if (DVI->getValue()) + if (DVI->hasArgList() || DVI->getValue(0)) return false; return true; } @@ -1360,7 +1360,7 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar, SmallVector<DbgValueInst *, 1> DbgValues; findDbgValues(DbgValues, APN); for (auto *DVI : DbgValues) { - assert(DVI->getValue() == APN); + assert(is_contained(DVI->getValues(), APN)); if ((DVI->getVariable() == DIVar) && (DVI->getExpression() == DIExpr)) return true; } @@ -1387,13 +1387,19 @@ static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) { // 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 // intead. - if (DII->isAddressOfVariable()) - if (auto *AI = dyn_cast_or_null<AllocaInst>(DII->getVariableLocationOp(0))) + 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<AllocaInst>(DII->getVariableLocationOp(0))) { if (Optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) { assert(ValueSize.isScalable() == FragmentSize->isScalable() && "Both sizes should agree on the scalable flag."); return TypeSize::isKnownGE(ValueSize, *FragmentSize); } + } + } // Could not determine size of variable. Conservatively return false. return false; } @@ -1596,17 +1602,26 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB, ValueToValueMapTy DbgValueMap; for (auto &I : *BB) { if (auto DbgII = dyn_cast<DbgVariableIntrinsic>(&I)) { - if (auto *Loc = - dyn_cast_or_null<PHINode>(DbgII->getVariableLocationOp(0))) - DbgValueMap.insert({Loc, DbgII}); + for (Value *V : DbgII->location_ops()) + if (auto *Loc = dyn_cast_or_null<PHINode>(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. + SmallDenseMap<std::pair<BasicBlock *, DbgVariableIntrinsic *>, + DbgVariableIntrinsic *> + NewDbgValueMap; // 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. + // 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. @@ -1616,15 +1631,27 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB, auto V = DbgValueMap.find(VI); if (V != DbgValueMap.end()) { auto *DbgII = cast<DbgVariableIntrinsic>(V->second); - DbgVariableIntrinsic *NewDbgII = - cast<DbgVariableIntrinsic>(DbgII->clone()); - NewDbgII->replaceVariableLocationOp(VI, PHI); - auto InsertionPt = Parent->getFirstInsertionPt(); - assert(InsertionPt != Parent->end() && "Ill-formed basic block"); - NewDbgII->insertBefore(&*InsertionPt); + auto NewDI = NewDbgValueMap.find({Parent, DbgII}); + if (NewDI == NewDbgValueMap.end()) { + auto *NewDbgII = cast<DbgVariableIntrinsic>(DbgII->clone()); + NewDI = NewDbgValueMap.insert({{Parent, DbgII}, NewDbgII}).first; + } + 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); + } } /// Finds all intrinsics declaring local variables as living in the memory that @@ -1665,11 +1692,25 @@ void llvm::findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V) { // DenseMap lookup. if (!V->isUsedByMetadata()) return; - if (auto *L = LocalAsMetadata::getIfExists(V)) - if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) + // TODO: If this value appears multiple times in a DIArgList, we should still + // only add the owning DbgValueInst once; use this set to track ArgListUsers. + // This behaviour can be removed when we can automatically remove duplicates. + SmallPtrSet<DbgValueInst *, 4> EncounteredDbgValues; + if (auto *L = LocalAsMetadata::getIfExists(V)) { + if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) { for (User *U : MDV->users()) if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U)) DbgValues.push_back(DVI); + } + for (Metadata *AL : L->getAllArgListUsers()) { + if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), AL)) { + for (User *U : MDV->users()) + if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U)) + if (EncounteredDbgValues.insert(DVI).second) + DbgValues.push_back(DVI); + } + } + } } void llvm::findDbgUsers(SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers, @@ -1678,11 +1719,25 @@ void llvm::findDbgUsers(SmallVectorImpl<DbgVariableIntrinsic *> &DbgUsers, // DenseMap lookup. if (!V->isUsedByMetadata()) return; - if (auto *L = LocalAsMetadata::getIfExists(V)) - if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) + // TODO: If this value appears multiple times in a DIArgList, we should still + // only add the owning DbgValueInst once; use this set to track ArgListUsers. + // This behaviour can be removed when we can automatically remove duplicates. + SmallPtrSet<DbgVariableIntrinsic *, 4> EncounteredDbgValues; + if (auto *L = LocalAsMetadata::getIfExists(V)) { + if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) { for (User *U : MDV->users()) if (DbgVariableIntrinsic *DII = dyn_cast<DbgVariableIntrinsic>(U)) DbgUsers.push_back(DII); + } + for (Metadata *AL : L->getAllArgListUsers()) { + if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), AL)) { + for (User *U : MDV->users()) + if (DbgVariableIntrinsic *DII = dyn_cast<DbgVariableIntrinsic>(U)) + if (EncounteredDbgValues.insert(DII).second) + DbgUsers.push_back(DII); + } + } + } } bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress, @@ -1752,9 +1807,14 @@ void llvm::salvageDebugInfoForDbgValues( // are implicitly pointing out the value as a DWARF memory location // description. bool StackValue = isa<DbgValueInst>(DII); + auto DIILocation = DII->location_ops(); + assert( + is_contained(DIILocation, &I) && + "DbgVariableIntrinsic must use salvaged instruction as its location"); + unsigned LocNo = std::distance(DIILocation.begin(), find(DIILocation, &I)); DIExpression *DIExpr = - salvageDebugInfoImpl(I, DII->getExpression(), StackValue); + salvageDebugInfoImpl(I, DII->getExpression(), StackValue, LocNo); // salvageDebugInfoImpl should fail on examining the first element of // DbgUsers, or none of them. @@ -1778,7 +1838,7 @@ void llvm::salvageDebugInfoForDbgValues( DIExpression *llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr, - bool WithStackValue) { + bool WithStackValue, unsigned LocNo) { auto &M = *I.getModule(); auto &DL = M.getDataLayout(); @@ -1786,7 +1846,7 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I, auto doSalvage = [&](SmallVectorImpl<uint64_t> &Ops) -> DIExpression * { DIExpression *DIExpr = SrcDIExpr; if (!Ops.empty()) { - DIExpr = DIExpression::prependOpcodes(DIExpr, Ops, WithStackValue); + DIExpr = DIExpression::appendOpsToArg(DIExpr, Ops, LocNo, WithStackValue); } return DIExpr; }; |