Author: Stephen Tozer
Date: 2026-07-06T11:59:49+01:00
New Revision: 7f7c7cd7764b13af6858679c3dbcf0df4f0979b4

URL: 
https://github.com/llvm/llvm-project/commit/7f7c7cd7764b13af6858679c3dbcf0df4f0979b4
DIFF: 
https://github.com/llvm/llvm-project/commit/7f7c7cd7764b13af6858679c3dbcf0df4f0979b4.diff

LOG: Revert "[llvm-dwarfdump][LineCov 3/3] Add IR analysis for variable 
coverage (…"

This reverts commit 5f4940efe9c121fb84ada13be9001f24cbef4a4c.

Added: 
    

Modified: 
    llvm/docs/CommandGuide/llvm-dwarfdump.rst
    llvm/test/tools/llvm-dwarfdump/X86/coverage.test
    llvm/tools/llvm-dwarfdump/Coverage.cpp
    llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
    llvm/tools/llvm-dwarfdump/llvm-dwarfdump.h

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-dwarfdump.rst 
b/llvm/docs/CommandGuide/llvm-dwarfdump.rst
index 22f2edfc30f57..03d3623259610 100644
--- a/llvm/docs/CommandGuide/llvm-dwarfdump.rst
+++ b/llvm/docs/CommandGuide/llvm-dwarfdump.rst
@@ -203,12 +203,6 @@ OPTIONS
             File to use as the baseline for variable coverage statistics
             (implies :option:`--show-variable-coverage`)
 
-.. option:: --variable-coverage-bitcode-file
-
-            File containing LLVM IR (bitcode or textual) used for calculating
-            variable definedness in coverage statistics (implies
-            :option:`--show-variable-coverage`)
-
 .. option:: --combine-inline-variable-instances
 
             Use with :option:`--show-variable-coverage` to average variable

diff  --git a/llvm/test/tools/llvm-dwarfdump/X86/coverage.test 
b/llvm/test/tools/llvm-dwarfdump/X86/coverage.test
index 5539ef93c9999..647f277ae64e5 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/coverage.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/coverage.test
@@ -36,27 +36,3 @@ BASELINE-NEXT: fn1 u test.c:4 1 14 0.0714 7 0.5
 BASELINE-NEXT: fn1 v test.c:13 0 14 0 7 0.5
 BASELINE-NEXT: fn1 x test.c:3 7 14 0.5 7 0.5
 BASELINE-NEXT: fn1 y test.c:3 7 14 0.5 7 0.5
-
-RUN: llvm-dwarfdump --show-variable-coverage 
--variable-coverage-bitcode-file=%S/Inputs/coverage.ll %t.o | FileCheck %s 
--check-prefix=BITCODE
-
-BITCODE:      Variable coverage statistics:
-BITCODE-NEXT: Function InlChain Variable Decl LinesCovered
-BITCODE-NEXT: f k test.c:20 2
-BITCODE-NEXT: f l test.c:20 3
-BITCODE-NEXT: fn1 a test.c:11 6
-BITCODE-NEXT: fn1 u test.c:4 12
-BITCODE-NEXT: fn1 v test.c:13 4
-BITCODE-NEXT: fn1 x test.c:3 13
-BITCODE-NEXT: fn1 y test.c:3 13
-
-RUN: llvm-dwarfdump --show-variable-coverage 
--variable-coverage-bitcode-file=%S/Inputs/coverage.ll --coverage-baseline %t.o 
%t-opt.o | FileCheck %s --check-prefix=BASELINE-BITCODE
-
-BASELINE-BITCODE:      Variable coverage statistics:
-BASELINE-BITCODE-NEXT: Function InlChain Variable Decl LinesCovered Baseline 
CoveredRatio LinesPresent LinesPresentRatio
-BASELINE-BITCODE-NEXT: f k test.c:20 2 2 1 2 1
-BASELINE-BITCODE-NEXT: f l test.c:20 3 3 1 3 1
-BASELINE-BITCODE-NEXT: fn1 a test.c:11 3 6 0.5 3 0.5
-BASELINE-BITCODE-NEXT: fn1 u test.c:4 1 12 0.0833 5 0.417
-BASELINE-BITCODE-NEXT: fn1 v test.c:13 0 4 0 2 0.5
-BASELINE-BITCODE-NEXT: fn1 x test.c:3 6 13 0.462 6 0.462
-BASELINE-BITCODE-NEXT: fn1 y test.c:3 6 13 0.462 6 0.462

diff  --git a/llvm/tools/llvm-dwarfdump/Coverage.cpp 
b/llvm/tools/llvm-dwarfdump/Coverage.cpp
index 8c525296a8c82..35ea9bc0a1deb 100644
--- a/llvm/tools/llvm-dwarfdump/Coverage.cpp
+++ b/llvm/tools/llvm-dwarfdump/Coverage.cpp
@@ -14,7 +14,6 @@
 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/IR/CFG.h"
-#include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DebugProgramInstruction.h"
 #include "llvm/IR/Instructions.h"
@@ -30,13 +29,6 @@ using namespace llvm::object;
 
 /// Pair of file index and line number representing a source location.
 typedef std::pair<uint16_t, size_t> SourceLocation;
-/// Pair of subroutine name and variable name representing a local variable.
-typedef std::pair<std::string, std::string> BitcodeVarKey;
-/// Pair of file name and line number representing a source location.
-typedef std::pair<StringRef, uint32_t> BitcodeSourceLocation;
-/// Maps local variables found in the bitcode to a set of source locations.
-typedef std::map<BitcodeVarKey, std::optional<DenseSet<BitcodeSourceLocation>>>
-    BitcodeLineMap;
 
 /// Adds source locations to the line set that correspond to an address range.
 static void addLines(const DWARFDebugLine::LineTable *LineTable,
@@ -56,14 +48,14 @@ static void addLines(const DWARFDebugLine::LineTable 
*LineTable,
   }
 }
 
-/// Converts the file index of each line in the set to use our own internal
-/// file index. This is required for a reliable comparison as the DWARF index
-/// may 
diff er across compilations.
+// Converts the file index of each line in the set to use our own internal
+// file index. This is required for a reliable comparison as the DWARF index 
may
+// 
diff er across compilations.
 static DenseSet<SourceLocation>
 convertFileIndices(DenseSet<SourceLocation> Lines,
                    const DWARFDebugLine::LineTable *const LineTable,
                    DenseMap<uint16_t, uint16_t> &FileIndexMap,
-                   StringMap<std::optional<uint16_t>> &FileNameMap) {
+                   StringMap<uint16_t> &FileNameMap) {
   DenseSet<SourceLocation> ResultLines;
   for (const auto &L : Lines) {
     uint16_t Index;
@@ -78,8 +70,8 @@ convertFileIndices(DenseSet<SourceLocation> Lines,
       assert(ValidIndex && "File index was not valid for its own line table");
 
       auto NameIt = FileNameMap.find(Name);
-      if (NameIt != FileNameMap.end() && NameIt->second) {
-        Index = *NameIt->second;
+      if (NameIt != FileNameMap.end()) {
+        Index = NameIt->second;
       } else {
         Index = FileNameMap.size();
         FileNameMap.insert({Name, Index});
@@ -101,8 +93,7 @@ static DenseSet<SourceLocation>
 computeVariableCoverage(DWARFDie VariableDIE,
                         const DWARFDebugLine::LineTable *const LineTable,
                         DenseMap<uint16_t, uint16_t> &FileIndexMap,
-                        StringMap<std::optional<uint16_t>> &FileNameMap,
-                        BitcodeLineMap::value_type *DefinedLines) {
+                        StringMap<uint16_t> &FileNameMap) {
   // The optionals below will be empty if no address ranges were found, and
   // present (but containing an empty set) if ranges were found but contained 
no
   // source locations, in order to distinguish the two cases.
@@ -141,46 +132,11 @@ computeVariableCoverage(DWARFDie VariableDIE,
   else if (ParentLines)
     set_intersect(*Lines, *ParentLines);
 
-  auto ResultLines =
-      convertFileIndices(Lines.value_or(DenseSet<SourceLocation>()), LineTable,
-                         FileIndexMap, FileNameMap);
-
-  if (DefinedLines) {
-    // Remove any lines where the variable does not have a defined value.
-    auto &DL = DefinedLines->second;
-    if (DL) {
-      DenseSet<SourceLocation> IndexLines;
-      for (const auto &L : *DL) {
-        auto NameIt = FileNameMap.find(L.first);
-        if (NameIt != FileNameMap.end()) {
-          if (NameIt->second)
-            IndexLines.insert({*NameIt->second, L.second});
-        } else {
-          // LineTable::getFileNameByIndex can return absolute paths even when
-          // relative paths are requested, so search for keys that end with 
this
-          // path as well.
-          for (const auto &NameEntry : FileNameMap) {
-            auto Name = NameEntry.first();
-            if (Name.find(L.first, Name.size() - L.first.size()) !=
-                std::string_view::npos) {
-              FileNameMap.insert({L.first, NameEntry.second});
-              IndexLines.insert({*NameEntry.second, L.second});
-            }
-          }
-          if (FileNameMap.find(L.first) == FileNameMap.end()) {
-            assert(0 && "Files found in bitcode but not in DWARF");
-            FileNameMap.insert({L.first, std::nullopt});
-          }
-        }
-      }
-      if (!Lines)
-        assert(0 && "Source lines found in bitcode but not in DWARF");
-      else
-        set_intersect(ResultLines, IndexLines);
-    }
-  }
+  if (!Lines)
+    return {};
 
-  return ResultLines;
+  return convertFileIndices(Lines.value_or(DenseSet<SourceLocation>()),
+                            LineTable, FileIndexMap, FileNameMap);
 }
 
 /// Adds source locations to the line set that are within an inlined 
subroutine.
@@ -207,7 +163,7 @@ static DenseSet<SourceLocation>
 computeSubroutineCoverage(DWARFDie SubroutineDIE,
                           const DWARFDebugLine::LineTable *const LineTable,
                           DenseMap<uint16_t, uint16_t> &FileIndexMap,
-                          StringMap<std::optional<uint16_t>> &FileNameMap) {
+                          StringMap<uint16_t> &FileNameMap) {
   auto Ranges = SubroutineDIE.getAddressRanges();
   DenseSet<SourceLocation> Lines;
   if (Ranges) {
@@ -239,147 +195,6 @@ static const SmallVector<DWARFDie> 
getParentSubroutines(DWARFDie DIE) {
   return Parents;
 }
 
-static bool isInScope(MDNode *Scope, const DebugLoc &Loc) {
-  MDNode *Parent = Loc.getScope();
-  while (Parent != Scope) {
-    auto *S = dyn_cast_if_present<DIScope>(Parent);
-    if (!S)
-      return false;
-    Parent = S->getScope();
-  }
-  return true;
-}
-
-/// Determines whether an instruction stores to a location. For the purposes of
-/// this analysis, we consider any call-like instruction with the location as 
an
-/// argument to be a store to it.
-static bool isStoreToLocation(const DataLayout &DL, Instruction &I,
-                              Value *Loc) {
-  std::optional<at::AssignmentInfo> Info;
-  if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
-    if (SI->getPointerOperand() == Loc)
-      return true;
-    Info = at::getAssignmentInfo(DL, SI);
-  } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&I)) {
-    if (MI->getDest() == Loc)
-      return true;
-    Info = at::getAssignmentInfo(DL, MI);
-  } else if (CallBase *CI = dyn_cast<CallBase>(&I)) {
-    return CI->hasArgument(Loc);
-  }
-  return Info && Info->Base == Loc;
-}
-
-typedef SmallDenseMap<BasicBlock *, Instruction *, 8> VarDefinitionMap;
-
-struct VarState {
-  DbgVariableRecord &DVR;
-  VarDefinitionMap Definitions;
-};
-
-/// Adds source locations to the line set for instructions in a basic block,
-/// starting with a specific instruction.
-static void addModuleLines(Instruction *I, VarState &Var,
-                           DenseSet<std::pair<StringRef, uint32_t>> &Lines) {
-  auto *VarScope = Var.DVR.getVariable()->getScope();
-  do {
-    auto &Loc = I->getDebugLoc();
-    DIScope *Scope;
-    if (Loc && isInScope(VarScope, Loc) && Loc.getLine() &&
-        (Scope = dyn_cast_if_present<DIScope>(Loc.getScope()))) {
-      Lines.insert({Scope->getFilename(), Loc.getLine()});
-    }
-  } while ((I = I->getNextNode()));
-}
-
-/// Computes the defined lines of all variables in an IR module.
-static BitcodeLineMap processModule(Module *Mod) {
-  BitcodeLineMap Result;
-  std::vector<VarState> Vars;
-  for (auto &F : Mod->functions()) {
-    Vars.clear();
-    for (auto &BB : F) {
-      for (auto &I : BB) {
-        for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
-          if (DVR.isKillLocation()) {
-            assert(0 && "Variable in bitcode has been optimized out");
-            continue;
-          }
-          if (DVR.isDbgDeclare()) {
-            // For #dbg_declare, don't treat the variable as live until we find
-            // a store to it.
-            Vars.push_back(VarState{DVR, VarDefinitionMap()});
-          } else if (DVR.isDbgValue()) {
-            // For #dbg_value, the variable is live immediately from this 
point.
-            if (DVR.getDebugLoc().getInlinedAt() != nullptr) {
-              assert(0 && "Variable in bitcode has been inlined");
-              continue;
-            }
-            auto Var = find_if(Vars, [&](auto &Var) {
-              return Var.DVR.getVariable() == DVR.getVariable();
-            });
-            if (Var != Vars.end())
-              // If a basic block contains multiple stores to a variable, use
-              // the earliest one by allowing the insertion to silently fail if
-              // the basic block is already in the map.
-              Var->Definitions.insert({&BB, &I});
-            else
-              Vars.push_back(VarState{DVR, {{&BB, &I}}});
-          }
-        }
-      }
-    }
-
-    for (auto &BB : F) {
-      for (auto &I : BB) {
-        for (auto &Var : Vars) {
-          if (isStoreToLocation(Mod->getDataLayout(), I, Var.DVR.getValue())) {
-            // The variable is live from the instruction after the store. As
-            // above, the earliest store in this basic block will be used.
-            Var.Definitions.insert({&BB, I.getNextNode()});
-          }
-        }
-      }
-    }
-
-    for (auto &Var : Vars) {
-      SmallPtrSet<BasicBlock *, 8> Visited;
-      DenseSet<std::pair<StringRef, uint32_t>> Lines;
-
-      // Visit all basic blocks that are reachable from the entry block without
-      // going through a block that stores to the variable.
-      SmallVector<BasicBlock *> BlocksToVisit{&F.getEntryBlock()};
-      while (!BlocksToVisit.empty()) {
-        BasicBlock *BB = BlocksToVisit.pop_back_val();
-        if (!Visited.insert(BB).second)
-          continue;
-
-        auto I = Var.Definitions.find(BB);
-        if (I != Var.Definitions.end()) {
-          // Block contains a definition: add all lines after it to the set
-          if (I->second != nullptr)
-            addModuleLines(I->second, Var, Lines);
-        } else {
-          // Block does not contain a definition: visit its successors
-          auto S = successors(BB);
-          BlocksToVisit.append(S.begin(), S.end());
-        }
-      }
-
-      // All unvisited basic blocks must only be reachable by going through a
-      // block that stores to the variable, so add lines to the set for all of
-      // their instructions.
-      for (auto &BB : F)
-        if (!Visited.count(&BB))
-          addModuleLines(&*BB.begin(), Var, Lines);
-
-      BitcodeVarKey Key(F.getName(), Var.DVR.getVariable()->getName());
-      Result.emplace(Key, Lines);
-    }
-  }
-  return Result;
-}
-
 struct VarKey {
   const char *const SubprogramName;
   const char *const Name;
@@ -480,21 +295,9 @@ static void displayVariableCoverage(const VarKey &Key, 
const VarCoverage &Var,
 bool dwarfdump::showVariableCoverage(ObjectFile &Obj, DWARFContext &DICtx,
                                      ObjectFile *BaselineObj,
                                      DWARFContext *BaselineCtx,
-                                     StringRef BitcodeFile,
                                      bool CombineInstances, raw_ostream &OS) {
-  BitcodeLineMap LM;
-  LLVMContext Context;
-  if (!BitcodeFile.empty()) {
-    SMDiagnostic Err;
-    std::unique_ptr<Module> Mod = parseIRFile(BitcodeFile, Err, Context);
-    if (!Err.getMessage().empty())
-      Err.print("llvm-dwarfdump", OS);
-    else
-      LM = processModule(Mod.get());
-  }
-
   BaselineVarMap BaselineVars;
-  StringMap<std::optional<uint16_t>> FileNameMap;
+  StringMap<uint16_t> FileNameMap;
 
   if (BaselineCtx) {
     for (const auto &U : BaselineCtx->info_section_units()) {
@@ -514,10 +317,8 @@ bool dwarfdump::showVariableCoverage(ObjectFile &Obj, 
DWARFContext &DICtx,
         if (!Key)
           continue;
 
-        const auto DefinedLines = LM.find({Key->SubprogramName, Key->Name});
-        auto Cov = computeVariableCoverage(
-            VariableDIE, LT, FileIndexMap, FileNameMap,
-            DefinedLines != LM.end() ? &*DefinedLines : nullptr);
+        auto Cov =
+            computeVariableCoverage(VariableDIE, LT, FileIndexMap, 
FileNameMap);
         const auto SubroutineCov = computeSubroutineCoverage(
             SubroutineDIE, LT, FileIndexMap, FileNameMap);
         set_intersect(Cov, SubroutineCov);
@@ -548,10 +349,8 @@ bool dwarfdump::showVariableCoverage(ObjectFile &Obj, 
DWARFContext &DICtx,
       if (!Key)
         continue;
 
-      const auto DefinedLines = LM.find({Key->SubprogramName, Key->Name});
-      auto Cov = computeVariableCoverage(
-          VariableDIE, LT, FileIndexMap, FileNameMap,
-          DefinedLines != LM.end() ? &*DefinedLines : nullptr);
+      auto Cov =
+          computeVariableCoverage(VariableDIE, LT, FileIndexMap, FileNameMap);
       const auto SubroutineCov = computeSubroutineCoverage(
           SubroutineDIE, LT, FileIndexMap, FileNameMap);
       set_intersect(Cov, SubroutineCov);

diff  --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp 
b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 4d7fc7e3108bf..a97a154e28080 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -343,12 +343,6 @@ static opt<std::string>
                      desc("File to use as the baseline for variable coverage "
                           "statistics (implies --show-variable-coverage)"),
                      value_desc("filename"), cat(DwarfDumpCategory));
-static opt<std::string>
-    BitcodeFile("variable-coverage-bitcode-file",
-                desc("File containing LLVM IR (bitcode or textual) used for "
-                     "calculating variable definedness in coverage statistics "
-                     "(implies --show-variable-coverage)"),
-                value_desc("filename"), cat(DwarfDumpCategory));
 static opt<bool> CombineInstances(
     "combine-inline-variable-instances",
     desc(
@@ -927,7 +921,7 @@ int main(int argc, char **argv) {
   if (DumpAll)
     DumpType = DIDT_All;
   if (DumpType == DIDT_Null && !ShowVariableCoverage &&
-      CoverageBaseline.empty() && BitcodeFile.empty()) {
+      CoverageBaseline.empty()) {
     if (Verbose || Verify)
       DumpType = DIDT_All;
     else
@@ -986,17 +980,17 @@ int main(int argc, char **argv) {
       auto showCoverage = [&](ObjectFile &Obj, DWARFContext &DICtx,
                               const Twine &Filename, raw_ostream &OS) {
         return showVariableCoverage(Obj, DICtx, &BaselineObj, &BaselineCtx,
-                                    BitcodeFile, CombineInstances, OS);
+                                    CombineInstances, OS);
       };
       for (StringRef Object : Objects)
         Success &= handleFile(Object, showCoverage, OutputFile.os());
       return true;
     };
     Success &= handleFile(CoverageBaseline, handleBaseline, OutputFile.os());
-  } else if (ShowVariableCoverage || !BitcodeFile.empty()) {
+  } else if (ShowVariableCoverage) {
     auto showCoverage = [&](ObjectFile &Obj, DWARFContext &DICtx,
                             const Twine &Filename, raw_ostream &OS) {
-      return showVariableCoverage(Obj, DICtx, nullptr, nullptr, BitcodeFile,
+      return showVariableCoverage(Obj, DICtx, nullptr, nullptr,
                                   CombineInstances, OS);
     };
     for (StringRef Object : Objects)

diff  --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.h 
b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.h
index e9d0433cc3f49..90a49e8f75ffc 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.h
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.h
@@ -41,8 +41,8 @@ bool collectObjectSectionSizes(object::ObjectFile &Obj, 
DWARFContext &DICtx,
 
 bool showVariableCoverage(object::ObjectFile &Obj, DWARFContext &DICtx,
                           object::ObjectFile *BaselineObj,
-                          DWARFContext *BaselineCtx, StringRef BitcodeFile,
-                          bool CombineInstances, raw_ostream &OS);
+                          DWARFContext *BaselineCtx, bool CombineInstances,
+                          raw_ostream &OS);
 } // namespace dwarfdump
 } // namespace llvm
 


        
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to