Skip to content

Add a pass to collect dropped var statistics for MIR #126686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 12, 2025

Conversation

rastogishubham
Copy link
Contributor

This patch attempts to reland #120780 while addressing the issues that caused the patch to be reverted.

Namely:

  1. The patch had included code from the llvm/Passes directory in the llvm/CodeGen directory.

  2. The patch increased the backend compile time by 2% due to adding a very expensive include in MachineFunctionPass.h

The patch has been re-structured so that there is no dependency between the llvm/Passes and llvm/CodeGen directory, by moving the base class, class DroppedVariableStats to the llvm/IR directory.

The expensive include in MachineFunctionPass.h has been changed to contain forward declarations instead of other header includes which was pulling a ton of code into MachineFunctionPass.h and should resolve any issues when it comes to compile time increase.

@llvmbot
Copy link
Member

llvmbot commented Feb 11, 2025

@llvm/pr-subscribers-llvm-ir

Author: Shubham Sandeep Rastogi (rastogishubham)

Changes

This patch attempts to reland #120780 while addressing the issues that caused the patch to be reverted.

Namely:

  1. The patch had included code from the llvm/Passes directory in the llvm/CodeGen directory.

  2. The patch increased the backend compile time by 2% due to adding a very expensive include in MachineFunctionPass.h

The patch has been re-structured so that there is no dependency between the llvm/Passes and llvm/CodeGen directory, by moving the base class, class DroppedVariableStats to the llvm/IR directory.

The expensive include in MachineFunctionPass.h has been changed to contain forward declarations instead of other header includes which was pulling a ton of code into MachineFunctionPass.h and should resolve any issues when it comes to compile time increase.


Patch is 65.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/126686.diff

13 Files Affected:

  • (added) llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h (+59)
  • (modified) llvm/include/llvm/CodeGen/MachineFunctionPass.h (+2)
  • (renamed) llvm/include/llvm/IR/DroppedVariableStats.h (+27-119)
  • (modified) llvm/include/llvm/Passes/DroppedVariableStatsIR.h (+19-31)
  • (modified) llvm/lib/CodeGen/CMakeLists.txt (+1)
  • (added) llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp (+95)
  • (modified) llvm/lib/CodeGen/MachineFunctionPass.cpp (+14-1)
  • (modified) llvm/lib/IR/CMakeLists.txt (+1)
  • (added) llvm/lib/IR/DroppedVariableStats.cpp (+147)
  • (modified) llvm/lib/Passes/DroppedVariableStatsIR.cpp (+38)
  • (modified) llvm/unittests/CodeGen/CMakeLists.txt (+1)
  • (added) llvm/unittests/CodeGen/DroppedVariableStatsMIRTest.cpp (+1081)
  • (modified) llvm/unittests/IR/DroppedVariableStatsIRTest.cpp (+7-7)
diff --git a/llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h b/llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h
new file mode 100644
index 000000000000000..4285c594ce1e43f
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/DroppedVariableStatsMIR.h
@@ -0,0 +1,59 @@
+///===- DroppedVariableStatsMIR.h - Opt Diagnostics -*- C++ -*-------------===//
+///
+/// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+/// Exceptions. See https://llvm.org/LICENSE.txt for license information.
+/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+///
+///===---------------------------------------------------------------------===//
+/// \file
+/// Dropped Variable Statistics for Debug Information. Reports any number
+/// of DBG_VALUEs that get dropped due to an optimization pass.
+///
+///===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H
+#define LLVM_CODEGEN_DROPPEDVARIABLESTATSMIR_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/DroppedVariableStats.h"
+
+namespace llvm {
+
+/// A class to collect and print dropped debug information due to MIR
+/// optimization passes. After every MIR pass is run, it will print how many
+/// #DBG_VALUEs were dropped due to that pass.
+class DroppedVariableStatsMIR : public DroppedVariableStats {
+public:
+  DroppedVariableStatsMIR() : llvm::DroppedVariableStats(false) {}
+
+  void runBeforePass(StringRef PassID, MachineFunction *MF);
+
+  void runAfterPass(StringRef PassID, MachineFunction *MF);
+
+private:
+  const MachineFunction *MFunc;
+  /// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
+  /// after a pass has run to facilitate dropped variable calculation for an
+  /// llvm::MachineFunction.
+  void runOnMachineFunction(const MachineFunction *MF, bool Before);
+  /// Iterate over all Instructions in a MachineFunction and report any dropped
+  /// debug information.
+  void calculateDroppedVarStatsOnMachineFunction(const MachineFunction *MF,
+                                                 StringRef PassID,
+                                                 StringRef FuncOrModName);
+  /// Override base class method to run on an llvm::MachineFunction
+  /// specifically.
+  virtual void
+  visitEveryInstruction(unsigned &DroppedCount,
+                        DenseMap<VarID, DILocation *> &InlinedAtsMap,
+                        VarID Var) override;
+  /// Override base class method to run on DBG_VALUEs specifically.
+  virtual void visitEveryDebugRecord(
+      DenseSet<VarID> &VarIDSet,
+      DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
+      StringRef FuncName, bool Before) override;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/CodeGen/MachineFunctionPass.h b/llvm/include/llvm/CodeGen/MachineFunctionPass.h
index caaf22c2139e31a..8d7e4192003d22a 100644
--- a/llvm/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/llvm/include/llvm/CodeGen/MachineFunctionPass.h
@@ -18,6 +18,7 @@
 #ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
 #define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
 
+#include "llvm/CodeGen/DroppedVariableStatsMIR.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/Pass.h"
 
@@ -67,6 +68,7 @@ class MachineFunctionPass : public FunctionPass {
   MachineFunctionProperties RequiredProperties;
   MachineFunctionProperties SetProperties;
   MachineFunctionProperties ClearedProperties;
+  DroppedVariableStatsMIR DroppedVarStatsMF;
 
   /// createPrinterPass - Get a machine function printer pass.
   Pass *createPrinterPass(raw_ostream &O,
diff --git a/llvm/include/llvm/Passes/DroppedVariableStats.h b/llvm/include/llvm/IR/DroppedVariableStats.h
similarity index 52%
rename from llvm/include/llvm/Passes/DroppedVariableStats.h
rename to llvm/include/llvm/IR/DroppedVariableStats.h
index 30fbeae703b03bc..ebd74a69a8b91d3 100644
--- a/llvm/include/llvm/Passes/DroppedVariableStats.h
+++ b/llvm/include/llvm/IR/DroppedVariableStats.h
@@ -14,13 +14,19 @@
 #ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
 #define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
 
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/PassInstrumentation.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <tuple>
 
 namespace llvm {
 
+class DIScope;
+class DILocalVariable;
+class Function;
+class DILocation;
+class DebugLoc;
+class StringRef;
+
 /// A unique key that represents a debug variable.
 /// First const DIScope *: Represents the scope of the debug variable.
 /// Second const DIScope *: Represents the InlinedAt scope of the debug
@@ -33,13 +39,7 @@ using VarID =
 /// statistics.
 class DroppedVariableStats {
 public:
-  DroppedVariableStats(bool DroppedVarStatsEnabled)
-      : DroppedVariableStatsEnabled(DroppedVarStatsEnabled) {
-    if (DroppedVarStatsEnabled)
-      llvm::outs()
-          << "Pass Level, Pass Name, Num of Dropped Variables, Func or "
-             "Module Name\n";
-  };
+  DroppedVariableStats(bool DroppedVarStatsEnabled);
 
   virtual ~DroppedVariableStats() {}
 
@@ -50,20 +50,9 @@ class DroppedVariableStats {
   bool getPassDroppedVariables() { return PassDroppedVariables; }
 
 protected:
-  void setup() {
-    DebugVariablesStack.push_back(
-        {DenseMap<const Function *, DebugVariables>()});
-    InlinedAts.push_back(
-        {DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});
-  }
-
-  void cleanup() {
-    assert(!DebugVariablesStack.empty() &&
-           "DebugVariablesStack shouldn't be empty!");
-    assert(!InlinedAts.empty() && "InlinedAts shouldn't be empty!");
-    DebugVariablesStack.pop_back();
-    InlinedAts.pop_back();
-  }
+  void setup();
+
+  void cleanup();
 
   bool DroppedVariableStatsEnabled = false;
   struct DebugVariables {
@@ -73,7 +62,6 @@ class DroppedVariableStats {
     DenseSet<VarID> DebugVariablesAfter;
   };
 
-protected:
   /// A stack of a DenseMap, that maps DebugVariables for every pass to an
   /// llvm::Function. A stack is used because an optimization pass can call
   /// other passes.
@@ -90,78 +78,27 @@ class DroppedVariableStats {
   void calculateDroppedStatsAndPrint(DebugVariables &DbgVariables,
                                      StringRef FuncName, StringRef PassID,
                                      StringRef FuncOrModName,
-                                     StringRef PassLevel,
-                                     const Function *Func) {
-    unsigned DroppedCount = 0;
-    DenseSet<VarID> &DebugVariablesBeforeSet =
-        DbgVariables.DebugVariablesBefore;
-    DenseSet<VarID> &DebugVariablesAfterSet = DbgVariables.DebugVariablesAfter;
-    auto It = InlinedAts.back().find(FuncName);
-    if (It == InlinedAts.back().end())
-      return;
-    DenseMap<VarID, DILocation *> &InlinedAtsMap = It->second;
-    // Find an Instruction that shares the same scope as the dropped #dbg_value
-    // or has a scope that is the child of the scope of the #dbg_value, and has
-    // an inlinedAt equal to the inlinedAt of the #dbg_value or it's inlinedAt
-    // chain contains the inlinedAt of the #dbg_value, if such an Instruction is
-    // found, debug information is dropped.
-    for (VarID Var : DebugVariablesBeforeSet) {
-      if (DebugVariablesAfterSet.contains(Var))
-        continue;
-      visitEveryInstruction(DroppedCount, InlinedAtsMap, Var);
-      removeVarFromAllSets(Var, Func);
-    }
-    if (DroppedCount > 0) {
-      llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount
-                   << ", " << FuncOrModName << "\n";
-      PassDroppedVariables = true;
-    } else
-      PassDroppedVariables = false;
-  }
+                                     StringRef PassLevel, const Function *Func);
 
   /// Check if a \p Var has been dropped or is a false positive. Also update the
   /// \p DroppedCount if a debug variable is dropped.
   bool updateDroppedCount(DILocation *DbgLoc, const DIScope *Scope,
                           const DIScope *DbgValScope,
                           DenseMap<VarID, DILocation *> &InlinedAtsMap,
-                          VarID Var, unsigned &DroppedCount) {
-    // If the Scope is a child of, or equal to the DbgValScope and is inlined at
-    // the Var's InlinedAt location, return true to signify that the Var has
-    // been dropped.
-    if (isScopeChildOfOrEqualTo(Scope, DbgValScope))
-      if (isInlinedAtChildOfOrEqualTo(DbgLoc->getInlinedAt(),
-                                      InlinedAtsMap[Var])) {
-        // Found another instruction in the variable's scope, so there exists a
-        // break point at which the variable could be observed. Count it as
-        // dropped.
-        DroppedCount++;
-        return true;
-      }
-    return false;
-  }
+                          VarID Var, unsigned &DroppedCount);
+
   /// Run code to populate relevant data structures over an llvm::Function or
   /// llvm::MachineFunction.
-  void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before) {
-    auto &VarIDSet = (Before ? DbgVariables.DebugVariablesBefore
-                             : DbgVariables.DebugVariablesAfter);
-    auto &InlinedAtsMap = InlinedAts.back();
-    if (Before)
-      InlinedAtsMap.try_emplace(FuncName, DenseMap<VarID, DILocation *>());
-    VarIDSet = DenseSet<VarID>();
-    visitEveryDebugRecord(VarIDSet, InlinedAtsMap, FuncName, Before);
-  }
+  void run(DebugVariables &DbgVariables, StringRef FuncName, bool Before);
+
   /// Populate the VarIDSet and InlinedAtMap with the relevant information
   /// needed for before and after pass analysis to determine dropped variable
   /// status.
   void populateVarIDSetAndInlinedMap(
       const DILocalVariable *DbgVar, DebugLoc DbgLoc, DenseSet<VarID> &VarIDSet,
       DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
-      StringRef FuncName, bool Before) {
-    VarID Key{DbgVar->getScope(), DbgLoc->getInlinedAtScope(), DbgVar};
-    VarIDSet.insert(Key);
-    if (Before)
-      InlinedAtsMap[FuncName].try_emplace(Key, DbgLoc.getInlinedAt());
-  }
+      StringRef FuncName, bool Before);
+
   /// Visit every llvm::Instruction or llvm::MachineInstruction and check if the
   /// debug variable denoted by its ID \p Var may have been dropped by an
   /// optimization pass.
@@ -179,47 +116,18 @@ class DroppedVariableStats {
 private:
   /// Remove a dropped debug variable's VarID from all Sets in the
   /// DroppedVariablesBefore stack.
-  void removeVarFromAllSets(VarID Var, const Function *F) {
-    // Do not remove Var from the last element, it will be popped from the
-    // stack.
-    for (auto &DebugVariablesMap : llvm::drop_end(DebugVariablesStack))
-      DebugVariablesMap[F].DebugVariablesBefore.erase(Var);
-  }
+  void removeVarFromAllSets(VarID Var, const Function *F);
+
   /// Return true if \p Scope is the same as \p DbgValScope or a child scope of
   /// \p DbgValScope, return false otherwise.
   bool isScopeChildOfOrEqualTo(const DIScope *Scope,
-                               const DIScope *DbgValScope) {
-    while (Scope != nullptr) {
-      if (VisitedScope.find(Scope) == VisitedScope.end()) {
-        VisitedScope.insert(Scope);
-        if (Scope == DbgValScope) {
-          VisitedScope.clear();
-          return true;
-        }
-        Scope = Scope->getScope();
-      } else {
-        VisitedScope.clear();
-        return false;
-      }
-    }
-    return false;
-  }
+                               const DIScope *DbgValScope);
+
   /// Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
   /// the InlinedAt chain, return false otherwise.
   bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
-                                   const DILocation *DbgValInlinedAt) {
-    if (DbgValInlinedAt == InlinedAt)
-      return true;
-    if (!DbgValInlinedAt)
-      return false;
-    auto *IA = InlinedAt;
-    while (IA) {
-      if (IA == DbgValInlinedAt)
-        return true;
-      IA = IA->getInlinedAt();
-    }
-    return false;
-  }
+                                   const DILocation *DbgValInlinedAt);
+
   bool PassDroppedVariables = false;
 };
 
diff --git a/llvm/include/llvm/Passes/DroppedVariableStatsIR.h b/llvm/include/llvm/Passes/DroppedVariableStatsIR.h
index 18847b5c1ead838..72b91dbc7ed5297 100644
--- a/llvm/include/llvm/Passes/DroppedVariableStatsIR.h
+++ b/llvm/include/llvm/Passes/DroppedVariableStatsIR.h
@@ -14,12 +14,17 @@
 #ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
 #define LLVM_CODEGEN_DROPPEDVARIABLESTATSIR_H
 
-#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Passes/DroppedVariableStats.h"
+#include "llvm/IR/DroppedVariableStats.h"
 
 namespace llvm {
 
+class Any;
+class StringRef;
+class PassInstrumentationCallbacks;
+class Function;
+class Module;
+class DILocation;
+
 /// A class to collect and print dropped debug information due to LLVM IR
 /// optimization passes. After every LLVM IR pass is run, it will print how many
 /// #dbg_values were dropped due to that pass.
@@ -28,56 +33,42 @@ class DroppedVariableStatsIR : public DroppedVariableStats {
   DroppedVariableStatsIR(bool DroppedVarStatsEnabled)
       : llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
 
-  void runBeforePass(StringRef P, Any IR) {
-    setup();
-    if (const auto *M = unwrapIR<Module>(IR))
-      return this->runOnModule(P, M, true);
-    if (const auto *F = unwrapIR<Function>(IR))
-      return this->runOnFunction(P, F, true);
-  }
-
-  void runAfterPass(StringRef P, Any IR) {
-    if (const auto *M = unwrapIR<Module>(IR))
-      runAfterPassModule(P, M);
-    else if (const auto *F = unwrapIR<Function>(IR))
-      runAfterPassFunction(P, F);
-    cleanup();
-  }
+  void runBeforePass(StringRef P, Any IR);
+
+  void runAfterPass(StringRef P, Any IR);
 
   void registerCallbacks(PassInstrumentationCallbacks &PIC);
 
 private:
   const Function *Func;
 
-  void runAfterPassFunction(StringRef PassID, const Function *F) {
-    runOnFunction(PassID, F, false);
-    calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(),
-                                       "Function");
-  }
+  void runAfterPassFunction(StringRef PassID, const Function *F);
+
+  void runAfterPassModule(StringRef PassID, const Module *M);
 
-  void runAfterPassModule(StringRef PassID, const Module *M) {
-    runOnModule(PassID, M, false);
-    calculateDroppedVarStatsOnModule(M, PassID, M->getName().str(), "Module");
-  }
   /// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
   /// after a pass has run to facilitate dropped variable calculation for an
   /// llvm::Function.
   void runOnFunction(StringRef PassID, const Function *F, bool Before);
+
   /// Iterate over all Instructions in a Function and report any dropped debug
   /// information.
   void calculateDroppedVarStatsOnFunction(const Function *F, StringRef PassID,
                                           StringRef FuncOrModName,
                                           StringRef PassLevel);
+
   /// Populate DebugVariablesBefore, DebugVariablesAfter, InlinedAts before or
   /// after a pass has run to facilitate dropped variable calculation for an
   /// llvm::Module. Calls runOnFunction on every Function in the Module.
   void runOnModule(StringRef PassID, const Module *M, bool Before);
+
   /// Iterate over all Functions in a Module and report any dropped debug
   /// information. Will call calculateDroppedVarStatsOnFunction on every
   /// Function.
   void calculateDroppedVarStatsOnModule(const Module *M, StringRef PassID,
                                         StringRef FuncOrModName,
                                         StringRef PassLevel);
+
   /// Override base class method to run on an llvm::Function specifically.
   virtual void
   visitEveryInstruction(unsigned &DroppedCount,
@@ -90,10 +81,7 @@ class DroppedVariableStatsIR : public DroppedVariableStats {
       DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
       StringRef FuncName, bool Before) override;
 
-  template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR) {
-    const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
-    return IRPtr ? *IRPtr : nullptr;
-  }
+  template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR);
 };
 
 } // namespace llvm
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 88f863d8204d092..23ec3310079d3e8 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMCodeGen
   DeadMachineInstructionElim.cpp
   DetectDeadLanes.cpp
   DFAPacketizer.cpp
+  DroppedVariableStatsMIR.cpp
   DwarfEHPrepare.cpp
   EarlyIfConversion.cpp
   EdgeBundles.cpp
diff --git a/llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp b/llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp
new file mode 100644
index 000000000000000..9a1d4fb5d888a60
--- /dev/null
+++ b/llvm/lib/CodeGen/DroppedVariableStatsMIR.cpp
@@ -0,0 +1,95 @@
+///===- DroppedVariableStatsMIR.cpp ---------------------------------------===//
+///
+/// Part of the LLVM Project, under the Apache License v2.0 with LLVM
+/// Exceptions. See https://llvm.org/LICENSE.txt for license information.
+/// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+///
+///===---------------------------------------------------------------------===//
+/// \file
+/// Dropped Variable Statistics for Debug Information. Reports any number
+/// of DBG_VALUEs that get dropped due to an optimization pass.
+///
+///===---------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/DroppedVariableStatsMIR.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+
+using namespace llvm;
+
+void DroppedVariableStatsMIR::runBeforePass(StringRef PassID,
+                                            MachineFunction *MF) {
+  if (PassID == "Debug Variable Analysis")
+    return;
+  setup();
+  return runOnMachineFunction(MF, true);
+}
+
+void DroppedVariableStatsMIR::runAfterPass(StringRef PassID,
+                                           MachineFunction *MF) {
+  if (PassID == "Debug Variable Analysis")
+    return;
+  runOnMachineFunction(MF, false);
+  calculateDroppedVarStatsOnMachineFunction(MF, PassID, MF->getName().str());
+  cleanup();
+}
+
+void DroppedVariableStatsMIR::runOnMachineFunction(const MachineFunction *MF,
+                                                   bool Before) {
+  auto &DebugVariables = DebugVariablesStack.back()[&MF->getFunction()];
+  auto FuncName = MF->getName();
+  MFunc = MF;
+  run(DebugVariables, FuncName, Before);
+}
+
+void DroppedVariableStatsMIR::calculateDroppedVarStatsOnMachineFunction(
+    const MachineFunction *MF, StringRef PassID, StringRef FuncOrModName) {
+  MFunc = MF;
+  StringRef FuncName = MF->getName();
+  const Function *Func = &MF->getFunction();
+  DebugVariables &DbgVariables = DebugVariablesStack.back()[Func];
+  calculateDroppedStatsAndPrint(DbgVariables, FuncName, PassID, FuncOrModName,
+                                "MachineFunction", Func);
+}
+
+void DroppedVariableStatsMIR::visitEveryInstruction(
+    unsigned &DroppedCount, DenseMap<VarID, DILocation *> &InlinedAtsMap,
+    VarID Var) {
+  unsigned PrevDroppedCount = DroppedCount;
+  const DIScope *DbgValScope = std::get<0>(Var);
+  for (const auto &MBB : *MFunc) {
+    for (const auto &MI : MBB) {
+      if (!MI.isDebugInstr()) {
+        auto *DbgLoc = MI.getDebugLoc().get();
+        if (!DbgLoc)
+          continue;
+
+        auto *Scope = DbgLoc->getScope();
+        if (updateDroppedCount(DbgLoc, Scope, DbgValScope, InlinedAtsMap, Var,
+                               DroppedCount))
+          break;
+      }
+    }
+    if (PrevDroppedCount != DroppedCount) {
+      PrevDroppedCount = DroppedCount;
+      break;
+    }
+  }
+}
+
+void DroppedVariableStatsMIR::visitEveryDebugRecord(
+    DenseSet<VarID> &VarIDSet,
+    DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
+    StringRef FuncName, bool Before) {
+  for (const auto &MBB : *MFunc) {
+    for (const auto &MI : MBB) {
+      if (MI.isDebugValueLike()) {
+        auto *DbgVar = MI.getDebugVariable();
+        if (!DbgVar)
+          continue;
+        auto DbgLoc = MI.getDebugLoc();
+        populateVarIDSetAndInlinedMap(DbgVar, DbgLoc, VarIDSet, I...
[truncated]

@rastogishubham
Copy link
Contributor Author

@nikic I measured the time to compile clang with and without this patch using time ninja clang and noticed no significant difference in compile time. Please let me know if this is unsatisfactory in any way.

Without patch:
ninja clang 5289.37s user 449.03s system 1252% cpu 7:38.06 total

With Patc:
ninja clang 5326.41s user 446.89s system 1270% cpu 7:34.38 total

@rastogishubham
Copy link
Contributor Author

@chapuni I hope the way the code is re-structured doesn't cause any issues like the previous patch did.

Copy link

github-actions bot commented Feb 11, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@chapuni
Copy link
Contributor

chapuni commented Feb 11, 2025

Looks reasonable, from layering side.

Also Rewrite DroppedVariableStats to reduce .h file size

The DroppedVariableStats.h file include pulls in a lot of code and leads
to a significant compilation slowdown if included in
MachineFunctionPass.h, which is needed to enable dropped variable
statistics for MIR.

This patch moves all the code to a DroppedVariableStats.cpp file and
replaces those expensive includes with forward declarations to resolve
the issue.
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto PassName = getPassName();
DroppedVarStatsMF.runBeforePass(PassName, &MF);
RV = runOnMachineFunction(MF);
DroppedVarStatsMF.runAfterPass(PassName, &MF);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this usage, why is it necessary to store DroppedVarStatsMF on the MachineFunction? Isn't it possible to instantiate it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, you are correct, that will work, thanks for the suggestion!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikic is the patch good to be upstreamed?

Copy link
Contributor

@chapuni chapuni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Please wait for @nikic's approval.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new patch addresses my concerns. I assume someone else has already reviewed the original patch in more detail.

@rastogishubham
Copy link
Contributor Author

rastogishubham commented Feb 12, 2025

The new patch addresses my concerns. I assume someone else has already reviewed the original patch in more detail.

Yes, it has already been reviewed earlier in detail, thank you!

This patch uses the DroppedVariableStats class to add dropped variable
statistics for MIR passes.

Reland 44de16f
@rastogishubham rastogishubham merged commit 92f916f into llvm:main Feb 12, 2025
4 of 6 checks passed
@rastogishubham rastogishubham deleted the MIRDroppedStats branch February 12, 2025 22:08
rastogishubham added a commit to rastogishubham/llvm-project that referenced this pull request Feb 13, 2025
This patch attempts to reland
llvm#120780 while addressing the
issues that caused the patch to be reverted.

Namely:

1. The patch had included code from the llvm/Passes directory in the
llvm/CodeGen directory.

2. The patch increased the backend compile time by 2% due to adding a
very expensive include in MachineFunctionPass.h

The patch has been re-structured so that there is no dependency between
the llvm/Passes and llvm/CodeGen directory, by moving the base class,
`class DroppedVariableStats` to the llvm/IR directory.

The expensive include in MachineFunctionPass.h has been changed to
contain forward declarations instead of other header includes which was
pulling a ton of code into MachineFunctionPass.h and should resolve any
issues when it comes to compile time increase.

(cherry picked from commit 92f916f)
@llvm-ci
Copy link
Collaborator

llvm-ci commented Feb 13, 2025

LLVM Buildbot has detected a new failure on builder lld-x86_64-win running on as-worker-93 while building llvm at step 7 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/146/builds/2281

Here is the relevant piece of the build log for the reference
Step 7 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM-Unit :: Support/./SupportTests.exe/38/87' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe-LLVM-Unit-6192-38-87.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=87 GTEST_SHARD_INDEX=38 C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe
--

Script:
--
C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe --gtest_filter=ProgramEnvTest.CreateProcessLongPath
--
C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp(160): error: Expected equality of these values:
  0
  RC
    Which is: -2

C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp(163): error: fs::remove(Twine(LongPath)): did not return errc::success.
error number: 13
error message: permission denied



C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp:160
Expected equality of these values:
  0
  RC
    Which is: -2

C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp:163
fs::remove(Twine(LongPath)): did not return errc::success.
error number: 13
error message: permission denied




********************


flovent pushed a commit to flovent/llvm-project that referenced this pull request Feb 13, 2025
This patch attempts to reland
llvm#120780 while addressing the
issues that caused the patch to be reverted.

Namely:

1. The patch had included code from the llvm/Passes directory in the
llvm/CodeGen directory.

2. The patch increased the backend compile time by 2% due to adding a
very expensive include in MachineFunctionPass.h

The patch has been re-structured so that there is no dependency between
the llvm/Passes and llvm/CodeGen directory, by moving the base class,
`class DroppedVariableStats` to the llvm/IR directory.

The expensive include in MachineFunctionPass.h has been changed to
contain forward declarations instead of other header includes which was
pulling a ton of code into MachineFunctionPass.h and should resolve any
issues when it comes to compile time increase.
joaosaffran pushed a commit to joaosaffran/llvm-project that referenced this pull request Feb 14, 2025
This patch attempts to reland
llvm#120780 while addressing the
issues that caused the patch to be reverted.

Namely:

1. The patch had included code from the llvm/Passes directory in the
llvm/CodeGen directory.

2. The patch increased the backend compile time by 2% due to adding a
very expensive include in MachineFunctionPass.h

The patch has been re-structured so that there is no dependency between
the llvm/Passes and llvm/CodeGen directory, by moving the base class,
`class DroppedVariableStats` to the llvm/IR directory.

The expensive include in MachineFunctionPass.h has been changed to
contain forward declarations instead of other header includes which was
pulling a ton of code into MachineFunctionPass.h and should resolve any
issues when it comes to compile time increase.
sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Feb 24, 2025
This patch attempts to reland
llvm#120780 while addressing the
issues that caused the patch to be reverted.

Namely:

1. The patch had included code from the llvm/Passes directory in the
llvm/CodeGen directory.

2. The patch increased the backend compile time by 2% due to adding a
very expensive include in MachineFunctionPass.h

The patch has been re-structured so that there is no dependency between
the llvm/Passes and llvm/CodeGen directory, by moving the base class,
`class DroppedVariableStats` to the llvm/IR directory.

The expensive include in MachineFunctionPass.h has been changed to
contain forward declarations instead of other header includes which was
pulling a ton of code into MachineFunctionPass.h and should resolve any
issues when it comes to compile time increase.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants