From 8c878ada4e1df8b37aea9ff44a5fb2b25d2b2a1f Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Fri, 28 Aug 2026 13:58:47 +0800 Subject: [CodeGen] Separate pass instrumentation ownership --- .../rcc/CodeGen/MachinePassInstrumentation.h | 153 ++++++++++++++ backend/include/rcc/CodeGen/MachinePassManager.h | 2 +- backend/include/rcc/IR/PassInstrumentation.h | 219 ++++++++------------- 3 files changed, 238 insertions(+), 136 deletions(-) create mode 100644 backend/include/rcc/CodeGen/MachinePassInstrumentation.h (limited to 'backend/include') diff --git a/backend/include/rcc/CodeGen/MachinePassInstrumentation.h b/backend/include/rcc/CodeGen/MachinePassInstrumentation.h new file mode 100644 index 0000000..9cc5098 --- /dev/null +++ b/backend/include/rcc/CodeGen/MachinePassInstrumentation.h @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_MACHINEPASSINSTRUMENTATION_H +#define RCC_CODEGEN_MACHINEPASSINSTRUMENTATION_H + +#include "rcc/CodeGen/MachineFunctionAnalysisManager.h" +#include "rcc/IR/PassInstrumentation.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class CompilationUnit; +class MachineFunction; +struct MachinePassResult; +struct CompilationUnitPassResult; + +struct InstrumentationStatistic final { + std::string Name; + bool IsAnalysis = false; + std::uint64_t Invocations = 0; + std::uint64_t CacheHits = 0; + std::uint64_t Changes = 0; + std::uint64_t Failures = 0; + std::uint64_t TotalNanoseconds = 0; +}; + +struct MachineActionID final { + std::string Pass; + std::string Rule; + MachineFunctionStableID Function; + MachineInstrStableID Instruction; + + [[nodiscard]] std::string toString() const; + + friend bool operator==(const MachineActionID &, const MachineActionID &) = default; +}; + +struct MachineActionEvent final { + MachineActionID ID; + std::uint64_t Cost = 0; + bool Accepted = false; + + friend bool operator==(const MachineActionEvent &, const MachineActionEvent &) = default; +}; + +class MachinePassInstrumentation final { + using FunctionCallbackRegistry = PassInstrumentationCallbacks; + using UnitCallbackRegistry = + PassInstrumentationCallbacks; + +public: + using BeforeCallback = FunctionCallbackRegistry::BeforeCallback; + using AfterCallback = FunctionCallbackRegistry::AfterCallback; + using FailureCallback = FunctionCallbackRegistry::FailureCallback; + using BeforeAnalysisCallback = FunctionCallbackRegistry::BeforeAnalysisCallback; + using AfterAnalysisCallback = FunctionCallbackRegistry::AfterAnalysisCallback; + using AnalysisFailureCallback = FunctionCallbackRegistry::AnalysisFailureCallback; + using IRPrintCallback = + std::function; + using ChangeCallback = + std::function; + using ActionFilter = std::function; + + using BeforeUnitCallback = UnitCallbackRegistry::BeforeCallback; + using AfterUnitCallback = UnitCallbackRegistry::AfterCallback; + using UnitFailureCallback = UnitCallbackRegistry::FailureCallback; + using BeforeUnitAnalysisCallback = UnitCallbackRegistry::BeforeAnalysisCallback; + using AfterUnitAnalysisCallback = UnitCallbackRegistry::AfterAnalysisCallback; + using UnitAnalysisFailureCallback = UnitCallbackRegistry::AnalysisFailureCallback; + + void addBeforeCallback(BeforeCallback Callback); + void addAfterCallback(AfterCallback Callback); + void addFailureCallback(FailureCallback Callback); + void addBeforeAnalysisCallback(BeforeAnalysisCallback Callback); + void addAfterAnalysisCallback(AfterAnalysisCallback Callback); + void addAnalysisFailureCallback(AnalysisFailureCallback Callback); + void addIRPrintCallback(IRPrintCallback Callback); + void addChangeCallback(ChangeCallback Callback); + void setActionFilter(ActionFilter Filter); + void setPerFunctionFuel(std::optional Fuel); + + void addBeforeUnitCallback(BeforeUnitCallback Callback); + void addAfterUnitCallback(AfterUnitCallback Callback); + void addUnitFailureCallback(UnitFailureCallback Callback); + void addBeforeUnitAnalysisCallback(BeforeUnitAnalysisCallback Callback); + void addAfterUnitAnalysisCallback(AfterUnitAnalysisCallback Callback); + void addUnitAnalysisFailureCallback(UnitAnalysisFailureCallback Callback); + + [[nodiscard]] std::vector statistics() const; + [[nodiscard]] std::vector actionEvents() const; + [[nodiscard]] bool requiresSerialFunctionExecution() const; + + [[nodiscard]] Expected requestAction(std::string_view Pass, std::string_view Rule, + const MachineFunction &Function, + MachineInstrStableID Instruction, std::uint64_t Cost); + [[nodiscard]] Expected requestAction(std::string_view Pass, std::string_view Rule, + const MachineFunction &Function, std::nullptr_t, + std::uint64_t Cost); + +private: + void before(std::string_view Name, const MachineFunction &Function) const; + void after(std::string_view Name, const MachineFunction &Function, + const MachinePassResult &Result, std::uint64_t Nanoseconds) const; + void failure(std::string_view Name, const MachineFunction &Function, const Error &ErrorValue, + std::uint64_t Nanoseconds = 0) const; + void beforeAnalysis(std::string_view Name, const MachineFunction &Function) const; + void afterAnalysis(std::string_view Name, const MachineFunction &Function, bool CacheHit, + std::uint64_t Nanoseconds) const; + void analysisFailure(std::string_view Name, const MachineFunction &Function, + const Error &ErrorValue, std::uint64_t Nanoseconds) const; + void change(std::string_view Name, const MachineFunction &Function, MachinePassChanges Changes, + bool FingerprintChanged) const; + + void beforeUnit(std::string_view Name, const CompilationUnit &Unit) const; + void afterUnit(std::string_view Name, const CompilationUnit &Unit, + const CompilationUnitPassResult &Result, std::uint64_t Nanoseconds) const; + void unitFailure(std::string_view Name, const CompilationUnit &Unit, const Error &ErrorValue, + std::uint64_t Nanoseconds = 0) const; + void beforeAnalysis(std::string_view Name, const CompilationUnit &Unit) const; + void afterAnalysis(std::string_view Name, const CompilationUnit &Unit, bool CacheHit, + std::uint64_t Nanoseconds) const; + void analysisFailure(std::string_view Name, const CompilationUnit &Unit, const Error &ErrorValue, + std::uint64_t Nanoseconds) const; + + [[nodiscard]] InstrumentationStatistic &statistic(std::string_view Name, bool IsAnalysis) const; + + FunctionCallbackRegistry FunctionCallbacks; + UnitCallbackRegistry UnitCallbacks; + mutable std::mutex Mutex; + mutable std::mutex ActionMutex; + std::vector IRPrint; + std::vector Change; + ActionFilter Filter; + std::optional PerFunctionFuel; + std::unordered_map ConsumedFuel; + std::vector ActionEvents; + mutable std::unordered_map Statistics; + + template friend struct AnalysisManagerInstrumentation; + template friend struct PassManagerCallbacks; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_MACHINEPASSINSTRUMENTATION_H diff --git a/backend/include/rcc/CodeGen/MachinePassManager.h b/backend/include/rcc/CodeGen/MachinePassManager.h index 3587395..af7a5d3 100644 --- a/backend/include/rcc/CodeGen/MachinePassManager.h +++ b/backend/include/rcc/CodeGen/MachinePassManager.h @@ -6,7 +6,7 @@ #include "rcc/CodeGen/InstructionDescriptor.h" #include "rcc/CodeGen/MachineFunctionAnalysisManager.h" #include "rcc/CodeGen/MachineFunctionProperties.h" -#include "rcc/IR/PassInstrumentation.h" +#include "rcc/CodeGen/MachinePassInstrumentation.h" #include #include diff --git a/backend/include/rcc/IR/PassInstrumentation.h b/backend/include/rcc/IR/PassInstrumentation.h index 8ba2d2e..b0a673a 100644 --- a/backend/include/rcc/IR/PassInstrumentation.h +++ b/backend/include/rcc/IR/PassInstrumentation.h @@ -3,168 +3,117 @@ #ifndef RCC_IR_PASSINSTRUMENTATION_H #define RCC_IR_PASSINSTRUMENTATION_H -#include "rcc/CodeGen/MachineFunctionAnalysisManager.h" +#include "rcc/Support/Error.h" #include #include #include -#include -#include #include -#include +#include #include namespace rcc { -class CompilationUnit; -class MachineFunction; -struct MachinePassResult; -struct CompilationUnitPassResult; - enum class InstrumentationPhase : std::uint8_t { Before, After, }; -struct InstrumentationStatistic final { - std::string Name; - bool IsAnalysis = false; - std::uint64_t Invocations = 0; - std::uint64_t CacheHits = 0; - std::uint64_t Changes = 0; - std::uint64_t Failures = 0; - std::uint64_t TotalNanoseconds = 0; -}; - -struct MachineActionID final { - std::string Pass; - std::string Rule; - MachineFunctionStableID Function; - MachineInstrStableID Instruction; - - [[nodiscard]] std::string toString() const; - - friend bool operator==(const MachineActionID &, const MachineActionID &) = default; -}; - -struct MachineActionEvent final { - MachineActionID ID; - std::uint64_t Cost = 0; - bool Accepted = false; - - friend bool operator==(const MachineActionEvent &, const MachineActionEvent &) = default; -}; - -class MachinePassInstrumentation final { +template class PassInstrumentationCallbacks final { public: - using BeforeCallback = std::function; - using AfterCallback = - std::function; - using FailureCallback = - std::function; - using BeforeAnalysisCallback = std::function; + using BeforeCallback = std::function; + using AfterCallback = std::function; + using FailureCallback = std::function; + using BeforeAnalysisCallback = std::function; using AfterAnalysisCallback = - std::function; + std::function; using AnalysisFailureCallback = - std::function; - using IRPrintCallback = - std::function; - using ChangeCallback = - std::function; - using ActionFilter = std::function; - - using BeforeUnitCallback = std::function; - using AfterUnitCallback = std::function; - using UnitFailureCallback = - std::function; - using BeforeUnitAnalysisCallback = std::function; - using AfterUnitAnalysisCallback = - std::function; - using UnitAnalysisFailureCallback = - std::function; - - void addBeforeCallback(BeforeCallback Callback); - void addAfterCallback(AfterCallback Callback); - void addFailureCallback(FailureCallback Callback); - void addBeforeAnalysisCallback(BeforeAnalysisCallback Callback); - void addAfterAnalysisCallback(AfterAnalysisCallback Callback); - void addAnalysisFailureCallback(AnalysisFailureCallback Callback); - void addIRPrintCallback(IRPrintCallback Callback); - void addChangeCallback(ChangeCallback Callback); - void setActionFilter(ActionFilter Filter); - void setPerFunctionFuel(std::optional Fuel); - - void addBeforeUnitCallback(BeforeUnitCallback Callback); - void addAfterUnitCallback(AfterUnitCallback Callback); - void addUnitFailureCallback(UnitFailureCallback Callback); - void addBeforeUnitAnalysisCallback(BeforeUnitAnalysisCallback Callback); - void addAfterUnitAnalysisCallback(AfterUnitAnalysisCallback Callback); - void addUnitAnalysisFailureCallback(UnitAnalysisFailureCallback Callback); - - [[nodiscard]] std::vector statistics() const; - [[nodiscard]] std::vector actionEvents() const; - [[nodiscard]] bool requiresSerialFunctionExecution() const; - - [[nodiscard]] Expected requestAction(std::string_view Pass, std::string_view Rule, - const MachineFunction &Function, - MachineInstrStableID Instruction, std::uint64_t Cost); - [[nodiscard]] Expected requestAction(std::string_view Pass, std::string_view Rule, - const MachineFunction &Function, std::nullptr_t, - std::uint64_t Cost); + std::function; + + void addBeforeCallback(BeforeCallback Callback) { + addCallback(Before, std::move(Callback)); + } + + void addAfterCallback(AfterCallback Callback) { + addCallback(After, std::move(Callback)); + } + + void addFailureCallback(FailureCallback Callback) { + addCallback(Failure, std::move(Callback)); + } + + void addBeforeAnalysisCallback(BeforeAnalysisCallback Callback) { + addCallback(BeforeAnalysis, std::move(Callback)); + } + + void addAfterAnalysisCallback(AfterAnalysisCallback Callback) { + addCallback(AfterAnalysis, std::move(Callback)); + } + + void addAnalysisFailureCallback(AnalysisFailureCallback Callback) { + addCallback(AnalysisFailure, std::move(Callback)); + } + + void runBefore(std::string_view Name, const IRUnitT &Unit) const { + for (const BeforeCallback &Callback : snapshot(Before)) + Callback(Name, Unit); + } + + void runAfter(std::string_view Name, const IRUnitT &Unit, const PassResultT &Result) const { + for (const AfterCallback &Callback : snapshot(After)) + Callback(Name, Unit, Result); + } + + void runFailure(std::string_view Name, const IRUnitT &Unit, const Error &FailureValue) const { + for (const FailureCallback &Callback : snapshot(Failure)) + Callback(Name, Unit, FailureValue); + } + + void runBeforeAnalysis(std::string_view Name, const IRUnitT &Unit) const { + for (const BeforeAnalysisCallback &Callback : snapshot(BeforeAnalysis)) + Callback(Name, Unit); + } + + void runAfterAnalysis(std::string_view Name, const IRUnitT &Unit, bool CacheHit, + std::uint64_t Nanoseconds) const { + for (const AfterAnalysisCallback &Callback : snapshot(AfterAnalysis)) + Callback(Name, Unit, CacheHit, Nanoseconds); + } + + void runAnalysisFailure(std::string_view Name, const IRUnitT &Unit, + const Error &FailureValue) const { + for (const AnalysisFailureCallback &Callback : snapshot(AnalysisFailure)) + Callback(Name, Unit, FailureValue); + } + + [[nodiscard]] bool empty() const { + std::scoped_lock Lock(Mutex); + return Before.empty() && After.empty() && Failure.empty() && BeforeAnalysis.empty() && + AfterAnalysis.empty() && AnalysisFailure.empty(); + } private: - void before(std::string_view Name, const MachineFunction &Function) const; - void after(std::string_view Name, const MachineFunction &Function, - const MachinePassResult &Result, std::uint64_t Nanoseconds) const; - void failure(std::string_view Name, const MachineFunction &Function, const Error &ErrorValue, - std::uint64_t Nanoseconds = 0) const; - void beforeAnalysis(std::string_view Name, const MachineFunction &Function) const; - void afterAnalysis(std::string_view Name, const MachineFunction &Function, bool CacheHit, - std::uint64_t Nanoseconds) const; - void analysisFailure(std::string_view Name, const MachineFunction &Function, - const Error &ErrorValue, std::uint64_t Nanoseconds) const; - void change(std::string_view Name, const MachineFunction &Function, MachinePassChanges Changes, - bool FingerprintChanged) const; - - void beforeUnit(std::string_view Name, const CompilationUnit &Unit) const; - void afterUnit(std::string_view Name, const CompilationUnit &Unit, - const CompilationUnitPassResult &Result, std::uint64_t Nanoseconds) const; - void unitFailure(std::string_view Name, const CompilationUnit &Unit, const Error &ErrorValue, - std::uint64_t Nanoseconds = 0) const; - void beforeAnalysis(std::string_view Name, const CompilationUnit &Unit) const; - void afterAnalysis(std::string_view Name, const CompilationUnit &Unit, bool CacheHit, - std::uint64_t Nanoseconds) const; - void analysisFailure(std::string_view Name, const CompilationUnit &Unit, const Error &ErrorValue, - std::uint64_t Nanoseconds) const; - - [[nodiscard]] InstrumentationStatistic &statistic(std::string_view Name, bool IsAnalysis) const; + template + void addCallback(std::vector &Callbacks, CallbackT Callback) { + if (!Callback) + return; + std::scoped_lock Lock(Mutex); + Callbacks.push_back(std::move(Callback)); + } + + template + [[nodiscard]] std::vector snapshot(const std::vector &Callbacks) const { + std::scoped_lock Lock(Mutex); + return Callbacks; + } mutable std::mutex Mutex; - mutable std::mutex ActionMutex; std::vector Before; std::vector After; std::vector Failure; std::vector BeforeAnalysis; std::vector AfterAnalysis; std::vector AnalysisFailure; - std::vector IRPrint; - std::vector Change; - ActionFilter Filter; - std::optional PerFunctionFuel; - std::unordered_map ConsumedFuel; - std::vector ActionEvents; - - std::vector BeforeUnit; - std::vector AfterUnit; - std::vector UnitFailure; - std::vector BeforeUnitAnalysis; - std::vector AfterUnitAnalysis; - std::vector UnitAnalysisFailure; - mutable std::unordered_map Statistics; - - template friend struct AnalysisManagerInstrumentation; - template friend struct PassManagerCallbacks; }; } // namespace rcc -- cgit v1.2.3