From c759cebef15bdac2ef160065efd116fe6ed540a7 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 1 Aug 2026 05:27:13 +0800 Subject: [CodeGen] Build the core MachineIR object model Add arena-owned, address-stable MachineFunction, MachineBasicBlock, and MachineInstr nodes with intrusive layout and instruction lists. Model every required MachineOperand category, reciprocal ties, source state, and immutable per-instruction memory references. Implement physical and virtual register def-use chains whose back-links survive operand vector moves, plus vreg properties, tombstones, live-ins, reserved registers, and atomic CFG updates. Exercise ownership, reallocation, unlink/relink, cross-function rejection, and sanitizer paths. --- backend/lib/CodeGen/MachineCFGUpdater.cpp | 181 ++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 backend/lib/CodeGen/MachineCFGUpdater.cpp (limited to 'backend/lib/CodeGen/MachineCFGUpdater.cpp') diff --git a/backend/lib/CodeGen/MachineCFGUpdater.cpp b/backend/lib/CodeGen/MachineCFGUpdater.cpp new file mode 100644 index 0000000..c78e318 --- /dev/null +++ b/backend/lib/CodeGen/MachineCFGUpdater.cpp @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/MachineCFGUpdater.h" + +#include "rcc/CodeGen/MachineBasicBlock.h" +#include "rcc/CodeGen/MachineFunction.h" + +#include +#include +#include +#include +#include + +namespace rcc { +namespace { + +[[nodiscard]] std::optional findSuccessorIndex(const MachineBasicBlock &From, + const MachineBasicBlock &To) { + const auto Successors = From.successors(); + for (std::size_t Index = 0; Index < Successors.size(); ++Index) { + if (Successors[Index].Block == &To) + return Index; + } + return std::nullopt; +} + +} // namespace + +Expected MachineCFGUpdater::verifyOwnership(const MachineBasicBlock &Block) const { + if (&Block.function() != Function) { + return makeUnexpected(ErrorCode::InvalidArgument, + "CFG block belongs to another machine function"); + } + return {}; +} + +Expected MachineCFGUpdater::addSuccessor(MachineBasicBlock &From, MachineBasicBlock &To, + BranchProbability Probability) { + auto FromOwnership = verifyOwnership(From); + if (!FromOwnership) + return std::unexpected(FromOwnership.error()); + auto ToOwnership = verifyOwnership(To); + if (!ToOwnership) + return std::unexpected(ToOwnership.error()); + + const auto Existing = findSuccessorIndex(From, To); + if (Existing) { + From.Successors[*Existing].Probability = + From.Successors[*Existing].Probability.saturatingAdd(Probability); + return {}; + } + + From.Successors.push_back(MachineSuccessor{&To, Probability}); + if (std::ranges::find(To.Predecessors, &From) == To.Predecessors.end()) + To.Predecessors.push_back(&From); + return {}; +} + +Expected MachineCFGUpdater::removeSuccessor(MachineBasicBlock &From, MachineBasicBlock &To) { + auto FromOwnership = verifyOwnership(From); + if (!FromOwnership) + return std::unexpected(FromOwnership.error()); + auto ToOwnership = verifyOwnership(To); + if (!ToOwnership) + return std::unexpected(ToOwnership.error()); + + const auto Successor = findSuccessorIndex(From, To); + if (!Successor) { + return makeUnexpected(ErrorCode::InvalidArgument, "CFG successor edge is not present"); + } + From.Successors.erase(From.Successors.begin() + static_cast(*Successor)); + + const auto Predecessor = std::ranges::find(To.Predecessors, &From); + if (Predecessor == To.Predecessors.end()) { + return makeUnexpected(ErrorCode::VerificationError, + "CFG successor has no reciprocal predecessor"); + } + To.Predecessors.erase(Predecessor); + return {}; +} + +Expected MachineCFGUpdater::replaceSuccessor(MachineBasicBlock &From, + MachineBasicBlock &OldTarget, + MachineBasicBlock &NewTarget) { + auto FromOwnership = verifyOwnership(From); + if (!FromOwnership) + return std::unexpected(FromOwnership.error()); + auto OldOwnership = verifyOwnership(OldTarget); + if (!OldOwnership) + return std::unexpected(OldOwnership.error()); + auto NewOwnership = verifyOwnership(NewTarget); + if (!NewOwnership) + return std::unexpected(NewOwnership.error()); + + if (&OldTarget == &NewTarget) + return {}; + + const auto Existing = findSuccessorIndex(From, OldTarget); + if (!Existing) { + return makeUnexpected(ErrorCode::InvalidArgument, "replaced CFG successor edge is not present"); + } + const BranchProbability Probability = From.Successors[*Existing].Probability; + + auto RemoveResult = removeSuccessor(From, OldTarget); + if (!RemoveResult) + return std::unexpected(RemoveResult.error()); + auto AddResult = addSuccessor(From, NewTarget, Probability); + if (!AddResult) { + auto RestoreResult = addSuccessor(From, OldTarget, Probability); + if (!RestoreResult) { + return makeUnexpected(ErrorCode::InternalError, + "failed to restore CFG edge after replacement failure"); + } + return std::unexpected(AddResult.error()); + } + return {}; +} + +Expected MachineCFGUpdater::updateBranchProbability(MachineBasicBlock &From, + MachineBasicBlock &To, + BranchProbability Probability) { + auto FromOwnership = verifyOwnership(From); + if (!FromOwnership) + return std::unexpected(FromOwnership.error()); + auto ToOwnership = verifyOwnership(To); + if (!ToOwnership) + return std::unexpected(ToOwnership.error()); + + const auto Successor = findSuccessorIndex(From, To); + if (!Successor) { + return makeUnexpected(ErrorCode::InvalidArgument, "updated CFG successor edge is not present"); + } + From.Successors[*Successor].Probability = Probability; + return {}; +} + +Expected MachineCFGUpdater::transferSuccessors(MachineBasicBlock &From, + MachineBasicBlock &To) { + auto FromOwnership = verifyOwnership(From); + if (!FromOwnership) + return std::unexpected(FromOwnership.error()); + auto ToOwnership = verifyOwnership(To); + if (!ToOwnership) + return std::unexpected(ToOwnership.error()); + if (&From == &To) + return {}; + + const std::vector Successors = From.Successors; + for (const MachineSuccessor &Successor : Successors) { + auto RemoveResult = removeSuccessor(From, *Successor.Block); + if (!RemoveResult) + return std::unexpected(RemoveResult.error()); + auto AddResult = addSuccessor(To, *Successor.Block, Successor.Probability); + if (!AddResult) + return std::unexpected(AddResult.error()); + } + return {}; +} + +Expected MachineCFGUpdater::disconnectBlock(MachineBasicBlock &Block) { + auto Ownership = verifyOwnership(Block); + if (!Ownership) + return std::unexpected(Ownership.error()); + + const std::vector Successors = Block.Successors; + for (const MachineSuccessor &Successor : Successors) { + auto Result = removeSuccessor(Block, *Successor.Block); + if (!Result) + return std::unexpected(Result.error()); + } + + const std::vector Predecessors = Block.Predecessors; + for (MachineBasicBlock *Predecessor : Predecessors) { + auto Result = removeSuccessor(*Predecessor, Block); + if (!Result) + return std::unexpected(Result.error()); + } + return {}; +} + +} // namespace rcc -- cgit v1.2.3