aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 18:13:19 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 18:13:19 +0800
commit2920d4547d2ccea40da547de5d07dd2383de5e87 (patch)
tree139a71b0ff6db081e1ae70a97cd81b031b1c59a0
parentff1029193a6c505e31b0b5df360c9af73b921b42 (diff)
downloadrcc-project-2920d4547d2ccea40da547de5d07dd2383de5e87.tar.gz
rcc-project-2920d4547d2ccea40da547de5d07dd2383de5e87.tar.xz
[CodeGen] Remove RCC fallthrough normalization
-rw-r--r--backend/include/rcc/CodeGen/MachineFallthrough.h27
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt2
-rw-r--r--backend/lib/CodeGen/MachineFallthrough.cpp163
-rw-r--r--backend/lib/CodeGen/MachineOptimizationPipeline.cpp4
-rw-r--r--backend/unittests/Target/RISCVLateCodeGenTest.cpp74
5 files changed, 0 insertions, 270 deletions
diff --git a/backend/include/rcc/CodeGen/MachineFallthrough.h b/backend/include/rcc/CodeGen/MachineFallthrough.h
deleted file mode 100644
index bb62e8a..0000000
--- a/backend/include/rcc/CodeGen/MachineFallthrough.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#ifndef RCC_CODEGEN_MACHINEFALLTHROUGH_H
-#define RCC_CODEGEN_MACHINEFALLTHROUGH_H
-
-#include "rcc/CodeGen/MachinePassManager.h"
-
-namespace rcc {
-
-class TargetInstrInfo;
-
-class MachineFallthroughPass final : public MachineFunctionPass {
-public:
- explicit MachineFallthroughPass(const TargetInstrInfo &Info) noexcept : Info(&Info) {}
-
- [[nodiscard]] const MachinePassContract &contract() const noexcept override;
- [[nodiscard]] Expected<MachinePassResult> run(MachineFunction &Function,
- const TargetDescription &Target,
- MachineFunctionAnalysisManager &Analyses) override;
-
-private:
- const TargetInstrInfo *Info;
-};
-
-} // namespace rcc
-
-#endif // RCC_CODEGEN_MACHINEFALLTHROUGH_H
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt
index 881e17e..6a7f38d 100644
--- a/backend/lib/CodeGen/CMakeLists.txt
+++ b/backend/lib/CodeGen/CMakeLists.txt
@@ -25,7 +25,6 @@ set(
MachineDebugInfo.cpp
MachineDCE.cpp
MachineFrameInfo.cpp
- MachineFallthrough.cpp
MachineFinalization.cpp
MachineFunction.cpp
MachineFunctionAttributes.cpp
@@ -112,7 +111,6 @@ set(
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineDebugInfo.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineDCE.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFrameInfo.h"
- "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFallthrough.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFinalization.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunction.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunctionAttributes.h"
diff --git a/backend/lib/CodeGen/MachineFallthrough.cpp b/backend/lib/CodeGen/MachineFallthrough.cpp
deleted file mode 100644
index 3619155..0000000
--- a/backend/lib/CodeGen/MachineFallthrough.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "rcc/CodeGen/MachineFallthrough.h"
-
-#include "rcc/CodeGen/LivePhysRegs.h"
-#include "rcc/CodeGen/LiveVariables.h"
-#include "rcc/CodeGen/MachineBasicBlock.h"
-#include "rcc/CodeGen/MachineFunction.h"
-#include "rcc/CodeGen/MachineFunctionCloner.h"
-#include "rcc/CodeGen/TargetDescription.h"
-#include "rcc/CodeGen/TargetInstrInfo.h"
-
-#include <optional>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace rcc {
-namespace {
-
-[[nodiscard]] const MachinePassContract &fallthroughContract() {
- static const MachinePassContract Contract = [] {
- MachinePassContract Value{
- .Name = "machine-fallthrough-normalization",
- .Requires = {MachineFunctionProperty::Selected, MachineFunctionProperty::NoPHIs,
- MachineFunctionProperty::NoVRegs, MachineFunctionProperty::TracksLiveness},
- .Sets = {},
- .Clears = {},
- .RequiredAnalyses = {MachineFunctionAnalysisManager::id<LiveVariablesAnalysis>()},
- .VerificationStage = PipelineStage::RegisterAllocated,
- };
- Value.ThreadSafety = PassThreadSafety::ThreadSafe;
- Value.DeclaredChanges = {MachinePassChange::Instructions, MachinePassChange::Operands};
- return Value;
- }();
- return Contract;
-}
-
-[[nodiscard]] Expected<std::vector<MachineBasicBlock *>>
-normalizeFallthroughs(MachineFunction &Function, const TargetDescription &Target,
- const TargetInstrInfo &Info) {
- std::vector<MachineBasicBlock *> ChangedBlocks;
- for (MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; Block = Block->next()) {
- MachineBasicBlock *LayoutSuccessor = Block->next();
- if (LayoutSuccessor == nullptr)
- continue;
- auto Analysis = Info.analyzeBranch(*Block, Function, Target);
- if (!Analysis)
- return std::unexpected(Analysis.error());
- if (Analysis->HasUnanalyzableTerminator)
- continue;
- bool Changed = false;
- if (Analysis->Conditional != nullptr && Analysis->Unconditional != nullptr &&
- Analysis->FalseTarget == LayoutSuccessor) {
- auto Removed = Info.removeBranch(*Analysis->Unconditional, Function, Target);
- if (!Removed)
- return std::unexpected(Removed.error());
- Changed = true;
- } else if (Analysis->Conditional != nullptr && Analysis->Unconditional != nullptr &&
- Analysis->TrueTarget == LayoutSuccessor && Analysis->FalseTarget != nullptr) {
- auto Reversed = Info.reverseBranchCondition(*Analysis->Conditional, *Analysis->FalseTarget,
- Function, Target);
- if (!Reversed)
- return std::unexpected(Reversed.error());
- auto Removed = Info.removeBranch(*Analysis->Unconditional, Function, Target);
- if (!Removed)
- return std::unexpected(Removed.error());
- Changed = true;
- } else if (Analysis->Conditional != nullptr && Analysis->Unconditional == nullptr &&
- Analysis->FalseTarget == LayoutSuccessor) {
- continue;
- } else if (Analysis->Conditional != nullptr && Analysis->Unconditional == nullptr &&
- Analysis->TrueTarget == LayoutSuccessor && Analysis->FalseTarget != nullptr) {
- auto Reversed = Info.reverseBranchCondition(*Analysis->Conditional, *Analysis->FalseTarget,
- Function, Target);
- if (!Reversed)
- return std::unexpected(Reversed.error());
- Changed = true;
- } else if (Analysis->Conditional != nullptr && Analysis->Unconditional == nullptr &&
- Analysis->FalseTarget != nullptr) {
- auto Inserted = Info.insertBranch(*Block, *Analysis->FalseTarget, Function, Target);
- if (!Inserted)
- return std::unexpected(Inserted.error());
- Changed = true;
- } else if (Analysis->Conditional == nullptr && Analysis->Unconditional != nullptr &&
- Analysis->TrueTarget == LayoutSuccessor) {
- auto Removed = Info.removeBranch(*Analysis->Unconditional, Function, Target);
- if (!Removed)
- return std::unexpected(Removed.error());
- Changed = true;
- } else if (Analysis->Conditional == nullptr && Analysis->Unconditional == nullptr &&
- Block->successors().size() == 1 &&
- Block->successors().front().Block != LayoutSuccessor) {
- MachineBasicBlock *Successor = Block->successors().front().Block;
- if (Successor == nullptr) {
- return makeUnexpected(ErrorCode::VerificationError,
- "fallthrough normalization encountered a null successor");
- }
- auto Inserted = Info.insertBranch(*Block, *Successor, Function, Target);
- if (!Inserted)
- return std::unexpected(Inserted.error());
- Changed = true;
- }
- if (Changed)
- ChangedBlocks.push_back(Block);
- }
- return ChangedBlocks;
-}
-
-} // namespace
-
-const MachinePassContract &MachineFallthroughPass::contract() const noexcept {
- return fallthroughContract();
-}
-
-Expected<MachinePassResult> MachineFallthroughPass::run(MachineFunction &Function,
- const TargetDescription &Target,
- MachineFunctionAnalysisManager &Analyses) {
- if (!Function.properties().containsAll(contract().Requires)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "fallthrough normalization requires allocated tracked-liveness MIR");
- }
- auto Trial = cloneMachineFunction(
- Function, Target,
- MachineFunctionCloneOptions{.NewStableID = Function.stableID(), .NewName = std::nullopt});
- if (!Trial)
- return std::unexpected(withErrorContext(Trial.error(), "fallthrough setup failed: "));
- MachineFunctionAnalysisManager TrialAnalyses;
- auto TrialLiveness =
- TrialAnalyses.getResult<LiveVariablesAnalysis>(*Trial->ClonedFunction, Target);
- if (!TrialLiveness)
- return std::unexpected(TrialLiveness.error());
- auto TrialChanged = normalizeFallthroughs(*Trial->ClonedFunction, Target, *Info);
- if (!TrialChanged)
- return std::unexpected(TrialChanged.error());
- auto TrialRepair = repairPostRAMachineBlockLiveness(*TrialChanged, Target, **TrialLiveness);
- if (!TrialRepair)
- return std::unexpected(TrialRepair.error());
-
- auto Liveness = Analyses.getResult<LiveVariablesAnalysis>(Function, Target);
- if (!Liveness)
- return std::unexpected(Liveness.error());
- auto ChangedBlocks = normalizeFallthroughs(Function, Target, *Info);
- if (!ChangedBlocks) {
- return std::unexpected(withErrorContext(ChangedBlocks.error(),
- "fallthrough diverged after a successful preflight: "));
- }
- auto Repaired = repairPostRAMachineBlockLiveness(*ChangedBlocks, Target, **Liveness);
- if (!Repaired)
- return std::unexpected(Repaired.error());
-
- MachinePassResult Result;
- Result.Changed = !ChangedBlocks->empty() || *Repaired;
- if (Result.Changed) {
- Result.Changes = {MachinePassChange::Instructions, MachinePassChange::Operands};
- Result.Preserved.preserve<LiveVariablesAnalysis>();
- } else {
- Result.Preserved = PreservedAnalyses::all();
- }
- return Result;
-}
-
-} // namespace rcc
diff --git a/backend/lib/CodeGen/MachineOptimizationPipeline.cpp b/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
index 7634ecd..f96d544 100644
--- a/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
+++ b/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
@@ -11,7 +11,6 @@
#include "rcc/CodeGen/MachineCombiner.h"
#include "rcc/CodeGen/MachineCopyPropagation.h"
#include "rcc/CodeGen/MachineDCE.h"
-#include "rcc/CodeGen/MachineFallthrough.h"
#include "rcc/CodeGen/MachineFinalization.h"
#include "rcc/CodeGen/MachineLICM.h"
#include "rcc/CodeGen/MachineMemoryFolding.h"
@@ -119,9 +118,6 @@ addPostRegisterAllocationPipeline(MachineFunctionPassManager &Pipeline,
Added = addPass<MachineBlockPlacementPass>(Pipeline);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineFallthroughPass>(Pipeline, TargetInfo.InstrInfo);
- if (!Added)
- return std::unexpected(Added.error());
Added = addPass<MachineBranchRelaxationPass>(Pipeline, TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
diff --git a/backend/unittests/Target/RISCVLateCodeGenTest.cpp b/backend/unittests/Target/RISCVLateCodeGenTest.cpp
index 955af50..8160370 100644
--- a/backend/unittests/Target/RISCVLateCodeGenTest.cpp
+++ b/backend/unittests/Target/RISCVLateCodeGenTest.cpp
@@ -10,7 +10,6 @@
#include "rcc/CodeGen/MachineBranchRelaxation.h"
#include "rcc/CodeGen/MachineCFGUpdater.h"
#include "rcc/CodeGen/MachineCopyPropagation.h"
-#include "rcc/CodeGen/MachineFallthrough.h"
#include "rcc/CodeGen/MachineFinalization.h"
#include "rcc/CodeGen/MachineFunction.h"
#include "rcc/CodeGen/MachineIRBuilder.h"
@@ -384,77 +383,6 @@ void testBlockPlacement(TestContext &Context, const rcc::TargetDescription &Targ
"block placement must put the highest-probability successor on the trace");
}
-void testFallthroughNormalization(TestContext &Context, const rcc::TargetDescription &Target) {
- auto Function = makeFunction(Context, "fallthrough", 2);
- if (!Function)
- return;
- rcc::MachineBasicBlock *Entry = appendBlock(Context, *Function);
- rcc::MachineBasicBlock *False = appendBlock(Context, *Function);
- rcc::MachineBasicBlock *True = appendBlock(Context, *Function);
- if (Entry == nullptr || False == nullptr || True == nullptr)
- return;
- auto Half = rcc::BranchProbability::fromFraction(1, 2);
- auto CFG = Function->cfgUpdater();
- Context.expect(Half && CFG.addSuccessor(*Entry, *True, *Half).has_value() &&
- CFG.addSuccessor(*Entry, *False, *Half).has_value(),
- "fallthrough CFG construction must succeed");
- rcc::MachineIRBuilder Builder(*Function, Target);
- Context.expect(Builder.setInsertPoint(*Entry).has_value(),
- "fallthrough insertion point must be established");
- rcc::MachineInstr *Conditional =
- buildConditional(Context, Builder, rcc::riscv::InstructionOpcode::BEQ, *True);
- rcc::MachineInstr *Jump = buildJAL(Context, Builder, *False);
- if (Conditional == nullptr || Jump == nullptr)
- return;
- setPostRAProperties(*Function);
- auto Liveness = rcc::rebuildMachineLiveness(*Function, Target);
- Context.expect(Liveness.has_value(), "fallthrough fixture liveness must be rebuilt");
- rcc::MachineFunctionAnalysisManager Analyses;
- rcc::MachineFallthroughPass Pass(rcc::riscv::instrInfo());
- auto Result = Pass.run(*Function, Target, Analyses);
- if (!Result)
- std::cerr << "fallthrough normalization failure: " << Result.error().message() << '\n';
- Context.expect(Result && Result->Changed && Conditional->next() == nullptr &&
- Jump->parent() == nullptr,
- "fallthrough normalization must remove a jump to the next block");
-}
-
-void testFallthroughMaterialization(TestContext &Context, const rcc::TargetDescription &Target) {
- auto Function = makeFunction(Context, "fallthrough_materialization", 8);
- if (!Function)
- return;
- rcc::MachineBasicBlock *Entry = appendBlock(Context, *Function);
- rcc::MachineBasicBlock *Padding = appendBlock(Context, *Function);
- rcc::MachineBasicBlock *True = appendBlock(Context, *Function);
- rcc::MachineBasicBlock *False = appendBlock(Context, *Function);
- if (Entry == nullptr || Padding == nullptr || True == nullptr || False == nullptr)
- return;
- auto Half = rcc::BranchProbability::fromFraction(1, 2);
- auto CFG = Function->cfgUpdater();
- Context.expect(Half && CFG.addSuccessor(*Entry, *True, *Half).has_value() &&
- CFG.addSuccessor(*Entry, *False, *Half).has_value(),
- "materialized fallthrough CFG construction must succeed");
- rcc::MachineIRBuilder Builder(*Function, Target);
- Context.expect(Builder.setInsertPoint(*Entry).has_value(),
- "materialized fallthrough insertion point must be established");
- rcc::MachineInstr *Conditional =
- buildConditional(Context, Builder, rcc::riscv::InstructionOpcode::BNE, *True);
- if (Conditional == nullptr)
- return;
- setPostRAProperties(*Function);
- Context.expect(rcc::rebuildMachineLiveness(*Function, Target).has_value(),
- "materialized fallthrough liveness must be rebuilt");
- rcc::MachineFunctionAnalysisManager Analyses;
- rcc::MachineFallthroughPass Pass(rcc::riscv::instrInfo());
- auto Result = Pass.run(*Function, Target, Analyses);
- if (!Result)
- std::cerr << "fallthrough materialization failure: " << Result.error().message() << '\n';
- Context.expect(Result && Result->Changed && Conditional->next() != nullptr &&
- Conditional->next()->opcode() == opcode(rcc::riscv::InstructionOpcode::JAL) &&
- branchTarget(*Conditional->next()) == False,
- "fallthrough normalization must materialize a displaced false edge");
-}
-
void testBranchOptimization(TestContext &Context, const rcc::TargetDescription &Target) {
auto Function = makeFunction(Context, "branch_optimization", 9);
if (!Function)
@@ -1359,8 +1287,6 @@ int main() {
if (!Target)
return Context.result();
testBlockPlacement(Context, *Target);
- testFallthroughNormalization(Context, *Target);
- testFallthroughMaterialization(Context, *Target);
testBranchOptimization(Context, *Target);
testTailDuplication(Context, *Target);
testBranchFoldingTailMerge(Context, *Target);