aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib')
-rw-r--r--backend/lib/Target/RISCV/RISCV.rccdesc4
-rw-r--r--backend/lib/Target/RISCV/RISCVCallLowering.cpp25
-rw-r--r--backend/lib/Target/RISCV/RISCVFrameLowering.cpp46
-rw-r--r--backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp32
4 files changed, 33 insertions, 74 deletions
diff --git a/backend/lib/Target/RISCV/RISCV.rccdesc b/backend/lib/Target/RISCV/RISCV.rccdesc
index f8e22d4..ea3a775 100644
--- a/backend/lib/Target/RISCV/RISCV.rccdesc
+++ b/backend/lib/Target/RISCV/RISCV.rccdesc
@@ -3351,6 +3351,8 @@ instructions:
- { kinds: [immediate, integer_immediate] }
- { kinds: [immediate, integer_immediate] }
num_explicit_defs: 0
+ implicit_defs: [{ register: X2 }]
+ implicit_uses: [{ register: X2 }]
flags: [pseudo, allowed_pre_legalizer, has_side_effects]
owner: prologue_epilogue_insertion
deadline: frame_finalized
@@ -3362,6 +3364,8 @@ instructions:
- { kinds: [immediate, integer_immediate] }
- { kinds: [immediate, integer_immediate] }
num_explicit_defs: 0
+ implicit_defs: [{ register: X2 }]
+ implicit_uses: [{ register: X2 }]
flags: [pseudo, allowed_pre_legalizer, has_side_effects]
owner: prologue_epilogue_insertion
deadline: frame_finalized
diff --git a/backend/lib/Target/RISCV/RISCVCallLowering.cpp b/backend/lib/Target/RISCV/RISCVCallLowering.cpp
index fd01d52..3a5805a 100644
--- a/backend/lib/Target/RISCV/RISCVCallLowering.cpp
+++ b/backend/lib/Target/RISCV/RISCVCallLowering.cpp
@@ -1172,20 +1172,20 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
[[nodiscard]] Expected<void> emitCallFrameAdjustment(MachineIRBuilder &Builder,
InstructionOpcode OpcodeValue,
- const CallFrameRequirements &Frame,
- MachineInstrFlag Flag) {
+ const CallFrameRequirements &Frame) {
+ if (Frame.SizeBytes > static_cast<std::uint64_t>(std::numeric_limits<std::int64_t>::max())) {
+ return makeUnexpected(ErrorCode::Unsupported,
+ "RISC-V call-frame size does not fit a MIR immediate");
+ }
auto Instruction = Builder.buildInstr(targetOpcode(OpcodeValue));
if (!Instruction)
return std::unexpected(Instruction.error());
- auto Size = addUnsignedImmediate(*Instruction, Frame.SizeBytes);
+ auto Size = Instruction->addImmediate(static_cast<std::int64_t>(Frame.SizeBytes));
if (!Size)
return std::unexpected(Size.error());
- auto Align = addUnsignedImmediate(*Instruction, Frame.Align.bytes());
- if (!Align)
- return std::unexpected(Align.error());
- auto Flags = Instruction->setFlags({Flag});
- if (!Flags)
- return std::unexpected(Flags.error());
+ auto PreparedBytes = Instruction->addImmediate(0);
+ if (!PreparedBytes)
+ return std::unexpected(PreparedBytes.error());
auto Built = Instruction->build();
if (!Built)
return std::unexpected(Built.error());
@@ -1371,8 +1371,8 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
[[nodiscard]] Expected<void> emitCall(MachineIRBuilder &Builder, const CallLoweringPlan &Plan) {
if (Plan.callFrame().EmitSetup) {
- auto Down = emitCallFrameAdjustment(Builder, InstructionOpcode::ADJCALLSTACKDOWN,
- Plan.callFrame(), MachineInstrFlag::FrameSetup);
+ auto Down =
+ emitCallFrameAdjustment(Builder, InstructionOpcode::ADJCALLSTACKDOWN, Plan.callFrame());
if (!Down)
return std::unexpected(Down.error());
}
@@ -1388,8 +1388,7 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
return std::unexpected(Call.error());
if (Plan.callFrame().EmitDestroy) {
- auto Up = emitCallFrameAdjustment(Builder, InstructionOpcode::ADJCALLSTACKUP, Plan.callFrame(),
- MachineInstrFlag::FrameDestroy);
+ auto Up = emitCallFrameAdjustment(Builder, InstructionOpcode::ADJCALLSTACKUP, Plan.callFrame());
if (!Up)
return std::unexpected(Up.error());
}
diff --git a/backend/lib/Target/RISCV/RISCVFrameLowering.cpp b/backend/lib/Target/RISCV/RISCVFrameLowering.cpp
index e47a9c8..4ba5540 100644
--- a/backend/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/backend/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -102,29 +102,33 @@ constexpr std::uint8_t DwarfOpBaseRegisterExtended = 0x92U;
struct CallFrameRequirement final {
std::int64_t Amount = 0;
- std::int64_t Alignment = 0;
+ std::int64_t PreparedBytes = 0;
std::int64_t AlignedAmount = 0;
};
[[nodiscard]] Expected<CallFrameRequirement> callFrameRequirement(const MachineInstr &Instruction) {
- if (Instruction.operandCount() != 2) {
+ if (Instruction.operandCount() < 2) {
return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V call-frame pseudo requires exactly amount and alignment");
+ "RISC-V call-frame pseudo requires amount and prepared-byte operands");
+ }
+ for (std::size_t Index = 2; Index < Instruction.operandCount(); ++Index) {
+ const MachineOperand *Operand = Instruction.operandAt(Index);
+ if (Operand == nullptr || !Operand->isRegister() || !Operand->isImplicit()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V call-frame pseudo has an unexpected explicit operand");
+ }
}
auto Amount = immediateValue(*Instruction.operandAt(0));
- auto RequestedAlignment = immediateValue(*Instruction.operandAt(1));
- if (!Amount || !RequestedAlignment || *Amount < 0 || *RequestedAlignment <= 0 ||
- !std::has_single_bit(static_cast<std::uint64_t>(*RequestedAlignment))) {
+ auto PreparedBytes = immediateValue(*Instruction.operandAt(1));
+ if (!Amount || !PreparedBytes || *Amount < 0 || *PreparedBytes < 0) {
return makeUnexpected(ErrorCode::VerificationError,
- "RISC-V call-frame amount or alignment is invalid");
+ "RISC-V call-frame amount or prepared-byte count is invalid");
}
- const std::uint64_t Alignment =
- std::max(StackAlignmentBytes, static_cast<std::uint64_t>(*RequestedAlignment));
- auto Aligned = alignTo(static_cast<std::uint64_t>(*Amount), Alignment);
+ auto Aligned = alignTo(static_cast<std::uint64_t>(*Amount), StackAlignmentBytes);
if (!Aligned || *Aligned > static_cast<std::uint64_t>(std::numeric_limits<std::int64_t>::max())) {
return makeUnexpected(ErrorCode::FrameLayoutFailed, "RISC-V call-frame amount is too large");
}
- return CallFrameRequirement{*Amount, *RequestedAlignment, static_cast<std::int64_t>(*Aligned)};
+ return CallFrameRequirement{*Amount, *PreparedBytes, static_cast<std::int64_t>(*Aligned)};
}
[[nodiscard]] Expected<std::int64_t> callFrameAmount(const MachineInstr &Instruction) {
@@ -148,23 +152,6 @@ struct CallFrameRequirement final {
if (!Object.isTombstone() && !Object.description()->IsDead)
Result = std::max(Result, Object.description()->Align.bytes());
}
- for (const MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr;
- Block = Block->next()) {
- for (const MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
- Instruction = Instruction->next()) {
- if (Instruction->opcode() != targetOpcode(InstructionOpcode::ADJCALLSTACKDOWN) &&
- Instruction->opcode() != targetOpcode(InstructionOpcode::ADJCALLSTACKUP)) {
- continue;
- }
- if (Instruction->operandCount() < 2)
- continue;
- auto Requested = immediateValue(*Instruction->operandAt(1));
- if (Requested && *Requested > 0 &&
- std::has_single_bit(static_cast<std::uint64_t>(*Requested))) {
- Result = std::max(Result, static_cast<std::uint64_t>(*Requested));
- }
- }
- }
return Result;
}
@@ -314,7 +301,8 @@ struct CallFrameRequirement final {
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V call-frame destroy has no matching setup");
}
- if (Active->Amount != Requirement->Amount || Active->Alignment != Requirement->Alignment) {
+ if (Active->Amount != Requirement->Amount ||
+ Active->PreparedBytes != Requirement->PreparedBytes) {
return makeUnexpected(ErrorCode::VerificationError,
"RISC-V call-frame setup and destroy requirements differ");
}
diff --git a/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp b/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp
index 81fc6dc..aee09a9 100644
--- a/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp
+++ b/backend/lib/Target/RISCV/RISCVRegisterAllocation.cpp
@@ -14,7 +14,6 @@
#include <algorithm>
#include <array>
-#include <bit>
#include <cstddef>
#include <cstdint>
#include <optional>
@@ -37,20 +36,6 @@ struct SpillForm final {
return RegisterClassID::fromValue(static_cast<std::uint32_t>(Value));
}
-[[nodiscard]] std::optional<std::int64_t> immediateValue(const MachineOperand &Operand) noexcept {
- if (const auto *Immediate = Operand.getIf<std::int64_t>())
- return *Immediate;
- const auto *Integer = Operand.getIf<IntegerImmediateOperand>();
- if (Integer == nullptr || Integer->Value.bitWidth() == 0 || Integer->Value.bitWidth() > 64) {
- return std::nullopt;
- }
- std::uint64_t Raw = Integer->Value.words().empty() ? 0 : Integer->Value.words().front();
- const std::uint32_t Width = Integer->Value.bitWidth();
- if (Width < 64 && (Raw & (std::uint64_t{1} << (Width - 1U))) != 0)
- Raw |= ~std::uint64_t{0} << Width;
- return std::bit_cast<std::int64_t>(Raw);
-}
-
[[nodiscard]] constexpr std::optional<SpillForm> spillForm(RegisterClassID Class) noexcept {
if (Class == registerClassID(RegisterClass::GPR) ||
Class == registerClassID(RegisterClass::GPRC) ||
@@ -129,23 +114,6 @@ public:
RequiredAlignment = std::max(RequiredAlignment, Object.description()->Align.bytes());
}
}
- for (const MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr;
- Block = Block->next()) {
- for (const MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
- Instruction = Instruction->next()) {
- if (Instruction->opcode() != targetOpcode(InstructionOpcode::ADJCALLSTACKDOWN) &&
- Instruction->opcode() != targetOpcode(InstructionOpcode::ADJCALLSTACKUP)) {
- continue;
- }
- if (Instruction->operandCount() < 2)
- continue;
- const auto Requested = immediateValue(*Instruction->operandAt(1));
- if (Requested && *Requested > 0 &&
- std::has_single_bit(static_cast<std::uint64_t>(*Requested))) {
- RequiredAlignment = std::max(RequiredAlignment, static_cast<std::uint64_t>(*Requested));
- }
- }
- }
const bool RequiresRealignment = RequiredAlignment > 16;
if (Reg.number() == static_cast<std::uint32_t>(PhysicalRegisterID::X9))
return RequiresRealignment;