diff options
Diffstat (limited to 'backend/lib')
| -rw-r--r-- | backend/lib/CodeGen/InlineSpiller.cpp | 18 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocBase.cpp | 2 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocBase.h | 7 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocBasic.cpp | 34 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocFast.cpp | 36 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocGreedy.cpp | 35 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocInternal.h | 23 | ||||
| -rw-r--r-- | backend/lib/CodeGen/RegAllocPBQP.cpp | 56 |
8 files changed, 42 insertions, 169 deletions
diff --git a/backend/lib/CodeGen/InlineSpiller.cpp b/backend/lib/CodeGen/InlineSpiller.cpp index 1d5ba10..4aa43ce 100644 --- a/backend/lib/CodeGen/InlineSpiller.cpp +++ b/backend/lib/CodeGen/InlineSpiller.cpp @@ -78,9 +78,10 @@ Expected<std::optional<std::vector<Register>>> Spiller::tryRematerialize(Registe if (Sites.empty()) return std::optional<std::vector<Register>>{}; - if (Actions != nullptr) { + if (ActionAnalyses != nullptr) { for (const UseSite &Site : Sites) { - auto Accepted = Actions->request("rematerialize", *Function, Site.Instruction->stableID()); + auto Accepted = ActionAnalyses->requestAction("rematerialize", *Function, + Site.Instruction->stableID()); if (!Accepted) return std::unexpected(Accepted.error()); if (!*Accepted) @@ -180,11 +181,12 @@ Expected<std::vector<Register>> Spiller::spillAtInstructions(Register VirtualReg } std::vector<Register> NewRegisters; - if (Actions != nullptr) { + if (ActionAnalyses != nullptr) { for (const SpillSite &Site : Sites) { if (Site.OperandIndices.empty()) continue; - auto Accepted = Actions->request("split-live-range", *Function, Site.Instruction->stableID()); + auto Accepted = ActionAnalyses->requestAction("split-live-range", *Function, + Site.Instruction->stableID()); if (!Accepted) return std::unexpected(Accepted.error()); if (!*Accepted) { @@ -283,12 +285,12 @@ Expected<std::vector<Register>> Spiller::spill(Register VirtualReg) { return makeUnexpected(ErrorCode::RegisterAllocationFailed, "register pressure requires spilling a non-spillable value"); } - if (Actions != nullptr) { + if (ActionAnalyses != nullptr) { const MachineOperand *Definition = Function->registerInfo().getUniqueVRegDef(VirtualReg); const MachineInstr *Instruction = Definition == nullptr ? nullptr : Definition->parent(); - auto Accepted = - Actions->request("spill", *Function, - Instruction == nullptr ? MachineInstrStableID{} : Instruction->stableID()); + auto Accepted = ActionAnalyses->requestAction( + "spill", *Function, + Instruction == nullptr ? MachineInstrStableID{} : Instruction->stableID()); if (!Accepted) return std::unexpected(Accepted.error()); if (!*Accepted) { diff --git a/backend/lib/CodeGen/RegAllocBase.cpp b/backend/lib/CodeGen/RegAllocBase.cpp index da526dd..291fc29 100644 --- a/backend/lib/CodeGen/RegAllocBase.cpp +++ b/backend/lib/CodeGen/RegAllocBase.cpp @@ -64,7 +64,7 @@ Expected<regalloc_detail::AllocationRunResult> RegAllocBase::run(VirtRegMap &Map return Left.opaqueValue() < Right.opaqueValue(); }); Spiller ValueSpiller(Function, Target, TargetInfo, Mapping, Options.EnableRematerialization, - Actions); + &Analyses); for (const Register VirtualReg : Round->Spilled) { VirtRegMapEntry *Entry = Mapping.entry(VirtualReg); if (Entry != nullptr) { diff --git a/backend/lib/CodeGen/RegAllocBase.h b/backend/lib/CodeGen/RegAllocBase.h index 8b09081..fd1c739 100644 --- a/backend/lib/CodeGen/RegAllocBase.h +++ b/backend/lib/CodeGen/RegAllocBase.h @@ -28,10 +28,10 @@ public: protected: RegAllocBase(MachineFunction &Function, const TargetDescription &Target, const TargetRegisterAllocationInfo &TargetInfo, - MachineFunctionAnalysisManager &Analyses, RegisterAllocationOptions Options, - MachineActionReplay *Actions = nullptr) noexcept + MachineFunctionAnalysisManager &Analyses, + RegisterAllocationOptions Options) noexcept : Function(Function), Target(Target), TargetInfo(TargetInfo), Analyses(Analyses), - Options(Options), Actions(Actions) {} + Options(Options) {} [[nodiscard]] virtual Expected<AllocationRoundResult> allocateRound(const LiveIntervalsAnalysis::Result &Intervals, VirtRegMap &Mapping) = 0; @@ -41,7 +41,6 @@ protected: const TargetRegisterAllocationInfo &TargetInfo; MachineFunctionAnalysisManager &Analyses; RegisterAllocationOptions Options; - MachineActionReplay *Actions = nullptr; }; [[nodiscard]] std::vector<const LiveInterval *> diff --git a/backend/lib/CodeGen/RegAllocBasic.cpp b/backend/lib/CodeGen/RegAllocBasic.cpp index 5cb5035..8acfa5b 100644 --- a/backend/lib/CodeGen/RegAllocBasic.cpp +++ b/backend/lib/CodeGen/RegAllocBasic.cpp @@ -5,7 +5,6 @@ #include "RegAllocBase.h" #include "rcc/CodeGen/LiveIntervals.h" #include "rcc/CodeGen/LiveRegMatrix.h" -#include "rcc/CodeGen/LiveVariables.h" #include <algorithm> #include <memory> @@ -101,41 +100,18 @@ Expected<MachinePassResult> BasicAllocatorPass::run(MachineFunction &Function, MachineFunctionAnalysisManager &Analyses) { if (Info == nullptr) return makeUnexpected(ErrorCode::InvalidArgument, "BasicAllocator requires target behavior"); - auto Trial = regalloc_detail::cloneForAllocation(Function, Target); - if (!Trial) - return std::unexpected(Trial.error()); const std::vector<PhysicalRegister> FunctionReserved = regalloc_detail::functionReservedRegisters(Function, Target, *Info); - auto TrialReserved = - regalloc_detail::reserveFunctionRegisters(*Trial->ClonedFunction, FunctionReserved); - if (!TrialReserved) - return std::unexpected(TrialReserved.error()); - MachineFunctionAnalysisManager TrialAnalyses; - auto Registered = registerStage11MachineAnalyses(TrialAnalyses); - if (!Registered) - return std::unexpected(Registered.error()); - BasicAllocatorEngine TrialAllocator(*Trial->ClonedFunction, Target, *Info, TrialAnalyses, - Options); - VirtRegMap TrialMapping(*Trial->ClonedFunction); - auto TrialRun = TrialAllocator.run(TrialMapping); - if (!TrialRun) - return std::unexpected(TrialRun.error()); - auto TrialVerification = - regalloc_detail::verifyAllocationTrial(*Trial->ClonedFunction, Target, contract()); - if (!TrialVerification) - return std::unexpected(TrialVerification.error()); + auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); + if (!Reserved) + return std::unexpected(Reserved.error()); BasicAllocatorEngine Allocator(Function, Target, *Info, Analyses, Options); auto Mapping = Analyses.getResult<VirtRegMapAnalysis>(Function, Target); if (!Mapping) return std::unexpected(Mapping.error()); auto Allocated = Allocator.run(**Mapping); - if (!Allocated) { - return std::unexpected(withErrorContext( - Allocated.error(), "BasicAllocator diverged after a successful transaction preflight: ")); - } - auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); - if (!Reserved) - return std::unexpected(Reserved.error()); + if (!Allocated) + return std::unexpected(Allocated.error()); Allocated->Changed |= *Reserved; MachinePassResult Result = regalloc_detail::passResult(*Allocated); Result.Preserved.preserve<VirtRegMapAnalysis>(); diff --git a/backend/lib/CodeGen/RegAllocFast.cpp b/backend/lib/CodeGen/RegAllocFast.cpp index 9448558..eca9494 100644 --- a/backend/lib/CodeGen/RegAllocFast.cpp +++ b/backend/lib/CodeGen/RegAllocFast.cpp @@ -11,7 +11,6 @@ #include "rcc/CodeGen/MachineInstr.h" #include "rcc/CodeGen/MachineOperand.h" #include "rcc/CodeGen/MachineRegisterInfo.h" -#include "rcc/CodeGen/Spiller.h" #include <algorithm> #include <cstddef> @@ -571,43 +570,18 @@ Expected<MachinePassResult> FastAllocatorPass::run(MachineFunction &Function, MachineFunctionAnalysisManager &Analyses) { if (Info == nullptr) return makeUnexpected(ErrorCode::InvalidArgument, "FastAllocator requires target behavior"); - auto Trial = regalloc_detail::cloneForAllocation(Function, Target); - if (!Trial) - return std::unexpected(Trial.error()); const std::vector<PhysicalRegister> FunctionReserved = regalloc_detail::functionReservedRegisters(Function, Target, *Info); - auto TrialReserved = - regalloc_detail::reserveFunctionRegisters(*Trial->ClonedFunction, FunctionReserved); - if (!TrialReserved) - return std::unexpected(TrialReserved.error()); - MachineFunctionAnalysisManager TrialAnalyses; - auto Registered = registerStage11MachineAnalyses(TrialAnalyses); - if (!Registered) - return std::unexpected(Registered.error()); - auto TrialLiveness = - TrialAnalyses.getResult<LiveVariablesAnalysis>(*Trial->ClonedFunction, Target); - if (!TrialLiveness) - return std::unexpected(TrialLiveness.error()); - FastAllocatorEngine TrialAllocator(*Trial->ClonedFunction, Target, *Info, **TrialLiveness); - auto TrialRun = TrialAllocator.run(); - if (!TrialRun) - return std::unexpected(TrialRun.error()); - auto TrialVerification = - regalloc_detail::verifyAllocationTrial(*Trial->ClonedFunction, Target, contract()); - if (!TrialVerification) - return std::unexpected(TrialVerification.error()); + auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); + if (!Reserved) + return std::unexpected(Reserved.error()); auto Liveness = Analyses.getResult<LiveVariablesAnalysis>(Function, Target); if (!Liveness) return std::unexpected(Liveness.error()); FastAllocatorEngine Allocator(Function, Target, *Info, **Liveness); auto Allocated = Allocator.run(); - if (!Allocated) { - return std::unexpected(withErrorContext( - Allocated.error(), "FastAllocator diverged after a successful transaction preflight: ")); - } - auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); - if (!Reserved) - return std::unexpected(Reserved.error()); + if (!Allocated) + return std::unexpected(Allocated.error()); Allocated->Changed |= *Reserved; return regalloc_detail::passResult(*Allocated); } diff --git a/backend/lib/CodeGen/RegAllocGreedy.cpp b/backend/lib/CodeGen/RegAllocGreedy.cpp index 317c297..c298c78 100644 --- a/backend/lib/CodeGen/RegAllocGreedy.cpp +++ b/backend/lib/CodeGen/RegAllocGreedy.cpp @@ -5,7 +5,6 @@ #include "RegAllocBase.h" #include "rcc/CodeGen/LiveIntervals.h" #include "rcc/CodeGen/LiveRegMatrix.h" -#include "rcc/CodeGen/LiveVariables.h" #include <algorithm> #include <cstdint> @@ -215,42 +214,18 @@ Expected<MachinePassResult> GreedyAllocatorPass::run(MachineFunction &Function, MachineFunctionAnalysisManager &Analyses) { if (Info == nullptr) return makeUnexpected(ErrorCode::InvalidArgument, "greedy allocator requires target behavior"); - auto Trial = regalloc_detail::cloneForAllocation(Function, Target); - if (!Trial) - return std::unexpected(Trial.error()); const std::vector<PhysicalRegister> FunctionReserved = regalloc_detail::functionReservedRegisters(Function, Target, *Info); - auto TrialReserved = - regalloc_detail::reserveFunctionRegisters(*Trial->ClonedFunction, FunctionReserved); - if (!TrialReserved) - return std::unexpected(TrialReserved.error()); - MachineFunctionAnalysisManager TrialAnalyses; - auto Registered = registerStage11MachineAnalyses(TrialAnalyses); - if (!Registered) - return std::unexpected(Registered.error()); - GreedyAllocatorEngine TrialAllocator(*Trial->ClonedFunction, Target, *Info, TrialAnalyses, - Options); - VirtRegMap TrialMapping(*Trial->ClonedFunction); - auto TrialRun = TrialAllocator.run(TrialMapping); - if (!TrialRun) - return std::unexpected(TrialRun.error()); - auto TrialVerification = - regalloc_detail::verifyAllocationTrial(*Trial->ClonedFunction, Target, contract()); - if (!TrialVerification) - return std::unexpected(TrialVerification.error()); - + auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); + if (!Reserved) + return std::unexpected(Reserved.error()); auto Mapping = Analyses.getResult<VirtRegMapAnalysis>(Function, Target); if (!Mapping) return std::unexpected(Mapping.error()); GreedyAllocatorEngine Allocator(Function, Target, *Info, Analyses, Options); auto Allocated = Allocator.run(**Mapping); - if (!Allocated) { - return std::unexpected(withErrorContext( - Allocated.error(), "greedy allocator diverged after a successful transaction preflight: ")); - } - auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); - if (!Reserved) - return std::unexpected(Reserved.error()); + if (!Allocated) + return std::unexpected(Allocated.error()); Allocated->Changed |= *Reserved; MachinePassResult Result = regalloc_detail::passResult(*Allocated); Result.Preserved.preserve<VirtRegMapAnalysis>(); diff --git a/backend/lib/CodeGen/RegAllocInternal.h b/backend/lib/CodeGen/RegAllocInternal.h index 3da6387..8d7af5a 100644 --- a/backend/lib/CodeGen/RegAllocInternal.h +++ b/backend/lib/CodeGen/RegAllocInternal.h @@ -9,11 +9,9 @@ #include "rcc/CodeGen/LiveIntervals.h" #include "rcc/CodeGen/MachineBasicBlock.h" #include "rcc/CodeGen/MachineFunction.h" -#include "rcc/CodeGen/MachineFunctionCloner.h" #include "rcc/CodeGen/MachineInstr.h" #include "rcc/CodeGen/MachineOperand.h" #include "rcc/CodeGen/MachineRegisterInfo.h" -#include "rcc/CodeGen/MachineVerifier.h" #include "rcc/CodeGen/RegAllocCommon.h" #include "rcc/CodeGen/TargetDescription.h" #include "rcc/CodeGen/TargetRegisterAllocationInfo.h" @@ -23,7 +21,6 @@ #include <algorithm> #include <cstddef> #include <cstdint> -#include <optional> #include <ranges> #include <span> #include <vector> @@ -222,26 +219,6 @@ reserveFunctionRegisters(MachineFunction &Function, std::span<const PhysicalRegi return Result; } -[[nodiscard]] inline Expected<void> verifyAllocationTrial(MachineFunction &Function, - const TargetDescription &Target, - const MachinePassContract &Contract) { - auto Transition = - Function.properties().applyTransition(Contract.Requires, Contract.Sets, Contract.Clears); - if (!Transition) - return std::unexpected(Transition.error()); - return MachineVerifier::verify(Function, Target, - MachineVerifierOptions{.Mode = MachineVerifierMode::Generic, - .Stage = Contract.VerificationStage, - .VerifyProperties = true}); -} - -[[nodiscard]] inline Expected<MachineFunctionCloneResult> -cloneForAllocation(const MachineFunction &Function, const TargetDescription &Target) { - return cloneMachineFunction( - Function, Target, - MachineFunctionCloneOptions{.NewStableID = Function.stableID(), .NewName = std::nullopt}); -} - [[nodiscard]] bool intervalsOverlapOnPhysicalRegisters(const LiveInterval &Left, PhysicalRegister LeftReg, const LiveInterval &Right, PhysicalRegister RightReg, diff --git a/backend/lib/CodeGen/RegAllocPBQP.cpp b/backend/lib/CodeGen/RegAllocPBQP.cpp index 792ae10..9081c37 100644 --- a/backend/lib/CodeGen/RegAllocPBQP.cpp +++ b/backend/lib/CodeGen/RegAllocPBQP.cpp @@ -6,7 +6,6 @@ #include "rcc/CodeGen/GenericOpcodes.h" #include "rcc/CodeGen/LiveIntervals.h" #include "rcc/CodeGen/LiveRegMatrix.h" -#include "rcc/CodeGen/LiveVariables.h" #include "rcc/CodeGen/MachineBasicBlock.h" #include "rcc/CodeGen/MachineFunction.h" #include "rcc/CodeGen/MachineInstr.h" @@ -86,9 +85,8 @@ class PBQPAllocatorEngine final : public RegAllocBase { public: PBQPAllocatorEngine(MachineFunction &Function, const TargetDescription &Target, const TargetRegisterAllocationInfo &TargetInfo, - MachineFunctionAnalysisManager &Analyses, RegisterAllocationOptions Options, - MachineActionReplay *Actions) - : RegAllocBase(Function, Target, TargetInfo, Analyses, Options, Actions) {} + MachineFunctionAnalysisManager &Analyses, RegisterAllocationOptions Options) + : RegAllocBase(Function, Target, TargetInfo, Analyses, Options) {} private: [[nodiscard]] Expected<AllocationRoundResult> @@ -178,8 +176,9 @@ private: std::swap(LeftKey, RightKey); const auto CopyPosition = CopyPairs.find({LeftKey, RightKey}); bool CopyRelated = Options.EnableCopyCoalescing && CopyPosition != CopyPairs.end(); - if (CopyRelated && Actions != nullptr) { - auto Accepted = Actions->request("coalesce-copy", Function, CopyPosition->second); + if (CopyRelated) { + auto Accepted = + Analyses.requestAction("coalesce-copy", Function, CopyPosition->second); if (!Accepted) return std::unexpected(Accepted.error()); CopyRelated = *Accepted; @@ -219,8 +218,6 @@ private: pbqp::DeterministicSolver Solver; auto Solution = Solver.solve(Problem, [&](const pbqp::SolverAction &Action) -> Expected<bool> { - if (Actions == nullptr) - return true; if (Action.Node.value() >= Nodes.size()) { return makeUnexpected(ErrorCode::InternalError, "PBQP action names an unknown allocation node"); @@ -233,7 +230,8 @@ private: Rule.append(".option-"); Rule.append(std::to_string(Action.Value)); } - return Actions->request(Rule, Function, actionInstructionForRegister(Function, VirtualReg)); + return Analyses.requestAction(Rule, Function, + actionInstructionForRegister(Function, VirtualReg)); }); if (!Solution) return std::unexpected(Solution.error()); @@ -296,46 +294,18 @@ Expected<MachinePassResult> PBQPAllocatorPass::run(MachineFunction &Function, MachineFunctionAnalysisManager &Analyses) { if (Info == nullptr) return makeUnexpected(ErrorCode::InvalidArgument, "PBQPAllocator requires target behavior"); - auto Trial = regalloc_detail::cloneForAllocation(Function, Target); - if (!Trial) - return std::unexpected(Trial.error()); const std::vector<PhysicalRegister> FunctionReserved = regalloc_detail::functionReservedRegisters(Function, Target, *Info); - auto TrialReserved = - regalloc_detail::reserveFunctionRegisters(*Trial->ClonedFunction, FunctionReserved); - if (!TrialReserved) - return std::unexpected(TrialReserved.error()); - MachineFunctionAnalysisManager TrialAnalyses; - auto Registered = registerStage11MachineAnalyses(TrialAnalyses); - if (!Registered) - return std::unexpected(Registered.error()); - MachineActionReplay Actions(Analyses, Trial->InstructionStableIDs); - PBQPAllocatorEngine TrialAllocator(*Trial->ClonedFunction, Target, *Info, TrialAnalyses, Options, - &Actions); - VirtRegMap TrialMapping(*Trial->ClonedFunction); - auto TrialRun = TrialAllocator.run(TrialMapping); - if (!TrialRun) - return std::unexpected(TrialRun.error()); - auto TrialVerification = - regalloc_detail::verifyAllocationTrial(*Trial->ClonedFunction, Target, contract()); - if (!TrialVerification) - return std::unexpected(TrialVerification.error()); - Actions.beginReplay(); - PBQPAllocatorEngine Allocator(Function, Target, *Info, Analyses, Options, &Actions); + auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); + if (!Reserved) + return std::unexpected(Reserved.error()); + PBQPAllocatorEngine Allocator(Function, Target, *Info, Analyses, Options); auto Mapping = Analyses.getResult<VirtRegMapAnalysis>(Function, Target); if (!Mapping) return std::unexpected(Mapping.error()); auto Allocated = Allocator.run(**Mapping); - if (!Allocated) { - return std::unexpected(withErrorContext( - Allocated.error(), "PBQPAllocator diverged after a successful transaction preflight: ")); - } - auto Replayed = Actions.finishReplay(); - if (!Replayed) - return std::unexpected(Replayed.error()); - auto Reserved = regalloc_detail::reserveFunctionRegisters(Function, FunctionReserved); - if (!Reserved) - return std::unexpected(Reserved.error()); + if (!Allocated) + return std::unexpected(Allocated.error()); Allocated->Changed |= *Reserved; MachinePassResult Result = regalloc_detail::passResult(*Allocated); Result.Preserved.preserve<VirtRegMapAnalysis>(); |
