aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib')
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt4
-rw-r--r--backend/lib/CodeGen/MachineDebugInfo.cpp164
-rw-r--r--backend/lib/CodeGen/MachineFrameInfo.cpp5
-rw-r--r--backend/lib/CodeGen/MachineFunctionCloner.cpp6
-rw-r--r--backend/lib/CodeGen/MachineFunctionRecords.cpp27
-rw-r--r--backend/lib/CodeGen/MachineIRBuilder.cpp34
-rw-r--r--backend/lib/CodeGen/MachineInstr.cpp9
-rw-r--r--backend/lib/CodeGen/MachineMetadata.cpp13
-rw-r--r--backend/lib/CodeGen/MachineOperand.cpp9
-rw-r--r--backend/lib/CodeGen/MachineVerifier.cpp25
10 files changed, 285 insertions, 11 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt
index ec95c3c..08ca00e 100644
--- a/backend/lib/CodeGen/CMakeLists.txt
+++ b/backend/lib/CodeGen/CMakeLists.txt
@@ -10,6 +10,7 @@ set(
MachineBasicBlock.cpp
MachineCFGUpdater.cpp
MachineConstantPool.cpp
+ MachineDebugInfo.cpp
MachineFrameInfo.cpp
MachineFunction.cpp
MachineFunctionAttributes.cpp
@@ -42,6 +43,7 @@ set(
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineBasicBlock.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineCFGUpdater.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineConstantPool.h"
+ "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineDebugInfo.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFrameInfo.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunction.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunctionAttributes.h"
@@ -103,6 +105,7 @@ rcc_backend_register_format_files(
"${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlock.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineCFGUpdater.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineConstantPool.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/MachineDebugInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineFrameInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineFunction.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineFunctionAttributes.cpp"
@@ -135,6 +138,7 @@ rcc_backend_register_tidy_files(
"${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlock.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineCFGUpdater.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineConstantPool.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/MachineDebugInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineFrameInfo.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineFunction.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineFunctionAttributes.cpp"
diff --git a/backend/lib/CodeGen/MachineDebugInfo.cpp b/backend/lib/CodeGen/MachineDebugInfo.cpp
new file mode 100644
index 0000000..35f68ca
--- /dev/null
+++ b/backend/lib/CodeGen/MachineDebugInfo.cpp
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "rcc/CodeGen/MachineDebugInfo.h"
+
+#include <utility>
+
+namespace rcc {
+
+Expected<MachineMetadataValue> MachineMetadataValue::reference(MachineMetadataReference Reference) {
+ if (!Reference.isValid()) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine metadata value reference must be valid");
+ }
+ return MachineMetadataValue(Reference);
+}
+
+MachineMetadataValue MachineMetadataValue::expression(MachineDIExpression Expression) {
+ return MachineMetadataValue(std::move(Expression));
+}
+
+Expected<void> MachineMetadataValue::verify(const MachineMetadataInfo &Metadata) const {
+ if (!isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "machine metadata value has no representation");
+ }
+ const MachineMetadataReference *Reference = reference();
+ if (Reference == nullptr)
+ return {};
+ return verifyMachineMetadataReference(*Reference, Metadata);
+}
+
+Expected<MachineDILocation>
+MachineDILocation::create(std::vector<MachineDILocationFrame> InlineChain,
+ std::optional<MachineMetadataReference> TerminalInlinedAt) {
+ MachineDILocation Result(std::move(InlineChain), TerminalInlinedAt);
+ auto Verification = Result.verifyStructure();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ return Result;
+}
+
+Expected<void> MachineDILocation::verifyStructure() const {
+ if (InlineChain.empty()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location requires at least one frame");
+ }
+ for (const MachineDILocationFrame &Frame : InlineChain) {
+ if (!Frame.Scope.isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location frame has an invalid scope");
+ }
+ if (Frame.Scope.scope() != MachineMetadataScope::EmbeddedIR) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location scope must reference embedded IR metadata");
+ }
+ if (Frame.AtomGroup > MaxAtomGroup) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location atom group exceeds 61 bits");
+ }
+ if (Frame.AtomRank > 7) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location atom rank exceeds three bits");
+ }
+ }
+ if (TerminalInlinedAt && !TerminalInlinedAt->isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location has an invalid terminal inlined-at reference");
+ }
+ if (TerminalInlinedAt && TerminalInlinedAt->scope() != MachineMetadataScope::EmbeddedIR) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "inline debug location inlined-at must reference embedded IR metadata");
+ }
+ return {};
+}
+
+Expected<void> MachineDILocation::verify(const MachineMetadataInfo &Metadata) const {
+ auto Structure = verifyStructure();
+ if (!Structure)
+ return Structure;
+ for (const MachineDILocationFrame &Frame : InlineChain) {
+ auto Scope = verifyMachineMetadataReference(Frame.Scope, Metadata);
+ if (!Scope)
+ return Scope;
+ }
+ if (TerminalInlinedAt)
+ return verifyMachineMetadataReference(*TerminalInlinedAt, Metadata);
+ return {};
+}
+
+Expected<MachineDebugLocation> MachineDebugLocation::reference(MachineMetadataReference Reference) {
+ if (!Reference.isValid()) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine debug location reference must be valid");
+ }
+ if (Reference.scope() != MachineMetadataScope::EmbeddedIR) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine debug location must reference embedded IR metadata");
+ }
+ return MachineDebugLocation(Reference);
+}
+
+MachineDebugLocation MachineDebugLocation::inlineLocation(MachineDILocation Location) {
+ return MachineDebugLocation(std::move(Location));
+}
+
+Expected<void> MachineDebugLocation::verify(const MachineMetadataInfo &Metadata) const {
+ if (!isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "machine debug location has no representation");
+ }
+ if (const MachineMetadataReference *Reference = reference())
+ return verifyMachineMetadataReference(*Reference, Metadata);
+ return inlineLocation()->verify(Metadata);
+}
+
+Expected<void> MachineVariableDebugInfo::verifyStructure() const {
+ if (!Variable && !Expression && !Location) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "variable debug information has no metadata");
+ }
+ if (Variable && !Variable->isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "variable debug information has an invalid variable reference");
+ }
+ if (Variable && Variable->scope() != MachineMetadataScope::EmbeddedIR) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "variable debug information must reference embedded IR metadata");
+ }
+ if (Expression && !Expression->isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "variable debug information has an invalid expression");
+ }
+ if (Expression && Expression->reference() != nullptr &&
+ Expression->reference()->scope() != MachineMetadataScope::EmbeddedIR) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "variable debug expression must reference embedded IR metadata");
+ }
+ if (Location && !Location->isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "variable debug information has an invalid location");
+ }
+ return {};
+}
+
+Expected<void> MachineVariableDebugInfo::verify(const MachineMetadataInfo &Metadata) const {
+ auto Structure = verifyStructure();
+ if (!Structure)
+ return Structure;
+ if (Variable) {
+ auto VariableResult = verifyMachineMetadataReference(*Variable, Metadata);
+ if (!VariableResult)
+ return VariableResult;
+ }
+ if (Expression) {
+ auto ExpressionResult = Expression->verify(Metadata);
+ if (!ExpressionResult)
+ return ExpressionResult;
+ }
+ if (Location)
+ return Location->verify(Metadata);
+ return {};
+}
+
+} // namespace rcc
diff --git a/backend/lib/CodeGen/MachineFrameInfo.cpp b/backend/lib/CodeGen/MachineFrameInfo.cpp
index 58eab00..c4d3cda 100644
--- a/backend/lib/CodeGen/MachineFrameInfo.cpp
+++ b/backend/lib/CodeGen/MachineFrameInfo.cpp
@@ -77,6 +77,11 @@ Expected<void> MachineFrameInfo::verifyDescription(const StackObjectDesc &Descri
"stack object lifetime boundaries must not be reused");
}
}
+ if (Description.DebugInfo) {
+ auto DebugInfoResult = Description.DebugInfo->verifyStructure();
+ if (!DebugInfoResult)
+ return DebugInfoResult;
+ }
return {};
}
diff --git a/backend/lib/CodeGen/MachineFunctionCloner.cpp b/backend/lib/CodeGen/MachineFunctionCloner.cpp
index e12e33e..dcf9712 100644
--- a/backend/lib/CodeGen/MachineFunctionCloner.cpp
+++ b/backend/lib/CodeGen/MachineFunctionCloner.cpp
@@ -386,6 +386,12 @@ cloneMemOperand(const MachineMemOperand &SourceOperand, CloneState &State) {
if (SourceInstruction->sourceLocation()) {
NewInstruction->setSourceLocation(*SourceInstruction->sourceLocation());
}
+ if (SourceInstruction->debugLocation()) {
+ auto DebugLocationResult =
+ NewInstruction->setDebugLocation(*SourceInstruction->debugLocation());
+ if (!DebugLocationResult)
+ return std::unexpected(DebugLocationResult.error());
+ }
if (SourceInstruction->origin())
NewInstruction->setOrigin(*SourceInstruction->origin());
if (SourceInstruction->debugInstrNumber() != 0) {
diff --git a/backend/lib/CodeGen/MachineFunctionRecords.cpp b/backend/lib/CodeGen/MachineFunctionRecords.cpp
index 9fda0d7..0a21581 100644
--- a/backend/lib/CodeGen/MachineFunctionRecords.cpp
+++ b/backend/lib/CodeGen/MachineFunctionRecords.cpp
@@ -80,6 +80,14 @@ verifyDebugValueSubstitution(const MachineDebugValueSubstitution &Substitution)
return {};
}
+[[nodiscard]] Expected<void> verifyEntryValue(const MachineEntryValueInfo &EntryValue) {
+ if (!EntryValue.Reg.isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "entry-value record requires a physical register");
+ }
+ return EntryValue.DebugInfo.verifyStructure();
+}
+
} // namespace
Expected<void>
@@ -143,6 +151,14 @@ MachineFunctionRecords::addDebugValueSubstitution(MachineDebugValueSubstitution
return {};
}
+Expected<void> MachineFunctionRecords::addEntryValue(MachineEntryValueInfo EntryValue) {
+ auto Verification = verifyEntryValue(EntryValue);
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ EntryValues.push_back(std::move(EntryValue));
+ return {};
+}
+
Expected<void> MachineFunctionRecords::verify() const {
if (CalleeSavedRegisters) {
auto CalleeSavedVerification = verifyCalleeSavedRegisters(*CalleeSavedRegisters);
@@ -210,6 +226,12 @@ Expected<void> MachineFunctionRecords::verify() const {
}
CompletedDebugReferences.insert(Path.begin(), Path.end());
}
+
+ for (const MachineEntryValueInfo &EntryValue : EntryValues) {
+ auto EntryValueVerification = verifyEntryValue(EntryValue);
+ if (!EntryValueVerification)
+ return EntryValueVerification;
+ }
return {};
}
@@ -258,6 +280,11 @@ MachineFunctionRecords::clone(const MachineFunctionCloneContext &CloneContext) c
if (!AddResult)
return std::unexpected(AddResult.error());
}
+ for (const MachineEntryValueInfo &Source : EntryValues) {
+ auto AddResult = Result.addEntryValue(Source);
+ if (!AddResult)
+ return std::unexpected(AddResult.error());
+ }
return Result;
}
diff --git a/backend/lib/CodeGen/MachineIRBuilder.cpp b/backend/lib/CodeGen/MachineIRBuilder.cpp
index 7f6421b..5afdd72 100644
--- a/backend/lib/CodeGen/MachineIRBuilder.cpp
+++ b/backend/lib/CodeGen/MachineIRBuilder.cpp
@@ -33,8 +33,8 @@ MachineInstrBuilder::MachineInstrBuilder(MachineInstrBuilder &&Other) noexcept
ExplicitOperands(std::move(Other.ExplicitOperands)),
ExtraImplicitOperands(std::move(Other.ExtraImplicitOperands)),
RequestedTies(std::move(Other.RequestedTies)), MemOperands(std::move(Other.MemOperands)),
- Flags(Other.Flags), Location(std::move(Other.Location)), Origin(Other.Origin),
- IsBuilt(Other.IsBuilt) {
+ Flags(Other.Flags), Location(std::move(Other.Location)),
+ DebugLocation(std::move(Other.DebugLocation)), Origin(Other.Origin), IsBuilt(Other.IsBuilt) {
Other.Function = nullptr;
Other.Target = nullptr;
Other.Descriptor = nullptr;
@@ -58,6 +58,7 @@ MachineInstrBuilder &MachineInstrBuilder::operator=(MachineInstrBuilder &&Other)
MemOperands = std::move(Other.MemOperands);
Flags = Other.Flags;
Location = std::move(Other.Location);
+ DebugLocation = std::move(Other.DebugLocation);
Origin = Other.Origin;
IsBuilt = Other.IsBuilt;
@@ -219,8 +220,9 @@ Expected<void> MachineInstrBuilder::addRegisterMask(std::shared_ptr<const Regist
return addOperand(std::move(*Operand));
}
-Expected<void> MachineInstrBuilder::addMetadata(std::string Marker, std::uint32_t TargetFlags) {
- auto Operand = MachineOperand::metadata(std::move(Marker), TargetFlags);
+Expected<void> MachineInstrBuilder::addMetadata(MachineMetadataValue Value,
+ std::uint32_t TargetFlags) {
+ auto Operand = MachineOperand::metadata(std::move(Value), TargetFlags);
if (!Operand)
return std::unexpected(Operand.error());
return addOperand(std::move(*Operand));
@@ -301,6 +303,25 @@ Expected<void> MachineInstrBuilder::clearSourceLocation() {
return {};
}
+Expected<void> MachineInstrBuilder::setDebugLocation(MachineDebugLocation NewLocation) {
+ auto Pending = ensurePending();
+ if (!Pending)
+ return std::unexpected(Pending.error());
+ if (!NewLocation.isValid()) {
+ return makeUnexpected(ErrorCode::InvalidArgument, "builder debug location is invalid");
+ }
+ DebugLocation = std::move(NewLocation);
+ return {};
+}
+
+Expected<void> MachineInstrBuilder::clearDebugLocation() {
+ auto Pending = ensurePending();
+ if (!Pending)
+ return std::unexpected(Pending.error());
+ DebugLocation.reset();
+ return {};
+}
+
Expected<void> MachineInstrBuilder::setOrigin(OriginID NewOrigin) {
auto Pending = ensurePending();
if (!Pending)
@@ -518,6 +539,11 @@ Expected<MachineInstr *> MachineInstrBuilder::build() {
Result->setFlags(Flags);
if (Location)
Result->setSourceLocation(std::move(*Location));
+ if (DebugLocation) {
+ auto DebugLocationResult = Result->setDebugLocation(std::move(*DebugLocation));
+ if (!DebugLocationResult)
+ return std::unexpected(DebugLocationResult.error());
+ }
if (Origin)
Result->setOrigin(*Origin);
diff --git a/backend/lib/CodeGen/MachineInstr.cpp b/backend/lib/CodeGen/MachineInstr.cpp
index aaeeacd..a8fe9b5 100644
--- a/backend/lib/CodeGen/MachineInstr.cpp
+++ b/backend/lib/CodeGen/MachineInstr.cpp
@@ -148,6 +148,15 @@ Expected<void> MachineInstr::untieOperand(std::size_t Index) {
return {};
}
+Expected<void> MachineInstr::setDebugLocation(MachineDebugLocation NewLocation) {
+ if (!NewLocation.isValid()) {
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "machine instruction debug location must be valid");
+ }
+ DebugLocation = std::move(NewLocation);
+ return {};
+}
+
Expected<void> MachineInstr::addMemOperand(const MachineMemOperand &MemOperand) {
if (!OwnerFunction->ownsMemOperand(MemOperand)) {
return makeUnexpected(ErrorCode::InvalidArgument,
diff --git a/backend/lib/CodeGen/MachineMetadata.cpp b/backend/lib/CodeGen/MachineMetadata.cpp
index 24a04e9..f789a74 100644
--- a/backend/lib/CodeGen/MachineMetadata.cpp
+++ b/backend/lib/CodeGen/MachineMetadata.cpp
@@ -111,4 +111,17 @@ Expected<MachineMetadataInfo> MachineMetadataInfo::clone() const {
return Result;
}
+Expected<void> verifyMachineMetadataReference(MachineMetadataReference Reference,
+ const MachineMetadataInfo &Metadata) {
+ if (!Reference.isValid()) {
+ return makeUnexpected(ErrorCode::VerificationError, "machine metadata reference is invalid");
+ }
+ if (Reference.scope() == MachineMetadataScope::MachineFunction &&
+ Metadata.node(Reference.slot()) == nullptr) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "machine metadata reference uses an undefined function slot");
+ }
+ return {};
+}
+
} // namespace rcc
diff --git a/backend/lib/CodeGen/MachineOperand.cpp b/backend/lib/CodeGen/MachineOperand.cpp
index 0e5febd..cd2d217 100644
--- a/backend/lib/CodeGen/MachineOperand.cpp
+++ b/backend/lib/CodeGen/MachineOperand.cpp
@@ -158,11 +158,12 @@ Expected<MachineOperand> MachineOperand::registerMask(std::shared_ptr<const Regi
return MachineOperand(Kind::RegisterMask, RegisterMaskOperand{std::move(Mask)}, TargetFlags);
}
-Expected<MachineOperand> MachineOperand::metadata(std::string Marker, std::uint32_t TargetFlags) {
- if (Marker.empty()) {
- return makeUnexpected(ErrorCode::InvalidArgument, "metadata operand marker cannot be empty");
+Expected<MachineOperand> MachineOperand::metadata(MachineMetadataValue Value,
+ std::uint32_t TargetFlags) {
+ if (!Value.isValid()) {
+ return makeUnexpected(ErrorCode::InvalidArgument, "metadata operand value must be valid");
}
- return MachineOperand(Kind::Metadata, MetadataOperand{std::move(Marker)}, TargetFlags);
+ return MachineOperand(Kind::Metadata, MetadataOperand{std::move(Value)}, TargetFlags);
}
MachineOperand MachineOperand::targetIndex(TargetIndex Index, std::int64_t Offset,
diff --git a/backend/lib/CodeGen/MachineVerifier.cpp b/backend/lib/CodeGen/MachineVerifier.cpp
index 2a29343..7e050ec 100644
--- a/backend/lib/CodeGen/MachineVerifier.cpp
+++ b/backend/lib/CodeGen/MachineVerifier.cpp
@@ -272,6 +272,11 @@ private:
if (Instruction.sourceLocation() && !Instruction.sourceLocation()->isValid()) {
return fail("instruction has an invalid source location");
}
+ if (Instruction.debugLocation()) {
+ auto DebugLocationResult = Instruction.debugLocation()->verify(Function.metadata());
+ if (!DebugLocationResult)
+ return failWith("instruction debug location", DebugLocationResult.error());
+ }
if (Instruction.origin() && Instruction.origin()->value() == 0)
return fail("instruction has an invalid origin ID");
@@ -293,9 +298,10 @@ private:
Address != nullptr && (Address->FunctionName.empty() || Address->BlockName.empty())) {
return fail("block-address operand has an incomplete name");
}
- if (const auto *Metadata = Operand.getIf<MetadataOperand>();
- Metadata != nullptr && Metadata->Marker.empty()) {
- return fail("metadata operand has an empty marker");
+ if (const auto *Metadata = Operand.getIf<MetadataOperand>(); Metadata != nullptr) {
+ auto MetadataResult = Metadata->Value.verify(Function.metadata());
+ if (!MetadataResult)
+ return failWith("metadata operand", MetadataResult.error());
}
if (const auto *Symbol = Operand.getIf<MCSymbolOperand>();
Symbol != nullptr && Symbol->Name.empty()) {
@@ -342,6 +348,11 @@ private:
return fail("stack object lifetime references a detached or unknown instruction");
}
}
+ if (Description->DebugInfo) {
+ auto DebugInfoResult = Description->DebugInfo->verify(Function.metadata());
+ if (!DebugInfoResult)
+ return failWith("stack object debug information", DebugInfoResult.error());
+ }
}
return {};
}
@@ -356,6 +367,14 @@ private:
if (!Target.registers().isKnownPhysicalRegister(Reg))
return fail("callee-saved register list references an unknown physical register");
}
+ for (const MachineEntryValueInfo &EntryValue : Records.entryValues()) {
+ if (!Target.registers().isKnownPhysicalRegister(EntryValue.Reg)) {
+ return fail("entry-value record references an unknown physical register");
+ }
+ auto DebugInfoResult = EntryValue.DebugInfo.verify(Function.metadata());
+ if (!DebugInfoResult)
+ return failWith("entry-value debug information", DebugInfoResult.error());
+ }
auto VerifyCall = [this](MachineInstrStableID ID,
std::string_view Kind) -> Expected<const MachineInstr *> {