aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/CodeGen')
-rw-r--r--backend/lib/CodeGen/MachineFunctionCloner.cpp39
-rw-r--r--backend/lib/CodeGen/MachineInstr.cpp69
-rw-r--r--backend/lib/CodeGen/MachineMemOperand.cpp55
-rw-r--r--backend/lib/CodeGen/MachineVerifier.cpp38
4 files changed, 200 insertions, 1 deletions
diff --git a/backend/lib/CodeGen/MachineFunctionCloner.cpp b/backend/lib/CodeGen/MachineFunctionCloner.cpp
index 7dcf5e2..9342c5a 100644
--- a/backend/lib/CodeGen/MachineFunctionCloner.cpp
+++ b/backend/lib/CodeGen/MachineFunctionCloner.cpp
@@ -414,6 +414,45 @@ cloneMemOperand(const MachineMemOperand &SourceOperand, CloneState &State) {
if (!DebugNumberResult)
return std::unexpected(DebugNumberResult.error());
}
+ if (SourceInstruction->preInstrSymbol()) {
+ auto SymbolResult =
+ NewInstruction->setPreInstrSymbol(std::string(*SourceInstruction->preInstrSymbol()));
+ if (!SymbolResult)
+ return std::unexpected(SymbolResult.error());
+ }
+ if (SourceInstruction->postInstrSymbol()) {
+ auto SymbolResult =
+ NewInstruction->setPostInstrSymbol(std::string(*SourceInstruction->postInstrSymbol()));
+ if (!SymbolResult)
+ return std::unexpected(SymbolResult.error());
+ }
+ if (SourceInstruction->heapAllocMarker()) {
+ auto MarkerResult =
+ NewInstruction->setHeapAllocMarker(*SourceInstruction->heapAllocMarker());
+ if (!MarkerResult)
+ return std::unexpected(MarkerResult.error());
+ }
+ if (SourceInstruction->pcSections()) {
+ auto SectionsResult = NewInstruction->setPCSections(*SourceInstruction->pcSections());
+ if (!SectionsResult)
+ return std::unexpected(SectionsResult.error());
+ }
+ if (SourceInstruction->mmra()) {
+ auto MMRAResult = NewInstruction->setMMRA(*SourceInstruction->mmra());
+ if (!MMRAResult)
+ return std::unexpected(MMRAResult.error());
+ }
+ if (SourceInstruction->cfiType()) {
+ auto TypeResult = NewInstruction->setCFIType(*SourceInstruction->cfiType());
+ if (!TypeResult)
+ return std::unexpected(TypeResult.error());
+ }
+ if (SourceInstruction->deactivationSymbol()) {
+ auto SymbolResult = NewInstruction->setDeactivationSymbol(
+ std::string(*SourceInstruction->deactivationSymbol()));
+ if (!SymbolResult)
+ return std::unexpected(SymbolResult.error());
+ }
auto AppendResult = DestinationBlock->appendInstruction(*NewInstruction);
if (!AppendResult)
diff --git a/backend/lib/CodeGen/MachineInstr.cpp b/backend/lib/CodeGen/MachineInstr.cpp
index a8fe9b5..7597651 100644
--- a/backend/lib/CodeGen/MachineInstr.cpp
+++ b/backend/lib/CodeGen/MachineInstr.cpp
@@ -12,6 +12,8 @@
#include <functional>
#include <limits>
#include <optional>
+#include <string>
+#include <string_view>
#include <utility>
namespace rcc {
@@ -157,6 +159,73 @@ Expected<void> MachineInstr::setDebugLocation(MachineDebugLocation NewLocation)
return {};
}
+std::optional<std::string_view> MachineInstr::preInstrSymbol() const noexcept {
+ if (!PreInstrSymbol)
+ return std::nullopt;
+ return *PreInstrSymbol;
+}
+
+Expected<void> MachineInstr::setPreInstrSymbol(std::string Symbol) {
+ if (Symbol.empty())
+ return makeUnexpected(ErrorCode::InvalidArgument, "pre-instruction symbol cannot be empty");
+ PreInstrSymbol = std::move(Symbol);
+ return {};
+}
+
+std::optional<std::string_view> MachineInstr::postInstrSymbol() const noexcept {
+ if (!PostInstrSymbol)
+ return std::nullopt;
+ return *PostInstrSymbol;
+}
+
+Expected<void> MachineInstr::setPostInstrSymbol(std::string Symbol) {
+ if (Symbol.empty())
+ return makeUnexpected(ErrorCode::InvalidArgument, "post-instruction symbol cannot be empty");
+ PostInstrSymbol = std::move(Symbol);
+ return {};
+}
+
+Expected<void> MachineInstr::setHeapAllocMarker(MachineMetadataReference Marker) {
+ if (!Marker.isValid())
+ return makeUnexpected(ErrorCode::InvalidArgument, "heap-allocation marker must be valid");
+ HeapAllocMarker = Marker;
+ return {};
+}
+
+Expected<void> MachineInstr::setPCSections(MachineMetadataReference Sections) {
+ if (!Sections.isValid())
+ return makeUnexpected(ErrorCode::InvalidArgument, "PC sections metadata must be valid");
+ PCSections = Sections;
+ return {};
+}
+
+Expected<void> MachineInstr::setMMRA(MachineMetadataReference Metadata) {
+ if (!Metadata.isValid())
+ return makeUnexpected(ErrorCode::InvalidArgument, "MMRA metadata must be valid");
+ MMRA = Metadata;
+ return {};
+}
+
+Expected<void> MachineInstr::setCFIType(std::uint64_t Type) {
+ if (Type == 0 || Type > std::numeric_limits<std::uint32_t>::max())
+ return makeUnexpected(ErrorCode::InvalidArgument, "CFI type must fit in nonzero uint32");
+ CFIType = static_cast<std::uint32_t>(Type);
+ return {};
+}
+
+std::optional<std::string_view> MachineInstr::deactivationSymbol() const noexcept {
+ if (!DeactivationSymbol)
+ return std::nullopt;
+ return *DeactivationSymbol;
+}
+
+Expected<void> MachineInstr::setDeactivationSymbol(std::string Symbol) {
+ if (Symbol.empty())
+ return makeUnexpected(ErrorCode::InvalidArgument, "deactivation symbol cannot be empty");
+ DeactivationSymbol = std::move(Symbol);
+ return {};
+}
+
Expected<void> MachineInstr::addMemOperand(const MachineMemOperand &MemOperand) {
if (!OwnerFunction->ownsMemOperand(MemOperand)) {
return makeUnexpected(ErrorCode::InvalidArgument,
diff --git a/backend/lib/CodeGen/MachineMemOperand.cpp b/backend/lib/CodeGen/MachineMemOperand.cpp
index 451dbdb..95e7237 100644
--- a/backend/lib/CodeGen/MachineMemOperand.cpp
+++ b/backend/lib/CodeGen/MachineMemOperand.cpp
@@ -2,6 +2,9 @@
#include "rcc/CodeGen/MachineMemOperand.h"
+#include <algorithm>
+#include <array>
+#include <ranges>
#include <utility>
namespace rcc {
@@ -160,6 +163,38 @@ MemoryBase MemoryBase::externalSymbol(std::string Name) {
return MemoryBase(Kind::ExternalSymbol, std::move(Name));
}
+MemoryBase MemoryBase::irValue(std::string Name) {
+ return MemoryBase(Kind::IRValue, std::move(Name));
+}
+
+MemoryBase MemoryBase::stack() {
+ return MemoryBase(Kind::Stack, std::monostate{});
+}
+
+MemoryBase MemoryBase::got() {
+ return MemoryBase(Kind::GOT, std::monostate{});
+}
+
+MemoryBase MemoryBase::constantPoolPseudo() {
+ return MemoryBase(Kind::ConstantPoolPseudo, std::monostate{});
+}
+
+MemoryBase MemoryBase::jumpTablePseudo() {
+ return MemoryBase(Kind::JumpTablePseudo, std::monostate{});
+}
+
+MemoryBase MemoryBase::callEntryGlobal(std::string Name) {
+ return MemoryBase(Kind::CallEntryGlobal, std::move(Name));
+}
+
+MemoryBase MemoryBase::callEntryExternal(std::string Name) {
+ return MemoryBase(Kind::CallEntryExternal, std::move(Name));
+}
+
+MemoryBase MemoryBase::custom(std::string Name) {
+ return MemoryBase(Kind::Custom, std::move(Name));
+}
+
std::optional<FrameIndex> MemoryBase::frameIndex() const noexcept {
if (BaseKind != Kind::FrameIndex)
return std::nullopt;
@@ -179,8 +214,11 @@ std::optional<JumpTableIndex> MemoryBase::jumpTableIndex() const noexcept {
}
std::optional<std::string_view> MemoryBase::symbolName() const noexcept {
- if (BaseKind != Kind::GlobalSymbol && BaseKind != Kind::ExternalSymbol)
+ if (BaseKind != Kind::GlobalSymbol && BaseKind != Kind::ExternalSymbol &&
+ BaseKind != Kind::IRValue && BaseKind != Kind::CallEntryGlobal &&
+ BaseKind != Kind::CallEntryExternal && BaseKind != Kind::Custom) {
return std::nullopt;
+ }
return std::get<std::string>(Value);
}
@@ -195,6 +233,10 @@ 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.Accesses.has(MemoryAccessFlag::Invariant) && (!IsLoad || IsStore)) {
return makeUnexpected(ErrorCode::InvalidArgument,
"invariant memory operands must be load-only");
@@ -208,6 +250,17 @@ Expected<MachineMemOperand> MachineMemOperand::create(MachineMemOperandDesc Desc
if (SymbolName && SymbolName->empty()) {
return makeUnexpected(ErrorCode::InvalidArgument, "memory base symbol name cannot be empty");
}
+ const std::array MetadataReferences{
+ Description.TBAA, Description.AliasScope,
+ Description.NoAlias, Description.NoAliasAddressSpace,
+ Description.RangeMetadata,
+ };
+ if (std::ranges::any_of(MetadataReferences, [](const auto &Reference) {
+ return Reference.has_value() && !Reference->isValid();
+ })) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine memory operand contains an invalid metadata reference");
+ }
return MachineMemOperand(std::move(Description));
}
diff --git a/backend/lib/CodeGen/MachineVerifier.cpp b/backend/lib/CodeGen/MachineVerifier.cpp
index fd027fe..3ebe683 100644
--- a/backend/lib/CodeGen/MachineVerifier.cpp
+++ b/backend/lib/CodeGen/MachineVerifier.cpp
@@ -12,11 +12,13 @@
#include "rcc/CodeGen/MachineRegisterInfo.h"
#include <algorithm>
+#include <array>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <ranges>
#include <string>
+#include <string_view>
#include <unordered_map>
#include <unordered_set>
#include <utility>
@@ -306,6 +308,29 @@ private:
if (!DebugLocationResult)
return failWith("instruction debug location", DebugLocationResult.error());
}
+ const auto VerifyAttachment = [this](const std::optional<MachineMetadataReference> &Reference,
+ std::string_view Name) -> Expected<void> {
+ if (!Reference)
+ return {};
+ auto Verification = verifyMachineMetadataReference(*Reference, Function.metadata());
+ if (!Verification)
+ return failWith(Name, Verification.error());
+ return {};
+ };
+ if (auto Verification =
+ VerifyAttachment(Instruction.heapAllocMarker(), "instruction heap-allocation marker");
+ !Verification) {
+ return Verification;
+ }
+ if (auto Verification =
+ VerifyAttachment(Instruction.pcSections(), "instruction PC sections metadata");
+ !Verification) {
+ return Verification;
+ }
+ if (auto Verification = VerifyAttachment(Instruction.mmra(), "instruction MMRA metadata");
+ !Verification) {
+ return Verification;
+ }
if (Instruction.origin() && Instruction.origin()->value() == 0)
return fail("instruction has an invalid origin ID");
@@ -364,6 +389,19 @@ private:
if (MemOperand == nullptr || !RegisteredMemOperands.contains(MemOperand)) {
return fail("instruction references a foreign or null MMO");
}
+ const MachineMemOperandDesc &Description = MemOperand->description();
+ const std::array MetadataReferences{
+ Description.TBAA, Description.AliasScope,
+ Description.NoAlias, Description.NoAliasAddressSpace,
+ Description.RangeMetadata,
+ };
+ for (const auto &Reference : MetadataReferences) {
+ if (!Reference)
+ continue;
+ auto Verification = verifyMachineMetadataReference(*Reference, Function.metadata());
+ if (!Verification)
+ return failWith("machine memory operand metadata", Verification.error());
+ }
}
return {};
}