aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/MachineMemOperand.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-11 17:37:42 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-11 17:37:42 +0800
commit6a7b083f322f4ac47e58cbf9d4d5fd4d1f6fecd0 (patch)
treef363c502f0e2b9cda2f12928049275a433db6ad4 /backend/lib/CodeGen/MachineMemOperand.cpp
parentadcf8c9b1bd1b47e00bf859693112cea1f7e8c9f (diff)
downloadrcc-project-6a7b083f322f4ac47e58cbf9d4d5fd4d1f6fecd0.tar.gz
rcc-project-6a7b083f322f4ac47e58cbf9d4d5fd4d1f6fecd0.tar.xz
[MIR] Accept fixed-baseline LLVM syntax
Diffstat (limited to 'backend/lib/CodeGen/MachineMemOperand.cpp')
-rw-r--r--backend/lib/CodeGen/MachineMemOperand.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/backend/lib/CodeGen/MachineMemOperand.cpp b/backend/lib/CodeGen/MachineMemOperand.cpp
index 95e7237..5f126fd 100644
--- a/backend/lib/CodeGen/MachineMemOperand.cpp
+++ b/backend/lib/CodeGen/MachineMemOperand.cpp
@@ -4,12 +4,22 @@
#include <algorithm>
#include <array>
+#include <bit>
#include <ranges>
#include <utility>
namespace rcc {
namespace {
+[[nodiscard]] std::uint64_t effectiveAlignment(std::uint64_t BaseAlignment,
+ std::int64_t Offset) noexcept {
+ if (Offset == 0)
+ return BaseAlignment;
+ const auto OffsetBits = static_cast<std::uint64_t>(Offset);
+ const std::uint64_t OffsetAlignment = std::uint64_t{1} << std::countr_zero(OffsetBits);
+ return std::min(BaseAlignment, OffsetAlignment);
+}
+
[[nodiscard]] bool isValidAtomicLoadOrdering(AtomicOrdering Ordering) noexcept {
return Ordering == AtomicOrdering::Unordered || Ordering == AtomicOrdering::Monotonic ||
Ordering == AtomicOrdering::Acquire || Ordering == AtomicOrdering::SequentiallyConsistent;
@@ -167,6 +177,17 @@ MemoryBase MemoryBase::irValue(std::string Name) {
return MemoryBase(Kind::IRValue, std::move(Name));
}
+Expected<MemoryBase> MemoryBase::irConstant(GenericConstantData Constant) {
+ auto Verification = Constant.verify();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ if (Constant.Type.Kind != GenericConstantTypeKind::Pointer) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine memory IR constant base must have pointer type");
+ }
+ return MemoryBase(Kind::IRConstant, std::move(Constant));
+}
+
MemoryBase MemoryBase::stack() {
return MemoryBase(Kind::Stack, std::monostate{});
}
@@ -222,6 +243,12 @@ std::optional<std::string_view> MemoryBase::symbolName() const noexcept {
return std::get<std::string>(Value);
}
+const GenericConstantData *MemoryBase::constantValue() const noexcept {
+ if (BaseKind != Kind::IRConstant)
+ return nullptr;
+ return std::get_if<GenericConstantData>(&Value);
+}
+
Expected<MachineMemOperand> MachineMemOperand::create(MachineMemOperandDesc Description) {
const bool IsLoad = Description.Accesses.has(MemoryAccessFlag::Load);
const bool IsStore = Description.Accesses.has(MemoryAccessFlag::Store);
@@ -233,9 +260,16 @@ Expected<MachineMemOperand> MachineMemOperand::create(MachineMemOperandDesc Desc
return makeUnexpected(ErrorCode::InvalidArgument,
"machine memory operand address space must fit in 24 bits");
}
- if (Description.BaseAlign && Description.BaseAlign->bytes() < Description.Align.bytes()) {
- return makeUnexpected(ErrorCode::InvalidArgument,
- "machine memory operand base alignment cannot be smaller than alignment");
+ if (Description.BaseAlign) {
+ const std::uint64_t Effective =
+ effectiveAlignment(Description.BaseAlign->bytes(), Description.Offset);
+ if (Effective != Description.Align.bytes()) {
+ return makeUnexpected(
+ ErrorCode::InvalidArgument,
+ "machine memory operand alignment is inconsistent with base alignment and offset");
+ }
+ if (*Description.BaseAlign == Description.Align)
+ Description.BaseAlign.reset();
}
if (Description.Accesses.has(MemoryAccessFlag::Invariant) && (!IsLoad || IsStore)) {
return makeUnexpected(ErrorCode::InvalidArgument,