[llvm] r304488 - Reapply "[Cloning] Take another pass at properly cloning debug info"
Keno Fischer via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 1 16:02:13 PDT 2017
Author: kfischer
Date: Thu Jun 1 18:02:12 2017
New Revision: 304488
URL: http://llvm.org/viewvc/llvm-project?rev=304488&view=rev
Log:
Reapply "[Cloning] Take another pass at properly cloning debug info"
This was rL304226, reverted in 304228 due to a clang assertion failure
on the build bots. That problem should have been addressed by clang
commit rL304470.
Modified:
llvm/trunk/include/llvm/IR/DebugLoc.h
llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
llvm/trunk/lib/IR/DebugLoc.cpp
llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp
llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
llvm/trunk/unittests/Transforms/Utils/Cloning.cpp
Modified: llvm/trunk/include/llvm/IR/DebugLoc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugLoc.h?rev=304488&r1=304487&r2=304488&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugLoc.h (original)
+++ llvm/trunk/include/llvm/IR/DebugLoc.h Thu Jun 1 18:02:12 2017
@@ -90,12 +90,6 @@ namespace llvm {
DenseMap<const MDNode *, MDNode *> &Cache,
bool ReplaceLast = false);
- /// Reparent all debug locations referenced by \c I that belong to \c OrigSP
- /// to become (possibly indirect) children of \c NewSP.
- static void reparentDebugInfo(Instruction &I, DISubprogram *OrigSP,
- DISubprogram *NewSP,
- DenseMap<const MDNode *, MDNode *> &Cache);
-
unsigned getLine() const;
unsigned getCol() const;
MDNode *getScope() const;
Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=304488&r1=304487&r2=304488&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Thu Jun 1 18:02:12 2017
@@ -36,6 +36,7 @@ class BasicBlock;
class BlockFrequencyInfo;
class CallInst;
class CallGraph;
+class DebugInfoFinder;
class DominatorTree;
class Function;
class Instruction;
@@ -110,7 +111,8 @@ struct ClonedCodeInfo {
///
BasicBlock *CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
const Twine &NameSuffix = "", Function *F = nullptr,
- ClonedCodeInfo *CodeInfo = nullptr);
+ ClonedCodeInfo *CodeInfo = nullptr,
+ DebugInfoFinder *DIFinder = nullptr);
/// CloneFunction - Return a copy of the specified function and add it to that
/// function's module. Also, any references specified in the VMap are changed
Modified: llvm/trunk/lib/IR/DebugLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugLoc.cpp?rev=304488&r1=304487&r2=304488&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugLoc.cpp (original)
+++ llvm/trunk/lib/IR/DebugLoc.cpp Thu Jun 1 18:02:12 2017
@@ -99,87 +99,6 @@ DebugLoc DebugLoc::appendInlinedAt(Debug
return Last;
}
-/// Reparent \c Scope from \c OrigSP to \c NewSP.
-static DIScope *reparentScope(LLVMContext &Ctx, DIScope *Scope,
- DISubprogram *OrigSP, DISubprogram *NewSP,
- DenseMap<const MDNode *, MDNode *> &Cache) {
- SmallVector<DIScope *, 3> ScopeChain;
- DIScope *Last = NewSP;
- DIScope *CurScope = Scope;
- do {
- if (auto *SP = dyn_cast<DISubprogram>(CurScope)) {
- // Don't rewrite this scope chain if it doesn't lead to the replaced SP.
- if (SP != OrigSP)
- return Scope;
- Cache.insert({OrigSP, NewSP});
- break;
- }
- if (auto *Found = Cache[CurScope]) {
- Last = cast<DIScope>(Found);
- break;
- }
- ScopeChain.push_back(CurScope);
- } while ((CurScope = CurScope->getScope().resolve()));
-
- // Starting from the top, rebuild the nodes to point to the new inlined-at
- // location (then rebuilding the rest of the chain behind it) and update the
- // map of already-constructed inlined-at nodes.
- for (const DIScope *MD : reverse(ScopeChain)) {
- if (auto *LB = dyn_cast<DILexicalBlock>(MD))
- Cache[MD] = Last = DILexicalBlock::getDistinct(
- Ctx, Last, LB->getFile(), LB->getLine(), LB->getColumn());
- else if (auto *LB = dyn_cast<DILexicalBlockFile>(MD))
- Cache[MD] = Last = DILexicalBlockFile::getDistinct(
- Ctx, Last, LB->getFile(), LB->getDiscriminator());
- else
- llvm_unreachable("illegal parent scope");
- }
- return Last;
-}
-
-void DebugLoc::reparentDebugInfo(Instruction &I, DISubprogram *OrigSP,
- DISubprogram *NewSP,
- DenseMap<const MDNode *, MDNode *> &Cache) {
- auto DL = I.getDebugLoc();
- if (!OrigSP || !NewSP || OrigSP == NewSP || !DL)
- return;
-
- // Reparent the debug location.
- auto &Ctx = I.getContext();
- DILocation *InlinedAt = DL->getInlinedAt();
- if (InlinedAt) {
- while (auto *IA = InlinedAt->getInlinedAt())
- InlinedAt = IA;
- auto NewScope =
- reparentScope(Ctx, InlinedAt->getScope(), OrigSP, NewSP, Cache);
- InlinedAt =
- DebugLoc::get(InlinedAt->getLine(), InlinedAt->getColumn(), NewScope);
- }
- I.setDebugLoc(
- DebugLoc::get(DL.getLine(), DL.getCol(),
- reparentScope(Ctx, DL->getScope(), OrigSP, NewSP, Cache),
- DebugLoc::appendInlinedAt(DL, InlinedAt, Ctx, Cache,
- ReplaceLastInlinedAt)));
-
- // Fix up debug variables to point to NewSP.
- auto reparentVar = [&](DILocalVariable *Var) {
- return DILocalVariable::get(
- Ctx,
- cast<DILocalScope>(
- reparentScope(Ctx, Var->getScope(), OrigSP, NewSP, Cache)),
- Var->getName(), Var->getFile(), Var->getLine(), Var->getType(),
- Var->getArg(), Var->getFlags(), Var->getAlignInBits());
- };
- if (auto *DbgValue = dyn_cast<DbgValueInst>(&I)) {
- auto *Var = DbgValue->getVariable();
- I.setOperand(2, MetadataAsValue::get(Ctx, reparentVar(Var)));
- } else if (auto *DbgDeclare = dyn_cast<DbgDeclareInst>(&I)) {
- auto *Var = DbgDeclare->getVariable();
- I.setOperand(1, MetadataAsValue::get(Ctx, reparentVar(Var)));
- }
-}
-
-
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void DebugLoc::dump() const {
if (!Loc)
Modified: llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp?rev=304488&r1=304487&r2=304488&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp (original)
+++ llvm/trunk/lib/Transforms/Coroutines/CoroSplit.cpp Thu Jun 1 18:02:12 2017
@@ -228,7 +228,7 @@ static Function *createClone(Function &F
SmallVector<ReturnInst *, 4> Returns;
- CloneFunctionInto(NewF, &F, VMap, /*ModuleLevelChanges=*/false, Returns);
+ CloneFunctionInto(NewF, &F, VMap, /*ModuleLevelChanges=*/true, Returns);
// Remove old returns.
for (ReturnInst *Return : Returns)
Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=304488&r1=304487&r2=304488&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Thu Jun 1 18:02:12 2017
@@ -37,10 +37,10 @@
using namespace llvm;
/// See comments in Cloning.h.
-BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB,
- ValueToValueMapTy &VMap,
+BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap,
const Twine &NameSuffix, Function *F,
- ClonedCodeInfo *CodeInfo) {
+ ClonedCodeInfo *CodeInfo,
+ DebugInfoFinder *DIFinder) {
DenseMap<const MDNode *, MDNode *> Cache;
BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), "", F);
if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix);
@@ -50,10 +50,11 @@ BasicBlock *llvm::CloneBasicBlock(const
// Loop over all instructions, and copy them over.
for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
II != IE; ++II) {
+
+ if (DIFinder && F->getParent() && II->getDebugLoc())
+ DIFinder->processLocation(*F->getParent(), II->getDebugLoc().get());
+
Instruction *NewInst = II->clone();
- if (F && F->getSubprogram())
- DebugLoc::reparentDebugInfo(*NewInst, BB->getParent()->getSubprogram(),
- F->getSubprogram(), Cache);
if (II->hasName())
NewInst->setName(II->getName()+NameSuffix);
NewBB->getInstList().push_back(NewInst);
@@ -122,31 +123,38 @@ void llvm::CloneFunctionInto(Function *N
AttributeList::get(NewFunc->getContext(), OldAttrs.getFnAttributes(),
OldAttrs.getRetAttributes(), NewArgAttrs));
+ bool MustCloneSP =
+ OldFunc->getParent() && OldFunc->getParent() == NewFunc->getParent();
+ DISubprogram *SP = OldFunc->getSubprogram();
+ if (SP) {
+ assert(!MustCloneSP || ModuleLevelChanges);
+ // Add mappings for some DebugInfo nodes that we don't want duplicated
+ // even if they're distinct.
+ auto &MD = VMap.MD();
+ MD[SP->getUnit()].reset(SP->getUnit());
+ MD[SP->getType()].reset(SP->getType());
+ MD[SP->getFile()].reset(SP->getFile());
+ // If we're not cloning into the same module, no need to clone the
+ // subprogram
+ if (!MustCloneSP)
+ MD[SP].reset(SP);
+ }
+
SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
OldFunc->getAllMetadata(MDs);
for (auto MD : MDs) {
- MDNode *NewMD;
- bool MustCloneSP =
- (MD.first == LLVMContext::MD_dbg && OldFunc->getParent() &&
- OldFunc->getParent() == NewFunc->getParent());
- if (MustCloneSP) {
- auto *SP = cast<DISubprogram>(MD.second);
- NewMD = DISubprogram::getDistinct(
- NewFunc->getContext(), SP->getScope(), SP->getName(),
- SP->getLinkageName(), SP->getFile(), SP->getLine(), SP->getType(),
- SP->isLocalToUnit(), SP->isDefinition(), SP->getScopeLine(),
- SP->getContainingType(), SP->getVirtuality(), SP->getVirtualIndex(),
- SP->getThisAdjustment(), SP->getFlags(), SP->isOptimized(),
- SP->getUnit(), SP->getTemplateParams(), SP->getDeclaration(),
- SP->getVariables(), SP->getThrownTypes());
- } else
- NewMD =
- MapMetadata(MD.second, VMap,
- ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
- TypeMapper, Materializer);
- NewFunc->addMetadata(MD.first, *NewMD);
+ NewFunc->addMetadata(
+ MD.first,
+ *MapMetadata(MD.second, VMap,
+ ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
+ TypeMapper, Materializer));
}
+ // When we remap instructions, we want to avoid duplicating inlined
+ // DISubprograms, so record all subprograms we find as we duplicate
+ // instructions and then freeze them in the MD map.
+ DebugInfoFinder DIFinder;
+
// Loop over all of the basic blocks in the function, cloning them as
// appropriate. Note that we save BE this way in order to handle cloning of
// recursive functions into themselves.
@@ -156,7 +164,8 @@ void llvm::CloneFunctionInto(Function *N
const BasicBlock &BB = *BI;
// Create a new basic block and copy instructions into it!
- BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo);
+ BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo,
+ SP ? &DIFinder : nullptr);
// Add basic block mapping.
VMap[&BB] = CBB;
@@ -178,6 +187,12 @@ void llvm::CloneFunctionInto(Function *N
Returns.push_back(RI);
}
+ for (DISubprogram *ISP : DIFinder.subprograms()) {
+ if (ISP != SP) {
+ VMap.MD()[ISP].reset(ISP);
+ }
+ }
+
// Loop over all of the instructions in the function, fixing up operand
// references as we go. This uses VMap to do all the hard work.
for (Function::iterator BB =
@@ -226,7 +241,7 @@ Function *llvm::CloneFunction(Function *
}
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
- CloneFunctionInto(NewF, F, VMap, /*ModuleLevelChanges=*/false, Returns, "",
+ CloneFunctionInto(NewF, F, VMap, F->getSubprogram() != nullptr, Returns, "",
CodeInfo);
return NewF;
Modified: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Cloning.cpp?rev=304488&r1=304487&r2=304488&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Thu Jun 1 18:02:12 2017
@@ -361,7 +361,7 @@ TEST_F(CloneFunc, NewFunctionCreated) {
// Test that a new subprogram entry was added and is pointing to the new
// function, while the original subprogram still points to the old one.
TEST_F(CloneFunc, Subprogram) {
- EXPECT_FALSE(verifyModule(*M));
+ EXPECT_FALSE(verifyModule(*M, &errs()));
EXPECT_EQ(3U, Finder->subprogram_count());
EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram());
}
More information about the llvm-commits
mailing list