Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1270,6 +1270,9 @@ /// instructions that are on different basic blocks. inline unsigned getDiscriminator() const; + /// Returns a new DILocation with updated \p Discriminator. + inline DILocation *cloneWithDiscriminator(unsigned Discriminator) const; + Metadata *getRawScope() const { return getOperand(0); } Metadata *getRawInlinedAt() const { if (getNumOperands() == 2) @@ -1612,6 +1615,22 @@ return 0; } +DILocation *DILocation::cloneWithDiscriminator(unsigned Discriminator) const { + DIScope *Scope = getScope(); + // Skip all parent DILexicalBlockFile that already have a discriminator + // assigned. We do not want to have nested DILexicalBlockFiles that have + // mutliple discriminators because only the leaf DILexicalBlockFile's + // dominator will be used. + for (auto *LBF = dyn_cast(Scope); + LBF && LBF->getDiscriminator() != 0; + LBF = dyn_cast(Scope)) + Scope = LBF->getScope(); + DILexicalBlockFile *NewScope = + DILexicalBlockFile::get(getContext(), Scope, getFile(), Discriminator); + return DILocation::get(getContext(), getLine(), getColumn(), NewScope, + getInlinedAt()); +} + class DINamespace : public DIScope { friend class LLVMContextImpl; friend class MDNode; Index: lib/Transforms/Utils/AddDiscriminators.cpp =================================================================== --- lib/Transforms/Utils/AddDiscriminators.cpp +++ lib/Transforms/Utils/AddDiscriminators.cpp @@ -57,12 +57,10 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -163,14 +161,10 @@ return false; bool Changed = false; - Module *M = F.getParent(); - LLVMContext &Ctx = M->getContext(); - DIBuilder Builder(*M, /*AllowUnresolved*/ false); typedef std::pair Location; - typedef SmallDenseMap ScopeMap; - typedef DenseMap BBScopeMap; - typedef DenseMap LocationBBMap; + typedef DenseSet BBSet; + typedef DenseMap LocationBBMap; typedef DenseMap LocationDiscriminatorMap; typedef DenseSet LocationSet; @@ -187,29 +181,18 @@ const DILocation *DIL = I.getDebugLoc(); if (!DIL) continue; - DIScope *Scope = DIL->getScope(); Location L = std::make_pair(DIL->getFilename(), DIL->getLine()); auto &BBMap = LBM[L]; - auto R = BBMap.insert({&B, ScopeMap()}); + auto R = BBMap.insert(&B); if (BBMap.size() == 1) continue; - bool InsertSuccess = R.second; - ScopeMap &Scopes = R.first->second; // If we could insert more than one block with the same line+file, a // discriminator is needed to distinguish both instructions. - auto R1 = Scopes.insert({Scope, nullptr}); - DILexicalBlockFile *&NewScope = R1.first->second; - if (!NewScope) { - unsigned Discriminator = InsertSuccess ? ++LDM[L] : LDM[L]; - auto *File = Builder.createFile(DIL->getFilename(), - Scope->getDirectory()); - NewScope = Builder.createLexicalBlockFile(Scope, File, Discriminator); - } - I.setDebugLoc(DILocation::get(Ctx, DIL->getLine(), DIL->getColumn(), - NewScope, DIL->getInlinedAt())); + unsigned Discriminator = R.second ? ++LDM[L] : LDM[L]; + I.setDebugLoc(DIL->cloneWithDiscriminator(Discriminator)); DEBUG(dbgs() << DIL->getFilename() << ":" << DIL->getLine() << ":" << DIL->getColumn() << ":" - << dyn_cast(NewScope)->getDiscriminator() + << Discriminator << " " << I << "\n"); Changed = true; } @@ -232,13 +215,7 @@ Location L = std::make_pair(CurrentDIL->getFilename(), CurrentDIL->getLine()); if (!CallLocations.insert(L).second) { - auto *Scope = CurrentDIL->getScope(); - auto *File = Builder.createFile(CurrentDIL->getFilename(), - Scope->getDirectory()); - auto *NewScope = Builder.createLexicalBlockFile(Scope, File, ++LDM[L]); - Current->setDebugLoc(DILocation::get(Ctx, CurrentDIL->getLine(), - CurrentDIL->getColumn(), NewScope, - CurrentDIL->getInlinedAt())); + Current->setDebugLoc(CurrentDIL->cloneWithDiscriminator(++LDM[L])); Changed = true; } } Index: test/Transforms/AddDiscriminators/inlined.ll =================================================================== --- test/Transforms/AddDiscriminators/inlined.ll +++ test/Transforms/AddDiscriminators/inlined.ll @@ -75,9 +75,7 @@ !17 = distinct !DILexicalBlock(scope: !7, file: !1, line: 1, column: 9) !18 = !DILocation(line: 1, column: 9, scope: !7) !19 = !DILocation(line: 1, column: 27, scope: !12, inlinedAt: !13) -; CHECK: ![[BR]] = !DILocation(line: 1, column: 9, scope: ![[BF2:[0-9]+]]) -; CHECK: ![[BF2]] = !DILexicalBlockFile(scope: ![[BF]], -; CHECK-SAME: discriminator: 1) +; CHECK: ![[BR]] = !DILocation(line: 1, column: 9, scope: !14) !20 = !DILocation(line: 1, column: 9, scope: !14) !21 = distinct !{!21, !18} !22 = !DILocation(line: 1, column: 56, scope: !12)