aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-12 21:35:21 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-12 21:35:21 +0800
commitf8daf08aba1f09c3024a70d3426891112d1662a2 (patch)
treedaf3a5e309e41c3bef92efdb496806061d2a2c02 /backend/lib
parent8721893d3ba605f5374d9c0c7987af6110355638 (diff)
downloadrcc-project-f8daf08aba1f09c3024a70d3426891112d1662a2.tar.gz
rcc-project-f8daf08aba1f09c3024a70d3426891112d1662a2.tar.xz
[RISCV] Consolidate instruction behavior in RISCVInstrInfo
Diffstat (limited to 'backend/lib')
-rw-r--r--backend/lib/CodeGen/MachineBranchOptimization.cpp5
-rw-r--r--backend/lib/CodeGen/MachineCopyPropagation.cpp6
-rw-r--r--backend/lib/CodeGen/MachineFallthrough.cpp5
-rw-r--r--backend/lib/CodeGen/MachineOptimizationPipeline.cpp18
-rw-r--r--backend/lib/CodeGen/MachineSSAExit.cpp16
-rw-r--r--backend/lib/CodeGen/MachineTailDuplication.cpp3
-rw-r--r--backend/lib/CodeGen/MachineTailMerge.cpp2
-rw-r--r--backend/lib/Target/RISCV/CMakeLists.txt11
-rw-r--r--backend/lib/Target/RISCV/RISCVCodeGen.cpp197
-rw-r--r--backend/lib/Target/RISCV/RISCVInstrInfo.cpp (renamed from backend/lib/Target/RISCV/RISCVBranchInfo.cpp)119
-rw-r--r--backend/lib/Target/RISCV/RISCVInstrInfo.h14
-rw-r--r--backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp4
-rw-r--r--backend/lib/Target/RISCV/RISCVPipeline.cpp9
13 files changed, 166 insertions, 243 deletions
diff --git a/backend/lib/CodeGen/MachineBranchOptimization.cpp b/backend/lib/CodeGen/MachineBranchOptimization.cpp
index 19127ea..df25a4a 100644
--- a/backend/lib/CodeGen/MachineBranchOptimization.cpp
+++ b/backend/lib/CodeGen/MachineBranchOptimization.cpp
@@ -142,7 +142,7 @@ namespace {
if (!RemovedUnconditional)
return std::unexpected(RemovedUnconditional.error());
}
- auto Inserted = Info.insertUnconditionalBranch(*Block, *Selected, Function, Target);
+ auto Inserted = Info.insertBranch(*Block, *Selected, Function, Target);
if (!Inserted)
return std::unexpected(Inserted.error());
@@ -269,8 +269,7 @@ namespace {
} else {
if (Predecessor->next() != Block)
continue;
- auto Inserted =
- Info.insertUnconditionalBranch(*Predecessor, *Successor, Function, Target);
+ auto Inserted = Info.insertBranch(*Predecessor, *Successor, Function, Target);
if (!Inserted)
return std::unexpected(Inserted.error());
}
diff --git a/backend/lib/CodeGen/MachineCopyPropagation.cpp b/backend/lib/CodeGen/MachineCopyPropagation.cpp
index f9211f9..60992a5 100644
--- a/backend/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/backend/lib/CodeGen/MachineCopyPropagation.cpp
@@ -12,8 +12,8 @@
#include "rcc/CodeGen/MachineOperand.h"
#include "rcc/CodeGen/MachineRegisterInfo.h"
#include "rcc/CodeGen/RegisterMask.h"
-#include "rcc/CodeGen/TargetCodeGen.h"
#include "rcc/CodeGen/TargetDescription.h"
+#include "rcc/CodeGen/TargetInstrInfo.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
#include <algorithm>
@@ -127,7 +127,7 @@ struct CopyOperands final {
[[nodiscard]] Expected<bool> propagateVirtualCopy(MachineInstr &Copy, const CopyOperands &Operands,
MachineFunction &Function,
const TargetDescription &Target,
- const TargetSSAInfo &Info) {
+ const TargetInstrInfo &Info) {
if (!Operands.Destination.isVirtual() || !Operands.Source.isVirtual())
return false;
if (Function.registerInfo().getUniqueVRegDef(Operands.Destination) !=
@@ -231,7 +231,7 @@ struct CopyOperands final {
[[nodiscard]] Expected<bool> propagatePhysicalCopy(MachineInstr &Copy, const CopyOperands &Operands,
MachineFunction &Function,
const TargetDescription &Target,
- const TargetSSAInfo &Info) {
+ const TargetInstrInfo &Info) {
const std::optional<PhysicalRegister> Destination = Operands.Destination.physicalRegister();
const std::optional<PhysicalRegister> Source = Operands.Source.physicalRegister();
if (!Destination || !Source || Operands.DestinationOperand->subReg().value() != 0 ||
diff --git a/backend/lib/CodeGen/MachineFallthrough.cpp b/backend/lib/CodeGen/MachineFallthrough.cpp
index a853f96..e912f0b 100644
--- a/backend/lib/CodeGen/MachineFallthrough.cpp
+++ b/backend/lib/CodeGen/MachineFallthrough.cpp
@@ -83,8 +83,7 @@ normalizeFallthroughs(MachineFunction &Function, const TargetDescription &Target
Changed = true;
} else if (Analysis->Conditional != nullptr && Analysis->Unconditional == nullptr &&
Analysis->FalseTarget != nullptr) {
- auto Inserted =
- Info.insertUnconditionalBranch(*Block, *Analysis->FalseTarget, Function, Target);
+ auto Inserted = Info.insertBranch(*Block, *Analysis->FalseTarget, Function, Target);
if (!Inserted)
return std::unexpected(Inserted.error());
Changed = true;
@@ -102,7 +101,7 @@ normalizeFallthroughs(MachineFunction &Function, const TargetDescription &Target
return makeUnexpected(ErrorCode::VerificationError,
"fallthrough normalization encountered a null successor");
}
- auto Inserted = Info.insertUnconditionalBranch(*Block, *Successor, Function, Target);
+ auto Inserted = Info.insertBranch(*Block, *Successor, Function, Target);
if (!Inserted)
return std::unexpected(Inserted.error());
Changed = true;
diff --git a/backend/lib/CodeGen/MachineOptimizationPipeline.cpp b/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
index 76dbd44..6d24034 100644
--- a/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
+++ b/backend/lib/CodeGen/MachineOptimizationPipeline.cpp
@@ -69,10 +69,10 @@ addSelectedSSAOptimizationPipeline(MachinePassManager &Pipeline,
Expected<void> addPreRegisterAllocationOptimizationPipeline(
MachinePassManager &Pipeline, const MachineOptimizationPipelineTargetInfo &TargetInfo) {
- auto Added = addPass<MachineBranchOptimizationPass>(Pipeline, TargetInfo.BranchInfo);
+ auto Added = addPass<MachineBranchOptimizationPass>(Pipeline, TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineCopyPropagationPass>(Pipeline, TargetInfo.SSA,
+ Added = addPass<MachineCopyPropagationPass>(Pipeline, TargetInfo.InstrInfo,
MachineCopyPropagationStage::PreRegisterAllocation);
if (!Added)
return std::unexpected(Added.error());
@@ -92,7 +92,7 @@ addPostRegisterAllocationPipeline(MachinePassManager &Pipeline,
auto Added = addPass<MachineStackSlotColoringPass>(Pipeline);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineCopyPropagationPass>(Pipeline, TargetInfo.SSA,
+ Added = addPass<MachineCopyPropagationPass>(Pipeline, TargetInfo.InstrInfo,
MachineCopyPropagationStage::PostRegisterAllocation);
if (!Added)
return std::unexpected(Added.error());
@@ -128,29 +128,29 @@ addPostRegisterAllocationPipeline(MachinePassManager &Pipeline,
Added = addPass<PostRASchedulerPass>(Pipeline, TargetInfo.SchedulingModel);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineTailDuplicationPass>(Pipeline, TargetInfo.BranchInfo);
+ Added = addPass<MachineTailDuplicationPass>(Pipeline, TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineTailMergePass>(Pipeline, TargetInfo.BranchInfo);
+ Added = addPass<MachineTailMergePass>(Pipeline, TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
Added = addPass<MachineBlockPlacementPass>(Pipeline);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineFallthroughPass>(Pipeline, TargetInfo.BranchInfo);
+ Added = addPass<MachineFallthroughPass>(Pipeline, TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<MachineBranchRelaxationPass>(Pipeline, TargetInfo.BranchInfo);
+ Added = addPass<MachineBranchRelaxationPass>(Pipeline, TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
Added = addPass<TargetLatePseudoExpansionPass>(Pipeline, TargetInfo.PseudoExpansion,
- TargetInfo.BranchInfo);
+ TargetInfo.InstrInfo);
if (!Added)
return std::unexpected(Added.error());
Added = addPass<FinalizeEmissionPseudosPass>(Pipeline);
if (!Added)
return std::unexpected(Added.error());
- return addPass<FinalEncodabilityVerifierPass>(Pipeline, TargetInfo.BranchInfo);
+ return addPass<FinalEncodabilityVerifierPass>(Pipeline, TargetInfo.InstrInfo);
}
} // namespace rcc
diff --git a/backend/lib/CodeGen/MachineSSAExit.cpp b/backend/lib/CodeGen/MachineSSAExit.cpp
index 76963ea..ec10b3b 100644
--- a/backend/lib/CodeGen/MachineSSAExit.cpp
+++ b/backend/lib/CodeGen/MachineSSAExit.cpp
@@ -167,7 +167,7 @@ struct PhiPlan final {
[[nodiscard]] Expected<MachineInstr *>
buildCopy(MachineFunction &Function, const TargetDescription &Target,
- const TargetSSAInfo &TargetInfo, MachineBasicBlock &Block, MachineInstr *Before,
+ const TargetInstrInfo &TargetInfo, MachineBasicBlock &Block, MachineInstr *Before,
RegisterValue Destination, RegisterValue Source, const MachineInstr *DebugSource) {
auto Legality = TargetInfo.validateCopy(Destination.Reg, Destination.SubReg, Source.Reg,
Source.SubReg, Function, Target);
@@ -388,7 +388,7 @@ buildImplicitDef(MachineFunction &Function, const TargetDescription &Target,
[[nodiscard]] Expected<MachineBasicBlock *>
placePhiCopiesOnEdge(MachineFunction &Function, const TargetDescription &Target,
- const TargetSSAInfo &TargetInfo, MachineBasicBlock &From,
+ const TargetInstrInfo &TargetInfo, MachineBasicBlock &From,
MachineBasicBlock &To,
std::unordered_map<EdgeKey, MachineBasicBlock *, EdgeKeyHash> &Cache,
MachinePassResult &PassResult) {
@@ -415,7 +415,7 @@ placePhiCopiesOnEdge(MachineFunction &Function, const TargetDescription &Target,
if (!OtherFallthrough)
return std::unexpected(OtherFallthrough.error());
if (*OtherFallthrough) {
- auto Branch = TargetInfo.insertUnconditionalBranch(*LayoutPredecessor, To, Function, Target);
+ auto Branch = TargetInfo.insertBranch(*LayoutPredecessor, To, Function, Target);
if (!Branch)
return std::unexpected(Branch.error());
PassResult.Changed = true;
@@ -445,7 +445,7 @@ placePhiCopiesOnEdge(MachineFunction &Function, const TargetDescription &Target,
auto LiveIns = copyLiveIns(To, *EdgeBlock);
if (!LiveIns)
return std::unexpected(LiveIns.error());
- auto Branch = TargetInfo.insertUnconditionalBranch(*EdgeBlock, To, Function, Target);
+ auto Branch = TargetInfo.insertBranch(*EdgeBlock, To, Function, Target);
if (!Branch)
return std::unexpected(Branch.error());
@@ -526,7 +526,7 @@ placePhiCopiesOnEdge(MachineFunction &Function, const TargetDescription &Target,
[[nodiscard]] Expected<void> expandRegSequence(MachineInstr &Instruction, MachineFunction &Function,
const TargetDescription &Target,
- const TargetSSAInfo &TargetInfo) {
+ const TargetInstrInfo &TargetInfo) {
if (Instruction.operandCount() < 3 || (Instruction.operandCount() - 1U) % 2U != 0) {
return makeUnexpected(ErrorCode::VerificationError,
"REG_SEQUENCE requires a destination and source/subregister pairs");
@@ -588,7 +588,7 @@ placePhiCopiesOnEdge(MachineFunction &Function, const TargetDescription &Target,
[[nodiscard]] Expected<void> expandInsertSubreg(MachineInstr &Instruction,
MachineFunction &Function,
const TargetDescription &Target,
- const TargetSSAInfo &TargetInfo) {
+ const TargetInstrInfo &TargetInfo) {
if (Instruction.operandCount() != 4) {
return makeUnexpected(ErrorCode::VerificationError,
"INSERT_SUBREG requires destination, base, inserted value, and index");
@@ -792,7 +792,7 @@ Expected<MachinePassResult> PHIEliminationPass::run(MachineFunction &Function,
MachineAnalysisManager &Analyses) {
if (Info == nullptr) {
return makeUnexpected(ErrorCode::InvalidArgument,
- "PHI elimination has no target SSA behavior interface");
+ "PHI elimination has no target instruction information");
}
auto Required = requireProperties(Function, contract());
if (!Required)
@@ -927,7 +927,7 @@ Expected<MachinePassResult> TwoAddressRewritePass::run(MachineFunction &Function
MachineAnalysisManager &Analyses) {
if (Info == nullptr) {
return makeUnexpected(ErrorCode::InvalidArgument,
- "two-address rewrite has no target SSA behavior interface");
+ "two-address rewrite has no target instruction information");
}
auto Required = requireProperties(Function, contract());
if (!Required)
diff --git a/backend/lib/CodeGen/MachineTailDuplication.cpp b/backend/lib/CodeGen/MachineTailDuplication.cpp
index a4b31b2..80c58c9 100644
--- a/backend/lib/CodeGen/MachineTailDuplication.cpp
+++ b/backend/lib/CodeGen/MachineTailDuplication.cpp
@@ -230,8 +230,7 @@ duplicateTailIntoPredecessor(const TailCandidate &Candidate, MachineBasicBlock &
if (!Removed)
return std::unexpected(Removed.error());
}
- auto NewBranch =
- Info.insertUnconditionalBranch(Predecessor, *Candidate.Successor, Function, Target);
+ auto NewBranch = Info.insertBranch(Predecessor, *Candidate.Successor, Function, Target);
if (!NewBranch)
return std::unexpected(NewBranch.error());
MachineCFGUpdater CFG = Function.cfgUpdater();
diff --git a/backend/lib/CodeGen/MachineTailMerge.cpp b/backend/lib/CodeGen/MachineTailMerge.cpp
index c8aad80..07608cc 100644
--- a/backend/lib/CodeGen/MachineTailMerge.cpp
+++ b/backend/lib/CodeGen/MachineTailMerge.cpp
@@ -279,7 +279,7 @@ redirectPredecessor(MachineBasicBlock &Predecessor, MachineBasicBlock &Duplicate
Analysis->FalseTarget == &Duplicate);
if (!IsImplicitEdge)
return false;
- auto Inserted = Info.insertUnconditionalBranch(Predecessor, Canonical, Function, Target);
+ auto Inserted = Info.insertBranch(Predecessor, Canonical, Function, Target);
if (!Inserted)
return std::unexpected(Inserted.error());
}
diff --git a/backend/lib/Target/RISCV/CMakeLists.txt b/backend/lib/Target/RISCV/CMakeLists.txt
index 68bd444..d28cdf3 100644
--- a/backend/lib/Target/RISCV/CMakeLists.txt
+++ b/backend/lib/Target/RISCV/CMakeLists.txt
@@ -47,7 +47,7 @@ set_source_files_properties(
add_library(
RCCBackendRISCV
- RISCVBranchInfo.cpp
+ RISCVInstrInfo.cpp
RISCVCodeGen.cpp
RISCVCallLowering.cpp
RISCVAssemblyPrinter.cpp
@@ -84,7 +84,9 @@ target_include_directories(
"$<BUILD_INTERFACE:${RCC_BACKEND_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${RCC_BACKEND_BINARY_DIR}/generated/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
- PRIVATE "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV"
+ PRIVATE
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ "${RCC_BACKEND_BINARY_DIR}/generated/lib/Target/RISCV"
)
target_link_libraries(
RCCBackendRISCV
@@ -116,7 +118,7 @@ install(
)
rcc_backend_register_format_files(
- "${CMAKE_CURRENT_SOURCE_DIR}/RISCVBranchInfo.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVAssemblyPrinter.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVCodeGen.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVCallLowering.cpp"
@@ -140,6 +142,7 @@ rcc_backend_register_format_files(
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVTarget.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVTargetConstant.cpp"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/Target/RISCV/RISCVCodeGen.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfo.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/Target/RISCV/RISCVAssemblyPrinter.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/Target/RISCV/RISCVCallLowering.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/Target/RISCV/RISCVInstPrinter.h"
@@ -156,7 +159,7 @@ rcc_backend_register_format_files(
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/Target/RISCV/RISCVTargetRelocationKinds.h"
)
rcc_backend_register_tidy_files(
- "${CMAKE_CURRENT_SOURCE_DIR}/RISCVBranchInfo.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVAssemblyPrinter.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVCodeGen.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RISCVCallLowering.cpp"
diff --git a/backend/lib/Target/RISCV/RISCVCodeGen.cpp b/backend/lib/Target/RISCV/RISCVCodeGen.cpp
index d03653f..00dba94 100644
--- a/backend/lib/Target/RISCV/RISCVCodeGen.cpp
+++ b/backend/lib/Target/RISCV/RISCVCodeGen.cpp
@@ -6512,198 +6512,6 @@ private:
}
};
-class RISCVSSAInfo final : public TargetSSAInfo {
-public:
- [[nodiscard]] Expected<bool> isFallthroughEdge(const MachineBasicBlock &From,
- const MachineBasicBlock &To,
- const MachineFunction &,
- const TargetDescription &Target) const override {
- if (From.next() != &To ||
- std::ranges::none_of(From.successors(), [&To](const MachineSuccessor &Successor) {
- return Successor.Block == &To;
- })) {
- return false;
- }
-
- bool CanFallThrough = true;
- for (const MachineInstr *Instruction = From.firstInstruction(); Instruction != nullptr;
- Instruction = Instruction->next()) {
- const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction->opcode());
- if (Descriptor == nullptr) {
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V fallthrough analysis encountered an unknown opcode");
- }
- if (!Descriptor->Flags.has(InstructionFlag::Terminator))
- continue;
- CanFallThrough = isConditionalBranch(Instruction->opcode());
- }
- return CanFallThrough;
- }
-
- [[nodiscard]] Expected<bool> rewriteBranchTarget(MachineBasicBlock &Block,
- MachineBasicBlock &OldTarget,
- MachineBasicBlock &NewTarget,
- MachineFunction &Function,
- const TargetDescription &Target) const override {
- if (&Block.function() != &Function || &OldTarget.function() != &Function ||
- &NewTarget.function() != &Function) {
- return makeUnexpected(ErrorCode::InvalidArgument,
- "RISC-V branch rewrite references another machine function");
- }
-
- bool Changed = false;
- for (MachineInstr *Instruction = Block.firstInstruction(); Instruction != nullptr;
- Instruction = Instruction->next()) {
- const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction->opcode());
- if (Descriptor == nullptr) {
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V branch rewrite encountered an unknown opcode");
- }
- if (!Descriptor->Flags.has(InstructionFlag::Branch) ||
- Descriptor->Flags.has(InstructionFlag::IndirectBranch)) {
- continue;
- }
- for (std::size_t Index = 0; Index < Instruction->operandCount(); ++Index) {
- MachineOperand *Operand = Instruction->operandAt(Index);
- const BasicBlockOperand *TargetOperand =
- Operand == nullptr ? nullptr : Operand->getIf<BasicBlockOperand>();
- if (TargetOperand == nullptr || TargetOperand->Block != &OldTarget)
- continue;
- auto Rewritten = Operand->setBasicBlock(NewTarget);
- if (!Rewritten)
- return std::unexpected(Rewritten.error());
- Changed = true;
- }
- }
- return Changed;
- }
-
- [[nodiscard]] Expected<void>
- insertUnconditionalBranch(MachineBasicBlock &Block, MachineBasicBlock &TargetBlock,
- MachineFunction &Function,
- const TargetDescription &Target) const override {
- if (&Block.function() != &Function || &TargetBlock.function() != &Function) {
- return makeUnexpected(ErrorCode::InvalidArgument,
- "RISC-V branch insertion references another machine function");
- }
- auto Zero = physicalRegister(PhysicalRegisterID::X0);
- if (!Zero)
- return std::unexpected(Zero.error());
- MachineIRBuilder Builder(Function, Target);
- auto Point = Builder.setInsertPoint(Block);
- if (!Point)
- return std::unexpected(Point.error());
- auto Branch = Builder.buildInstr(targetOpcode(InstructionOpcode::JAL));
- if (!Branch)
- return std::unexpected(Branch.error());
- auto Link = Branch->addDef(Register::fromPhysical(*Zero));
- if (!Link)
- return std::unexpected(Link.error());
- auto Destination = Branch->addBasicBlock(TargetBlock);
- if (!Destination)
- return std::unexpected(Destination.error());
- auto Built = Branch->build();
- if (!Built)
- return std::unexpected(Built.error());
- return {};
- }
-
- [[nodiscard]] Expected<void> validateCopy(Register Destination, SubRegIndex DestinationSubReg,
- Register Source, SubRegIndex SourceSubReg,
- const MachineFunction &Function,
- const TargetDescription &Target) const override {
- if (Destination.isNoRegister() || Source.isNoRegister()) {
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V COPY requires two nonzero registers");
- }
- if (DestinationSubReg.value() != 0 || SourceSubReg.value() != 0) {
- return makeUnexpected(ErrorCode::Unsupported, "RV64GC does not model register subindices");
- }
-
- auto DestinationShape = copyShape(Destination, Function, Target);
- if (!DestinationShape)
- return std::unexpected(DestinationShape.error());
- auto SourceShape = copyShape(Source, Function, Target);
- if (!SourceShape)
- return std::unexpected(SourceShape.error());
- if (DestinationShape->Bank == SourceShape->Bank) {
- if (DestinationShape->Width && SourceShape->Width &&
- DestinationShape->Width != SourceShape->Width) {
- return makeUnexpected(ErrorCode::Unsupported,
- "RISC-V same-bank COPY has incompatible register widths");
- }
- return {};
- }
-
- const RegisterBankID GPR =
- RegisterBankID::fromValue(static_cast<std::uint32_t>(RegisterBank::GPR));
- const RegisterBankID FPR =
- RegisterBankID::fromValue(static_cast<std::uint32_t>(RegisterBank::FPR));
- const bool IsCrossBankMove = (DestinationShape->Bank == GPR && SourceShape->Bank == FPR) ||
- (DestinationShape->Bank == FPR && SourceShape->Bank == GPR);
- if (!IsCrossBankMove) {
- return makeUnexpected(ErrorCode::Unsupported,
- "RISC-V COPY crosses unsupported register banks");
- }
- auto SupportedWidth = [](std::optional<std::uint32_t> Width) {
- return !Width || *Width == 32 || *Width == 64;
- };
- if (!SupportedWidth(DestinationShape->Width) || !SupportedWidth(SourceShape->Width)) {
- return makeUnexpected(ErrorCode::Unsupported,
- "RISC-V GPR/FPR COPY requires 32-bit or 64-bit values");
- }
- return {};
- }
-
-private:
- struct CopyShape final {
- RegisterBankID Bank;
- std::optional<std::uint32_t> Width;
- };
-
- [[nodiscard]] static bool isConditionalBranch(Opcode Value) noexcept {
- return Value == targetOpcode(InstructionOpcode::BEQ) ||
- Value == targetOpcode(InstructionOpcode::BNE) ||
- Value == targetOpcode(InstructionOpcode::BLT) ||
- Value == targetOpcode(InstructionOpcode::BGE) ||
- Value == targetOpcode(InstructionOpcode::BLTU) ||
- Value == targetOpcode(InstructionOpcode::BGEU);
- }
-
- [[nodiscard]] static Expected<CopyShape> copyShape(Register Reg, const MachineFunction &Function,
- const TargetDescription &Target) {
- if (Reg.isVirtual()) {
- auto Info = Function.registerInfo().virtualRegisterInfo(Reg);
- if (!Info)
- return std::unexpected(Info.error());
- const std::optional<RegisterBankID> &Bank = Info->get().Bank;
- const std::optional<RegisterClassID> &RegClass = Info->get().RegClass;
- if (!Bank || !RegClass) {
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V COPY virtual register is not fully constrained");
- }
- const RegisterClassDesc *Class = Target.registers().registerClass(RegClass.value());
- if (Class == nullptr) {
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V COPY references an unknown register class");
- }
- return CopyShape{Bank.value(), Class->SizeInBits};
- }
-
- const std::optional<PhysicalRegister> Physical = Reg.physicalRegister();
- if (!Physical || !Target.registers().isKnownPhysicalRegister(*Physical)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V COPY references an unknown physical register");
- }
- for (const RegisterBankDesc &Bank : Target.registers().registerBanks()) {
- if (Target.registers().bankContainsRegister(Bank.ID, *Physical))
- return CopyShape{Bank.ID, std::nullopt};
- }
- return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V physical register is not assigned to a register bank");
- }
-};
-
} // namespace
const TargetLegalizerInfo &legalizerInfo() noexcept {
@@ -6725,9 +6533,4 @@ const TargetInstructionSelector &instructionSelector() noexcept {
return Value;
}
-const TargetSSAInfo &ssaInfo() noexcept {
- static const RISCVSSAInfo Value;
- return Value;
-}
-
} // namespace rcc::riscv
diff --git a/backend/lib/Target/RISCV/RISCVBranchInfo.cpp b/backend/lib/Target/RISCV/RISCVInstrInfo.cpp
index 059bbef..6e26e2c 100644
--- a/backend/lib/Target/RISCV/RISCVBranchInfo.cpp
+++ b/backend/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "RISCVInstrInfo.h"
+
#include "rcc/CodeGen/InstructionDescriptor.h"
#include "rcc/CodeGen/MachineBasicBlock.h"
#include "rcc/CodeGen/MachineFunction.h"
@@ -8,7 +10,6 @@
#include "rcc/CodeGen/MachineOperand.h"
#include "rcc/CodeGen/MachineRegisterInfo.h"
#include "rcc/CodeGen/TargetDescription.h"
-#include "rcc/Target/RISCV/RISCVCodeGen.h"
#include "rcc/Target/RISCV/RISCVInstructions.h"
#include "rcc/Target/RISCV/RISCVRegisters.h"
#include "rcc/Target/RISCV/RISCVTarget.h"
@@ -497,7 +498,7 @@ selectLongBranchScratch(const MachineInstr &Instruction, const MachineBasicBlock
return true;
}
-class RISCVBranchInfo final : public TargetInstrInfo {
+class RISCVInstrInfo final : public TargetInstrInfo {
public:
[[nodiscard]] Expected<MachineBranchAnalysis>
analyzeBranch(MachineBasicBlock &Block, MachineFunction &Function,
@@ -623,9 +624,8 @@ public:
}
[[nodiscard]] Expected<MachineInstr *>
- insertUnconditionalBranch(MachineBasicBlock &Block, MachineBasicBlock &TargetBlock,
- MachineFunction &Function,
- const TargetDescription &Target) const override {
+ insertBranch(MachineBasicBlock &Block, MachineBasicBlock &TargetBlock, MachineFunction &Function,
+ const TargetDescription &Target) const override {
if (&Block.function() != &Function || &TargetBlock.function() != &Function)
return makeUnexpected(ErrorCode::InvalidArgument,
"RISC-V branch insertion references another function");
@@ -635,6 +635,75 @@ public:
return buildJAL(Function, Target, Block, nullptr, *Zero, TargetBlock);
}
+ [[nodiscard]] Expected<bool> isFallthroughEdge(const MachineBasicBlock &From,
+ const MachineBasicBlock &To,
+ const MachineFunction &Function,
+ const TargetDescription &Target) const override {
+ if (&From.function() != &Function || &To.function() != &Function)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "RISC-V fallthrough query references another machine function");
+ if (From.next() != &To ||
+ std::ranges::none_of(From.successors(), [&To](const MachineSuccessor &Successor) {
+ return Successor.Block == &To;
+ })) {
+ return false;
+ }
+
+ bool CanFallThrough = true;
+ for (const MachineInstr *Instruction = From.firstInstruction(); Instruction != nullptr;
+ Instruction = Instruction->next()) {
+ const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction->opcode());
+ if (Descriptor == nullptr)
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V fallthrough analysis encountered an unknown opcode");
+ if (Descriptor->Flags.has(InstructionFlag::Terminator))
+ CanFallThrough = isConditionalBranch(Instruction->opcode());
+ }
+ return CanFallThrough;
+ }
+
+ [[nodiscard]] Expected<void> validateCopy(Register Destination, SubRegIndex DestinationSubReg,
+ Register Source, SubRegIndex SourceSubReg,
+ const MachineFunction &Function,
+ const TargetDescription &Target) const override {
+ if (Destination.isNoRegister() || Source.isNoRegister())
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V COPY requires two nonzero registers");
+ if (DestinationSubReg.value() != 0 || SourceSubReg.value() != 0)
+ return makeUnexpected(ErrorCode::Unsupported, "RV64GC does not model register subindices");
+
+ auto DestinationShape = copyShape(Destination, Function, Target);
+ if (!DestinationShape)
+ return std::unexpected(DestinationShape.error());
+ auto SourceShape = copyShape(Source, Function, Target);
+ if (!SourceShape)
+ return std::unexpected(SourceShape.error());
+ if (DestinationShape->Bank == SourceShape->Bank) {
+ if (DestinationShape->Width && SourceShape->Width &&
+ DestinationShape->Width != SourceShape->Width)
+ return makeUnexpected(ErrorCode::Unsupported,
+ "RISC-V same-bank COPY has incompatible register widths");
+ return {};
+ }
+
+ const RegisterBankID GPR =
+ RegisterBankID::fromValue(static_cast<std::uint32_t>(RegisterBank::GPR));
+ const RegisterBankID FPR =
+ RegisterBankID::fromValue(static_cast<std::uint32_t>(RegisterBank::FPR));
+ const bool IsCrossBankMove = (DestinationShape->Bank == GPR && SourceShape->Bank == FPR) ||
+ (DestinationShape->Bank == FPR && SourceShape->Bank == GPR);
+ if (!IsCrossBankMove)
+ return makeUnexpected(ErrorCode::Unsupported,
+ "RISC-V COPY crosses unsupported register banks");
+ const auto SupportedWidth = [](std::optional<std::uint32_t> Width) {
+ return !Width || *Width == 32 || *Width == 64;
+ };
+ if (!SupportedWidth(DestinationShape->Width) || !SupportedWidth(SourceShape->Width))
+ return makeUnexpected(ErrorCode::Unsupported,
+ "RISC-V GPR/FPR COPY requires 32-bit or 64-bit values");
+ return {};
+ }
+
[[nodiscard]] Expected<std::uint32_t>
instructionSize(const MachineInstr &Instruction, const MachineFunction &,
const TargetDescription &Target) const override {
@@ -726,12 +795,48 @@ public:
return relaxJAL(Instruction, Offset, Function, Target);
return false;
}
+
+private:
+ struct CopyShape final {
+ RegisterBankID Bank;
+ std::optional<std::uint32_t> Width;
+ };
+
+ [[nodiscard]] static Expected<CopyShape> copyShape(Register Reg, const MachineFunction &Function,
+ const TargetDescription &Target) {
+ if (Reg.isVirtual()) {
+ auto Info = Function.registerInfo().virtualRegisterInfo(Reg);
+ if (!Info)
+ return std::unexpected(Info.error());
+ const std::optional<RegisterBankID> &Bank = Info->get().Bank;
+ const std::optional<RegisterClassID> &RegClass = Info->get().RegClass;
+ if (!Bank || !RegClass)
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V COPY virtual register is not fully constrained");
+ const RegisterClassDesc *Class = Target.registers().registerClass(*RegClass);
+ if (Class == nullptr)
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V COPY references an unknown register class");
+ return CopyShape{*Bank, Class->SizeInBits};
+ }
+
+ const std::optional<PhysicalRegister> Physical = Reg.physicalRegister();
+ if (!Physical || !Target.registers().isKnownPhysicalRegister(*Physical))
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V COPY references an unknown physical register");
+ for (const RegisterBankDesc &Bank : Target.registers().registerBanks()) {
+ if (Target.registers().bankContainsRegister(Bank.ID, *Physical))
+ return CopyShape{Bank.ID, std::nullopt};
+ }
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V physical register is not assigned to a register bank");
+ }
};
} // namespace
-const TargetInstrInfo &branchInfo() noexcept {
- static const RISCVBranchInfo Value;
+const TargetInstrInfo &instrInfo() noexcept {
+ static const RISCVInstrInfo Value;
return Value;
}
diff --git a/backend/lib/Target/RISCV/RISCVInstrInfo.h b/backend/lib/Target/RISCV/RISCVInstrInfo.h
new file mode 100644
index 0000000..62c7723
--- /dev/null
+++ b/backend/lib/Target/RISCV/RISCVInstrInfo.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_LIB_TARGET_RISCV_RISCVINSTRINFO_H
+#define RCC_LIB_TARGET_RISCV_RISCVINSTRINFO_H
+
+#include "rcc/CodeGen/TargetInstrInfo.h"
+
+namespace rcc::riscv {
+
+[[nodiscard]] const TargetInstrInfo &instrInfo() noexcept;
+
+} // namespace rcc::riscv
+
+#endif // RCC_LIB_TARGET_RISCV_RISCVINSTRINFO_H
diff --git a/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp b/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp
index 2f8c5d1..9301757 100644
--- a/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp
+++ b/backend/lib/Target/RISCV/RISCVOptimizationPipeline.cpp
@@ -1,18 +1,18 @@
// SPDX-License-Identifier: GPL-3.0-or-later
+#include "RISCVInstrInfo.h"
#include "rcc/Target/RISCV/RISCVCodeGen.h"
namespace rcc::riscv {
MachineOptimizationPipelineTargetInfo optimizationPipelineInfo() noexcept {
return {
- .SSA = ssaInfo(),
+ .InstrInfo = instrInfo(),
.Combiner = machineCombinerInfo(),
.MemoryFolding = memoryFoldingInfo(),
.FrameLowering = frameLowering(),
.PseudoExpansion = pseudoExpansionInfo(),
.SchedulingModel = schedulingModel(),
- .BranchInfo = branchInfo(),
};
}
diff --git a/backend/lib/Target/RISCV/RISCVPipeline.cpp b/backend/lib/Target/RISCV/RISCVPipeline.cpp
index 3665db5..08a4653 100644
--- a/backend/lib/Target/RISCV/RISCVPipeline.cpp
+++ b/backend/lib/Target/RISCV/RISCVPipeline.cpp
@@ -2,6 +2,7 @@
#include "rcc/Target/RISCV/RISCVPipeline.h"
+#include "RISCVInstrInfo.h"
#include "rcc/CodeGen/MachineCombiner.h"
#include "rcc/CodeGen/MachineFunction.h"
#include "rcc/CodeGen/MachineOptimizationPipeline.h"
@@ -45,10 +46,10 @@ template <typename PassT, typename... ArgumentT>
auto Added = addSelectedSSAOptimizationPipeline(Pipeline, optimizationPipelineInfo());
if (!Added)
return std::unexpected(Added.error());
- Added = addPass<PHIEliminationPass>(Pipeline, ssaInfo());
+ Added = addPass<PHIEliminationPass>(Pipeline, instrInfo());
if (!Added)
return std::unexpected(Added.error());
- return addPass<TwoAddressRewritePass>(Pipeline, ssaInfo());
+ return addPass<TwoAddressRewritePass>(Pipeline, instrInfo());
}
[[nodiscard]] Expected<void> addRegisterAllocationPipeline(MachinePassManager &Pipeline) {
@@ -104,13 +105,13 @@ Expected<void> addCanonicalPipeline(MachinePassManager &Pipeline, const MachineF
if (!Added)
return std::unexpected(Added.error());
if (!Function.properties().has(MachineFunctionProperty::NoPHIs)) {
- Added = addPass<PHIEliminationPass>(Pipeline, ssaInfo());
+ Added = addPass<PHIEliminationPass>(Pipeline, instrInfo());
if (!Added)
return std::unexpected(Added.error());
}
}
if (!Function.properties().has(MachineFunctionProperty::TiedOpsRewritten)) {
- auto Added = addPass<TwoAddressRewritePass>(Pipeline, ssaInfo());
+ auto Added = addPass<TwoAddressRewritePass>(Pipeline, instrInfo());
if (!Added)
return std::unexpected(Added.error());
}