[llvm] Add a pass to collect dropped variable statistics (PR #102233)

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 7 16:12:07 PDT 2024


================
@@ -2441,6 +2447,84 @@ void DotCfgChangeReporter::registerCallbacks(
   }
 }
 
+void DroppedVariableStats::registerCallbacks(
+    PassInstrumentationCallbacks &PIC) {
+  if (!DroppedVarStats)
+    return;
+
+  PIC.registerBeforeNonSkippedPassCallback(
+      [this](StringRef P, Any IR) { return this->runBeforePass(P, IR); });
+  PIC.registerAfterPassCallback(
+      [this](StringRef P, Any IR, const PreservedAnalyses &PA) {
+        return this->runAfterPass(P, IR, PA);
+      });
+}
+
+void DroppedVariableStats::runBeforePass(StringRef PassID, Any IR) {
+  DebugVariablesBefore.push_back(
+      std::make_pair(llvm::DenseSet<VarID>(), PassID.str()));
+  DebugVariablesAfter.push_back(
+      std::make_pair(llvm::DenseSet<VarID>(), PassID.str()));
+  if (auto *M = unwrapIR<Module>(IR))
+    return this->runOnModule(M, true);
+  if (auto *F = unwrapIR<Function>(IR))
+    return this->runOnFunction(F, true);
+  return;
+}
+
+void DroppedVariableStats::runOnFunction(const Function *F, bool Before) {
+  auto &DebugVariables = Before ? DebugVariablesBefore : DebugVariablesAfter;
+  for (auto &BB : *F) {
+    for (const Instruction &I : BB) {
+      for (DbgRecord &DR : I.getDbgRecordRange()) {
+        if (auto *Dbg = dyn_cast<DbgVariableRecord>(&DR)) {
+          llvm::StringRef UniqueName = Dbg->getVariable()->getName();
+          auto DbgLoc = DR.getDebugLoc();
+          unsigned Line = DbgLoc.getLine();
+          unsigned Col = DbgLoc->getColumn();
+          VarID Key(cast<DILocalScope>(DbgLoc.getScope()), UniqueName, Line,
+                    Col);
+          DebugVariables.back().first.insert(Key);
+        }
+      }
+    }
+  }
+}
+
+void DroppedVariableStats::runOnModule(const Module *M, bool Before) {
+  for (auto &F : *M)
+    runOnFunction(&F, Before);
+}
+
+void DroppedVariableStats::runAfterPass(StringRef PassID, Any IR,
+                                        const PreservedAnalyses &PA) {
+  assert(DebugVariablesBefore.back().second ==
+         DebugVariablesAfter.back().second);
+  unsigned DroppedCount = 0;
+  std::string PassLevel = "";
+  std::string FuncOrModName = "";
+  if (auto *M = unwrapIR<Module>(IR)) {
+    this->runOnModule(M, false);
+    PassLevel = "Module";
+    FuncOrModName = M->getName();
+  } else if (auto *F = unwrapIR<Function>(IR)) {
+    this->runOnFunction(F, false);
+    PassLevel = "Function";
+    FuncOrModName = F->getName();
+  } else {
+    return;
+  }
+  for (auto Var : DebugVariablesBefore.back().first)
+    if (!DebugVariablesAfter.back().first.contains(Var))
----------------
adrian-prantl wrote:

Is this doing a linear search through the SmallVector? How about sorting the vector and using std::lower_bound here?

https://github.com/llvm/llvm-project/pull/102233


More information about the llvm-commits mailing list