aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/CodeGen')
-rw-r--r--backend/lib/CodeGen/CMakeLists.txt6
-rw-r--r--backend/lib/CodeGen/GenericConstant.cpp868
-rw-r--r--backend/lib/CodeGen/MIRParser/MIParser.cpp2
-rw-r--r--backend/lib/CodeGen/MIRParser/MIRParser.cpp17
-rw-r--r--backend/lib/CodeGen/MIRPrinter.cpp19
-rw-r--r--backend/lib/CodeGen/MIRYamlMapping.cpp31
6 files changed, 40 insertions, 903 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt
index 4488903..012b0bb 100644
--- a/backend/lib/CodeGen/CMakeLists.txt
+++ b/backend/lib/CodeGen/CMakeLists.txt
@@ -6,7 +6,6 @@ set(
CommandFlags.cpp
GlobalObject.cpp
GenericOpcodes.cpp
- GenericConstant.cpp
FrameIndexElimination.cpp
InstructionDescriptor.cpp
LowLevelType.cpp
@@ -93,7 +92,6 @@ set(
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/CommandFlags.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/GlobalObject.h"
"${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/GenericOpcodes.h"
- "${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"
@@ -202,7 +200,7 @@ target_include_directories(
"$<BUILD_INTERFACE:${RCC_BACKEND_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
-target_link_libraries(RCCBackendCodeGen PUBLIC RCCBackend::Support)
+target_link_libraries(RCCBackendCodeGen PUBLIC RCCBackend::IR)
set_target_properties(
RCCBackendCodeGen
@@ -224,7 +222,6 @@ rcc_backend_register_format_files(
"${CMAKE_CURRENT_SOURCE_DIR}/CommandFlags.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GlobalObject.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GenericOpcodes.cpp"
- "${CMAKE_CURRENT_SOURCE_DIR}/GenericConstant.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/InstructionDescriptor.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LowLevelType.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlockAttributes.cpp"
@@ -312,7 +309,6 @@ rcc_backend_register_tidy_files(
"${CMAKE_CURRENT_SOURCE_DIR}/CommandFlags.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GlobalObject.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GenericOpcodes.cpp"
- "${CMAKE_CURRENT_SOURCE_DIR}/GenericConstant.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/InstructionDescriptor.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/LowLevelType.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/MachineBasicBlockAttributes.cpp"
diff --git a/backend/lib/CodeGen/GenericConstant.cpp b/backend/lib/CodeGen/GenericConstant.cpp
deleted file mode 100644
index afcdd44..0000000
--- a/backend/lib/CodeGen/GenericConstant.cpp
+++ /dev/null
@@ -1,868 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "rcc/CodeGen/GenericConstant.h"
-
-#include <algorithm>
-#include <bit>
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <optional>
-#include <utility>
-
-namespace rcc {
-namespace {
-
-constexpr std::size_t MaximumVerificationDepth = 1024;
-constexpr std::size_t MaximumVerificationNodes = std::size_t{1} << 24U;
-
-[[nodiscard]] bool isAggregateType(GenericConstantTypeKind Kind) noexcept {
- return Kind == GenericConstantTypeKind::Array || Kind == GenericConstantTypeKind::Vector ||
- Kind == GenericConstantTypeKind::Struct;
-}
-
-[[nodiscard]] const GenericConstantType &resolvedType(const GenericConstantType &Type) noexcept {
- const GenericConstantType *Resolved = &Type;
- std::size_t Depth = 0;
- while (Resolved->Kind == GenericConstantTypeKind::Named && Resolved->Elements.size() == 1 &&
- Depth++ <= MaximumVerificationDepth) {
- Resolved = &Resolved->Elements.front();
- }
- return *Resolved;
-}
-
-[[nodiscard]] bool sameResolvedType(const GenericConstantType &Left,
- const GenericConstantType &Right) noexcept {
- return resolvedType(Left) == resolvedType(Right);
-}
-
-[[nodiscard]] bool isIntegerScalarType(const GenericConstantType &Type) noexcept {
- const GenericConstantTypeKind Kind = resolvedType(Type).Kind;
- return Kind == GenericConstantTypeKind::Integer || Kind == GenericConstantTypeKind::Byte;
-}
-
-[[nodiscard]] std::optional<std::uint32_t>
-integerScalarBitWidth(const GenericConstantType &Type) noexcept {
- const GenericConstantType &Resolved = resolvedType(Type);
- if (Resolved.Kind == GenericConstantTypeKind::Integer)
- return Resolved.BitWidth;
- if (Resolved.Kind == GenericConstantTypeKind::Byte)
- return 8;
- return std::nullopt;
-}
-
-[[nodiscard]] bool isPointerScalarType(const GenericConstantType &Type) noexcept {
- return resolvedType(Type).Kind == GenericConstantTypeKind::Pointer;
-}
-
-[[nodiscard]] bool isFloatingScalarType(const GenericConstantType &Type) noexcept {
- return resolvedType(Type).Kind == GenericConstantTypeKind::Floating;
-}
-
-struct VectorShape final {
- std::uint64_t ElementCount = 0;
- bool Scalable = false;
-
- friend constexpr bool operator==(VectorShape Left, VectorShape Right) noexcept = default;
-};
-
-[[nodiscard]] std::optional<VectorShape> vectorShape(const GenericConstantType &Type) noexcept {
- const GenericConstantType &Resolved = resolvedType(Type);
- if (Resolved.Kind != GenericConstantTypeKind::Vector)
- return std::nullopt;
- return VectorShape{.ElementCount = Resolved.ElementCount, .Scalable = Resolved.Scalable};
-}
-
-[[nodiscard]] const GenericConstantType *
-vectorElementType(const GenericConstantType &Type) noexcept {
- const GenericConstantType &Resolved = resolvedType(Type);
- if (Resolved.Kind != GenericConstantTypeKind::Vector || Resolved.Elements.size() != 1)
- return nullptr;
- return &Resolved.Elements.front();
-}
-
-[[nodiscard]] bool hasSameVectorShape(const GenericConstantType &Left,
- const GenericConstantType &Right) noexcept {
- const auto LeftShape = vectorShape(Left);
- const auto RightShape = vectorShape(Right);
- return LeftShape == RightShape;
-}
-
-[[nodiscard]] bool isIntegerOrIntegerVectorType(const GenericConstantType &Type) noexcept {
- if (isIntegerScalarType(Type))
- return true;
- const GenericConstantType *Element = vectorElementType(Type);
- return Element != nullptr && isIntegerScalarType(*Element);
-}
-
-[[nodiscard]] bool isPointerOrPointerVectorType(const GenericConstantType &Type) noexcept {
- if (isPointerScalarType(Type))
- return true;
- const GenericConstantType *Element = vectorElementType(Type);
- return Element != nullptr && isPointerScalarType(*Element);
-}
-
-[[nodiscard]] std::optional<std::uint32_t>
-pointerAddressSpace(const GenericConstantType &Type) noexcept {
- const GenericConstantType &Resolved = resolvedType(Type);
- if (Resolved.Kind == GenericConstantTypeKind::Pointer)
- return Resolved.AddressSpace;
- const GenericConstantType *Element = vectorElementType(Resolved);
- if (Element == nullptr)
- return std::nullopt;
- const GenericConstantType &ResolvedElement = resolvedType(*Element);
- if (ResolvedElement.Kind != GenericConstantTypeKind::Pointer)
- return std::nullopt;
- return ResolvedElement.AddressSpace;
-}
-
-[[nodiscard]] bool isNonPointerBitCastType(const GenericConstantType &Type) noexcept {
- if (isIntegerScalarType(Type) || isFloatingScalarType(Type))
- return true;
- const GenericConstantType *Element = vectorElementType(Type);
- return Element != nullptr && (isIntegerScalarType(*Element) || isFloatingScalarType(*Element));
-}
-
-[[nodiscard]] std::optional<std::uint64_t>
-nonPointerFixedBitWidth(const GenericConstantType &Type) noexcept {
- const GenericConstantType &Resolved = resolvedType(Type);
- if (const auto Width = integerScalarBitWidth(Resolved))
- return *Width;
- if (Resolved.Kind == GenericConstantTypeKind::Floating)
- return getFloatSemanticsBitWidth(Resolved.Semantics);
- const GenericConstantType *Element = vectorElementType(Resolved);
- if (Element == nullptr || Resolved.Scalable)
- return std::nullopt;
- const auto ElementWidth = nonPointerFixedBitWidth(*Element);
- if (!ElementWidth || *ElementWidth == 0 ||
- Resolved.ElementCount > std::numeric_limits<std::uint64_t>::max() / *ElementWidth) {
- return std::nullopt;
- }
- return Resolved.ElementCount * *ElementWidth;
-}
-
-[[nodiscard]] bool hasIntegerCastShape(const GenericConstantType &Source,
- const GenericConstantType &Destination,
- bool RequireNarrowing) noexcept {
- const GenericConstantType &ResolvedSource = resolvedType(Source);
- const GenericConstantType &ResolvedDestination = resolvedType(Destination);
- if (const auto SourceWidth = integerScalarBitWidth(ResolvedSource)) {
- const auto DestinationWidth = integerScalarBitWidth(ResolvedDestination);
- return DestinationWidth && (RequireNarrowing ? *SourceWidth > *DestinationWidth
- : *SourceWidth == *DestinationWidth);
- }
- const GenericConstantType *SourceElement = vectorElementType(ResolvedSource);
- const GenericConstantType *DestinationElement = vectorElementType(ResolvedDestination);
- if (SourceElement == nullptr || DestinationElement == nullptr ||
- !hasSameVectorShape(ResolvedSource, ResolvedDestination)) {
- return false;
- }
- return hasIntegerCastShape(*SourceElement, *DestinationElement, RequireNarrowing);
-}
-
-[[nodiscard]] bool hasPointerIntegerCastShape(const GenericConstantType &Pointer,
- const GenericConstantType &Integer) noexcept {
- const GenericConstantType &ResolvedPointer = resolvedType(Pointer);
- const GenericConstantType &ResolvedInteger = resolvedType(Integer);
- if (isPointerScalarType(ResolvedPointer))
- return isIntegerScalarType(ResolvedInteger);
- const GenericConstantType *PointerElement = vectorElementType(ResolvedPointer);
- const GenericConstantType *IntegerElement = vectorElementType(ResolvedInteger);
- return PointerElement != nullptr && IntegerElement != nullptr &&
- hasSameVectorShape(ResolvedPointer, ResolvedInteger) &&
- isPointerScalarType(*PointerElement) && isIntegerScalarType(*IntegerElement);
-}
-
-[[nodiscard]] bool isSizedType(const GenericConstantType &Type, std::size_t Depth = 0) noexcept {
- if (Depth > MaximumVerificationDepth)
- return false;
- const GenericConstantType &Resolved = resolvedType(Type);
- switch (Resolved.Kind) {
- case GenericConstantTypeKind::Integer:
- case GenericConstantTypeKind::Byte:
- case GenericConstantTypeKind::Floating:
- case GenericConstantTypeKind::Pointer:
- return true;
- case GenericConstantTypeKind::Array:
- case GenericConstantTypeKind::Vector:
- return Resolved.Elements.size() == 1 && isSizedType(Resolved.Elements.front(), Depth + 1);
- case GenericConstantTypeKind::Struct:
- return std::ranges::all_of(Resolved.Elements, [Depth](const GenericConstantType &Element) {
- return isSizedType(Element, Depth + 1);
- });
- case GenericConstantTypeKind::Named:
- return Resolved.Elements.size() == 1 && isSizedType(Resolved.Elements.front(), Depth + 1);
- case GenericConstantTypeKind::Invalid:
- case GenericConstantTypeKind::Void:
- case GenericConstantTypeKind::Label:
- case GenericConstantTypeKind::Token:
- case GenericConstantTypeKind::Metadata:
- case GenericConstantTypeKind::Function:
- return false;
- }
- return false;
-}
-
-[[nodiscard]] bool signedIntegerLess(const APInt &Left, const APInt &Right) noexcept {
- if (Left.bitWidth() != Right.bitWidth())
- return false;
- if (Left.isNegative() != Right.isNegative())
- return Left.isNegative();
- const auto LeftWords = Left.words();
- const auto RightWords = Right.words();
- for (std::size_t Index = LeftWords.size(); Index != 0; --Index) {
- if (LeftWords[Index - 1U] != RightWords[Index - 1U])
- return LeftWords[Index - 1U] < RightWords[Index - 1U];
- }
- return false;
-}
-
-[[nodiscard]] bool hasOnlyValuePayload(const GenericConstantData &Value) noexcept {
- return Value.Symbol.empty() && Value.Block.empty() &&
- Value.ExpressionOpcode == GenericConstantExpressionOpcode::Invalid &&
- Value.ExpressionFlags.rawValue() == 0 && !Value.SourceElementType && !Value.InRangeStart &&
- !Value.InRangeEnd;
-}
-
-[[nodiscard]] Expected<void> verifyType(const GenericConstantType &Type, std::size_t Depth,
- std::size_t &Nodes) {
- if (Depth > MaximumVerificationDepth || ++Nodes > MaximumVerificationNodes) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant type exceeds structural limits");
- }
-
- const auto RequireNoElements = [&]() -> Expected<void> {
- if (!Type.Elements.empty()) {
- return makeUnexpected(ErrorCode::VerificationError,
- "scalar generic constant type cannot contain child types");
- }
- return {};
- };
-
- switch (Type.Kind) {
- case GenericConstantTypeKind::Invalid:
- return makeUnexpected(ErrorCode::VerificationError, "generic constant type is invalid");
- case GenericConstantTypeKind::Void:
- case GenericConstantTypeKind::Label:
- case GenericConstantTypeKind::Token:
- case GenericConstantTypeKind::Metadata:
- return RequireNoElements();
- case GenericConstantTypeKind::Integer:
- if (Type.BitWidth == 0 || Type.BitWidth > APInt::MaxBitWidth) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic integer type has an invalid bit width");
- }
- return RequireNoElements();
- case GenericConstantTypeKind::Byte:
- return RequireNoElements();
- case GenericConstantTypeKind::Floating:
- if (!getFloatSemanticsBitWidth(Type.Semantics)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic floating type has unknown semantics");
- }
- return RequireNoElements();
- case GenericConstantTypeKind::Pointer:
- return RequireNoElements();
- case GenericConstantTypeKind::Array:
- case GenericConstantTypeKind::Vector:
- if (Type.Elements.size() != 1 ||
- (Type.Kind == GenericConstantTypeKind::Vector && Type.ElementCount == 0)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic sequential type has an invalid element description");
- }
- return verifyType(Type.Elements.front(), Depth + 1, Nodes);
- case GenericConstantTypeKind::Struct:
- for (const GenericConstantType &Element : Type.Elements) {
- auto Result = verifyType(Element, Depth + 1, Nodes);
- if (!Result)
- return Result;
- }
- return {};
- case GenericConstantTypeKind::Function:
- if (Type.Elements.empty()) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic function type has no return type");
- }
- for (const GenericConstantType &Element : Type.Elements) {
- auto Result = verifyType(Element, Depth + 1, Nodes);
- if (!Result)
- return Result;
- }
- return {};
- case GenericConstantTypeKind::Named:
- if (Type.Name.empty() || Type.Elements.size() > 1) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic named type has an invalid identity");
- }
- if (!Type.Elements.empty())
- return verifyType(Type.Elements.front(), Depth + 1, Nodes);
- return {};
- }
- return makeUnexpected(ErrorCode::InternalError, "generic constant type kind is unhandled");
-}
-
-[[nodiscard]] Expected<void> verifyConstant(const GenericConstantData &Value, std::size_t Depth,
- std::size_t &Nodes) {
- if (Depth > MaximumVerificationDepth || ++Nodes > MaximumVerificationNodes) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant value exceeds structural limits");
- }
- std::size_t TypeNodes = 0;
- auto TypeResult = verifyType(Value.Type, 0, TypeNodes);
- if (!TypeResult)
- return TypeResult;
- const GenericConstantType &EffectiveType = resolvedType(Value.Type);
-
- const auto RequireEmptyScalarPayload = [&]() -> Expected<void> {
- if (Value.IntegerValue || Value.FloatingValue || !Value.ByteValue.empty() ||
- !Value.Elements.empty() || !hasOnlyValuePayload(Value)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant kind contains an unrelated payload");
- }
- return {};
- };
-
- switch (Value.Kind) {
- case GenericConstantKind::Invalid:
- return makeUnexpected(ErrorCode::VerificationError, "generic constant value is invalid");
- case GenericConstantKind::Integer:
- if (!Value.IntegerValue || Value.FloatingValue || !Value.ByteValue.empty() ||
- !Value.Elements.empty() || !hasOnlyValuePayload(Value) ||
- (EffectiveType.Kind != GenericConstantTypeKind::Integer &&
- EffectiveType.Kind != GenericConstantTypeKind::Byte) ||
- Value.IntegerValue->bitWidth() !=
- (EffectiveType.Kind == GenericConstantTypeKind::Byte ? 8U : EffectiveType.BitWidth)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic integer constant has an inconsistent payload");
- }
- return Value.IntegerValue->verify();
- case GenericConstantKind::Floating:
- if (!Value.FloatingValue || Value.IntegerValue || !Value.ByteValue.empty() ||
- !Value.Elements.empty() || !hasOnlyValuePayload(Value) ||
- EffectiveType.Kind != GenericConstantTypeKind::Floating ||
- Value.FloatingValue->semantics() != EffectiveType.Semantics) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic floating constant has an inconsistent payload");
- }
- return {};
- case GenericConstantKind::NullPointer:
- if (EffectiveType.Kind != GenericConstantTypeKind::Pointer) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic null constant must have pointer type");
- }
- return RequireEmptyScalarPayload();
- case GenericConstantKind::ZeroInitializer:
- case GenericConstantKind::Undef:
- case GenericConstantKind::Poison:
- if (EffectiveType.Kind == GenericConstantTypeKind::Invalid ||
- EffectiveType.Kind == GenericConstantTypeKind::Function) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic marker constant has an invalid type");
- }
- return RequireEmptyScalarPayload();
- case GenericConstantKind::Aggregate: {
- if (!isAggregateType(EffectiveType.Kind) || Value.IntegerValue || Value.FloatingValue ||
- !Value.ByteValue.empty() || !hasOnlyValuePayload(Value)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic aggregate constant has an inconsistent payload");
- }
- if ((EffectiveType.Kind == GenericConstantTypeKind::Array ||
- EffectiveType.Kind == GenericConstantTypeKind::Vector) &&
- Value.Elements.size() != EffectiveType.ElementCount) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic aggregate constant has the wrong element count");
- }
- if (EffectiveType.Kind == GenericConstantTypeKind::Struct &&
- Value.Elements.size() != EffectiveType.Elements.size()) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic struct constant has the wrong element count");
- }
- for (std::size_t Index = 0; Index < Value.Elements.size(); ++Index) {
- const GenericConstantType &ExpectedType =
- EffectiveType.Kind == GenericConstantTypeKind::Struct ? EffectiveType.Elements[Index]
- : EffectiveType.Elements.front();
- if (Value.Elements[Index].Type != ExpectedType) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic aggregate element type does not match its container");
- }
- auto Result = verifyConstant(Value.Elements[Index], Depth + 1, Nodes);
- if (!Result)
- return Result;
- }
- return {};
- }
- case GenericConstantKind::ByteString:
- if (EffectiveType.Kind != GenericConstantTypeKind::Array ||
- EffectiveType.Elements.size() != 1 ||
- (EffectiveType.Elements.front().Kind != GenericConstantTypeKind::Integer &&
- EffectiveType.Elements.front().Kind != GenericConstantTypeKind::Byte) ||
- (EffectiveType.Elements.front().Kind == GenericConstantTypeKind::Integer &&
- EffectiveType.Elements.front().BitWidth != 8) ||
- EffectiveType.ElementCount != Value.ByteValue.size() || Value.IntegerValue ||
- Value.FloatingValue || !Value.Elements.empty() || !hasOnlyValuePayload(Value)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic byte-string constant has an inconsistent type or payload");
- }
- return {};
- case GenericConstantKind::GlobalAddress:
- case GenericConstantKind::DSOLocalEquivalent:
- case GenericConstantKind::NoCFI:
- if (EffectiveType.Kind != GenericConstantTypeKind::Pointer || Value.Symbol.empty() ||
- Value.IntegerValue || Value.FloatingValue || !Value.ByteValue.empty() ||
- !Value.Elements.empty() || !Value.Block.empty() ||
- Value.ExpressionOpcode != GenericConstantExpressionOpcode::Invalid ||
- Value.ExpressionFlags.rawValue() != 0 || Value.SourceElementType || Value.InRangeStart ||
- Value.InRangeEnd) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic global-address constant has an inconsistent payload");
- }
- return {};
- case GenericConstantKind::BlockAddress:
- if (EffectiveType.Kind != GenericConstantTypeKind::Pointer || Value.Symbol.empty() ||
- Value.Block.empty() || Value.IntegerValue || Value.FloatingValue ||
- !Value.ByteValue.empty() || !Value.Elements.empty() ||
- Value.ExpressionOpcode != GenericConstantExpressionOpcode::Invalid ||
- Value.ExpressionFlags.rawValue() != 0 || Value.SourceElementType || Value.InRangeStart ||
- Value.InRangeEnd) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic block-address constant has an inconsistent payload");
- }
- return {};
- case GenericConstantKind::PointerAuth: {
- if (EffectiveType.Kind != GenericConstantTypeKind::Pointer || Value.Elements.size() < 2 ||
- Value.Elements.size() > 5 || Value.IntegerValue || Value.FloatingValue ||
- !Value.ByteValue.empty() || !hasOnlyValuePayload(Value)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic pointer-auth constant has an inconsistent payload");
- }
- for (const GenericConstantData &Element : Value.Elements) {
- auto Result = verifyConstant(Element, Depth + 1, Nodes);
- if (!Result)
- return Result;
- }
- const auto KeyBitWidth = integerScalarBitWidth(Value.Elements[1].Type);
- if (!isPointerScalarType(Value.Elements[0].Type) ||
- !sameResolvedType(Value.Type, Value.Elements[0].Type) || !KeyBitWidth ||
- KeyBitWidth.value() != 32) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic pointer-auth constant has invalid pointer or key operands");
- }
- if (Value.Elements.size() >= 3) {
- const auto DiscriminatorBitWidth = integerScalarBitWidth(Value.Elements[2].Type);
- if (!DiscriminatorBitWidth || DiscriminatorBitWidth.value() != 64) {
- return makeUnexpected(
- ErrorCode::VerificationError,
- "generic pointer-auth constant integer discriminator must be a scalar i64");
- }
- }
- for (std::size_t Index = 3; Index < Value.Elements.size(); ++Index) {
- if (!isPointerScalarType(Value.Elements[Index].Type)) {
- return makeUnexpected(
- ErrorCode::VerificationError,
- "generic pointer-auth constant address operands must be scalar pointers");
- }
- }
- return {};
- }
- case GenericConstantKind::Expression:
- if (Value.ExpressionOpcode == GenericConstantExpressionOpcode::Invalid ||
- Value.Elements.empty() || Value.IntegerValue || Value.FloatingValue ||
- !Value.ByteValue.empty() || !Value.Symbol.empty() || !Value.Block.empty()) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant expression has an inconsistent payload");
- }
- if ((Value.InRangeStart.has_value() != Value.InRangeEnd.has_value()) ||
- ((Value.InRangeStart || Value.InRangeEnd || Value.SourceElementType) &&
- Value.ExpressionOpcode != GenericConstantExpressionOpcode::GetElementPtr)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant expression has misplaced GEP state");
- }
- if (Value.ExpressionOpcode == GenericConstantExpressionOpcode::GetElementPtr &&
- !Value.SourceElementType) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic getelementptr constant has no source element type");
- }
- for (const GenericConstantData &Element : Value.Elements) {
- auto Result = verifyConstant(Element, Depth + 1, Nodes);
- if (!Result)
- return Result;
- }
-
- const bool IsBinary = Value.ExpressionOpcode == GenericConstantExpressionOpcode::Add ||
- Value.ExpressionOpcode == GenericConstantExpressionOpcode::Sub ||
- Value.ExpressionOpcode == GenericConstantExpressionOpcode::Xor;
- const bool IsGEP = Value.ExpressionOpcode == GenericConstantExpressionOpcode::GetElementPtr;
- const std::uint8_t Flags = Value.ExpressionFlags.rawValue();
- const std::uint8_t BinaryFlags =
- (std::uint8_t{1} << static_cast<std::uint8_t>(
- GenericConstantExpressionFlag::NoUnsignedWrap)) |
- (std::uint8_t{1} << static_cast<std::uint8_t>(GenericConstantExpressionFlag::NoSignedWrap));
- const std::uint8_t GEPFlags =
- (std::uint8_t{1} << static_cast<std::uint8_t>(GenericConstantExpressionFlag::InBounds)) |
- (std::uint8_t{1} << static_cast<std::uint8_t>(
- GenericConstantExpressionFlag::NoUnsignedSignedWrap)) |
- (std::uint8_t{1} << static_cast<std::uint8_t>(
- GenericConstantExpressionFlag::GEPNoUnsignedWrap));
- if ((!IsBinary && !IsGEP && Flags != 0) || (IsBinary && (Flags & ~BinaryFlags) != 0) ||
- (IsGEP && (Flags & ~GEPFlags) != 0)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant expression has invalid opcode flags");
- }
-
- const auto RequireExactOperandCount = [&Value](std::size_t Count) -> Expected<void> {
- if (Value.Elements.size() != Count) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic constant expression has the wrong operand count");
- }
- return {};
- };
- const GenericConstantType &FirstType = Value.Elements.front().Type;
- switch (Value.ExpressionOpcode) {
- case GenericConstantExpressionOpcode::Trunc:
- if (auto Count = RequireExactOperandCount(1); !Count)
- return Count;
- if (!hasIntegerCastShape(FirstType, Value.Type, true)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic trunc constant has incompatible integer types");
- }
- return {};
- case GenericConstantExpressionOpcode::BitCast: {
- if (auto Count = RequireExactOperandCount(1); !Count)
- return Count;
- const bool SourceIsPointer = isPointerOrPointerVectorType(FirstType);
- const bool DestinationIsPointer = isPointerOrPointerVectorType(Value.Type);
- if (SourceIsPointer || DestinationIsPointer) {
- const auto SourceAddressSpace = pointerAddressSpace(FirstType);
- const auto DestinationAddressSpace = pointerAddressSpace(Value.Type);
- if (!SourceIsPointer || !DestinationIsPointer || !SourceAddressSpace ||
- !DestinationAddressSpace || *SourceAddressSpace != *DestinationAddressSpace ||
- !hasSameVectorShape(FirstType, Value.Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic bitcast constant has incompatible pointer types");
- }
- return {};
- }
- const auto SourceWidth = nonPointerFixedBitWidth(FirstType);
- const auto DestinationWidth = nonPointerFixedBitWidth(Value.Type);
- if (!isNonPointerBitCastType(FirstType) || !isNonPointerBitCastType(Value.Type) ||
- !SourceWidth || !DestinationWidth || *SourceWidth != *DestinationWidth ||
- !hasSameVectorShape(FirstType, Value.Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic bitcast constant has incompatible fixed-width types");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::AddressSpaceCast: {
- if (auto Count = RequireExactOperandCount(1); !Count)
- return Count;
- const auto SourceAddressSpace = pointerAddressSpace(FirstType);
- const auto DestinationAddressSpace = pointerAddressSpace(Value.Type);
- if (!SourceAddressSpace || !DestinationAddressSpace ||
- *SourceAddressSpace == *DestinationAddressSpace ||
- !hasSameVectorShape(FirstType, Value.Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic addrspacecast constant has incompatible pointer types");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::IntToPtr:
- if (auto Count = RequireExactOperandCount(1); !Count)
- return Count;
- if (!hasPointerIntegerCastShape(Value.Type, FirstType)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic inttoptr constant has incompatible operand types");
- }
- return {};
- case GenericConstantExpressionOpcode::PtrToAddr:
- case GenericConstantExpressionOpcode::PtrToInt:
- if (auto Count = RequireExactOperandCount(1); !Count)
- return Count;
- if (!hasPointerIntegerCastShape(FirstType, Value.Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic pointer-to-integer constant has incompatible operand types");
- }
- return {};
- case GenericConstantExpressionOpcode::Add:
- case GenericConstantExpressionOpcode::Sub:
- case GenericConstantExpressionOpcode::Xor:
- if (auto Count = RequireExactOperandCount(2); !Count)
- return Count;
- if (!isIntegerOrIntegerVectorType(Value.Type) ||
- !sameResolvedType(Value.Elements[0].Type, Value.Type) ||
- !sameResolvedType(Value.Elements[1].Type, Value.Type)) {
- return makeUnexpected(
- ErrorCode::VerificationError,
- "generic binary constant requires equal integer operand and result types");
- }
- return {};
- case GenericConstantExpressionOpcode::GetElementPtr: {
- if (!Value.SourceElementType || !isSizedType(*Value.SourceElementType) ||
- !isPointerOrPointerVectorType(FirstType) || !isPointerOrPointerVectorType(Value.Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic getelementptr constant has invalid source or pointer types");
- }
- const auto BaseAddressSpace = pointerAddressSpace(FirstType);
- const auto ResultAddressSpace = pointerAddressSpace(Value.Type);
- if (!BaseAddressSpace || !ResultAddressSpace || *BaseAddressSpace != *ResultAddressSpace) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic getelementptr constant changes pointer address space");
- }
- std::optional<VectorShape> RequiredResultShape = vectorShape(FirstType);
- for (std::size_t Index = 1; Index < Value.Elements.size(); ++Index) {
- const GenericConstantType &IndexType = Value.Elements[Index].Type;
- if (!isIntegerOrIntegerVectorType(IndexType)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic getelementptr index must be an integer or integer vector");
- }
- if (const auto IndexShape = vectorShape(IndexType)) {
- if (RequiredResultShape && *RequiredResultShape != *IndexShape) {
- return makeUnexpected(
- ErrorCode::VerificationError,
- "generic getelementptr vector index has an incompatible element count");
- }
- RequiredResultShape = *IndexShape;
- }
- }
- if (RequiredResultShape != vectorShape(Value.Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic getelementptr result has an incompatible vector shape");
- }
- if (Value.InRangeStart && (Value.InRangeStart->bitWidth() != Value.InRangeEnd->bitWidth() ||
- !signedIntegerLess(*Value.InRangeStart, *Value.InRangeEnd))) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic getelementptr inrange interval is invalid");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::ShuffleVector: {
- if (auto Count = RequireExactOperandCount(3); !Count)
- return Count;
- const GenericConstantType *InputElement = vectorElementType(FirstType);
- const GenericConstantType *MaskElement = vectorElementType(Value.Elements[2].Type);
- const GenericConstantType *ResultElement = vectorElementType(Value.Type);
- const auto InputShape = vectorShape(FirstType);
- const auto MaskShape = vectorShape(Value.Elements[2].Type);
- const auto ResultShape = vectorShape(Value.Type);
- if (InputElement == nullptr || MaskElement == nullptr || ResultElement == nullptr ||
- !InputShape || !MaskShape || !ResultShape ||
- !sameResolvedType(FirstType, Value.Elements[1].Type) ||
- !integerScalarBitWidth(*MaskElement) || *integerScalarBitWidth(*MaskElement) != 32 ||
- InputShape->Scalable != MaskShape->Scalable ||
- !sameResolvedType(*InputElement, *ResultElement) ||
- ResultShape->ElementCount != MaskShape->ElementCount ||
- ResultShape->Scalable != MaskShape->Scalable) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic shufflevector constant has incompatible operand types");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::InsertElement: {
- if (auto Count = RequireExactOperandCount(3); !Count)
- return Count;
- const GenericConstantType *Element = vectorElementType(FirstType);
- if (Element == nullptr || !sameResolvedType(Value.Type, FirstType) ||
- !sameResolvedType(Value.Elements[1].Type, *Element) ||
- !isIntegerScalarType(Value.Elements[2].Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic insertelement constant has incompatible operand types");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::ExtractElement: {
- if (auto Count = RequireExactOperandCount(2); !Count)
- return Count;
- const GenericConstantType *Element = vectorElementType(FirstType);
- if (Element == nullptr || !sameResolvedType(Value.Type, *Element) ||
- !isIntegerScalarType(Value.Elements[1].Type)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic extractelement constant has incompatible operand types");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::Splat: {
- if (auto Count = RequireExactOperandCount(1); !Count)
- return Count;
- const GenericConstantType *Element = vectorElementType(Value.Type);
- if (Element == nullptr || !sameResolvedType(FirstType, *Element)) {
- return makeUnexpected(ErrorCode::VerificationError,
- "generic splat constant has incompatible operand types");
- }
- return {};
- }
- case GenericConstantExpressionOpcode::Invalid:
- break;
- }
- return makeUnexpected(ErrorCode::InternalError,
- "generic constant expression opcode is unhandled");
- }
- return makeUnexpected(ErrorCode::InternalError, "generic constant value kind is unhandled");
-}
-
-} // namespace
-
-Expected<GenericConstantType> GenericConstantType::integer(std::uint32_t Width) {
- if (Width == 0 || Width > APInt::MaxBitWidth)
- return makeUnexpected(ErrorCode::InvalidArgument, "generic integer type width is invalid");
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Integer;
- Type.BitWidth = Width;
- return Type;
-}
-
-GenericConstantType GenericConstantType::primitive(GenericConstantTypeKind PrimitiveKind) noexcept {
- GenericConstantType Type;
- Type.Kind = PrimitiveKind;
- return Type;
-}
-
-GenericConstantType GenericConstantType::byte() noexcept {
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Byte;
- Type.BitWidth = 8;
- return Type;
-}
-
-Expected<GenericConstantType> GenericConstantType::floating(FloatSemantics ValueSemantics) {
- if (!getFloatSemanticsBitWidth(ValueSemantics))
- return makeUnexpected(ErrorCode::InvalidArgument, "generic floating semantics is unknown");
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Floating;
- Type.Semantics = ValueSemantics;
- Type.BitWidth = getFloatSemanticsBitWidth(ValueSemantics).value_or(0);
- return Type;
-}
-
-GenericConstantType GenericConstantType::pointer(std::uint32_t PointerAddressSpace) noexcept {
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Pointer;
- Type.AddressSpace = PointerAddressSpace;
- return Type;
-}
-
-Expected<GenericConstantType> GenericConstantType::array(std::uint64_t Count,
- GenericConstantType Element) {
- auto Verification = Element.verify();
- if (!Verification)
- return std::unexpected(Verification.error());
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Array;
- Type.ElementCount = Count;
- Type.Elements.push_back(std::move(Element));
- return Type;
-}
-
-Expected<GenericConstantType>
-GenericConstantType::vector(std::uint64_t Count, GenericConstantType Element, bool IsScalable) {
- if (Count == 0)
- return makeUnexpected(ErrorCode::InvalidArgument, "generic vector type cannot be empty");
- auto Verification = Element.verify();
- if (!Verification)
- return std::unexpected(Verification.error());
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Vector;
- Type.ElementCount = Count;
- Type.Scalable = IsScalable;
- Type.Elements.push_back(std::move(Element));
- return Type;
-}
-
-Expected<GenericConstantType>
-GenericConstantType::structure(std::vector<GenericConstantType> MemberTypes, bool IsPacked) {
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Struct;
- Type.Packed = IsPacked;
- Type.Elements = std::move(MemberTypes);
- auto Verification = Type.verify();
- if (!Verification)
- return std::unexpected(Verification.error());
- return Type;
-}
-
-Expected<GenericConstantType>
-GenericConstantType::function(GenericConstantType Return,
- std::vector<GenericConstantType> Parameters, bool IsVarArg) {
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Function;
- Type.VarArg = IsVarArg;
- Type.Elements.reserve(Parameters.size() + 1);
- Type.Elements.push_back(std::move(Return));
- for (GenericConstantType &Parameter : Parameters)
- Type.Elements.push_back(std::move(Parameter));
- auto Verification = Type.verify();
- if (!Verification)
- return std::unexpected(Verification.error());
- return Type;
-}
-
-Expected<GenericConstantType> GenericConstantType::named(std::string TypeName, bool IsNumericName) {
- if (TypeName.empty())
- return makeUnexpected(ErrorCode::InvalidArgument, "generic named type cannot be empty");
- GenericConstantType Type;
- Type.Kind = GenericConstantTypeKind::Named;
- Type.Name = std::move(TypeName);
- Type.NumericName = IsNumericName;
- return Type;
-}
-
-Expected<void> GenericConstantType::verify() const {
- std::size_t Nodes = 0;
- return verifyType(*this, 0, Nodes);
-}
-
-Expected<GenericConstantData> GenericConstantData::integer(APInt Value) {
- auto Type = GenericConstantType::integer(Value.bitWidth());
- if (!Type)
- return std::unexpected(Type.error());
- GenericConstantData Result;
- Result.Type = std::move(*Type);
- Result.Kind = GenericConstantKind::Integer;
- Result.IntegerValue = std::move(Value);
- return Result;
-}
-
-Expected<GenericConstantData> GenericConstantData::floating(APFloat Value) {
- auto Type = GenericConstantType::floating(Value.semantics());
- if (!Type)
- return std::unexpected(Type.error());
- GenericConstantData Result;
- Result.Type = std::move(*Type);
- Result.Kind = GenericConstantKind::Floating;
- Result.FloatingValue = Value;
- return Result;
-}
-
-Expected<GenericConstantData> GenericConstantData::byteString(GenericConstantType ValueType,
- std::vector<std::byte> Bytes) {
- GenericConstantData Result;
- Result.Type = std::move(ValueType);
- Result.Kind = GenericConstantKind::ByteString;
- Result.ByteValue = std::move(Bytes);
- auto Verification = Result.verify();
- if (!Verification)
- return std::unexpected(Verification.error());
- return Result;
-}
-
-Expected<void> GenericConstantData::verify() const {
- std::size_t Nodes = 0;
- return verifyConstant(*this, 0, Nodes);
-}
-
-bool GenericConstantData::referencesSymbol() const noexcept {
- switch (Kind) {
- case GenericConstantKind::GlobalAddress:
- case GenericConstantKind::BlockAddress:
- case GenericConstantKind::DSOLocalEquivalent:
- case GenericConstantKind::NoCFI:
- return true;
- default:
- break;
- }
- for (const GenericConstantData &Element : Elements) {
- if (Element.referencesSymbol())
- return true;
- }
- return false;
-}
-
-} // namespace rcc
diff --git a/backend/lib/CodeGen/MIRParser/MIParser.cpp b/backend/lib/CodeGen/MIRParser/MIParser.cpp
index 183e6b3..0015b02 100644
--- a/backend/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/backend/lib/CodeGen/MIRParser/MIParser.cpp
@@ -3,6 +3,7 @@
#include "rcc/CodeGen/MIRParser/MIParser.h"
#include "MILexer.h"
+#include "rcc/AsmParser/LLParser.h"
#include "rcc/CodeGen/GenericOpcodes.h"
#include "rcc/CodeGen/InlineAsm.h"
#include "rcc/CodeGen/InstructionDescriptor.h"
@@ -17,7 +18,6 @@
#include "rcc/CodeGen/TargetDescription.h"
#include "rcc/CodeGen/TargetMIRTextInfo.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
-#include "rcc/MIR/LLVMConstantSyntax.h"
#include <algorithm>
#include <array>
diff --git a/backend/lib/CodeGen/MIRParser/MIRParser.cpp b/backend/lib/CodeGen/MIRParser/MIRParser.cpp
index e22f1bc..3b89491 100644
--- a/backend/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/backend/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -18,7 +18,7 @@
#include "rcc/CodeGen/TargetDescription.h"
#include "rcc/CodeGen/TargetMIRTextInfo.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
-#include "rcc/MIR/LLVMConstantSyntax.h"
+#include "rcc/IR/DataLayout.h"
#include <algorithm>
#include <array>
@@ -74,11 +74,8 @@ std::string_view MIRDocumentParser::effectiveDataLayout() const noexcept {
return {};
}
-LLVMConstantSyntaxOptions MIRDocumentParser::pointerLayoutOptions() const noexcept {
- return {
- .DataLayout = effectiveDataLayout(),
- .NamedTypes = {},
- };
+Expected<DataLayout> MIRDocumentParser::dataLayout() const {
+ return DataLayout::parse(effectiveDataLayout());
}
bool MIRDocumentParser::requireKind(const yaml::Node &Node, yaml::NodeKind Kind,
@@ -160,7 +157,13 @@ MIRDocumentParseResult MIRDocumentParser::run() {
}
if (!effectiveDataLayout().empty()) {
- auto PointerSize = llvmPointerSizeInBits(0, pointerLayoutOptions());
+ auto Layout = dataLayout();
+ if (!Layout) {
+ static_cast<void>(
+ importError(Stream->documents()[FirstContent].Range, Layout.error(), "mir-data-layout"));
+ return std::move(Result);
+ }
+ auto PointerSize = Layout->getPointerSizeInBits();
if (!PointerSize) {
static_cast<void>(importError(Stream->documents()[FirstContent].Range, PointerSize.error(),
"mir-data-layout"));
diff --git a/backend/lib/CodeGen/MIRPrinter.cpp b/backend/lib/CodeGen/MIRPrinter.cpp
index ea201b9..d8a6945 100644
--- a/backend/lib/CodeGen/MIRPrinter.cpp
+++ b/backend/lib/CodeGen/MIRPrinter.cpp
@@ -24,7 +24,7 @@
#include "rcc/CodeGen/TargetDescription.h"
#include "rcc/CodeGen/TargetMIRTextInfo.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
-#include "rcc/MIR/LLVMConstantSyntax.h"
+#include "rcc/IR/DataLayout.h"
#include <algorithm>
#include <array>
@@ -424,10 +424,9 @@ MIRDocumentPrinter::verifyOmittedEmbeddedIRLayout(const MachineFunction &Functio
"DataLayout");
}
- const LLVMConstantSyntaxOptions LayoutOptions{
- .DataLayout = Options.DataLayout,
- .NamedTypes = {},
- };
+ auto Layout = DataLayout::parse(Options.DataLayout);
+ if (!Layout)
+ return std::unexpected(Layout.error());
for (const VirtualRegisterInfo &RegisterInfo : Function.registerInfo().virtualRegisters()) {
if (RegisterInfo.IsTombstone || !RegisterInfo.Type ||
!RegisterInfo.Type->isPointerOrPointerVector()) {
@@ -438,7 +437,7 @@ MIRDocumentPrinter::verifyOmittedEmbeddedIRLayout(const MachineFunction &Functio
return makeUnexpected(ErrorCode::VerificationError,
"pointer virtual register has no address space");
}
- auto PointerSize = llvmPointerSizeInBits(*AddressSpace, LayoutOptions);
+ auto PointerSize = Layout->getPointerSizeInBits(*AddressSpace);
if (!PointerSize) {
return makeUnexpected(ErrorCode::InvalidArgument,
"printer DataLayout cannot determine pointer width: " +
@@ -457,7 +456,7 @@ MIRDocumentPrinter::verifyOmittedEmbeddedIRLayout(const MachineFunction &Functio
const auto *Generic = std::get_if<GenericConstantData>(&Description->Value);
if (Generic == nullptr)
continue;
- auto StorageSize = llvmConstantStorageSize(Generic->Type, LayoutOptions);
+ auto StorageSize = Layout->getTypeAllocSize(Generic->Type);
if (!StorageSize) {
return makeUnexpected(ErrorCode::InvalidArgument,
"printer DataLayout cannot lay out generic constant: " +
@@ -1085,7 +1084,7 @@ Expected<void> MIRDocumentPrinter::printConstants(const MachineFunction &Functio
Expected<std::string> Value =
makeUnexpected(ErrorCode::Unsupported, "constant-pool kind is not MIR serializable");
if (const auto *Generic = std::get_if<GenericConstantData>(&Description->Value)) {
- Value = printLLVMConstant(*Generic);
+ Value = Generic->toLLVMString();
} else if (const auto *TargetConstantValue = std::get_if<TargetConstant>(&Description->Value)) {
IsTargetSpecific = true;
Value = Target.mirText().printTargetConstant(*TargetConstantValue);
@@ -2264,7 +2263,7 @@ Expected<void> BodyPrinter::printOperand(const MachineOperand &Operand, bool IsE
auto Constant = GenericConstantData::floating(Bits);
if (!Constant)
return std::unexpected(Constant.error());
- auto Text = printLLVMConstant(*Constant);
+ auto Text = Constant->toLLVMString();
if (!Text)
return std::unexpected(Text.error());
Output.append(*Text);
@@ -2620,7 +2619,7 @@ Expected<void> BodyPrinter::printMemoryBase(const MemoryBase &Base, std::int64_t
return makeUnexpected(ErrorCode::VerificationError,
"IR-constant memory base has no constant value");
}
- auto Printed = printLLVMConstant(*Constant);
+ auto Printed = Constant->toLLVMString();
if (!Printed)
return std::unexpected(Printed.error());
Output.push_back('`');
diff --git a/backend/lib/CodeGen/MIRYamlMapping.cpp b/backend/lib/CodeGen/MIRYamlMapping.cpp
index 9ca8cad..b68761d 100644
--- a/backend/lib/CodeGen/MIRYamlMapping.cpp
+++ b/backend/lib/CodeGen/MIRYamlMapping.cpp
@@ -3,6 +3,7 @@
#include "rcc/CodeGen/MIRYamlMapping.h"
#include "MIRParser/MILexer.h"
+#include "rcc/AsmParser/LLParser.h"
#include "rcc/CodeGen/MachineBasicBlock.h"
#include "rcc/CodeGen/MachineConstantPool.h"
#include "rcc/CodeGen/MachineFrameInfo.h"
@@ -18,7 +19,6 @@
#include "rcc/CodeGen/TargetDescription.h"
#include "rcc/CodeGen/TargetMIRTextInfo.h"
#include "rcc/CodeGen/TargetRegisterInfo.h"
-#include "rcc/MIR/LLVMConstantSyntax.h"
#include <algorithm>
#include <array>
@@ -259,8 +259,8 @@ bool MIRDocumentParser::parseConstants(const yaml::Node &Root, MachineFunction &
std::string_view{"alignment"},
std::string_view{"isTargetSpecific"},
};
- std::vector<LLVMNamedTypeDefinition> NamedTypes;
- const std::string_view DataLayout = effectiveDataLayout();
+ std::vector<LLNamedTypeDefinition> NamedTypes;
+ const std::string_view DataLayoutText = effectiveDataLayout();
if (ActiveDocument->EmbeddedIR) {
const auto Definitions = ActiveDocument->EmbeddedIR->typeDefinitions();
NamedTypes.reserve(Definitions.size());
@@ -270,6 +270,9 @@ bool MIRDocumentParser::parseConstants(const yaml::Node &Root, MachineFunction &
.NumericName = Definition.NumericName});
}
}
+ auto Layout = DataLayout::parse(DataLayoutText);
+ if (!Layout)
+ return importError(Constants->range(), Layout.error(), "mir-data-layout");
std::unordered_set<std::uint32_t> IDs;
for (const yaml::NodeID ConstantID : Constants->sequence()) {
const yaml::Node *Constant = node(ConstantID);
@@ -328,14 +331,13 @@ bool MIRDocumentParser::parseConstants(const yaml::Node &Root, MachineFunction &
std::string_view ValueText;
if (scalar(*ValueNode, ValueText, "LLVM constant"))
return true;
- const LLVMConstantSyntaxOptions ConstantOptions{
- .DataLayout = DataLayout,
+ const LLParserOptions ConstantOptions{
.NamedTypes = NamedTypes,
};
auto Data = parseLLVMConstant(trim(ValueText), ConstantOptions);
if (!Data)
return importError(ValueNode->range(), Data.error(), "mir-llvm-constant");
- auto Size = llvmConstantStorageSize(Data->Type, ConstantOptions);
+ auto Size = Layout->getTypeAllocSize(Data->Type);
if (!Size)
return importError(ValueNode->range(), Size.error(), "mir-llvm-constant");
@@ -346,11 +348,14 @@ bool MIRDocumentParser::parseConstants(const yaml::Node &Root, MachineFunction &
if (alignment(*AlignmentNode, Description.Align, true))
return true;
} else {
- auto Preferred = llvmConstantPreferredAlignment(
- std::get<GenericConstantData>(Description.Value).Type, ConstantOptions);
+ auto Preferred =
+ Layout->getPrefTypeAlign(std::get<GenericConstantData>(Description.Value).Type);
if (!Preferred)
return importError(ValueNode->range(), Preferred.error(), "mir-llvm-constant");
- Description.Align = *Preferred;
+ auto PreferredAlignment = Alignment::create(*Preferred);
+ if (!PreferredAlignment)
+ return importError(ValueNode->range(), PreferredAlignment.error(), "mir-llvm-constant");
+ Description.Align = *PreferredAlignment;
}
auto Added = Function.constantPool().addEntry(std::move(Description));
if (!Added)
@@ -2219,9 +2224,11 @@ bool MIRDocumentParser::parseBody(const yaml::Node &Root, MachineFunction &Funct
}
if (!effectiveDataLayout().empty()) {
- const LLVMConstantSyntaxOptions PointerOptions = pointerLayoutOptions();
- Context.PointerSizeInBits = [PointerOptions](std::uint32_t AddressSpace) {
- return llvmPointerSizeInBits(AddressSpace, PointerOptions);
+ auto Layout = dataLayout();
+ if (!Layout)
+ return importError(BodyRange, Layout.error(), "mir-data-layout");
+ Context.PointerSizeInBits = [Layout = std::move(*Layout)](std::uint32_t AddressSpace) {
+ return Layout.getPointerSizeInBits(AddressSpace);
};
}
Context.SyncScopes = ActiveDocument->SyncScopes;