[llvm] Add a pass to collect dropped var stats for MIR. (PR #115566)
Orlando Cazalet-Hyams via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 15 01:53:38 PST 2024
================
@@ -0,0 +1,199 @@
+///===- DroppedVariableStats.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 or DBG_VALUEs that get dropped due to an optimization pass.
+///
+///===---------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
+#define LLVM_CODEGEN_DROPPEDVARIABLESTATS_H
+
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassInstrumentation.h"
+
+namespace llvm {
+
+/// A unique key that represents a #dbg_value.
+using VarID =
+ std::tuple<const DIScope *, const DIScope *, const DILocalVariable *>;
+
+/// A base class to collect and print dropped debug information variable
+/// 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";
+ };
+ // We intend this to be unique per-compilation, thus no copies.
+ DroppedVariableStats(const DroppedVariableStats &) = delete;
+ void operator=(const DroppedVariableStats &) = delete;
+
+ bool getPassDroppedVariables() { return PassDroppedVariables; }
+
+protected:
+ void setup() {
+ DebugVariablesStack.push_back(
+ {DenseMap<const Function *, DebugVariables>()});
+ InlinedAts.push_back(
+ {DenseMap<StringRef, DenseMap<VarID, DILocation *>>()});
+ return;
+ }
+
+ void cleanup() {
+ DebugVariablesStack.pop_back();
+ InlinedAts.pop_back();
+ return;
+ }
+
+ bool PassDroppedVariables = false;
+ bool DroppedVariableStatsEnabled = false;
+
+ struct DebugVariables {
+ /// DenseSet of VarIDs before an optimization pass has run.
+ DenseSet<VarID> DebugVariablesBefore;
+ /// DenseSet of VarIDs after an optimization pass has run.
+ DenseSet<VarID> DebugVariablesAfter;
+ };
+
+ /// 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.
+ SmallVector<DenseMap<const Function *, DebugVariables>> DebugVariablesStack;
+
+ /// A DenseSet tracking whether a scope was visited before.
+ DenseSet<const DIScope *> VisitedScope;
+ /// A stack of DenseMaps, which map the name of an llvm::Function to a
+ /// DenseMap of VarIDs and their inlinedAt locations before an optimization
+ /// pass has run.
+ SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>> InlinedAts;
+ /// Remove a dropped #dbg_value 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);
+ }
+ /// Return true if \p Scope is the same as \p DbgValScope or a child scope of
+ /// \p DbgValScope, return false otherwise.
+ bool isScopeChildOfOrEqualTo(DIScope *Scope, 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);
+};
+
+/// 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.
+class DroppedVariableStatsIR : public DroppedVariableStats {
+public:
+ DroppedVariableStatsIR(bool DroppedVarStatsEnabled)
+ : llvm::DroppedVariableStats(DroppedVarStatsEnabled) {}
+
+ void runBeforePass(Any IR) {
+ setup();
+ if (const auto *M = unwrapIR<Module>(IR))
+ return this->runOnModule(M, true);
+ if (const auto *F = unwrapIR<Function>(IR))
+ return this->runOnFunction(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);
+ return cleanup();
+ }
+
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+ void runAfterPassFunction(StringRef PassID, const Function *F) {
+ runOnFunction(F, false);
+ calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(),
+ "Function");
+ }
+
+ void runAfterPassModule(StringRef PassID, const Module *M) {
+ runOnModule(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(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,
+ std::string FuncOrModName,
+ std::string 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(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,
+ std::string FuncOrModName,
+ std::string PassLevel);
+
+ template <typename IRUnitT> static const IRUnitT *unwrapIR(Any IR) {
+ const IRUnitT **IRPtr = llvm::any_cast<const IRUnitT *>(&IR);
+ return IRPtr ? *IRPtr : nullptr;
+ }
+};
+
+/// 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.
----------------
OCHyams wrote:
this typo still seems to exist? (maybe the change got lost in a force push?)
https://github.com/llvm/llvm-project/pull/115566
More information about the llvm-commits
mailing list