aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib')
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt8
-rw-r--r--backend/lib/CodeGen/MachineBasicBlockAttributes.cpp83
-rw-r--r--backend/lib/CodeGen/MachineFunctionAttributes.cpp63
-rw-r--r--backend/lib/CodeGen/MachineFunctionCloner.cpp2
-rw-r--r--backend/lib/CodeGen/MachineIRTypes.cpp9
-rw-r--r--backend/lib/CodeGen/MachineMemOperand.cpp8
-rw-r--r--backend/lib/CodeGen/MachineVerifier.cpp6
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;