diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h index 9267b10c0ab1..e4185448f015 100644 --- a/llvm/include/llvm/Transforms/Utils/Local.h +++ b/llvm/include/llvm/Transforms/Utils/Local.h @@ -32,6 +32,7 @@ class BranchInst; class Instruction; class CallInst; class DbgDeclareInst; +class DbgValueInst; class StoreInst; class LoadInst; class Value; @@ -48,6 +49,8 @@ class LazyValueInfo; template class SmallVectorImpl; +typedef SmallVector DbgValueList; + //===----------------------------------------------------------------------===// // Local constant propagation. // @@ -255,14 +258,19 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP, /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value /// that has an associated llvm.dbg.decl intrinsic. -bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, +void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder); /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value /// that has an associated llvm.dbg.decl intrinsic. -bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, +void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, LoadInst *LI, DIBuilder &Builder); +/// Inserts a llvm.dbg.value intrinsic after a phi of an alloca'd value +/// that has an associated llvm.dbg.decl intrinsic. +void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, + PHINode *LI, DIBuilder &Builder); + /// Lowers llvm.dbg.declare intrinsics into appropriate set of /// llvm.dbg.value intrinsics. bool LowerDbgDeclare(Function &F); @@ -270,6 +278,9 @@ bool LowerDbgDeclare(Function &F); /// Finds the llvm.dbg.declare intrinsic corresponding to an alloca, if any. DbgDeclareInst *FindAllocaDbgDeclare(Value *V); +/// Finds the llvm.dbg.value intrinsics corresponding to an alloca, if any. +void FindAllocaDbgValues(DbgValueList &DbgValues, Value *V); + /// Replaces llvm.dbg.declare instruction 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 diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index c1ef655be4be..9b28f837d706 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1053,9 +1053,27 @@ static bool LdStHasDebugValue(DILocalVariable *DIVar, DIExpression *DIExpr, return false; } +/// See if there is a dbg.value intrinsic for DIVar for the PHI node. +static bool PhiHasDebugValue(DILocalVariable *DIVar, + DIExpression *DIExpr, + PHINode *APN) { + // Since we can't guarantee that the original dbg.declare instrinsic + // is removed by LowerDbgDeclare(), we need to make sure that we are + // not inserting the same dbg.value intrinsic over and over. + DbgValueList DbgValues; + FindAllocaDbgValues(DbgValues, APN); + for (auto DVI : DbgValues) { + assert (DVI->getValue() == APN); + assert (DVI->getOffset() == 0); + if ((DVI->getVariable() == DIVar) && (DVI->getExpression() == DIExpr)) + return true; + } + return false; +} + /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value /// that has an associated llvm.dbg.decl intrinsic. -bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, +void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder) { auto *DIVar = DDI->getVariable(); auto *DIExpr = DDI->getExpression(); @@ -1096,19 +1114,18 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, } else if (!LdStHasDebugValue(DIVar, DIExpr, SI)) Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIVar, DIExpr, DDI->getDebugLoc(), SI); - return true; } /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value /// that has an associated llvm.dbg.decl intrinsic. -bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, +void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, LoadInst *LI, DIBuilder &Builder) { auto *DIVar = DDI->getVariable(); auto *DIExpr = DDI->getExpression(); assert(DIVar && "Missing variable"); if (LdStHasDebugValue(DIVar, DIExpr, LI)) - return true; + return; // 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 @@ -1117,7 +1134,26 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, Instruction *DbgValue = Builder.insertDbgValueIntrinsic( LI, 0, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr); DbgValue->insertAfter(LI); - return true; +} + +/// Inserts a llvm.dbg.value intrinsic after a phi +/// that has an associated llvm.dbg.decl intrinsic. +void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, + PHINode *APN, DIBuilder &Builder) { + auto *DIVar = DDI->getVariable(); + auto *DIExpr = DDI->getExpression(); + assert(DIVar && "Missing variable"); + + if (PhiHasDebugValue(DIVar, DIExpr, APN)) + return; + + auto BB = APN->getParent(); + auto InsertionPt = BB->getFirstInsertionPt(); + if (InsertionPt != BB->end()) { + Instruction *DbgValue = Builder.insertDbgValueIntrinsic( + APN, 0, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr); + DbgValue->insertBefore(&*InsertionPt); + } } /// Determine whether this alloca is either a VLA or an array. @@ -1187,6 +1223,16 @@ DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) { return nullptr; } +/// FindAllocaDbgValues - Finds the llvm.dbg.value intrinsics describing the +/// alloca 'V', if any. +void llvm::FindAllocaDbgValues(DbgValueList &DbgValues, Value *V) { + if (auto *L = LocalAsMetadata::getIfExists(V)) + if (auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L)) + for (User *U : MDV->users()) + if (DbgValueInst *DVI = dyn_cast(U)) + DbgValues.push_back(DVI); +} + static void DIExprAddDeref(SmallVectorImpl &Expr) { Expr.push_back(dwarf::DW_OP_deref); } diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index cbf385d56339..35faa6f65efd 100644 --- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -907,6 +907,8 @@ NextIteration: // The currently active variable for this block is now the PHI. IncomingVals[AllocaNo] = APN; + if (DbgDeclareInst *DDI = AllocaDbgDeclares[AllocaNo]) + ConvertDebugDeclareToDebugValue(DDI, APN, DIB); // Get the next phi node. ++PNI;