aboutsummaryrefslogtreecommitdiff
path: root/backend/include
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include')
-rw-r--r--backend/include/rcc/CodeGen/GlobalISel/InstructionSelect.h4
-rw-r--r--backend/include/rcc/CodeGen/GlobalISel/Legalizer.h4
-rw-r--r--backend/include/rcc/CodeGen/GlobalISel/RegBankSelect.h4
-rw-r--r--backend/include/rcc/CodeGen/LiveIntervals.h7
-rw-r--r--backend/include/rcc/CodeGen/LiveVariables.h12
-rw-r--r--backend/include/rcc/CodeGen/MachineAnalyses.h35
-rw-r--r--backend/include/rcc/CodeGen/MachineBlockPlacement.h11
-rw-r--r--backend/include/rcc/CodeGen/MachineBranchOptimization.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineBranchRelaxation.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineCSE.h10
-rw-r--r--backend/include/rcc/CodeGen/MachineCombiner.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineCopyPropagation.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineDCE.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineFallthrough.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineFinalization.h6
-rw-r--r--backend/include/rcc/CodeGen/MachineFunctionAnalysisManager.h133
-rw-r--r--backend/include/rcc/CodeGen/MachineLICM.h10
-rw-r--r--backend/include/rcc/CodeGen/MachineMemoryFolding.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineOptimizationPipeline.h11
-rw-r--r--backend/include/rcc/CodeGen/MachinePass.h720
-rw-r--r--backend/include/rcc/CodeGen/MachinePassManager.h134
-rw-r--r--backend/include/rcc/CodeGen/MachinePseudoExpansion.h10
-rw-r--r--backend/include/rcc/CodeGen/MachineScheduler.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineShrinkWrapping.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineSink.h8
-rw-r--r--backend/include/rcc/CodeGen/MachineStackSlotColoring.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineTailDuplication.h4
-rw-r--r--backend/include/rcc/CodeGen/MachineTailMerge.h4
-rw-r--r--backend/include/rcc/CodeGen/PHIElimination.h4
-rw-r--r--backend/include/rcc/CodeGen/PostRAScheduler.h4
-rw-r--r--backend/include/rcc/CodeGen/PrologueEpilogueInsertion.h4
-rw-r--r--backend/include/rcc/CodeGen/RegAllocCommon.h2
-rw-r--r--backend/include/rcc/CodeGen/RegAllocFast.h4
-rw-r--r--backend/include/rcc/CodeGen/RegAllocPBQP.h2
-rw-r--r--backend/include/rcc/CodeGen/SlotIndexes.h7
-rw-r--r--backend/include/rcc/CodeGen/TwoAddressInstructionPass.h4
-rw-r--r--backend/include/rcc/CodeGen/VirtRegMap.h4
-rw-r--r--backend/include/rcc/IR/PassInstrumentation.h227
-rw-r--r--backend/include/rcc/IR/PassManager.h531
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVPipeline.h4
-rw-r--r--backend/include/rcc/Tooling/BackendDriver.h2
-rw-r--r--backend/include/rcc/Tooling/PipelineDriver.h2
42 files changed, 1142 insertions, 826 deletions
diff --git a/backend/include/rcc/CodeGen/GlobalISel/InstructionSelect.h b/backend/include/rcc/CodeGen/GlobalISel/InstructionSelect.h
index 0c034cd..f342cdc 100644
--- a/backend/include/rcc/CodeGen/GlobalISel/InstructionSelect.h
+++ b/backend/include/rcc/CodeGen/GlobalISel/InstructionSelect.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_GLOBALISEL_INSTRUCTIONSELECT_H
#include "rcc/CodeGen/GlobalISel/InstructionSelector.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -16,7 +16,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h b/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h
index 7f86d16..dfeda22 100644
--- a/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h
+++ b/backend/include/rcc/CodeGen/GlobalISel/Legalizer.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_GLOBALISEL_LEGALIZER_H
#include "rcc/CodeGen/GlobalISel/LegalizerInfo.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <memory>
@@ -20,7 +20,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/GlobalISel/RegBankSelect.h b/backend/include/rcc/CodeGen/GlobalISel/RegBankSelect.h
index 256d748..a7fc6bf 100644
--- a/backend/include/rcc/CodeGen/GlobalISel/RegBankSelect.h
+++ b/backend/include/rcc/CodeGen/GlobalISel/RegBankSelect.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_GLOBALISEL_REGBANKSELECT_H
#define RCC_CODEGEN_GLOBALISEL_REGBANKSELECT_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/RegisterBankInfo.h"
namespace rcc {
@@ -16,7 +16,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const RegisterBankInfo *Info;
diff --git a/backend/include/rcc/CodeGen/LiveIntervals.h b/backend/include/rcc/CodeGen/LiveIntervals.h
index a45c593..b5ba05a 100644
--- a/backend/include/rcc/CodeGen/LiveIntervals.h
+++ b/backend/include/rcc/CodeGen/LiveIntervals.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_LIVEINTERVALS_H
#include "rcc/CodeGen/LiveInterval.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/RegisterMask.h"
#include <cstdint>
@@ -64,8 +64,9 @@ public:
return "LiveIntervals";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
} // namespace rcc
diff --git a/backend/include/rcc/CodeGen/LiveVariables.h b/backend/include/rcc/CodeGen/LiveVariables.h
index 28a66c1..c95e7d8 100644
--- a/backend/include/rcc/CodeGen/LiveVariables.h
+++ b/backend/include/rcc/CodeGen/LiveVariables.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_LIVEVARIABLES_H
#include "rcc/CodeGen/LiveRegUnits.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/Register.h"
#include "rcc/Support/Error.h"
@@ -82,8 +82,9 @@ public:
return "LiveVariables";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
class RebuildMachineLivenessPass final : public MachineFunctionPass {
@@ -91,14 +92,15 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
};
[[nodiscard]] Expected<void> verifyTrackedMachineLiveness(const MachineFunction &Function,
const TargetDescription &Target);
[[nodiscard]] Expected<bool> rebuildMachineLiveness(MachineFunction &Function,
const TargetDescription &Target);
-[[nodiscard]] Expected<void> registerStage11MachineAnalyses(MachineAnalysisManager &Analyses);
+[[nodiscard]] Expected<void>
+registerStage11MachineAnalyses(MachineFunctionAnalysisManager &Analyses);
} // namespace rcc
diff --git a/backend/include/rcc/CodeGen/MachineAnalyses.h b/backend/include/rcc/CodeGen/MachineAnalyses.h
index eda550d..4adb300 100644
--- a/backend/include/rcc/CodeGen/MachineAnalyses.h
+++ b/backend/include/rcc/CodeGen/MachineAnalyses.h
@@ -5,7 +5,7 @@
#include "rcc/CodeGen/MachineBasicBlock.h"
#include "rcc/CodeGen/MachineIRTypes.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/StableID.h"
#include "rcc/Support/Error.h"
@@ -62,8 +62,9 @@ public:
return "MachineDominatorTree";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
struct MachineLoop final {
@@ -107,8 +108,9 @@ public:
return "MachineLoopInfo";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
class MachineBranchProbabilityAnalysis final {
@@ -130,8 +132,9 @@ public:
return "MachineBranchProbability";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
class MachineBlockFrequencyAnalysis final {
@@ -152,8 +155,9 @@ public:
return "MachineBlockFrequency";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
enum class MachineAliasResult : std::uint8_t {
@@ -175,8 +179,9 @@ public:
return "MachineAliasAnalysis";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
enum class MachineMemoryDependencyKind : std::uint8_t {
@@ -233,11 +238,13 @@ public:
return "MachineMemoryDependence";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
-[[nodiscard]] Expected<void> registerStage8MachineAnalyses(MachineAnalysisManager &Analyses);
+[[nodiscard]] Expected<void>
+registerStage8MachineAnalyses(MachineFunctionAnalysisManager &Analyses);
} // namespace rcc
diff --git a/backend/include/rcc/CodeGen/MachineBlockPlacement.h b/backend/include/rcc/CodeGen/MachineBlockPlacement.h
index 52ddafd..41d5f2d 100644
--- a/backend/include/rcc/CodeGen/MachineBlockPlacement.h
+++ b/backend/include/rcc/CodeGen/MachineBlockPlacement.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEBLOCKPLACEMENT_H
#define RCC_CODEGEN_MACHINEBLOCKPLACEMENT_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -12,13 +12,12 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
- [[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
- const TargetDescription &Target,
- MachineAnalysisManager &Analyses,
- MachineActionReplay &Actions) const;
+ [[nodiscard]] Expected<MachinePassResult>
+ runImplementation(MachineFunction &Function, const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses, MachineActionReplay &Actions) const;
};
} // namespace rcc
diff --git a/backend/include/rcc/CodeGen/MachineBranchOptimization.h b/backend/include/rcc/CodeGen/MachineBranchOptimization.h
index 9f120dc..e578d72 100644
--- a/backend/include/rcc/CodeGen/MachineBranchOptimization.h
+++ b/backend/include/rcc/CodeGen/MachineBranchOptimization.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEBRANCHOPTIMIZATION_H
#define RCC_CODEGEN_MACHINEBRANCHOPTIMIZATION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -24,7 +24,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult>
diff --git a/backend/include/rcc/CodeGen/MachineBranchRelaxation.h b/backend/include/rcc/CodeGen/MachineBranchRelaxation.h
index 03c7fa7..5b359b4 100644
--- a/backend/include/rcc/CodeGen/MachineBranchRelaxation.h
+++ b/backend/include/rcc/CodeGen/MachineBranchRelaxation.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEBRANCHRELAXATION_H
#define RCC_CODEGEN_MACHINEBRANCHRELAXATION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -24,7 +24,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/MachineCSE.h b/backend/include/rcc/CodeGen/MachineCSE.h
index 1c2057b..dc10b62 100644
--- a/backend/include/rcc/CodeGen/MachineCSE.h
+++ b/backend/include/rcc/CodeGen/MachineCSE.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINECSE_H
#define RCC_CODEGEN_MACHINECSE_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -20,12 +20,12 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
- [[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
- const TargetDescription &Target,
- MachineAnalysisManager &Analyses);
+ [[nodiscard]] Expected<MachinePassResult>
+ runImplementation(MachineFunction &Function, const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
MachineCSEOptions Options;
};
diff --git a/backend/include/rcc/CodeGen/MachineCombiner.h b/backend/include/rcc/CodeGen/MachineCombiner.h
index ef7f432..3850b91 100644
--- a/backend/include/rcc/CodeGen/MachineCombiner.h
+++ b/backend/include/rcc/CodeGen/MachineCombiner.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_MACHINECOMBINER_H
#include "rcc/CodeGen/MachineCombinerPattern.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -24,7 +24,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/MachineCopyPropagation.h b/backend/include/rcc/CodeGen/MachineCopyPropagation.h
index 43baa7e..ab8b23f 100644
--- a/backend/include/rcc/CodeGen/MachineCopyPropagation.h
+++ b/backend/include/rcc/CodeGen/MachineCopyPropagation.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINECOPYPROPAGATION_H
#define RCC_CODEGEN_MACHINECOPYPROPAGATION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
#include <cstdint>
@@ -30,7 +30,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/MachineDCE.h b/backend/include/rcc/CodeGen/MachineDCE.h
index 893108d..8860b0f 100644
--- a/backend/include/rcc/CodeGen/MachineDCE.h
+++ b/backend/include/rcc/CodeGen/MachineDCE.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEDCE_H
#define RCC_CODEGEN_MACHINEDCE_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -12,7 +12,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/MachineFallthrough.h b/backend/include/rcc/CodeGen/MachineFallthrough.h
index 5793330..bb62e8a 100644
--- a/backend/include/rcc/CodeGen/MachineFallthrough.h
+++ b/backend/include/rcc/CodeGen/MachineFallthrough.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEFALLTHROUGH_H
#define RCC_CODEGEN_MACHINEFALLTHROUGH_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -16,7 +16,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetInstrInfo *Info;
diff --git a/backend/include/rcc/CodeGen/MachineFinalization.h b/backend/include/rcc/CodeGen/MachineFinalization.h
index 1927691..d12ee0b 100644
--- a/backend/include/rcc/CodeGen/MachineFinalization.h
+++ b/backend/include/rcc/CodeGen/MachineFinalization.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEFINALIZATION_H
#define RCC_CODEGEN_MACHINEFINALIZATION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -14,7 +14,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
};
class FinalEncodabilityVerifierPass final : public MachineFunctionPass {
@@ -25,7 +25,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetInstrInfo *BranchInfo;
diff --git a/backend/include/rcc/CodeGen/MachineFunctionAnalysisManager.h b/backend/include/rcc/CodeGen/MachineFunctionAnalysisManager.h
new file mode 100644
index 0000000..9685e45
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MachineFunctionAnalysisManager.h
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MACHINEFUNCTIONANALYSISMANAGER_H
+#define RCC_CODEGEN_MACHINEFUNCTIONANALYSISMANAGER_H
+
+#include "rcc/CodeGen/StableID.h"
+#include "rcc/IR/PassManager.h"
+
+#include <cstdint>
+#include <initializer_list>
+
+namespace rcc {
+
+class CompilationUnit;
+class MachineFunction;
+class MachinePassInstrumentation;
+
+enum class MachinePassChange : std::uint32_t {
+ None = 0,
+ Instructions = 1U << 0U,
+ Operands = 1U << 1U,
+ Registers = 1U << 2U,
+ CFG = 1U << 3U,
+ BlockLayout = 1U << 4U,
+ Frame = 1U << 5U,
+ ConstantPool = 1U << 6U,
+ JumpTable = 1U << 7U,
+ TargetState = 1U << 8U,
+};
+
+class MachinePassChanges final {
+public:
+ constexpr MachinePassChanges() noexcept = default;
+ constexpr MachinePassChanges(std::initializer_list<MachinePassChange> Changes) noexcept {
+ for (const MachinePassChange Change : Changes)
+ add(Change);
+ }
+
+ [[nodiscard]] static constexpr MachinePassChanges all() noexcept {
+ return fromRaw((1U << 9U) - 1U);
+ }
+
+ [[nodiscard]] static constexpr MachinePassChanges fromRaw(std::uint32_t Bits) noexcept {
+ MachinePassChanges Result;
+ Result.Bits = Bits & rawMask();
+ return Result;
+ }
+
+ constexpr void add(MachinePassChange Change) noexcept {
+ Bits |= static_cast<std::uint32_t>(Change);
+ }
+
+ [[nodiscard]] constexpr bool has(MachinePassChange Change) const noexcept {
+ return (Bits & static_cast<std::uint32_t>(Change)) != 0;
+ }
+
+ [[nodiscard]] constexpr bool contains(MachinePassChanges Other) const noexcept {
+ return (Bits & Other.Bits) == Other.Bits;
+ }
+
+ [[nodiscard]] constexpr bool intersects(MachinePassChanges Other) const noexcept {
+ return (Bits & Other.Bits) != 0;
+ }
+
+ [[nodiscard]] constexpr bool empty() const noexcept {
+ return Bits == 0;
+ }
+
+ [[nodiscard]] constexpr std::uint32_t rawValue() const noexcept {
+ return Bits;
+ }
+
+ friend constexpr bool operator==(MachinePassChanges Left,
+ MachinePassChanges Right) noexcept = default;
+
+private:
+ [[nodiscard]] static constexpr std::uint32_t rawMask() noexcept {
+ return (1U << 9U) - 1U;
+ }
+
+ std::uint32_t Bits = 0;
+};
+
+template <>
+struct AnalysisManagerInstrumentation<MachineFunction, MachinePassInstrumentation> final {
+ static void beforeAnalysis(MachinePassInstrumentation *Instrumentation, std::string_view Name,
+ const MachineFunction &Function);
+ static void afterAnalysis(MachinePassInstrumentation *Instrumentation, std::string_view Name,
+ const MachineFunction &Function, bool CacheHit,
+ std::uint64_t Nanoseconds);
+ static void analysisFailure(MachinePassInstrumentation *Instrumentation, std::string_view Name,
+ const MachineFunction &Function, const Error &Failure,
+ std::uint64_t Nanoseconds);
+ [[nodiscard]] static Expected<bool> requestAction(MachinePassInstrumentation *Instrumentation,
+ std::string_view Pass, std::string_view Rule,
+ const MachineFunction &Function,
+ MachineInstrStableID Instruction,
+ std::uint64_t Cost);
+ [[nodiscard]] static Expected<bool> requestAction(MachinePassInstrumentation *Instrumentation,
+ std::string_view Pass, std::string_view Rule,
+ const MachineFunction &Function, std::nullptr_t,
+ std::uint64_t Cost);
+};
+
+template <>
+struct AnalysisManagerInstrumentation<CompilationUnit, MachinePassInstrumentation> final {
+ static void beforeAnalysis(MachinePassInstrumentation *Instrumentation, std::string_view Name,
+ const CompilationUnit &Unit);
+ static void afterAnalysis(MachinePassInstrumentation *Instrumentation, std::string_view Name,
+ const CompilationUnit &Unit, bool CacheHit, std::uint64_t Nanoseconds);
+ static void analysisFailure(MachinePassInstrumentation *Instrumentation, std::string_view Name,
+ const CompilationUnit &Unit, const Error &Failure,
+ std::uint64_t Nanoseconds);
+};
+
+using MachineAnalysisRegistration = AnalysisRegistration<MachinePassChanges>;
+using CompilationUnitAnalysisRegistration = AnalysisRegistration<MachinePassChanges>;
+
+using MachineFunctionAnalysisManager =
+ AnalysisManager<MachineFunction, MachineAnalysisRegistration, MachinePassChanges,
+ MachinePassInstrumentation>;
+using CompilationUnitAnalysisManager =
+ AnalysisManager<CompilationUnit, CompilationUnitAnalysisRegistration, MachinePassChanges,
+ MachinePassInstrumentation>;
+
+[[nodiscard]] Expected<void>
+registerStage8MachineAnalyses(MachineFunctionAnalysisManager &Analyses);
+[[nodiscard]] Expected<void>
+registerStage11MachineAnalyses(MachineFunctionAnalysisManager &Analyses);
+
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MACHINEFUNCTIONANALYSISMANAGER_H
diff --git a/backend/include/rcc/CodeGen/MachineLICM.h b/backend/include/rcc/CodeGen/MachineLICM.h
index 66b7ef8..5efaf20 100644
--- a/backend/include/rcc/CodeGen/MachineLICM.h
+++ b/backend/include/rcc/CodeGen/MachineLICM.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINELICM_H
#define RCC_CODEGEN_MACHINELICM_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
#include <cstdint>
@@ -29,12 +29,12 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
- [[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
- const TargetDescription &Target,
- MachineAnalysisManager &Analyses);
+ [[nodiscard]] Expected<MachinePassResult>
+ runImplementation(MachineFunction &Function, const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
MachineCodeMotionStage Stage = MachineCodeMotionStage::SelectedSSA;
MachineLICMOptions Options;
diff --git a/backend/include/rcc/CodeGen/MachineMemoryFolding.h b/backend/include/rcc/CodeGen/MachineMemoryFolding.h
index 9a5b47a..9f415d7 100644
--- a/backend/include/rcc/CodeGen/MachineMemoryFolding.h
+++ b/backend/include/rcc/CodeGen/MachineMemoryFolding.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEMEMORYFOLDING_H
#define RCC_CODEGEN_MACHINEMEMORYFOLDING_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -24,7 +24,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult>
diff --git a/backend/include/rcc/CodeGen/MachineOptimizationPipeline.h b/backend/include/rcc/CodeGen/MachineOptimizationPipeline.h
index 10bcbc6..51b4ed2 100644
--- a/backend/include/rcc/CodeGen/MachineOptimizationPipeline.h
+++ b/backend/include/rcc/CodeGen/MachineOptimizationPipeline.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEOPTIMIZATIONPIPELINE_H
#define RCC_CODEGEN_MACHINEOPTIMIZATIONPIPELINE_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -23,17 +23,18 @@ struct MachineOptimizationPipelineTargetInfo final {
const TargetSchedulingModel &SchedulingModel;
};
-[[nodiscard]] Expected<void> registerMachineOptimizationAnalyses(MachineAnalysisManager &Analyses);
+[[nodiscard]] Expected<void>
+registerMachineOptimizationAnalyses(MachineFunctionAnalysisManager &Analyses);
[[nodiscard]] Expected<void>
-addSelectedSSAOptimizationPipeline(MachinePassManager &Pipeline,
+addSelectedSSAOptimizationPipeline(MachineFunctionPassManager &Pipeline,
const MachineOptimizationPipelineTargetInfo &TargetInfo);
[[nodiscard]] Expected<void> addPreRegisterAllocationOptimizationPipeline(
- MachinePassManager &Pipeline, const MachineOptimizationPipelineTargetInfo &TargetInfo);
+ MachineFunctionPassManager &Pipeline, const MachineOptimizationPipelineTargetInfo &TargetInfo);
[[nodiscard]] Expected<void>
-addPostRegisterAllocationPipeline(MachinePassManager &Pipeline,
+addPostRegisterAllocationPipeline(MachineFunctionPassManager &Pipeline,
const MachineOptimizationPipelineTargetInfo &TargetInfo);
} // namespace rcc
diff --git a/backend/include/rcc/CodeGen/MachinePass.h b/backend/include/rcc/CodeGen/MachinePass.h
deleted file mode 100644
index ee67924..0000000
--- a/backend/include/rcc/CodeGen/MachinePass.h
+++ /dev/null
@@ -1,720 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#ifndef RCC_CODEGEN_MACHINEPASS_H
-#define RCC_CODEGEN_MACHINEPASS_H
-
-#include "rcc/CodeGen/InstructionDescriptor.h"
-#include "rcc/CodeGen/MachineFunctionProperties.h"
-#include "rcc/CodeGen/StableID.h"
-#include "rcc/Support/Error.h"
-
-#include <concepts>
-#include <cstddef>
-#include <cstdint>
-#include <functional>
-#include <initializer_list>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <span>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-namespace rcc {
-
-class CompilationUnit;
-class MachineFunction;
-class MachineVerifier;
-class TargetDescription;
-
-using AnalysisID = const void *;
-
-enum class MachinePassChange : std::uint32_t {
- None = 0,
- Instructions = 1U << 0U,
- Operands = 1U << 1U,
- Registers = 1U << 2U,
- CFG = 1U << 3U,
- BlockLayout = 1U << 4U,
- Frame = 1U << 5U,
- ConstantPool = 1U << 6U,
- JumpTable = 1U << 7U,
- TargetState = 1U << 8U,
-};
-
-class MachinePassChanges final {
-public:
- constexpr MachinePassChanges() noexcept = default;
- constexpr MachinePassChanges(std::initializer_list<MachinePassChange> Changes) noexcept {
- for (const MachinePassChange Change : Changes)
- add(Change);
- }
-
- [[nodiscard]] static constexpr MachinePassChanges all() noexcept {
- return fromRaw((1U << 9U) - 1U);
- }
-
- [[nodiscard]] static constexpr MachinePassChanges fromRaw(std::uint32_t Bits) noexcept {
- MachinePassChanges Result;
- Result.Bits = Bits & rawMask();
- return Result;
- }
-
- constexpr void add(MachinePassChange Change) noexcept {
- Bits |= static_cast<std::uint32_t>(Change);
- }
-
- [[nodiscard]] constexpr bool has(MachinePassChange Change) const noexcept {
- return (Bits & static_cast<std::uint32_t>(Change)) != 0;
- }
-
- [[nodiscard]] constexpr bool contains(MachinePassChanges Other) const noexcept {
- return (Bits & Other.Bits) == Other.Bits;
- }
-
- [[nodiscard]] constexpr bool intersects(MachinePassChanges Other) const noexcept {
- return (Bits & Other.Bits) != 0;
- }
-
- [[nodiscard]] constexpr bool empty() const noexcept {
- return Bits == 0;
- }
-
- [[nodiscard]] constexpr std::uint32_t rawValue() const noexcept {
- return Bits;
- }
-
- friend constexpr bool operator==(MachinePassChanges Left,
- MachinePassChanges Right) noexcept = default;
-
-private:
- [[nodiscard]] static constexpr std::uint32_t rawMask() noexcept {
- return (1U << 9U) - 1U;
- }
-
- std::uint32_t Bits = 0;
-};
-
-class PreservedAnalyses final {
-public:
- [[nodiscard]] static PreservedAnalyses all() noexcept {
- PreservedAnalyses Result;
- Result.PreserveAll = true;
- return Result;
- }
-
- [[nodiscard]] static PreservedAnalyses none() noexcept {
- return {};
- }
-
- void preserve(AnalysisID ID) {
- if (ID != nullptr)
- Preserved.insert(ID);
- }
-
- template <typename AnalysisT> void preserve() {
- preserve(analysisID<AnalysisT>());
- }
-
- [[nodiscard]] bool preserves(AnalysisID ID) const noexcept {
- return PreserveAll || (ID != nullptr && Preserved.contains(ID));
- }
-
- [[nodiscard]] bool preservesAll() const noexcept {
- return PreserveAll;
- }
-
- template <typename AnalysisT> [[nodiscard]] static AnalysisID analysisID() noexcept {
- static const std::uint8_t Token = 0;
- return &Token;
- }
-
-private:
- bool PreserveAll = false;
- std::unordered_set<AnalysisID> Preserved;
-};
-
-enum class PassThreadSafety : std::uint8_t {
- NotThreadSafe,
- ThreadSafe,
-};
-
-struct PassParameter final {
- std::string Name;
- std::string Description;
- std::optional<std::string> DefaultValue;
- bool Required = false;
-};
-
-struct MachinePassRegistrationMetadata {
- std::vector<PassParameter> Parameters;
- PassThreadSafety ThreadSafety = PassThreadSafety::NotThreadSafe;
- MachinePassChanges DeclaredChanges = MachinePassChanges::all();
-};
-
-struct MachinePassContract final : MachinePassRegistrationMetadata {
- std::string Name;
- MachineFunctionProperties Requires;
- MachineFunctionProperties Sets;
- MachineFunctionProperties Clears;
- std::vector<AnalysisID> RequiredAnalyses;
- std::optional<PipelineStage> VerificationStage;
-};
-
-struct MachinePassResult final {
- bool Changed = false;
- MachinePassChanges Changes;
- PreservedAnalyses Preserved = PreservedAnalyses::none();
-};
-
-struct CompilationUnitPassContract final {
- std::string Name;
- std::vector<AnalysisID> RequiredAnalyses;
- std::vector<PassParameter> Parameters;
- MachinePassChanges DeclaredChanges = MachinePassChanges::all();
-};
-
-struct CompilationUnitPassResult final {
- bool Changed = false;
- MachinePassChanges Changes;
- PreservedAnalyses PreservedUnitAnalyses = PreservedAnalyses::none();
- PreservedAnalyses PreservedFunctionAnalyses = PreservedAnalyses::none();
-};
-
-struct MachineAnalysisRegistration final {
- AnalysisID ID = nullptr;
- std::string Name;
- std::vector<AnalysisID> Dependencies;
- MachinePassChanges InvalidatedBy = MachinePassChanges::all();
- PassThreadSafety ThreadSafety = PassThreadSafety::NotThreadSafe;
-};
-
-struct CompilationUnitAnalysisRegistration final {
- AnalysisID ID = nullptr;
- std::string Name;
- std::vector<AnalysisID> Dependencies;
- MachinePassChanges InvalidatedBy = MachinePassChanges::all();
-};
-
-class MachinePassInstrumentation;
-
-class MachineAnalysisManager final {
-public:
- MachineAnalysisManager() = default;
- MachineAnalysisManager(const MachineAnalysisManager &) = delete;
- MachineAnalysisManager &operator=(const MachineAnalysisManager &) = delete;
- MachineAnalysisManager(MachineAnalysisManager &&) = delete;
- MachineAnalysisManager &operator=(MachineAnalysisManager &&) = delete;
- ~MachineAnalysisManager() = default;
-
- template <typename AnalysisT> [[nodiscard]] static AnalysisID id() noexcept {
- return PreservedAnalyses::analysisID<AnalysisT>();
- }
-
- template <typename AnalysisT>
- [[nodiscard]] Expected<void> registerAnalysis(MachineAnalysisRegistration Registration = {}) {
- using ResultT = typename AnalysisT::Result;
- if (Registration.ID == nullptr)
- Registration.ID = id<AnalysisT>();
- if (Registration.Name.empty()) {
- if constexpr (requires {
- { AnalysisT::name() } -> std::convertible_to<std::string_view>;
- }) {
- Registration.Name = std::string(AnalysisT::name());
- } else {
- Registration.Name = "unnamed-machine-analysis";
- }
- }
-
- ErasedRunner Runner = [](MachineFunction &Function, const TargetDescription &Target,
- MachineAnalysisManager &Manager) -> Expected<std::shared_ptr<void>> {
- auto Computed = AnalysisT::run(Function, Target, Manager);
- if (!Computed)
- return std::unexpected(Computed.error());
- return std::shared_ptr<void>(new ResultT(std::move(*Computed)),
- [](void *Value) { delete static_cast<ResultT *>(Value); });
- };
- ErasedInvalidator Invalidator = [](void *Value, const MachineFunction &Function,
- const PreservedAnalyses &Preserved) -> bool {
- if constexpr (requires(ResultT &Result, const MachineFunction &InputFunction,
- const PreservedAnalyses &Analyses) {
- { Result.invalidate(InputFunction, Analyses) } -> std::convertible_to<bool>;
- }) {
- return static_cast<ResultT *>(Value)->invalidate(Function, Preserved);
- }
- return true;
- };
- return registerAnalysisImpl(std::move(Registration), std::move(Runner), std::move(Invalidator));
- }
-
- template <typename AnalysisT>
- [[nodiscard]] Expected<typename AnalysisT::Result *> getResult(MachineFunction &Function,
- const TargetDescription &Target) {
- const AnalysisID Key = id<AnalysisT>();
- if (!isRegistered(Key)) {
- auto Registered = registerAnalysis<AnalysisT>();
- if (!Registered)
- return std::unexpected(Registered.error());
- }
- auto Result = getResultImpl(Key, Function, Target);
- if (!Result)
- return std::unexpected(Result.error());
- return static_cast<typename AnalysisT::Result *>(*Result);
- }
-
- void invalidate(MachineFunction &Function, const PreservedAnalyses &Preserved,
- MachinePassChanges Changes) noexcept;
- void invalidate(MachineFunction &Function, const PreservedAnalyses &Preserved) noexcept {
- invalidate(Function, Preserved, MachinePassChanges::all());
- }
- [[nodiscard]] bool hasCached(const MachineFunction &Function, AnalysisID ID) const noexcept;
- [[nodiscard]] bool isRegistered(AnalysisID ID) const noexcept;
- [[nodiscard]] std::size_t cachedResultCount(const MachineFunction &Function) const noexcept;
- void clear(MachineFunction &Function) noexcept;
- void clearAll() noexcept;
-
- [[nodiscard]] Expected<std::unique_ptr<MachineAnalysisManager>> forkEmpty() const;
- [[nodiscard]] Expected<bool>
- requestAction(std::string_view Action, const MachineFunction &Function, std::uint64_t Cost = 1);
- [[nodiscard]] Expected<bool> requestAction(std::string_view Rule, const MachineFunction &Function,
- MachineInstrStableID Instruction,
- std::uint64_t Cost = 1);
-
-private:
- using ErasedRunner = std::function<Expected<std::shared_ptr<void>>(
- MachineFunction &, const TargetDescription &, MachineAnalysisManager &)>;
- using ErasedInvalidator =
- std::function<bool(void *, const MachineFunction &, const PreservedAnalyses &)>;
-
- struct RegisteredAnalysis final {
- MachineAnalysisRegistration Info;
- ErasedRunner Runner;
- ErasedInvalidator Invalidator;
- };
-
- struct CacheEntry final {
- std::shared_ptr<void> Value;
- AnalysisID ID = nullptr;
- };
-
- [[nodiscard]] Expected<void> registerAnalysisImpl(MachineAnalysisRegistration Registration,
- ErasedRunner Runner,
- ErasedInvalidator Invalidator);
- [[nodiscard]] Expected<void *> getResultImpl(AnalysisID ID, MachineFunction &Function,
- const TargetDescription &Target);
- [[nodiscard]] Expected<void> materializeDependencies(const RegisteredAnalysis &Registration,
- MachineFunction &Function,
- const TargetDescription &Target);
- [[nodiscard]] Expected<void>
- validateParallelRequirements(std::span<const AnalysisID> RequiredAnalyses) const;
- void setInstrumentation(MachinePassInstrumentation *NewInstrumentation) noexcept {
- Instrumentation = NewInstrumentation;
- }
-
- std::unordered_map<AnalysisID, RegisteredAnalysis> Registry;
- std::unordered_map<MachineFunction *, std::unordered_map<AnalysisID, CacheEntry>> Cache;
- std::unordered_map<MachineFunction *, std::vector<AnalysisID>> ActiveComputations;
- MachinePassInstrumentation *Instrumentation = nullptr;
- std::string ActivePass;
-
- friend class MachinePassManager;
- friend class CompilationUnitPassManager;
- friend Expected<void> registerStage8MachineAnalyses(MachineAnalysisManager &Analyses);
- friend Expected<void> registerStage11MachineAnalyses(MachineAnalysisManager &Analyses);
-};
-
-class CompilationUnitAnalysisManager final {
-public:
- CompilationUnitAnalysisManager() = default;
- CompilationUnitAnalysisManager(const CompilationUnitAnalysisManager &) = delete;
- CompilationUnitAnalysisManager &operator=(const CompilationUnitAnalysisManager &) = delete;
- CompilationUnitAnalysisManager(CompilationUnitAnalysisManager &&) = delete;
- CompilationUnitAnalysisManager &operator=(CompilationUnitAnalysisManager &&) = delete;
- ~CompilationUnitAnalysisManager() = default;
-
- template <typename AnalysisT> [[nodiscard]] static AnalysisID id() noexcept {
- return PreservedAnalyses::analysisID<AnalysisT>();
- }
-
- template <typename AnalysisT>
- [[nodiscard]] Expected<void>
- registerAnalysis(CompilationUnitAnalysisRegistration Registration = {}) {
- using ResultT = typename AnalysisT::Result;
- if (Registration.ID == nullptr)
- Registration.ID = id<AnalysisT>();
- if (Registration.Name.empty()) {
- if constexpr (requires {
- { AnalysisT::name() } -> std::convertible_to<std::string_view>;
- }) {
- Registration.Name = std::string(AnalysisT::name());
- } else {
- Registration.Name = "unnamed-compilation-unit-analysis";
- }
- }
-
- ErasedRunner Runner =
- [](CompilationUnit &Unit, const TargetDescription &Target,
- CompilationUnitAnalysisManager &Manager) -> Expected<std::shared_ptr<void>> {
- auto Computed = AnalysisT::run(Unit, Target, Manager);
- if (!Computed)
- return std::unexpected(Computed.error());
- return std::shared_ptr<void>(new ResultT(std::move(*Computed)),
- [](void *Value) { delete static_cast<ResultT *>(Value); });
- };
- ErasedInvalidator Invalidator = [](void *Value, const CompilationUnit &Unit,
- const PreservedAnalyses &Preserved) -> bool {
- if constexpr (requires(ResultT &Result, const CompilationUnit &InputUnit,
- const PreservedAnalyses &Analyses) {
- { Result.invalidate(InputUnit, Analyses) } -> std::convertible_to<bool>;
- }) {
- return static_cast<ResultT *>(Value)->invalidate(Unit, Preserved);
- }
- return true;
- };
- return registerAnalysisImpl(std::move(Registration), std::move(Runner), std::move(Invalidator));
- }
-
- template <typename AnalysisT>
- [[nodiscard]] Expected<typename AnalysisT::Result *> getResult(CompilationUnit &Unit,
- const TargetDescription &Target) {
- const AnalysisID Key = id<AnalysisT>();
- if (!isRegistered(Key)) {
- auto Registered = registerAnalysis<AnalysisT>();
- if (!Registered)
- return std::unexpected(Registered.error());
- }
- auto Result = getResultImpl(Key, Unit, Target);
- if (!Result)
- return std::unexpected(Result.error());
- return static_cast<typename AnalysisT::Result *>(*Result);
- }
-
- void invalidate(CompilationUnit &Unit, const PreservedAnalyses &Preserved,
- MachinePassChanges Changes) noexcept;
- [[nodiscard]] bool hasCached(const CompilationUnit &Unit, AnalysisID ID) const noexcept;
- [[nodiscard]] bool isRegistered(AnalysisID ID) const noexcept;
- void clear(CompilationUnit &Unit) noexcept;
- void clearAll() noexcept;
-
-private:
- using ErasedRunner = std::function<Expected<std::shared_ptr<void>>(
- CompilationUnit &, const TargetDescription &, CompilationUnitAnalysisManager &)>;
- using ErasedInvalidator =
- std::function<bool(void *, const CompilationUnit &, const PreservedAnalyses &)>;
-
- struct RegisteredAnalysis final {
- CompilationUnitAnalysisRegistration Info;
- ErasedRunner Runner;
- ErasedInvalidator Invalidator;
- };
-
- struct CacheEntry final {
- std::shared_ptr<void> Value;
- AnalysisID ID = nullptr;
- };
-
- [[nodiscard]] Expected<void>
- registerAnalysisImpl(CompilationUnitAnalysisRegistration Registration, ErasedRunner Runner,
- ErasedInvalidator Invalidator);
- [[nodiscard]] Expected<void *> getResultImpl(AnalysisID ID, CompilationUnit &Unit,
- const TargetDescription &Target);
- [[nodiscard]] Expected<void> materializeDependencies(const RegisteredAnalysis &Registration,
- CompilationUnit &Unit,
- const TargetDescription &Target);
- void setInstrumentation(MachinePassInstrumentation *NewInstrumentation) noexcept {
- Instrumentation = NewInstrumentation;
- }
-
- std::unordered_map<AnalysisID, RegisteredAnalysis> Registry;
- std::unordered_map<CompilationUnit *, std::unordered_map<AnalysisID, CacheEntry>> Cache;
- std::unordered_map<CompilationUnit *, std::vector<AnalysisID>> ActiveComputations;
- MachinePassInstrumentation *Instrumentation = nullptr;
-
- friend class CompilationUnitPassManager;
-};
-
-class MachineFunctionPass {
-public:
- MachineFunctionPass() = default;
- MachineFunctionPass(const MachineFunctionPass &) = delete;
- MachineFunctionPass &operator=(const MachineFunctionPass &) = delete;
- virtual ~MachineFunctionPass() = default;
-
- [[nodiscard]] virtual const MachinePassContract &contract() const noexcept = 0;
- [[nodiscard]] virtual Expected<MachinePassResult> run(MachineFunction &Function,
- const TargetDescription &Target,
- MachineAnalysisManager &Analyses) = 0;
-};
-
-class CompilationUnitPass {
-public:
- CompilationUnitPass() = default;
- CompilationUnitPass(const CompilationUnitPass &) = delete;
- CompilationUnitPass &operator=(const CompilationUnitPass &) = delete;
- virtual ~CompilationUnitPass() = default;
-
- [[nodiscard]] virtual const CompilationUnitPassContract &contract() const noexcept = 0;
- [[nodiscard]] virtual Expected<CompilationUnitPassResult>
- run(CompilationUnit &Unit, const TargetDescription &Target,
- CompilationUnitAnalysisManager &UnitAnalyses, MachineAnalysisManager &FunctionAnalyses) = 0;
-};
-
-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 MachineActionReplay final {
-public:
- explicit MachineActionReplay(MachineAnalysisManager &Analyses) noexcept : Analyses(&Analyses) {}
- MachineActionReplay(
- MachineAnalysisManager &Analyses,
- const std::unordered_map<MachineInstrStableID, MachineInstrStableID> &SourceToClone)
- : Analyses(&Analyses) {
- for (const auto &[Source, Clone] : SourceToClone)
- RecordingInstructionIDs.try_emplace(Clone, Source);
- }
-
- [[nodiscard]] Expected<bool> request(std::string_view Rule, const MachineFunction &Function,
- MachineInstrStableID Instruction = {},
- std::uint64_t Cost = 1);
- void beginReplay() noexcept;
- [[nodiscard]] Expected<void> finishReplay() const;
-
-private:
- struct Decision final {
- std::string Rule;
- MachineFunctionStableID Function;
- MachineInstrStableID Instruction;
- std::uint64_t Cost = 0;
- bool Accepted = false;
- };
-
- MachineAnalysisManager *Analyses = nullptr;
- std::unordered_map<MachineInstrStableID, MachineInstrStableID> RecordingInstructionIDs;
- std::vector<Decision> Decisions;
- std::size_t NextDecision = 0;
- bool IsReplaying = false;
-};
-
-class MachinePassInstrumentation final {
-public:
- using BeforeCallback = std::function<void(std::string_view, const MachineFunction &)>;
- using AfterCallback =
- std::function<void(std::string_view, const MachineFunction &, const MachinePassResult &)>;
- using FailureCallback =
- std::function<void(std::string_view, const MachineFunction &, const Error &)>;
- using BeforeAnalysisCallback = std::function<void(std::string_view, const MachineFunction &)>;
- using AfterAnalysisCallback =
- std::function<void(std::string_view, const MachineFunction &, bool, std::uint64_t)>;
- using AnalysisFailureCallback =
- std::function<void(std::string_view, const MachineFunction &, const Error &)>;
- using IRPrintCallback =
- std::function<void(InstrumentationPhase, std::string_view, const MachineFunction &)>;
- using ChangeCallback =
- std::function<void(std::string_view, const MachineFunction &, MachinePassChanges, bool)>;
- using ActionFilter = std::function<bool(const MachineActionID &, std::uint64_t)>;
-
- using BeforeUnitCallback = std::function<void(std::string_view, const CompilationUnit &)>;
- using AfterUnitCallback = std::function<void(std::string_view, const CompilationUnit &,
- const CompilationUnitPassResult &)>;
- using UnitFailureCallback =
- std::function<void(std::string_view, const CompilationUnit &, const Error &)>;
- using BeforeUnitAnalysisCallback = std::function<void(std::string_view, const CompilationUnit &)>;
- using AfterUnitAnalysisCallback =
- std::function<void(std::string_view, const CompilationUnit &, bool, std::uint64_t)>;
- using UnitAnalysisFailureCallback =
- std::function<void(std::string_view, const CompilationUnit &, const Error &)>;
-
- 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<std::uint64_t> 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<InstrumentationStatistic> statistics() const;
- [[nodiscard]] std::vector<MachineActionEvent> actionEvents() const;
- void clearStatistics();
-
-private:
- struct BufferedEvents final {
- const TargetDescription *Target = nullptr;
- std::vector<std::function<void()>> Events;
- };
-
- [[nodiscard]] bool bufferFunctionEvent(const MachineFunction &Function,
- std::function<void(const MachineFunction &)> Replay) const;
- void beginBuffering(BufferedEvents &Buffer, const TargetDescription &Target) const noexcept;
- void endBuffering() const noexcept;
- void replayBufferedEvents(BufferedEvents &Buffer) const;
-
- 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;
- [[nodiscard]] Expected<bool> requestAction(const MachineActionID &Action,
- const MachineFunction &Function, std::uint64_t Cost);
-
- 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 beforeUnitAnalysis(std::string_view Name, const CompilationUnit &Unit) const;
- void afterUnitAnalysis(std::string_view Name, const CompilationUnit &Unit, bool CacheHit,
- std::uint64_t Nanoseconds) const;
- void unitAnalysisFailure(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;
-
- mutable std::mutex Mutex;
- mutable std::mutex ActionMutex;
- std::vector<BeforeCallback> Before;
- std::vector<AfterCallback> After;
- std::vector<FailureCallback> Failure;
- std::vector<BeforeAnalysisCallback> BeforeAnalysis;
- std::vector<AfterAnalysisCallback> AfterAnalysis;
- std::vector<AnalysisFailureCallback> AnalysisFailure;
- std::vector<IRPrintCallback> IRPrint;
- std::vector<ChangeCallback> Change;
- ActionFilter Filter;
- std::optional<std::uint64_t> PerFunctionFuel;
- std::unordered_map<std::uint64_t, std::uint64_t> ConsumedFuel;
- std::vector<MachineActionEvent> ActionEvents;
-
- std::vector<BeforeUnitCallback> BeforeUnit;
- std::vector<AfterUnitCallback> AfterUnit;
- std::vector<UnitFailureCallback> UnitFailure;
- std::vector<BeforeUnitAnalysisCallback> BeforeUnitAnalysis;
- std::vector<AfterUnitAnalysisCallback> AfterUnitAnalysis;
- std::vector<UnitAnalysisFailureCallback> UnitAnalysisFailure;
- mutable std::unordered_map<std::string, InstrumentationStatistic> Statistics;
-
- static thread_local BufferedEvents *ActiveBuffer;
-
- friend class CompilationUnitAnalysisManager;
- friend class CompilationUnitPassManager;
- friend class MachineAnalysisManager;
- friend class MachinePassManager;
-};
-
-struct MachinePassManagerOptions final {
- bool VerifyBefore = true;
- bool VerifyEach = true;
- bool DetectUnreportedChanges = false;
-};
-
-class MachinePassManager final {
-public:
- using PassList = std::vector<std::unique_ptr<MachineFunctionPass>>;
-
- explicit MachinePassManager(MachinePassManagerOptions Options = {}) : Options(Options) {}
-
- MachinePassManager(const MachinePassManager &) = delete;
- MachinePassManager &operator=(const MachinePassManager &) = delete;
-
- [[nodiscard]] Expected<void> addPass(std::unique_ptr<MachineFunctionPass> Pass);
- [[nodiscard]] Expected<void> run(MachineFunction &Function, const TargetDescription &Target,
- MachineAnalysisManager &Analyses,
- MachinePassInstrumentation *Instrumentation = nullptr) const;
- [[nodiscard]] Expected<void>
- runFunctions(CompilationUnit &Unit, const TargetDescription &Target,
- const MachineAnalysisManager &AnalysisPrototype, std::size_t ThreadCount,
- MachinePassInstrumentation *Instrumentation = nullptr) const;
-
- [[nodiscard]] std::size_t size() const noexcept {
- return Passes.size();
- }
-
- [[nodiscard]] PassList takePasses() && noexcept {
- return std::move(Passes);
- }
-
-private:
- [[nodiscard]] Expected<void> validateContract(const MachinePassContract &Contract) const;
-
- MachinePassManagerOptions Options;
- PassList Passes;
-};
-
-struct CompilationUnitPassManagerOptions final {
- bool VerifyBefore = true;
- bool VerifyEach = true;
-};
-
-class CompilationUnitPassManager final {
-public:
- explicit CompilationUnitPassManager(CompilationUnitPassManagerOptions Options = {})
- : Options(Options) {}
-
- CompilationUnitPassManager(const CompilationUnitPassManager &) = delete;
- CompilationUnitPassManager &operator=(const CompilationUnitPassManager &) = delete;
-
- [[nodiscard]] Expected<void> addPass(std::unique_ptr<CompilationUnitPass> Pass);
- [[nodiscard]] Expected<void> run(CompilationUnit &Unit, const TargetDescription &Target,
- CompilationUnitAnalysisManager &UnitAnalyses,
- MachineAnalysisManager &FunctionAnalyses,
- MachinePassInstrumentation *Instrumentation = nullptr) const;
-
-private:
- CompilationUnitPassManagerOptions Options;
- std::vector<std::unique_ptr<CompilationUnitPass>> Passes;
-};
-
-} // namespace rcc
-
-#endif // RCC_CODEGEN_MACHINEPASS_H
diff --git a/backend/include/rcc/CodeGen/MachinePassManager.h b/backend/include/rcc/CodeGen/MachinePassManager.h
new file mode 100644
index 0000000..3587395
--- /dev/null
+++ b/backend/include/rcc/CodeGen/MachinePassManager.h
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_CODEGEN_MACHINEPASSMANAGER_H
+#define RCC_CODEGEN_MACHINEPASSMANAGER_H
+
+#include "rcc/CodeGen/InstructionDescriptor.h"
+#include "rcc/CodeGen/MachineFunctionAnalysisManager.h"
+#include "rcc/CodeGen/MachineFunctionProperties.h"
+#include "rcc/IR/PassInstrumentation.h"
+
+#include <cstddef>
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+namespace rcc {
+
+class CompilationUnit;
+class MachineFunction;
+class TargetDescription;
+
+struct MachinePassRegistrationMetadata {
+ std::vector<PassParameter> Parameters;
+ PassThreadSafety ThreadSafety = PassThreadSafety::NotThreadSafe;
+ MachinePassChanges DeclaredChanges = MachinePassChanges::all();
+};
+
+struct MachinePassContract final : MachinePassRegistrationMetadata {
+ std::string Name;
+ MachineFunctionProperties Requires;
+ MachineFunctionProperties Sets;
+ MachineFunctionProperties Clears;
+ std::vector<AnalysisID> RequiredAnalyses;
+ std::optional<PipelineStage> VerificationStage;
+};
+
+struct MachinePassResult final {
+ bool Changed = false;
+ MachinePassChanges Changes;
+ PreservedAnalyses Preserved = PreservedAnalyses::none();
+};
+
+struct CompilationUnitPassContract final {
+ std::string Name;
+ std::vector<AnalysisID> RequiredAnalyses;
+ std::vector<PassParameter> Parameters;
+ MachinePassChanges DeclaredChanges = MachinePassChanges::all();
+};
+
+struct CompilationUnitPassResult final {
+ bool Changed = false;
+ MachinePassChanges Changes;
+ PreservedAnalyses PreservedUnitAnalyses = PreservedAnalyses::none();
+ PreservedAnalyses PreservedFunctionAnalyses = PreservedAnalyses::none();
+};
+
+class MachineFunctionPass {
+public:
+ MachineFunctionPass() = default;
+ MachineFunctionPass(const MachineFunctionPass &) = delete;
+ MachineFunctionPass &operator=(const MachineFunctionPass &) = delete;
+ virtual ~MachineFunctionPass() = default;
+
+ [[nodiscard]] virtual const MachinePassContract &contract() const noexcept = 0;
+ [[nodiscard]] virtual Expected<MachinePassResult>
+ run(MachineFunction &Function, const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses) = 0;
+};
+
+class CompilationUnitPass {
+public:
+ CompilationUnitPass() = default;
+ CompilationUnitPass(const CompilationUnitPass &) = delete;
+ CompilationUnitPass &operator=(const CompilationUnitPass &) = delete;
+ virtual ~CompilationUnitPass() = default;
+
+ [[nodiscard]] virtual const CompilationUnitPassContract &contract() const noexcept = 0;
+ [[nodiscard]] virtual Expected<CompilationUnitPassResult>
+ run(CompilationUnit &Unit, const TargetDescription &Target,
+ CompilationUnitAnalysisManager &UnitAnalyses,
+ MachineFunctionAnalysisManager &FunctionAnalyses) = 0;
+};
+
+struct MachinePassManagerOptions final {
+ bool VerifyBefore = true;
+ bool VerifyEach = true;
+ bool DetectUnreportedChanges = false;
+};
+
+template <>
+struct PassManagerCallbacks<MachineFunction, MachineFunctionPass, MachinePassManagerOptions> final {
+ using PassList = std::vector<std::unique_ptr<MachineFunctionPass>>;
+
+ [[nodiscard]] static Expected<void> validate(const MachineFunctionPass &Pass);
+ [[nodiscard]] static Expected<void>
+ run(const PassList &Passes, const MachinePassManagerOptions &Options, MachineFunction &Function,
+ const TargetDescription &Target, MachineFunctionAnalysisManager &Analyses,
+ MachinePassInstrumentation *Instrumentation = nullptr);
+ [[nodiscard]] static Expected<void>
+ runFunctions(const PassList &Passes, const MachinePassManagerOptions &Options,
+ CompilationUnit &Unit, const TargetDescription &Target,
+ const MachineFunctionAnalysisManager &AnalysisPrototype, std::size_t ThreadCount,
+ MachinePassInstrumentation *Instrumentation = nullptr);
+};
+
+using MachineFunctionPassManager =
+ PassManager<MachineFunction, MachineFunctionPass, MachinePassManagerOptions>;
+
+struct CompilationUnitPassManagerOptions final {
+ bool VerifyBefore = true;
+ bool VerifyEach = true;
+};
+
+template <>
+struct PassManagerCallbacks<CompilationUnit, CompilationUnitPass, CompilationUnitPassManagerOptions>
+ final {
+ using PassList = std::vector<std::unique_ptr<CompilationUnitPass>>;
+
+ [[nodiscard]] static Expected<void> validate(const CompilationUnitPass &Pass);
+ [[nodiscard]] static Expected<void> run(const PassList &Passes,
+ const CompilationUnitPassManagerOptions &Options,
+ CompilationUnit &Unit, const TargetDescription &Target,
+ CompilationUnitAnalysisManager &UnitAnalyses,
+ MachineFunctionAnalysisManager &FunctionAnalyses,
+ MachinePassInstrumentation *Instrumentation = nullptr);
+};
+
+using CompilationUnitPassManager =
+ PassManager<CompilationUnit, CompilationUnitPass, CompilationUnitPassManagerOptions>;
+
+} // namespace rcc
+
+#endif // RCC_CODEGEN_MACHINEPASSMANAGER_H
diff --git a/backend/include/rcc/CodeGen/MachinePseudoExpansion.h b/backend/include/rcc/CodeGen/MachinePseudoExpansion.h
index 8c47441..7d4b309 100644
--- a/backend/include/rcc/CodeGen/MachinePseudoExpansion.h
+++ b/backend/include/rcc/CodeGen/MachinePseudoExpansion.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINEPSEUDOEXPANSION_H
#define RCC_CODEGEN_MACHINEPSEUDOEXPANSION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/TargetPseudoExpansion.h"
namespace rcc {
@@ -18,7 +18,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetPseudoExpansionInfo *Info;
@@ -32,7 +32,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetPseudoExpansionInfo *Info;
@@ -45,7 +45,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetPseudoExpansionInfo *Info;
@@ -60,7 +60,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetPseudoExpansionInfo *Info;
diff --git a/backend/include/rcc/CodeGen/MachineScheduler.h b/backend/include/rcc/CodeGen/MachineScheduler.h
index 2b48fe7..bfe9265 100644
--- a/backend/include/rcc/CodeGen/MachineScheduler.h
+++ b/backend/include/rcc/CodeGen/MachineScheduler.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINESCHEDULER_H
#define RCC_CODEGEN_MACHINESCHEDULER_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -25,7 +25,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetSchedulingModel *Model;
diff --git a/backend/include/rcc/CodeGen/MachineShrinkWrapping.h b/backend/include/rcc/CodeGen/MachineShrinkWrapping.h
index ec295cd..14edeb7 100644
--- a/backend/include/rcc/CodeGen/MachineShrinkWrapping.h
+++ b/backend/include/rcc/CodeGen/MachineShrinkWrapping.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINESHRINKWRAPPING_H
#define RCC_CODEGEN_MACHINESHRINKWRAPPING_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -24,7 +24,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetFrameLowering *Info;
diff --git a/backend/include/rcc/CodeGen/MachineSink.h b/backend/include/rcc/CodeGen/MachineSink.h
index 92aceba..5b47f9b 100644
--- a/backend/include/rcc/CodeGen/MachineSink.h
+++ b/backend/include/rcc/CodeGen/MachineSink.h
@@ -22,12 +22,12 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
- [[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
- const TargetDescription &Target,
- MachineAnalysisManager &Analyses);
+ [[nodiscard]] Expected<MachinePassResult>
+ runImplementation(MachineFunction &Function, const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
MachineCodeMotionStage Stage = MachineCodeMotionStage::SelectedSSA;
MachineSinkOptions Options;
diff --git a/backend/include/rcc/CodeGen/MachineStackSlotColoring.h b/backend/include/rcc/CodeGen/MachineStackSlotColoring.h
index 19c1c70..9aae710 100644
--- a/backend/include/rcc/CodeGen/MachineStackSlotColoring.h
+++ b/backend/include/rcc/CodeGen/MachineStackSlotColoring.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINESTACKSLOTCOLORING_H
#define RCC_CODEGEN_MACHINESTACKSLOTCOLORING_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -21,7 +21,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function) const;
diff --git a/backend/include/rcc/CodeGen/MachineTailDuplication.h b/backend/include/rcc/CodeGen/MachineTailDuplication.h
index 1c21bdf..f52f638 100644
--- a/backend/include/rcc/CodeGen/MachineTailDuplication.h
+++ b/backend/include/rcc/CodeGen/MachineTailDuplication.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINETAILDUPLICATION_H
#define RCC_CODEGEN_MACHINETAILDUPLICATION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -25,7 +25,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult>
diff --git a/backend/include/rcc/CodeGen/MachineTailMerge.h b/backend/include/rcc/CodeGen/MachineTailMerge.h
index 7237d58..0b9938e 100644
--- a/backend/include/rcc/CodeGen/MachineTailMerge.h
+++ b/backend/include/rcc/CodeGen/MachineTailMerge.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_MACHINETAILMERGE_H
#define RCC_CODEGEN_MACHINETAILMERGE_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <cstddef>
@@ -24,7 +24,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult>
diff --git a/backend/include/rcc/CodeGen/PHIElimination.h b/backend/include/rcc/CodeGen/PHIElimination.h
index 3d69152..1443303 100644
--- a/backend/include/rcc/CodeGen/PHIElimination.h
+++ b/backend/include/rcc/CodeGen/PHIElimination.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_PHIELIMINATION_H
#define RCC_CODEGEN_PHIELIMINATION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -16,7 +16,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/PostRAScheduler.h b/backend/include/rcc/CodeGen/PostRAScheduler.h
index 13b08df..3254d1e 100644
--- a/backend/include/rcc/CodeGen/PostRAScheduler.h
+++ b/backend/include/rcc/CodeGen/PostRAScheduler.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_POSTRASCHEDULER_H
#define RCC_CODEGEN_POSTRASCHEDULER_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/MachineScheduler.h"
namespace rcc {
@@ -19,7 +19,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetSchedulingModel *Model;
diff --git a/backend/include/rcc/CodeGen/PrologueEpilogueInsertion.h b/backend/include/rcc/CodeGen/PrologueEpilogueInsertion.h
index b94715a..a5d0028 100644
--- a/backend/include/rcc/CodeGen/PrologueEpilogueInsertion.h
+++ b/backend/include/rcc/CodeGen/PrologueEpilogueInsertion.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_PROLOGUEEPILOGUEINSERTION_H
#define RCC_CODEGEN_PROLOGUEEPILOGUEINSERTION_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -16,7 +16,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult>
diff --git a/backend/include/rcc/CodeGen/RegAllocCommon.h b/backend/include/rcc/CodeGen/RegAllocCommon.h
index 0df9799..ac3aa56 100644
--- a/backend/include/rcc/CodeGen/RegAllocCommon.h
+++ b/backend/include/rcc/CodeGen/RegAllocCommon.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_REGALLOCCOMMON_H
#define RCC_CODEGEN_REGALLOCCOMMON_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include <memory>
diff --git a/backend/include/rcc/CodeGen/RegAllocFast.h b/backend/include/rcc/CodeGen/RegAllocFast.h
index 84cf30c..6ee2881 100644
--- a/backend/include/rcc/CodeGen/RegAllocFast.h
+++ b/backend/include/rcc/CodeGen/RegAllocFast.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_REGALLOCFAST_H
#define RCC_CODEGEN_REGALLOCFAST_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/TargetRegisterAllocationInfo.h"
namespace rcc {
@@ -15,7 +15,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetRegisterAllocationInfo *Info;
diff --git a/backend/include/rcc/CodeGen/RegAllocPBQP.h b/backend/include/rcc/CodeGen/RegAllocPBQP.h
index 368cbee..0ae0088 100644
--- a/backend/include/rcc/CodeGen/RegAllocPBQP.h
+++ b/backend/include/rcc/CodeGen/RegAllocPBQP.h
@@ -17,7 +17,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const TargetRegisterAllocationInfo *Info;
diff --git a/backend/include/rcc/CodeGen/SlotIndexes.h b/backend/include/rcc/CodeGen/SlotIndexes.h
index 1767596..423cc64 100644
--- a/backend/include/rcc/CodeGen/SlotIndexes.h
+++ b/backend/include/rcc/CodeGen/SlotIndexes.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_SLOTINDEXES_H
#include "rcc/CodeGen/MachineIRTypes.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/StableID.h"
#include "rcc/Support/Error.h"
@@ -115,8 +115,9 @@ public:
return "SlotIndexes";
}
- [[nodiscard]] static Expected<Result>
- run(MachineFunction &Function, const TargetDescription &Target, MachineAnalysisManager &Analyses);
+ [[nodiscard]] static Expected<Result> run(MachineFunction &Function,
+ const TargetDescription &Target,
+ MachineFunctionAnalysisManager &Analyses);
};
} // namespace rcc
diff --git a/backend/include/rcc/CodeGen/TwoAddressInstructionPass.h b/backend/include/rcc/CodeGen/TwoAddressInstructionPass.h
index 696b46c..3c9e9dc 100644
--- a/backend/include/rcc/CodeGen/TwoAddressInstructionPass.h
+++ b/backend/include/rcc/CodeGen/TwoAddressInstructionPass.h
@@ -3,7 +3,7 @@
#ifndef RCC_CODEGEN_TWOADDRESSINSTRUCTIONPASS_H
#define RCC_CODEGEN_TWOADDRESSINSTRUCTIONPASS_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
namespace rcc {
@@ -16,7 +16,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
[[nodiscard]] Expected<MachinePassResult> runImplementation(MachineFunction &Function,
diff --git a/backend/include/rcc/CodeGen/VirtRegMap.h b/backend/include/rcc/CodeGen/VirtRegMap.h
index f37af84..30ef450 100644
--- a/backend/include/rcc/CodeGen/VirtRegMap.h
+++ b/backend/include/rcc/CodeGen/VirtRegMap.h
@@ -4,7 +4,7 @@
#define RCC_CODEGEN_VIRTREGMAP_H
#include "rcc/CodeGen/MachineFrameInfo.h"
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
#include <cstdint>
@@ -82,7 +82,7 @@ public:
[[nodiscard]] const MachinePassContract &contract() const noexcept override;
[[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
const TargetDescription &Target,
- MachineAnalysisManager &Analyses) override;
+ MachineFunctionAnalysisManager &Analyses) override;
private:
const VirtRegMap *Mapping;
diff --git a/backend/include/rcc/IR/PassInstrumentation.h b/backend/include/rcc/IR/PassInstrumentation.h
new file mode 100644
index 0000000..082ec81
--- /dev/null
+++ b/backend/include/rcc/IR/PassInstrumentation.h
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_IR_PASSINSTRUMENTATION_H
+#define RCC_IR_PASSINSTRUMENTATION_H
+
+#include "rcc/CodeGen/MachineFunctionAnalysisManager.h"
+
+#include <cstdint>
+#include <functional>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
+namespace rcc {
+
+class CompilationUnit;
+class MachineFunction;
+class TargetDescription;
+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 {
+public:
+ using BeforeCallback = std::function<void(std::string_view, const MachineFunction &)>;
+ using AfterCallback =
+ std::function<void(std::string_view, const MachineFunction &, const MachinePassResult &)>;
+ using FailureCallback =
+ std::function<void(std::string_view, const MachineFunction &, const Error &)>;
+ using BeforeAnalysisCallback = std::function<void(std::string_view, const MachineFunction &)>;
+ using AfterAnalysisCallback =
+ std::function<void(std::string_view, const MachineFunction &, bool, std::uint64_t)>;
+ using AnalysisFailureCallback =
+ std::function<void(std::string_view, const MachineFunction &, const Error &)>;
+ using IRPrintCallback =
+ std::function<void(InstrumentationPhase, std::string_view, const MachineFunction &)>;
+ using ChangeCallback =
+ std::function<void(std::string_view, const MachineFunction &, MachinePassChanges, bool)>;
+ using ActionFilter = std::function<bool(const MachineActionID &, std::uint64_t)>;
+
+ using BeforeUnitCallback = std::function<void(std::string_view, const CompilationUnit &)>;
+ using AfterUnitCallback = std::function<void(std::string_view, const CompilationUnit &,
+ const CompilationUnitPassResult &)>;
+ using UnitFailureCallback =
+ std::function<void(std::string_view, const CompilationUnit &, const Error &)>;
+ using BeforeUnitAnalysisCallback = std::function<void(std::string_view, const CompilationUnit &)>;
+ using AfterUnitAnalysisCallback =
+ std::function<void(std::string_view, const CompilationUnit &, bool, std::uint64_t)>;
+ using UnitAnalysisFailureCallback =
+ std::function<void(std::string_view, const CompilationUnit &, const Error &)>;
+
+ 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<std::uint64_t> 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<InstrumentationStatistic> statistics() const;
+ [[nodiscard]] std::vector<MachineActionEvent> actionEvents() const;
+
+ [[nodiscard]] Expected<bool> requestAction(std::string_view Pass, std::string_view Rule,
+ const MachineFunction &Function,
+ MachineInstrStableID Instruction, std::uint64_t Cost);
+ [[nodiscard]] Expected<bool> requestAction(std::string_view Pass, std::string_view Rule,
+ const MachineFunction &Function, std::nullptr_t,
+ std::uint64_t Cost);
+
+private:
+ struct BufferedEvents final {
+ const TargetDescription *Target = nullptr;
+ std::vector<std::function<void()>> Events;
+ };
+
+ [[nodiscard]] bool bufferFunctionEvent(const MachineFunction &Function,
+ std::function<void(const MachineFunction &)> Replay) const;
+ void beginBuffering(BufferedEvents &Buffer, const TargetDescription &Target) const noexcept;
+ void endBuffering() const noexcept;
+ void replayBufferedEvents(BufferedEvents &Buffer) const;
+
+ 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;
+
+ mutable std::mutex Mutex;
+ mutable std::mutex ActionMutex;
+ std::vector<BeforeCallback> Before;
+ std::vector<AfterCallback> After;
+ std::vector<FailureCallback> Failure;
+ std::vector<BeforeAnalysisCallback> BeforeAnalysis;
+ std::vector<AfterAnalysisCallback> AfterAnalysis;
+ std::vector<AnalysisFailureCallback> AnalysisFailure;
+ std::vector<IRPrintCallback> IRPrint;
+ std::vector<ChangeCallback> Change;
+ ActionFilter Filter;
+ std::optional<std::uint64_t> PerFunctionFuel;
+ std::unordered_map<std::uint64_t, std::uint64_t> ConsumedFuel;
+ std::vector<MachineActionEvent> ActionEvents;
+
+ std::vector<BeforeUnitCallback> BeforeUnit;
+ std::vector<AfterUnitCallback> AfterUnit;
+ std::vector<UnitFailureCallback> UnitFailure;
+ std::vector<BeforeUnitAnalysisCallback> BeforeUnitAnalysis;
+ std::vector<AfterUnitAnalysisCallback> AfterUnitAnalysis;
+ std::vector<UnitAnalysisFailureCallback> UnitAnalysisFailure;
+ mutable std::unordered_map<std::string, InstrumentationStatistic> Statistics;
+
+ static thread_local BufferedEvents *ActiveBuffer;
+
+ template <typename, typename> friend struct AnalysisManagerInstrumentation;
+ template <typename, typename, typename> friend struct PassManagerCallbacks;
+};
+
+class MachineActionReplay final {
+public:
+ template <typename AnalysisManagerT>
+ explicit MachineActionReplay(AnalysisManagerT &Analyses)
+ : Request([&Analyses](std::string_view Rule, const MachineFunction &Function,
+ MachineInstrStableID Instruction, std::uint64_t Cost) {
+ return Analyses.requestAction(Rule, Function, Instruction, Cost);
+ }) {}
+
+ template <typename AnalysisManagerT>
+ MachineActionReplay(
+ AnalysisManagerT &Analyses,
+ const std::unordered_map<MachineInstrStableID, MachineInstrStableID> &SourceToClone)
+ : MachineActionReplay(Analyses) {
+ for (const auto &[Source, Clone] : SourceToClone)
+ RecordingInstructionIDs.try_emplace(Clone, Source);
+ }
+
+ [[nodiscard]] Expected<bool> request(std::string_view Rule, const MachineFunction &Function,
+ MachineInstrStableID Instruction = {},
+ std::uint64_t Cost = 1);
+ void beginReplay() noexcept;
+ [[nodiscard]] Expected<void> finishReplay() const;
+
+private:
+ struct Decision final {
+ std::string Rule;
+ MachineFunctionStableID Function;
+ MachineInstrStableID Instruction;
+ std::uint64_t Cost = 0;
+ bool Accepted = false;
+ };
+
+ std::function<Expected<bool>(std::string_view, const MachineFunction &, MachineInstrStableID,
+ std::uint64_t)>
+ Request;
+ std::unordered_map<MachineInstrStableID, MachineInstrStableID> RecordingInstructionIDs;
+ std::vector<Decision> Decisions;
+ std::size_t NextDecision = 0;
+ bool IsReplaying = false;
+};
+
+} // namespace rcc
+
+#endif // RCC_IR_PASSINSTRUMENTATION_H
diff --git a/backend/include/rcc/IR/PassManager.h b/backend/include/rcc/IR/PassManager.h
new file mode 100644
index 0000000..b3ab088
--- /dev/null
+++ b/backend/include/rcc/IR/PassManager.h
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_IR_PASSMANAGER_H
+#define RCC_IR_PASSMANAGER_H
+
+#include "rcc/Support/Error.h"
+
+#include <algorithm>
+#include <chrono>
+#include <concepts>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <optional>
+#include <ranges>
+#include <set>
+#include <span>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+namespace rcc {
+
+class TargetDescription;
+
+using AnalysisID = const void *;
+
+class PreservedAnalyses final {
+public:
+ [[nodiscard]] static PreservedAnalyses all() noexcept {
+ PreservedAnalyses Result;
+ Result.PreserveAll = true;
+ return Result;
+ }
+
+ [[nodiscard]] static PreservedAnalyses none() noexcept {
+ return {};
+ }
+
+ void preserve(AnalysisID ID) {
+ if (ID != nullptr)
+ Preserved.insert(ID);
+ }
+
+ template <typename AnalysisT> void preserve() {
+ preserve(analysisID<AnalysisT>());
+ }
+
+ [[nodiscard]] bool preserves(AnalysisID ID) const noexcept {
+ return PreserveAll || (ID != nullptr && Preserved.contains(ID));
+ }
+
+ [[nodiscard]] bool preservesAll() const noexcept {
+ return PreserveAll;
+ }
+
+ template <typename AnalysisT> [[nodiscard]] static AnalysisID analysisID() noexcept {
+ static const std::uint8_t Token = 0;
+ return &Token;
+ }
+
+private:
+ bool PreserveAll = false;
+ std::unordered_set<AnalysisID> Preserved;
+};
+
+enum class PassThreadSafety : std::uint8_t {
+ NotThreadSafe,
+ ThreadSafe,
+};
+
+struct PassParameter final {
+ std::string Name;
+ std::string Description;
+ std::optional<std::string> DefaultValue;
+ bool Required = false;
+};
+
+template <typename IRUnitT, typename InstrumentationT> struct AnalysisManagerInstrumentation {
+ static void beforeAnalysis(InstrumentationT *, std::string_view, const IRUnitT &) {}
+ static void afterAnalysis(InstrumentationT *, std::string_view, const IRUnitT &, bool,
+ std::uint64_t) {}
+ static void analysisFailure(InstrumentationT *, std::string_view, const IRUnitT &, const Error &,
+ std::uint64_t) {}
+
+ template <typename InstructionT>
+ [[nodiscard]] static Expected<bool> requestAction(InstrumentationT *, std::string_view,
+ std::string_view, const IRUnitT &, InstructionT,
+ std::uint64_t) {
+ return true;
+ }
+};
+
+template <typename ChangeT> struct AnalysisRegistration final {
+ AnalysisID ID = nullptr;
+ std::string Name;
+ std::vector<AnalysisID> Dependencies;
+ ChangeT InvalidatedBy = ChangeT::all();
+ PassThreadSafety ThreadSafety = PassThreadSafety::NotThreadSafe;
+};
+
+template <typename IRUnitT, typename PassT, typename OptionsT> struct PassManagerCallbacks;
+
+template <typename IRUnitT, typename PassT, typename OptionsT> class PassManager {
+public:
+ using PassList = std::vector<std::unique_ptr<PassT>>;
+ using Callbacks = PassManagerCallbacks<IRUnitT, PassT, OptionsT>;
+
+ explicit PassManager(OptionsT Options = {}) : Options(Options) {}
+ PassManager(const PassManager &) = delete;
+ PassManager &operator=(const PassManager &) = delete;
+ PassManager(PassManager &&) = default;
+ PassManager &operator=(PassManager &&) = default;
+ ~PassManager() = default;
+
+ [[nodiscard]] Expected<void> addPass(std::unique_ptr<PassT> Pass) {
+ if (!Pass)
+ return makeUnexpected(ErrorCode::InvalidArgument, "pass manager cannot add a null pass");
+ auto Validation = Callbacks::validate(*Pass);
+ if (!Validation)
+ return std::unexpected(Validation.error());
+ Passes.push_back(std::move(Pass));
+ return {};
+ }
+
+ template <typename... Args>
+ [[nodiscard]] Expected<void> run(IRUnitT &Unit, Args &&...Arguments) const {
+ return Callbacks::run(Passes, Options, Unit, std::forward<Args>(Arguments)...);
+ }
+
+ template <typename... Args>
+ [[nodiscard]] Expected<void> runFunctions(Args &&...Arguments) const
+ requires requires(const PassList &InputPasses, const OptionsT &InputOptions,
+ Args &&...InputArguments) {
+ Callbacks::runFunctions(InputPasses, InputOptions, std::forward<Args>(InputArguments)...);
+ }
+ {
+ return Callbacks::runFunctions(Passes, Options, std::forward<Args>(Arguments)...);
+ }
+
+ [[nodiscard]] std::size_t size() const noexcept {
+ return Passes.size();
+ }
+
+ [[nodiscard]] PassList takePasses() && noexcept {
+ return std::move(Passes);
+ }
+
+private:
+ PassList Passes;
+ OptionsT Options;
+};
+
+template <typename IRUnitT, typename RegistrationT, typename ChangeT, typename InstrumentationT>
+class AnalysisManager {
+public:
+ using Self = AnalysisManager<IRUnitT, RegistrationT, ChangeT, InstrumentationT>;
+
+ AnalysisManager() = default;
+ AnalysisManager(const AnalysisManager &) = delete;
+ AnalysisManager &operator=(const AnalysisManager &) = delete;
+ AnalysisManager(AnalysisManager &&) = delete;
+ AnalysisManager &operator=(AnalysisManager &&) = delete;
+ ~AnalysisManager() = default;
+
+ template <typename AnalysisT> [[nodiscard]] static AnalysisID id() noexcept {
+ return PreservedAnalyses::analysisID<AnalysisT>();
+ }
+
+ template <typename AnalysisT>
+ [[nodiscard]] Expected<void> registerAnalysis(RegistrationT Registration = {}) {
+ using ResultT = typename AnalysisT::Result;
+ if (Registration.ID == nullptr)
+ Registration.ID = id<AnalysisT>();
+ if (Registration.Name.empty()) {
+ if constexpr (requires {
+ { AnalysisT::name() } -> std::convertible_to<std::string_view>;
+ })
+ Registration.Name = std::string(AnalysisT::name());
+ else
+ Registration.Name = "unnamed-analysis";
+ }
+
+ ErasedRunner Runner = [](IRUnitT &Unit, const TargetDescription &Target,
+ Self &Manager) -> Expected<std::shared_ptr<void>> {
+ auto Computed = AnalysisT::run(Unit, Target, Manager);
+ if (!Computed)
+ return std::unexpected(Computed.error());
+ return std::shared_ptr<void>(new ResultT(std::move(*Computed)),
+ [](void *Value) { delete static_cast<ResultT *>(Value); });
+ };
+ ErasedInvalidator Invalidator = [](void *Value, const IRUnitT &Unit,
+ const PreservedAnalyses &Preserved) -> bool {
+ if constexpr (requires(ResultT &Result, const IRUnitT &InputUnit,
+ const PreservedAnalyses &Analyses) {
+ { Result.invalidate(InputUnit, Analyses) } -> std::convertible_to<bool>;
+ })
+ return static_cast<ResultT *>(Value)->invalidate(Unit, Preserved);
+ return true;
+ };
+ return registerAnalysisImpl(std::move(Registration), std::move(Runner), std::move(Invalidator));
+ }
+
+ template <typename AnalysisT>
+ [[nodiscard]] Expected<typename AnalysisT::Result *> getResult(IRUnitT &Unit,
+ const TargetDescription &Target) {
+ const AnalysisID Key = id<AnalysisT>();
+ if (!isRegistered(Key)) {
+ auto Registered = registerAnalysis<AnalysisT>();
+ if (!Registered)
+ return std::unexpected(Registered.error());
+ }
+ auto Result = getResultImpl(Key, Unit, Target);
+ if (!Result)
+ return std::unexpected(Result.error());
+ return static_cast<typename AnalysisT::Result *>(*Result);
+ }
+
+ [[nodiscard]] Expected<void *> getResultByID(AnalysisID ID, IRUnitT &Unit,
+ const TargetDescription &Target) {
+ return getResultImpl(ID, Unit, Target);
+ }
+
+ void invalidate(IRUnitT &Unit, const PreservedAnalyses &Preserved, ChangeT Changes) noexcept {
+ const auto UnitPosition = Cache.find(&Unit);
+ if (UnitPosition == Cache.end() || Preserved.preservesAll() || Changes.empty())
+ return;
+
+ std::set<AnalysisID> Invalid;
+ for (auto &[ID, Entry] : UnitPosition->second) {
+ if (Preserved.preserves(ID))
+ continue;
+ const auto Registration = Registry.find(ID);
+ if (Registration == Registry.end() ||
+ Registration->second.Info.InvalidatedBy.intersects(Changes)) {
+ const bool ShouldInvalidate =
+ Registration == Registry.end() || !Entry.Value || !Registration->second.Invalidator ||
+ Registration->second.Invalidator(Entry.Value.get(), Unit, Preserved);
+ if (ShouldInvalidate)
+ Invalid.insert(ID);
+ }
+ }
+
+ bool Added = true;
+ while (Added) {
+ Added = false;
+ for (const auto &[ID, Entry] : UnitPosition->second) {
+ (void)Entry;
+ if (Invalid.contains(ID) || Preserved.preserves(ID))
+ continue;
+ const auto Registration = Registry.find(ID);
+ if (Registration != Registry.end() &&
+ std::ranges::any_of(
+ Registration->second.Info.Dependencies,
+ [&Invalid](AnalysisID Dependency) { return Invalid.contains(Dependency); }))
+ Added = Invalid.insert(ID).second || Added;
+ }
+ }
+
+ for (const AnalysisID ID : Invalid)
+ UnitPosition->second.erase(ID);
+ if (UnitPosition->second.empty())
+ Cache.erase(UnitPosition);
+ }
+
+ void invalidate(IRUnitT &Unit, const PreservedAnalyses &Preserved) noexcept {
+ invalidate(Unit, Preserved, ChangeT::all());
+ }
+
+ [[nodiscard]] bool hasCached(const IRUnitT &Unit, AnalysisID ID) const noexcept {
+ const auto UnitPosition = Cache.find(const_cast<IRUnitT *>(&Unit));
+ if (UnitPosition == Cache.end())
+ return false;
+ const auto AnalysisPosition = UnitPosition->second.find(ID);
+ return AnalysisPosition != UnitPosition->second.end() && AnalysisPosition->second.Value;
+ }
+
+ [[nodiscard]] std::size_t cachedResultCount(const IRUnitT &Unit) const noexcept {
+ const auto Position = Cache.find(const_cast<IRUnitT *>(&Unit));
+ return Position == Cache.end() ? 0 : Position->second.size();
+ }
+
+ [[nodiscard]] bool isRegistered(AnalysisID ID) const noexcept {
+ return ID != nullptr && Registry.contains(ID);
+ }
+
+ void clear(IRUnitT &Unit) noexcept {
+ Cache.erase(&Unit);
+ ActiveComputations.erase(&Unit);
+ }
+
+ void clearAll() noexcept {
+ Cache.clear();
+ ActiveComputations.clear();
+ }
+
+ [[nodiscard]] Expected<std::unique_ptr<Self>> forkEmpty() const {
+ if (!ActiveComputations.empty())
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "cannot fork an analysis manager during analysis computation");
+ auto Result = std::make_unique<Self>();
+ Result->Registry = Registry;
+ return Result;
+ }
+
+ [[nodiscard]] Expected<void> replaceRegistrations(Self &&Source) {
+ if (!Cache.empty() || !ActiveComputations.empty() || !Source.Cache.empty() ||
+ !Source.ActiveComputations.empty())
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "analysis registrations can only be replaced on empty managers");
+ Registry = std::move(Source.Registry);
+ return {};
+ }
+
+ [[nodiscard]] Expected<void>
+ validateParallelRequirements(std::span<const AnalysisID> RequiredAnalyses) const {
+ std::vector<AnalysisID> Worklist(RequiredAnalyses.begin(), RequiredAnalyses.end());
+ std::unordered_set<AnalysisID> Visited;
+ for (std::size_t Index = 0; Index < Worklist.size(); ++Index) {
+ const AnalysisID ID = Worklist[Index];
+ if (ID == nullptr || !Visited.insert(ID).second)
+ continue;
+ const auto Position = Registry.find(ID);
+ if (Position == Registry.end())
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "parallel pass requires an unregistered analysis");
+ if (Position->second.Info.ThreadSafety != PassThreadSafety::ThreadSafe)
+ return makeUnexpected(ErrorCode::InvalidArgument, "parallel pipeline requires analysis '" +
+ Position->second.Info.Name +
+ "' to be marked thread-safe");
+ Worklist.insert(Worklist.end(), Position->second.Info.Dependencies.begin(),
+ Position->second.Info.Dependencies.end());
+ }
+ return {};
+ }
+
+ void setInstrumentation(InstrumentationT *NewInstrumentation) noexcept {
+ Instrumentation = NewInstrumentation;
+ }
+
+ void setActivePass(std::string Name) {
+ ActivePass = std::move(Name);
+ }
+
+ template <typename InstructionT>
+ [[nodiscard]] Expected<bool> requestAction(std::string_view Rule, const IRUnitT &Unit,
+ InstructionT Instruction, std::uint64_t Cost = 1) {
+ if (Rule.empty() || Cost == 0)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "pass action requires a name and nonzero cost");
+ if (Instrumentation == nullptr)
+ return true;
+ return AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::requestAction(
+ Instrumentation, ActivePass.empty() ? "unscoped" : ActivePass, Rule, Unit, Instruction,
+ Cost);
+ }
+
+ [[nodiscard]] Expected<bool> requestAction(std::string_view Rule, const IRUnitT &Unit,
+ std::uint64_t Cost = 1) {
+ if (Rule.empty() || Cost == 0)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "pass action requires a name and nonzero cost");
+ if (Instrumentation == nullptr)
+ return true;
+ return AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::requestAction(
+ Instrumentation, ActivePass.empty() ? "unscoped" : ActivePass, Rule, Unit, nullptr, Cost);
+ }
+
+ [[nodiscard]] const std::string &activePass() const noexcept {
+ return ActivePass;
+ }
+
+private:
+ using ErasedRunner =
+ std::function<Expected<std::shared_ptr<void>>(IRUnitT &, const TargetDescription &, Self &)>;
+ using ErasedInvalidator = std::function<bool(void *, const IRUnitT &, const PreservedAnalyses &)>;
+
+ struct RegisteredAnalysis final {
+ RegistrationT Info;
+ ErasedRunner Runner;
+ ErasedInvalidator Invalidator;
+ };
+
+ struct CacheEntry final {
+ std::shared_ptr<void> Value;
+ AnalysisID ID = nullptr;
+ };
+
+ [[nodiscard]] static bool hasDuplicateAnalysisIDs(std::span<const AnalysisID> IDs) {
+ std::unordered_set<AnalysisID> Unique;
+ for (const AnalysisID ID : IDs) {
+ if (ID == nullptr || !Unique.insert(ID).second)
+ return true;
+ }
+ return false;
+ }
+
+ [[nodiscard]] Expected<void> registerAnalysisImpl(RegistrationT Registration, ErasedRunner Runner,
+ ErasedInvalidator Invalidator) {
+ if (Registration.ID == nullptr || Registration.Name.empty() || !Runner || !Invalidator)
+ return makeUnexpected(ErrorCode::InvalidArgument, "analysis registration is incomplete");
+ if (hasDuplicateAnalysisIDs(Registration.Dependencies))
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "analysis dependencies must be non-null and unique");
+ if (std::ranges::find(Registration.Dependencies, Registration.ID) !=
+ Registration.Dependencies.end())
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "analysis cannot directly depend on itself");
+ if (Registry.contains(Registration.ID))
+ return makeUnexpected(ErrorCode::InvalidArgument, "analysis ID is already registered");
+ if (std::ranges::any_of(Registry, [&Registration](const auto &Entry) {
+ return Entry.second.Info.Name == Registration.Name;
+ }))
+ return makeUnexpected(ErrorCode::InvalidArgument, "analysis name is already registered");
+ Registry.emplace(Registration.ID, RegisteredAnalysis{std::move(Registration), std::move(Runner),
+ std::move(Invalidator)});
+ return {};
+ }
+
+ [[nodiscard]] Expected<void *> getResultImpl(AnalysisID ID, IRUnitT &Unit,
+ const TargetDescription &Target) {
+ if (ID == nullptr)
+ return makeUnexpected(ErrorCode::InvalidArgument, "analysis ID cannot be null");
+ auto &UnitCache = Cache[&Unit];
+ if (const auto Cached = UnitCache.find(ID); Cached != UnitCache.end() && Cached->second.Value) {
+ const auto Registration = Registry.find(ID);
+ const std::string_view Name = Registration == Registry.end()
+ ? std::string_view{"unknown-analysis"}
+ : std::string_view{Registration->second.Info.Name};
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::afterAnalysis(
+ Instrumentation, Name, Unit, true, 0);
+ return Cached->second.Value.get();
+ }
+
+ const auto RegistrationPosition = Registry.find(ID);
+ if (RegistrationPosition == Registry.end())
+ return makeUnexpected(ErrorCode::InvalidArgument, "analysis ID is not registered");
+ const RegisteredAnalysis &Registration = RegistrationPosition->second;
+ auto &Stack = ActiveComputations[&Unit];
+ if (std::ranges::find(Stack, ID) != Stack.end()) {
+ Error Failure(ErrorCode::InvalidArgument,
+ "analysis dependency cycle reaches '" + Registration.Info.Name + "'");
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::analysisFailure(
+ Instrumentation, Registration.Info.Name, Unit, Failure, 0);
+ return std::unexpected(std::move(Failure));
+ }
+
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::beforeAnalysis(
+ Instrumentation, Registration.Info.Name, Unit);
+ const auto Start = std::chrono::steady_clock::now();
+ Stack.push_back(ID);
+ for (const AnalysisID Dependency : Registration.Info.Dependencies) {
+ if (!Registry.contains(Dependency)) {
+ Stack.pop_back();
+ if (Stack.empty())
+ ActiveComputations.erase(&Unit);
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "analysis depends on an unregistered analysis");
+ }
+ auto DependencyResult = getResultImpl(Dependency, Unit, Target);
+ if (!DependencyResult) {
+ Stack.pop_back();
+ if (Stack.empty())
+ ActiveComputations.erase(&Unit);
+ Error Failure = DependencyResult.error();
+ std::string Message = "analysis '" + Registration.Info.Name + "' failed: ";
+ Message.append(Failure.message());
+ Failure = Error(Failure.code(), std::move(Message));
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::analysisFailure(
+ Instrumentation, Registration.Info.Name, Unit, Failure, elapsedNanoseconds(Start));
+ return std::unexpected(std::move(Failure));
+ }
+ }
+
+ auto Computed = Registration.Runner(Unit, Target, *this);
+ Stack.pop_back();
+ if (Stack.empty())
+ ActiveComputations.erase(&Unit);
+ const std::uint64_t Duration = elapsedNanoseconds(Start);
+ if (!Computed) {
+ Error Failure = Computed.error();
+ std::string Message = "analysis '" + Registration.Info.Name + "' failed: ";
+ Message.append(Failure.message());
+ Failure = Error(Failure.code(), std::move(Message));
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::analysisFailure(
+ Instrumentation, Registration.Info.Name, Unit, Failure, Duration);
+ return std::unexpected(std::move(Failure));
+ }
+ if (!*Computed) {
+ Error Failure(ErrorCode::InternalError,
+ "analysis '" + Registration.Info.Name + "' returned a null result");
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::analysisFailure(
+ Instrumentation, Registration.Info.Name, Unit, Failure, Duration);
+ return std::unexpected(std::move(Failure));
+ }
+
+ void *Result = Computed->get();
+ UnitCache.emplace(ID, CacheEntry{std::move(*Computed), ID});
+ if (Instrumentation != nullptr)
+ AnalysisManagerInstrumentation<IRUnitT, InstrumentationT>::afterAnalysis(
+ Instrumentation, Registration.Info.Name, Unit, false, Duration);
+ return Result;
+ }
+
+ [[nodiscard]] static std::uint64_t
+ elapsedNanoseconds(std::chrono::steady_clock::time_point Start) noexcept {
+ const auto Elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::steady_clock::now() - Start);
+ return Elapsed.count() <= 0 ? 0 : static_cast<std::uint64_t>(Elapsed.count());
+ }
+
+ std::unordered_map<AnalysisID, RegisteredAnalysis> Registry;
+ std::unordered_map<IRUnitT *, std::unordered_map<AnalysisID, CacheEntry>> Cache;
+ std::unordered_map<IRUnitT *, std::vector<AnalysisID>> ActiveComputations;
+ InstrumentationT *Instrumentation = nullptr;
+ std::string ActivePass;
+};
+
+} // namespace rcc
+
+#endif // RCC_IR_PASSMANAGER_H
diff --git a/backend/include/rcc/Target/RISCV/RISCVPipeline.h b/backend/include/rcc/Target/RISCV/RISCVPipeline.h
index ba0428b..8b27032 100644
--- a/backend/include/rcc/Target/RISCV/RISCVPipeline.h
+++ b/backend/include/rcc/Target/RISCV/RISCVPipeline.h
@@ -3,7 +3,7 @@
#ifndef RCC_TARGET_RISCV_RISCVPIPELINE_H
#define RCC_TARGET_RISCV_RISCVPIPELINE_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/Support/Error.h"
#include "rcc/Target/RISCV/RISCVSubtarget.h"
@@ -19,7 +19,7 @@ class TargetDescription;
namespace riscv {
-[[nodiscard]] Expected<void> addCanonicalPipeline(MachinePassManager &Pipeline,
+[[nodiscard]] Expected<void> addCanonicalPipeline(MachineFunctionPassManager &Pipeline,
const MachineFunction &Function,
const RISCVSubtarget &Subtarget);
[[nodiscard]] Expected<std::unique_ptr<MachineFunctionPass>>
diff --git a/backend/include/rcc/Tooling/BackendDriver.h b/backend/include/rcc/Tooling/BackendDriver.h
index 7b62b6d..6b04de9 100644
--- a/backend/include/rcc/Tooling/BackendDriver.h
+++ b/backend/include/rcc/Tooling/BackendDriver.h
@@ -3,7 +3,7 @@
#ifndef RCC_TOOLING_BACKENDDRIVER_H
#define RCC_TOOLING_BACKENDDRIVER_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/Support/Error.h"
#include "rcc/Tooling/ArtifactStore.h"
#include "rcc/Tooling/PipelineDriver.h"
diff --git a/backend/include/rcc/Tooling/PipelineDriver.h b/backend/include/rcc/Tooling/PipelineDriver.h
index 5d2dc45..849b2f7 100644
--- a/backend/include/rcc/Tooling/PipelineDriver.h
+++ b/backend/include/rcc/Tooling/PipelineDriver.h
@@ -3,7 +3,7 @@
#ifndef RCC_TOOLING_PIPELINEDRIVER_H
#define RCC_TOOLING_PIPELINEDRIVER_H
-#include "rcc/CodeGen/MachinePass.h"
+#include "rcc/CodeGen/MachinePassManager.h"
#include "rcc/MIR/MIRDocument.h"
#include "rcc/Tooling/BackendInvocation.h"