aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen
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
parentadcf8c9b1bd1b47e00bf859693112cea1f7e8c9f (diff)
downloadrcc-project-6a7b083f322f4ac47e58cbf9d4d5fd4d1f6fecd0.tar.gz
rcc-project-6a7b083f322f4ac47e58cbf9d4d5fd4d1f6fecd0.tar.xz
[MIR] Accept fixed-baseline LLVM syntax
Diffstat (limited to 'backend/lib/CodeGen')
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt1
-rw-r--r--backend/lib/CodeGen/CompilationUnit.cpp39
-rw-r--r--backend/lib/CodeGen/InstructionDescriptor.cpp8
-rw-r--r--backend/lib/CodeGen/MachineFunction.cpp2
-rw-r--r--backend/lib/CodeGen/MachineFunctionCloner.cpp8
-rw-r--r--backend/lib/CodeGen/MachineMemOperand.cpp40
-rw-r--r--backend/lib/CodeGen/MachineOperand.cpp59
-rw-r--r--backend/lib/CodeGen/MachinePseudoExpansion.cpp22
-rw-r--r--backend/lib/CodeGen/MachineRegisterInfo.cpp1
-rw-r--r--backend/lib/CodeGen/MachineVerifier.cpp58
10 files changed, 165 insertions, 73 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt
index 15f1772..d25d164 100644
--- a/backend/lib/CodeGen/CMakeLists.txt
+++ b/backend/lib/CodeGen/CMakeLists.txt
@@ -88,6 +88,7 @@ set(
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/GenericConstant.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/FrameIndexElimination.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/InstructionDescriptor.h"
+ "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/InlineAsm.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/LowLevelType.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineBasicBlockAttributes.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineCFIInfo.h"
diff --git a/backend/lib/CodeGen/CompilationUnit.cpp b/backend/lib/CodeGen/CompilationUnit.cpp
index 5ec54bc..a017851 100644
--- a/backend/lib/CodeGen/CompilationUnit.cpp
+++ b/backend/lib/CodeGen/CompilationUnit.cpp
@@ -22,13 +22,11 @@ CompilationUnit &CompilationUnit::operator=(CompilationUnit &&) noexcept = defau
CompilationUnit::~CompilationUnit() = default;
Expected<MachineFunction *> CompilationUnit::createMachineFunction(std::string Name) {
- if (Name.empty())
- return makeUnexpected(ErrorCode::InvalidArgument, "machine function name cannot be empty");
- if (FunctionNameToIndex.contains(Name)) {
+ if (!Name.empty() && FunctionNameToIndex.contains(Name)) {
return makeUnexpected(ErrorCode::InvalidArgument,
"machine function name is already present in the compilation unit");
}
- if (GlobalNameToIndex.contains(Name)) {
+ if (!Name.empty() && GlobalNameToIndex.contains(Name)) {
return makeUnexpected(ErrorCode::InvalidArgument,
"machine function name conflicts with a global object");
}
@@ -42,7 +40,8 @@ Expected<MachineFunction *> CompilationUnit::createMachineFunction(std::string N
MachineFunction *Result = Function->get();
const std::size_t Index = Functions.size();
- FunctionNameToIndex.emplace(std::string(Result->name()), Index);
+ if (!Result->name().empty())
+ FunctionNameToIndex.emplace(std::string(Result->name()), Index);
Functions.push_back(std::move(*Function));
return Result;
}
@@ -129,23 +128,20 @@ const GlobalObjectDesc *CompilationUnit::globalObject(std::string_view Name) con
}
Expected<void> CompilationUnit::verify() const {
- if (FunctionNameToIndex.size() != Functions.size()) {
- return makeUnexpected(ErrorCode::VerificationError,
- "compilation unit function name index has an inconsistent size");
- }
if (GlobalNameToIndex.size() != GlobalObjects.size()) {
return makeUnexpected(ErrorCode::VerificationError,
"compilation unit global object name index has an inconsistent size");
}
std::unordered_set<MachineFunctionStableID> StableIDs;
+ std::size_t NamedFunctionCount = 0;
for (std::size_t Index = 0; Index < Functions.size(); ++Index) {
const std::unique_ptr<MachineFunction> &Function = Functions[Index];
if (Function == nullptr) {
return makeUnexpected(ErrorCode::VerificationError,
"compilation unit contains a null machine function");
}
- if (Function->name().empty() || !Function->stableID().isValid()) {
+ if (!Function->stableID().isValid()) {
return makeUnexpected(ErrorCode::VerificationError,
"compilation unit contains an invalid machine function identity");
}
@@ -154,16 +150,23 @@ Expected<void> CompilationUnit::verify() const {
"compilation unit contains duplicate machine function StableIDs");
}
- const auto Position = FunctionNameToIndex.find(Function->name());
- if (Position == FunctionNameToIndex.end() || Position->second != Index) {
- return makeUnexpected(ErrorCode::VerificationError,
- "compilation unit function name index is inconsistent");
- }
- if (GlobalNameToIndex.contains(Function->name())) {
- return makeUnexpected(ErrorCode::VerificationError,
- "function name conflicts with a global object symbol");
+ if (!Function->name().empty()) {
+ ++NamedFunctionCount;
+ const auto Position = FunctionNameToIndex.find(Function->name());
+ if (Position == FunctionNameToIndex.end() || Position->second != Index) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "compilation unit function name index is inconsistent");
+ }
+ if (GlobalNameToIndex.contains(Function->name())) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "function name conflicts with a global object symbol");
+ }
}
}
+ if (FunctionNameToIndex.size() != NamedFunctionCount) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "compilation unit function name index has an inconsistent size");
+ }
for (std::size_t Index = 0; Index < GlobalObjects.size(); ++Index) {
const std::unique_ptr<GlobalObjectDesc> &Object = GlobalObjects[Index];
diff --git a/backend/lib/CodeGen/InstructionDescriptor.cpp b/backend/lib/CodeGen/InstructionDescriptor.cpp
index 48d4f10..fa00537 100644
--- a/backend/lib/CodeGen/InstructionDescriptor.cpp
+++ b/backend/lib/CodeGen/InstructionDescriptor.cpp
@@ -395,8 +395,12 @@ Expected<void> InstructionSet::validateExplicitOperands(const InstructionDescrip
}
const OperandDescriptor &OperandDesc = descriptorForOperand(Descriptor, *Shape, Index);
const auto Validation = validateOperand(OperandDesc, Operand, RegInfo);
- if (!Validation)
- return std::unexpected(Validation.error());
+ if (!Validation) {
+ return makeUnexpected(
+ Validation.error().code(),
+ "operand " + std::to_string(Index) + " of '" + Descriptor.Name + "': " +
+ std::string(Validation.error().message()));
+ }
if (Operand.isRegister()) {
if (isDefRole(OperandDesc.RegisterRole)) {
if (SawUse) {
diff --git a/backend/lib/CodeGen/MachineFunction.cpp b/backend/lib/CodeGen/MachineFunction.cpp
index 7f4c3a9..b870858 100644
--- a/backend/lib/CodeGen/MachineFunction.cpp
+++ b/backend/lib/CodeGen/MachineFunction.cpp
@@ -57,8 +57,6 @@ private:
Expected<std::unique_ptr<MachineFunction>>
MachineFunction::create(std::string Name, MachineFunctionStableID StableID) {
- if (Name.empty())
- return makeUnexpected(ErrorCode::InvalidArgument, "machine function name cannot be empty");
if (!StableID.isValid())
return makeUnexpected(ErrorCode::InvalidArgument, "machine function StableID must be valid");
return std::unique_ptr<MachineFunction>(new MachineFunction(std::move(Name), StableID));
diff --git a/backend/lib/CodeGen/MachineFunctionCloner.cpp b/backend/lib/CodeGen/MachineFunctionCloner.cpp
index 0048194..1a66e66 100644
--- a/backend/lib/CodeGen/MachineFunctionCloner.cpp
+++ b/backend/lib/CodeGen/MachineFunctionCloner.cpp
@@ -202,6 +202,14 @@ cloneMemOperand(const MachineMemOperand &SourceOperand, CloneState &State) {
if (!DestinationReg)
return std::unexpected(DestinationReg.error());
+ if (SourceInfo.Name) {
+ auto DestinationInfo =
+ State.Destination.registerInfo().virtualRegisterInfo(*DestinationReg);
+ if (!DestinationInfo)
+ return std::unexpected(DestinationInfo.error());
+ DestinationInfo->get().Name = SourceInfo.Name;
+ }
+
if (SourceInfo.Bank) {
auto SetResult =
State.Destination.registerInfo().setRegisterBank(*DestinationReg, *SourceInfo.Bank);
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,
diff --git a/backend/lib/CodeGen/MachineOperand.cpp b/backend/lib/CodeGen/MachineOperand.cpp
index d1d152e..c81a7c3 100644
--- a/backend/lib/CodeGen/MachineOperand.cpp
+++ b/backend/lib/CodeGen/MachineOperand.cpp
@@ -121,31 +121,12 @@ Expected<IntegerImmediate> IntegerImmediate::parseDecimal(std::uint32_t BitWidth
Word = static_cast<std::uint64_t>(Product);
Carry = static_cast<std::uint64_t>(Product >> 64U);
}
- if (Carry != 0 || (Words.back() & ~integerHighWordMask(BitWidth)) != 0) {
- return makeUnexpected(ErrorCode::ParseError,
- "integer immediate does not fit its declared bit width");
- }
}
+ // LLVM integer literals are arbitrary precision and are extended or
+ // truncated to the declared bit width before becoming a constant.
+ Words.back() &= integerHighWordMask(BitWidth);
if (Negative) {
- if (std::ranges::all_of(Words, [](std::uint64_t Word) { return Word == 0; })) {
- return makeUnexpected(ErrorCode::ParseError,
- "negative zero is not a canonical integer immediate");
- }
- const std::uint32_t SignBit = BitWidth - 1U;
- const std::size_t SignWord = SignBit / 64U;
- const std::uint64_t SignMask = std::uint64_t{1} << (SignBit % 64U);
- bool Fits = Words[SignWord] <= SignMask;
- for (std::size_t Index = SignWord + 1; Index < Words.size(); ++Index)
- Fits = Fits && Words[Index] == 0;
- if (Words[SignWord] == SignMask) {
- for (std::size_t Index = 0; Index < SignWord; ++Index)
- Fits = Fits && Words[Index] == 0;
- }
- if (!Fits) {
- return makeUnexpected(ErrorCode::ParseError,
- "negative integer immediate does not fit its declared bit width");
- }
for (std::uint64_t &Word : Words)
Word = ~Word;
std::uint64_t Carry = 1;
@@ -186,6 +167,36 @@ std::string IntegerImmediate::toUnsignedDecimal() const {
return Digits;
}
+std::string IntegerImmediate::toSignedDecimal() const {
+ if (!isNegative())
+ return toUnsignedDecimal();
+
+ std::vector<std::uint64_t> Magnitude = Words;
+ for (std::uint64_t &Word : Magnitude)
+ Word = ~Word;
+ std::uint64_t Carry = 1;
+ for (std::uint64_t &Word : Magnitude) {
+ const std::uint64_t Previous = Word;
+ Word += Carry;
+ Carry = Carry != 0 && Word < Previous ? 1 : 0;
+ }
+ Magnitude.back() &= integerHighWordMask(BitWidth);
+
+ std::string Digits;
+ while (!std::ranges::all_of(Magnitude, [](std::uint64_t Word) { return Word == 0; })) {
+ unsigned __int128 Remainder = 0;
+ for (auto Iterator = Magnitude.rbegin(); Iterator != Magnitude.rend(); ++Iterator) {
+ const unsigned __int128 Dividend = (Remainder << 64U) | *Iterator;
+ *Iterator = static_cast<std::uint64_t>(Dividend / 10U);
+ Remainder = Dividend % 10U;
+ }
+ Digits.push_back(static_cast<char>('0' + static_cast<unsigned>(Remainder)));
+ }
+ std::ranges::reverse(Digits);
+ Digits.insert(Digits.begin(), '-');
+ return Digits;
+}
+
Expected<void> IntegerImmediate::verify() const {
return verifyIntegerImmediate(BitWidth, Words, ErrorCode::VerificationError);
}
@@ -324,10 +335,6 @@ Expected<MachineOperand> MachineOperand::globalSymbol(std::string Name, std::int
Expected<MachineOperand> MachineOperand::externalSymbol(std::string Name, std::int64_t Offset,
std::uint32_t TargetFlags) {
- if (Name.empty()) {
- return makeUnexpected(ErrorCode::InvalidArgument,
- "external symbol operand name cannot be empty");
- }
return MachineOperand(Kind::ExternalSymbol, ExternalSymbolOperand{std::move(Name), Offset},
TargetFlags);
}
diff --git a/backend/lib/CodeGen/MachinePseudoExpansion.cpp b/backend/lib/CodeGen/MachinePseudoExpansion.cpp
index 676804a..924c515 100644
--- a/backend/lib/CodeGen/MachinePseudoExpansion.cpp
+++ b/backend/lib/CodeGen/MachinePseudoExpansion.cpp
@@ -200,13 +200,20 @@ using BlockSizeSnapshot = std::vector<std::pair<MachineBlockStableID, std::uint6
return Error(Failure.code(), std::move(Prefix));
}
+[[nodiscard]] std::vector<MachineInstr *> layoutInstructions(MachineFunction &Function) {
+ std::vector<MachineInstr *> Result;
+ for (MachineBasicBlock *Block = Function.firstBlock(); Block != nullptr; Block = Block->next())
+ for (MachineInstr *Instruction = Block->firstInstruction(); Instruction != nullptr;
+ Instruction = Instruction->next())
+ Result.push_back(Instruction);
+ return Result;
+}
+
[[nodiscard]] Expected<MachinePassResult>
prepareImplementation(MachineFunction &Function, const TargetDescription &Target,
const TargetPseudoExpansionInfo &Info, MachineActionReplay &Actions) {
bool Changed = false;
- for (MachineInstr *Instruction : Function.allInstructions()) {
- if (Instruction == nullptr || Instruction->parent() == nullptr)
- continue;
+ for (MachineInstr *Instruction : layoutInstructions(Function)) {
const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction->opcode());
if (Descriptor == nullptr)
return makeUnexpected(ErrorCode::VerificationError,
@@ -255,10 +262,7 @@ expandImplementation(MachineFunction &Function, const TargetDescription &Target,
SizesBefore = std::move(*Snapshot);
}
std::vector<MachineInstr *> Worklist;
- for (MachineInstr *Instruction : Function.allInstructions()) {
- if (Instruction != nullptr && Instruction->parent() != nullptr)
- Worklist.push_back(Instruction);
- }
+ Worklist = layoutInstructions(Function);
bool Changed = false;
for (MachineInstr *Instruction : Worklist) {
if (Instruction->parent() == nullptr)
@@ -325,9 +329,7 @@ expandImplementation(MachineFunction &Function, const TargetDescription &Target,
}
}
}
- for (MachineInstr *Instruction : Function.allInstructions()) {
- if (Instruction == nullptr || Instruction->parent() == nullptr)
- continue;
+ for (MachineInstr *Instruction : layoutInstructions(Function)) {
const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction->opcode());
if (Descriptor != nullptr && Descriptor->Flags.has(InstructionFlag::Pseudo) &&
Descriptor->Owner == ownerFor(Phase)) {
diff --git a/backend/lib/CodeGen/MachineRegisterInfo.cpp b/backend/lib/CodeGen/MachineRegisterInfo.cpp
index 7bd0ef3..2fe74d0 100644
--- a/backend/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/backend/lib/CodeGen/MachineRegisterInfo.cpp
@@ -90,6 +90,7 @@ Expected<void> MachineRegisterInfo::eraseVirtualRegister(Register Reg) {
}
Info->get().IsTombstone = true;
+ Info->get().Name.reset();
Info->get().Type.reset();
Info->get().Bank.reset();
Info->get().RegClass.reset();
diff --git a/backend/lib/CodeGen/MachineVerifier.cpp b/backend/lib/CodeGen/MachineVerifier.cpp
index be7462b..3d9fbdb 100644
--- a/backend/lib/CodeGen/MachineVerifier.cpp
+++ b/backend/lib/CodeGen/MachineVerifier.cpp
@@ -10,6 +10,7 @@
#include "rcc/CodeGen/MachineInstr.h"
#include "rcc/CodeGen/MachineLiveness.h"
#include "rcc/CodeGen/MachineMemOperand.h"
+#include "rcc/CodeGen/MachineMetadata.h"
#include "rcc/CodeGen/MachineOperand.h"
#include "rcc/CodeGen/MachineRegisterInfo.h"
@@ -28,6 +29,42 @@
namespace rcc {
namespace {
+[[nodiscard]] std::string formatDebugInstruction(const MachineInstr &Instruction,
+ const TargetDescription &Target) {
+ const InstructionDescriptor *Descriptor = Target.instructionDescriptor(Instruction.opcode());
+ std::string Result = Descriptor == nullptr ? "<unknown>" : Descriptor->Name;
+ for (std::size_t Index = 0; Index < Instruction.operandCount(); ++Index) {
+ if (Index == 0)
+ Result.push_back(' ');
+ else
+ Result.append(", ");
+ const MachineOperand &Operand = Instruction.operands()[Index];
+ if (const auto *Immediate = Operand.getIf<std::int64_t>()) {
+ Result.append(std::to_string(*Immediate));
+ continue;
+ }
+ if (const auto *RegisterValue = Operand.getIf<Register>()) {
+ if (RegisterValue->isNoRegister()) {
+ Result.append("$noreg");
+ continue;
+ }
+ if (RegisterValue->isVirtual()) {
+ Result.push_back('%');
+ Result.append(std::to_string(*RegisterValue->virtualIndex()));
+ continue;
+ }
+ const auto Physical = RegisterValue->physicalRegister();
+ const PhysicalRegisterDesc *Register =
+ Physical ? Target.registers().physicalRegister(*Physical) : nullptr;
+ Result.push_back('$');
+ Result.append(Register == nullptr ? RegisterValue->toString() : Register->Name);
+ continue;
+ }
+ Result.append("<operand>");
+ }
+ return Result;
+}
+
class FunctionVerifier final {
public:
FunctionVerifier(const MachineFunction &Function, const TargetDescription &Target,
@@ -35,7 +72,7 @@ public:
: Function(Function), Target(Target), Options(Options) {}
[[nodiscard]] Expected<void> run() {
- if (Function.name().empty() || !Function.stableID().isValid())
+ if (!Function.stableID().isValid())
return fail("function identity is invalid");
auto AttributeResult = Function.attributes().verify();
@@ -309,6 +346,14 @@ private:
if (Instruction.sourceLocation() && !Instruction.sourceLocation()->isValid()) {
return fail("instruction has an invalid source location");
}
+ const Opcode OpcodeValue = Instruction.opcode();
+ const bool IsDebugValue = OpcodeValue == opcode(GenericOpcode::DBG_VALUE) ||
+ OpcodeValue == opcode(GenericOpcode::DBG_VALUE_LIST);
+ if (IsDebugValue && Instruction.operandCount() == 4 && !Instruction.debugLocation()) {
+ return fail("Bad machine code: Missing DebugLoc for debug instruction\n"
+ "- instruction: " +
+ formatDebugInstruction(Instruction, Target));
+ }
if (Instruction.debugLocation()) {
auto DebugLocationResult = Instruction.debugLocation()->verify(Function.metadata());
if (!DebugLocationResult)
@@ -359,10 +404,6 @@ private:
Global != nullptr && Global->Name.empty()) {
return fail("global symbol operand has an empty name");
}
- if (const auto *External = Operand.getIf<ExternalSymbolOperand>();
- External != nullptr && External->Name.empty()) {
- return fail("external symbol operand has an empty name");
- }
if (const auto *Address = Operand.getIf<BlockAddressOperand>();
Address != nullptr && (Address->FunctionName.empty() || Address->BlockName.empty())) {
return fail("block-address operand has an incomplete name");
@@ -534,13 +575,6 @@ private:
return std::unexpected(Call.error());
}
- for (const MachinePrefetchTarget &Prefetch : Records.prefetchTargets()) {
- const std::uint64_t Key = (static_cast<std::uint64_t>(Prefetch.Block.BaseID) << 32U) |
- static_cast<std::uint64_t>(Prefetch.Block.CloneID);
- if (!LinkedBlockProfileIDs.contains(Key))
- return fail("prefetch target references an unknown bb_id");
- }
-
if (!Records.debugValueSubstitutions().empty() &&
!Function.attributes().has(MachineFunctionAttribute::DebugInstrRef)) {
return fail("debug value substitutions require DebugInstrRef");