diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-01 17:36:40 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-01 17:36:40 +0800 |
| commit | 787f3a7a20958bfa6f231abccc617f4d8de25c4d (patch) | |
| tree | 775d2913f48fc5f3a6e44bc6da986da9e52754ef /backend/lib/CodeGen | |
| parent | 77d76b73a614820bf45024b053db376f35b06d10 (diff) | |
| download | rcc-project-787f3a7a20958bfa6f231abccc617f4d8de25c4d.tar.gz rcc-project-787f3a7a20958bfa6f231abccc617f4d8de25c4d.tar.xz | |
[CodeGen] Add MIR function and block attributes
Diffstat (limited to 'backend/lib/CodeGen')
| -rw-r--r-- | backend/lib/CodeGen/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineBasicBlockAttributes.cpp | 83 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineFunctionAttributes.cpp | 63 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineFunctionCloner.cpp | 2 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineIRTypes.cpp | 9 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineMemOperand.cpp | 8 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineVerifier.cpp | 6 |
7 files changed, 171 insertions, 8 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt index 2c4f6f8..35e9a23 100644 --- a/backend/lib/CodeGen/CMakeLists.txt +++ b/backend/lib/CodeGen/CMakeLists.txt @@ -5,12 +5,14 @@ set( CompilationUnit.cpp InstructionDescriptor.cpp LowLevelType.cpp + MachineBasicBlockAttributes.cpp MachineCompilationStatus.cpp MachineBasicBlock.cpp MachineCFGUpdater.cpp MachineConstantPool.cpp MachineFrameInfo.cpp MachineFunction.cpp + MachineFunctionAttributes.cpp MachineFunctionCloner.cpp MachineIRTypes.cpp MachineIRBuilder.cpp @@ -33,12 +35,14 @@ set( "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/CompilationUnit.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/InstructionDescriptor.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/MachineCompilationStatus.h" "${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/MachineFrameInfo.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunction.h" + "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunctionAttributes.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineFunctionCloner.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineIRTypes.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/MachineIRBuilder.h" @@ -90,12 +94,14 @@ rcc_backend_register_format_files( "${CMAKE_CURRENT_SOURCE_DIR}/CompilationUnit.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/InstructionDescriptor.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/LowLevelType.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlockAttributes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineCompilationStatus.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlock.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineCFGUpdater.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineConstantPool.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineFrameInfo.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineFunction.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/MachineFunctionAttributes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineFunctionCloner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineIRTypes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineIRBuilder.cpp" @@ -118,12 +124,14 @@ rcc_backend_register_tidy_files( "${CMAKE_CURRENT_SOURCE_DIR}/CompilationUnit.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/InstructionDescriptor.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/LowLevelType.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlockAttributes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineCompilationStatus.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlock.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineCFGUpdater.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineConstantPool.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineFrameInfo.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineFunction.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/MachineFunctionAttributes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineFunctionCloner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineIRTypes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/MachineIRBuilder.cpp" diff --git a/backend/lib/CodeGen/MachineBasicBlockAttributes.cpp b/backend/lib/CodeGen/MachineBasicBlockAttributes.cpp new file mode 100644 index 0000000..8cb6d48 --- /dev/null +++ b/backend/lib/CodeGen/MachineBasicBlockAttributes.cpp @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/MachineBasicBlockAttributes.h" + +#include <cstdint> +#include <string> +#include <string_view> +#include <utility> + +namespace rcc { + +std::string_view getMachineBasicBlockAttributeName(MachineBasicBlockAttribute Attribute) noexcept { + switch (Attribute) { + case MachineBasicBlockAttribute::MachineBlockAddressTaken: + return "MachineBlockAddressTaken"; + case MachineBasicBlockAttribute::IRBlockAddressTaken: + return "IRBlockAddressTaken"; + case MachineBasicBlockAttribute::LandingPad: + return "LandingPad"; + case MachineBasicBlockAttribute::InlineAsmBrIndirectTarget: + return "InlineAsmBrIndirectTarget"; + case MachineBasicBlockAttribute::EHFuncletEntry: + return "EHFuncletEntry"; + case MachineBasicBlockAttribute::EHScopeEntry: + return "EHScopeEntry"; + case MachineBasicBlockAttribute::Count: + return "Invalid"; + } + return "Invalid"; +} + +Expected<MachineBasicBlockAttributes> +MachineBasicBlockAttributes::fromRawFlags(std::uint8_t RawFlags) { + if ((RawFlags & static_cast<std::uint8_t>(~ValidFlags)) != 0) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine basic block attributes contain unknown flag bits"); + } + MachineBasicBlockAttributes Result; + Result.Flags = RawFlags; + return Result; +} + +Expected<void> MachineBasicBlockAttributes::setName(std::string NewName) { + if (NewName.empty()) { + return makeUnexpected(ErrorCode::InvalidArgument, "machine basic block name cannot be empty"); + } + Name = std::move(NewName); + return {}; +} + +Expected<void> MachineBasicBlockAttributes::setIRBlockName(std::string NewName) { + if (NewName.empty()) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine basic block IR name cannot be empty"); + } + IRBlockName = std::move(NewName); + return {}; +} + +Expected<void> MachineBasicBlockAttributes::verify() const { + if ((Flags & static_cast<std::uint8_t>(~ValidFlags)) != 0) { + return makeUnexpected(ErrorCode::VerificationError, + "machine basic block attributes contain unknown flag bits"); + } + if (Name && Name->empty()) { + return makeUnexpected(ErrorCode::VerificationError, "machine basic block name cannot be empty"); + } + if (IRBlockName && IRBlockName->empty()) { + return makeUnexpected(ErrorCode::VerificationError, + "machine basic block IR name cannot be empty"); + } + if (has(MachineBasicBlockAttribute::IRBlockAddressTaken) && !IRBlockName) { + return makeUnexpected(ErrorCode::VerificationError, + "IR-block-address-taken block requires an IR block reference"); + } + if (BlockAlignment.bytes() == 0) { + return makeUnexpected(ErrorCode::VerificationError, + "machine basic block alignment must be nonzero"); + } + return {}; +} + +} // namespace rcc diff --git a/backend/lib/CodeGen/MachineFunctionAttributes.cpp b/backend/lib/CodeGen/MachineFunctionAttributes.cpp new file mode 100644 index 0000000..799e701 --- /dev/null +++ b/backend/lib/CodeGen/MachineFunctionAttributes.cpp @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/MachineFunctionAttributes.h" + +#include <cstdint> +#include <string_view> + +namespace rcc { + +std::string_view getMachineFunctionAttributeName(MachineFunctionAttribute Attribute) noexcept { + switch (Attribute) { + case MachineFunctionAttribute::ExposesReturnsTwice: + return "ExposesReturnsTwice"; + case MachineFunctionAttribute::HasWinCFI: + return "HasWinCFI"; + case MachineFunctionAttribute::HasFakeUses: + return "HasFakeUses"; + case MachineFunctionAttribute::CallsEHReturn: + return "CallsEHReturn"; + case MachineFunctionAttribute::CallsUnwindInit: + return "CallsUnwindInit"; + case MachineFunctionAttribute::HasEHContTarget: + return "HasEHContTarget"; + case MachineFunctionAttribute::HasEHScopes: + return "HasEHScopes"; + case MachineFunctionAttribute::HasEHFunclets: + return "HasEHFunclets"; + case MachineFunctionAttribute::IsOutlined: + return "IsOutlined"; + case MachineFunctionAttribute::DebugInstrRef: + return "DebugInstrRef"; + case MachineFunctionAttribute::TracksDebugUserValues: + return "TracksDebugUserValues"; + case MachineFunctionAttribute::Count: + return "Invalid"; + } + return "Invalid"; +} + +Expected<MachineFunctionAttributes> +MachineFunctionAttributes::fromRawFlags(std::uint16_t RawFlags) { + if ((RawFlags & static_cast<std::uint16_t>(~ValidFlags)) != 0) { + return makeUnexpected(ErrorCode::InvalidArgument, + "machine function attributes contain unknown flag bits"); + } + MachineFunctionAttributes Result; + Result.Flags = RawFlags; + return Result; +} + +Expected<void> MachineFunctionAttributes::verify() const { + if ((Flags & static_cast<std::uint16_t>(~ValidFlags)) != 0) { + return makeUnexpected(ErrorCode::VerificationError, + "machine function attributes contain unknown flag bits"); + } + if (FunctionAlignment && FunctionAlignment->bytes() == 0) { + return makeUnexpected(ErrorCode::VerificationError, + "machine function alignment must be nonzero"); + } + return {}; +} + +} // namespace rcc diff --git a/backend/lib/CodeGen/MachineFunctionCloner.cpp b/backend/lib/CodeGen/MachineFunctionCloner.cpp index d365fd0..971ef3c 100644 --- a/backend/lib/CodeGen/MachineFunctionCloner.cpp +++ b/backend/lib/CodeGen/MachineFunctionCloner.cpp @@ -290,6 +290,7 @@ cloneMemOperand(const MachineMemOperand &SourceOperand, CloneState &State) { auto AppendResult = State.Destination.appendBlock(**DestinationBlock); if (!AppendResult) return std::unexpected(AppendResult.error()); + (*DestinationBlock)->attributes() = SourceBlock->attributes(); State.Blocks.emplace(SourceBlock, *DestinationBlock); State.Result.BlockStableIDs.emplace(SourceBlock->stableID(), (*DestinationBlock)->stableID()); @@ -616,6 +617,7 @@ Expected<MachineFunctionCloneResult> cloneMachineFunction(const MachineFunction return std::unexpected(CompilationStatus.error()); Result.ClonedFunction->compilationStatus() = std::move(*CompilationStatus); Result.ClonedFunction->properties() = Source.properties(); + Result.ClonedFunction->attributes() = Source.attributes(); auto DestinationVerification = MachineVerifier::verify(*Result.ClonedFunction, Target); if (!DestinationVerification) return std::unexpected(DestinationVerification.error()); diff --git a/backend/lib/CodeGen/MachineIRTypes.cpp b/backend/lib/CodeGen/MachineIRTypes.cpp index 7f97e98..b5348b3 100644 --- a/backend/lib/CodeGen/MachineIRTypes.cpp +++ b/backend/lib/CodeGen/MachineIRTypes.cpp @@ -2,8 +2,17 @@ #include "rcc/CodeGen/MachineIRTypes.h" +#include <bit> + namespace rcc { +Expected<Alignment> Alignment::create(std::uint64_t Bytes) { + if (!std::has_single_bit(Bytes)) { + return makeUnexpected(ErrorCode::InvalidArgument, "alignment must be a nonzero power of two"); + } + return Alignment(Bytes); +} + Expected<BranchProbability> BranchProbability::fromFraction(std::uint32_t Numerator, std::uint32_t Denominator) { if (Denominator == 0) { diff --git a/backend/lib/CodeGen/MachineMemOperand.cpp b/backend/lib/CodeGen/MachineMemOperand.cpp index 76aabd1..451dbdb 100644 --- a/backend/lib/CodeGen/MachineMemOperand.cpp +++ b/backend/lib/CodeGen/MachineMemOperand.cpp @@ -2,7 +2,6 @@ #include "rcc/CodeGen/MachineMemOperand.h" -#include <bit> #include <utility> namespace rcc { @@ -119,13 +118,6 @@ MemoryAccessFlags::MemoryAccessFlags(std::initializer_list<MemoryAccessFlag> Fla set(Flag); } -Expected<Alignment> Alignment::create(std::uint64_t Bytes) { - if (!std::has_single_bit(Bytes)) { - return makeUnexpected(ErrorCode::InvalidArgument, "alignment must be a nonzero power of two"); - } - return Alignment(Bytes); -} - Expected<MemorySize> MemorySize::fixed(std::uint64_t Bytes) { if (Bytes == 0) return makeUnexpected(ErrorCode::InvalidArgument, "fixed memory size must be nonzero"); diff --git a/backend/lib/CodeGen/MachineVerifier.cpp b/backend/lib/CodeGen/MachineVerifier.cpp index b507079..905d685 100644 --- a/backend/lib/CodeGen/MachineVerifier.cpp +++ b/backend/lib/CodeGen/MachineVerifier.cpp @@ -34,6 +34,9 @@ public: if (Function.name().empty() || !Function.stableID().isValid()) return fail("function identity is invalid"); + auto AttributeResult = Function.attributes().verify(); + if (!AttributeResult) + return failWith("function attributes", AttributeResult.error()); if (Function.targetState().hasValue()) { auto TargetStateResult = Function.targetState().verify(); if (!TargetStateResult) @@ -134,6 +137,9 @@ private: if (!Block->stableID().isValid() || !BlockIDs.insert(Block->stableID()).second) { return fail("arena block registry contains an invalid or duplicate StableID"); } + auto AttributeResult = Block->attributes().verify(); + if (!AttributeResult) + return failWith("basic block attributes", AttributeResult.error()); } std::unordered_set<MachineInstrStableID> InstructionIDs; |
