From aa7c85ca71859aab15bdf1e6dc1ea3a5aa5d1e28 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Thu, 13 Aug 2026 06:52:15 +0800 Subject: [Support] Split APInt and APFloat ownership --- backend/include/rcc/ADT/APFloat.h | 78 ++++++++++++++++++++++++++ backend/include/rcc/ADT/APInt.h | 74 ++++++++++++++++++++++++ backend/include/rcc/CodeGen/GenericConstant.h | 15 ++--- backend/include/rcc/CodeGen/GlobalObject.h | 12 ++-- backend/include/rcc/CodeGen/LowLevelType.h | 30 +--------- backend/include/rcc/CodeGen/MachineIRBuilder.h | 6 +- backend/include/rcc/CodeGen/MachineOperand.h | 78 ++------------------------ backend/include/rcc/MIR/LLVMConstantSyntax.h | 1 + 8 files changed, 176 insertions(+), 118 deletions(-) create mode 100644 backend/include/rcc/ADT/APFloat.h create mode 100644 backend/include/rcc/ADT/APInt.h (limited to 'backend/include') diff --git a/backend/include/rcc/ADT/APFloat.h b/backend/include/rcc/ADT/APFloat.h new file mode 100644 index 0000000..9b56a19 --- /dev/null +++ b/backend/include/rcc/ADT/APFloat.h @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_ADT_APFLOAT_H +#define RCC_ADT_APFLOAT_H + +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include + +namespace rcc { + +enum class FloatSemantics : std::uint8_t { + IEEEHalf, + BFloat, + IEEESingle, + IEEEDouble, + IEEEQuad, + PPCDoubleDouble, + Float8E5M2, + Float8E5M2FNUZ, + Float8E4M3, + Float8E4M3FN, + Float8E4M3FNUZ, + Float8E4M3B11FNUZ, + Float8E3M4, + FloatTF32, + Float8E8M0FNU, + Float6E3M2FN, + Float6E2M3FN, + Float4E2M1FN, + X87DoubleExtended, + Count, +}; + +[[nodiscard]] std::optional +getFloatSemanticsBitWidth(FloatSemantics Semantics) noexcept; +[[nodiscard]] std::string_view getFloatSemanticsSpelling(FloatSemantics Semantics) noexcept; + +class APFloat final { +public: + [[nodiscard]] static Expected create(FloatSemantics Semantics, + std::span Words); + [[nodiscard]] static Expected parse(FloatSemantics Semantics, std::string_view Text); + + [[nodiscard]] FloatSemantics semantics() const noexcept { + return Semantics; + } + + [[nodiscard]] std::uint32_t bitWidth() const noexcept { + return getFloatSemanticsBitWidth(Semantics).value_or(0); + } + + [[nodiscard]] std::span words() const noexcept { + return std::span(Words).first(WordCount); + } + + [[nodiscard]] std::string toString() const; + + friend bool operator==(const APFloat &Left, const APFloat &Right) = default; + +private: + APFloat(FloatSemantics Semantics, std::array Words, + std::uint8_t WordCount) noexcept + : Semantics(Semantics), Words(Words), WordCount(WordCount) {} + + FloatSemantics Semantics; + std::array Words; + std::uint8_t WordCount; +}; + +} // namespace rcc + +#endif // RCC_ADT_APFLOAT_H diff --git a/backend/include/rcc/ADT/APInt.h b/backend/include/rcc/ADT/APInt.h new file mode 100644 index 0000000..abd10f9 --- /dev/null +++ b/backend/include/rcc/ADT/APInt.h @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_ADT_APINT_H +#define RCC_ADT_APINT_H + +#include "rcc/Support/Error.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace rcc { + +class APInt final { +public: + static constexpr std::uint32_t MaxBitWidth = std::uint32_t{1} << 23U; + + APInt() = default; + explicit APInt(std::uint64_t Value); + + [[nodiscard]] static Expected create(std::uint32_t BitWidth, + std::span Words); + [[nodiscard]] static Expected fromUnsigned(std::uint32_t BitWidth, std::uint64_t Value); + [[nodiscard]] static Expected fromSigned(std::uint32_t BitWidth, std::int64_t Value); + [[nodiscard]] static Expected parseDecimal(std::uint32_t BitWidth, std::string_view Text); + [[nodiscard]] static Expected parseLLVMHex(std::uint32_t BitWidth, std::string_view Text); + + [[nodiscard]] std::uint32_t bitWidth() const noexcept { + return BitWidth; + } + + [[nodiscard]] std::span words() const noexcept { + return Words; + } + + [[nodiscard]] bool isZero() const noexcept; + [[nodiscard]] bool isNegative() const noexcept; + [[nodiscard]] std::size_t activeBitWidth() const noexcept; + [[nodiscard]] std::size_t countrZero() const noexcept; + [[nodiscard]] std::uint64_t word(std::size_t Index) const noexcept; + [[nodiscard]] int compare(const APInt &Other) const noexcept; + [[nodiscard]] int compareToShifted(const APInt &Other, std::size_t OtherShift) const noexcept; + + void multiplySmall(std::uint32_t Multiplier); + void addSmall(std::uint32_t Value); + void setBit(std::size_t Bit); + void clearBit(std::size_t Bit) noexcept; + void shiftRight(std::size_t Amount) noexcept; + [[nodiscard]] APInt shiftedLeft(std::size_t Amount) const; + void subtract(const APInt &Other) noexcept; + + [[nodiscard]] std::string toUnsignedDecimal() const; + [[nodiscard]] std::string toSignedDecimal() const; + [[nodiscard]] Expected verify() const; + + friend bool operator==(const APInt &Left, const APInt &Right) = default; + +private: + APInt(std::uint32_t BitWidth, std::vector Words) + : BitWidth(BitWidth), Words(std::move(Words)) {} + + void normalizeMagnitude() noexcept; + + std::uint32_t BitWidth = 0; + std::vector Words; +}; + +} // namespace rcc + +#endif // RCC_ADT_APINT_H diff --git a/backend/include/rcc/CodeGen/GenericConstant.h b/backend/include/rcc/CodeGen/GenericConstant.h index 92a8f13..4219c24 100644 --- a/backend/include/rcc/CodeGen/GenericConstant.h +++ b/backend/include/rcc/CodeGen/GenericConstant.h @@ -3,8 +3,9 @@ #ifndef RCC_CODEGEN_GENERICCONSTANT_H #define RCC_CODEGEN_GENERICCONSTANT_H +#include "rcc/ADT/APFloat.h" +#include "rcc/ADT/APInt.h" #include "rcc/CodeGen/LowLevelType.h" -#include "rcc/CodeGen/MachineOperand.h" #include "rcc/Support/Error.h" #include @@ -144,8 +145,8 @@ private: struct GenericConstantData final { GenericConstantType Type; GenericConstantKind Kind = GenericConstantKind::Invalid; - std::optional IntegerValue; - std::optional FloatingValue; + std::optional IntegerValue; + std::optional FloatingValue; std::vector ByteValue; std::vector Elements; std::string Symbol; @@ -155,11 +156,11 @@ struct GenericConstantData final { GenericConstantExpressionOpcode ExpressionOpcode = GenericConstantExpressionOpcode::Invalid; GenericConstantExpressionFlags ExpressionFlags; std::optional SourceElementType; - std::optional InRangeStart; - std::optional InRangeEnd; + std::optional InRangeStart; + std::optional InRangeEnd; - [[nodiscard]] static Expected integer(IntegerImmediate Value); - [[nodiscard]] static Expected floating(FloatingPointBits Value); + [[nodiscard]] static Expected integer(APInt Value); + [[nodiscard]] static Expected floating(APFloat Value); [[nodiscard]] static Expected byteString(GenericConstantType Type, std::vector Bytes); diff --git a/backend/include/rcc/CodeGen/GlobalObject.h b/backend/include/rcc/CodeGen/GlobalObject.h index 49f1f42..798dcd8 100644 --- a/backend/include/rcc/CodeGen/GlobalObject.h +++ b/backend/include/rcc/CodeGen/GlobalObject.h @@ -82,8 +82,8 @@ public: GlobalInitializer &operator=(GlobalInitializer &&) noexcept = default; ~GlobalInitializer() = default; - [[nodiscard]] static GlobalInitializer integer(IntegerImmediate Value); - [[nodiscard]] static GlobalInitializer floating(FloatingPointBits Value); + [[nodiscard]] static GlobalInitializer integer(APInt Value); + [[nodiscard]] static GlobalInitializer floating(APFloat Value); [[nodiscard]] static Expected bytes(std::vector Value); [[nodiscard]] static Expected zeroFill(std::uint64_t Size); [[nodiscard]] static Expected repeated(std::uint64_t Count, @@ -108,10 +108,10 @@ public: private: using StorageT = - std::variant, - GlobalZeroFill, GlobalRepeatedInitializer, GlobalAggregateInitializer, - GlobalSymbolAddress, GlobalSymbolDifference, TargetConstant, - GlobalAlignmentPadding, GlobalUndefinedStorage>; + std::variant, GlobalZeroFill, + GlobalRepeatedInitializer, GlobalAggregateInitializer, GlobalSymbolAddress, + GlobalSymbolDifference, TargetConstant, GlobalAlignmentPadding, + GlobalUndefinedStorage>; explicit GlobalInitializer(StorageT Storage) : Storage(std::move(Storage)) {} diff --git a/backend/include/rcc/CodeGen/LowLevelType.h b/backend/include/rcc/CodeGen/LowLevelType.h index 116ffd5..e6ff174 100644 --- a/backend/include/rcc/CodeGen/LowLevelType.h +++ b/backend/include/rcc/CodeGen/LowLevelType.h @@ -3,6 +3,7 @@ #ifndef RCC_CODEGEN_LOWLEVELTYPE_H #define RCC_CODEGEN_LOWLEVELTYPE_H +#include "rcc/ADT/APFloat.h" #include "rcc/Support/Error.h" #include @@ -15,35 +16,6 @@ namespace rcc { -enum class FloatSemantics : std::uint8_t { - IEEEHalf, - BFloat, - IEEESingle, - IEEEDouble, - IEEEQuad, - PPCDoubleDouble, - Float8E5M2, - Float8E5M2FNUZ, - Float8E4M3, - Float8E4M3FN, - Float8E4M3FNUZ, - Float8E4M3B11FNUZ, - Float8E3M4, - FloatTF32, - Float8E8M0FNU, - Float6E3M2FN, - Float6E2M3FN, - Float4E2M1FN, - X87DoubleExtended, - Count, -}; - -[[nodiscard]] bool isKnownFloatSemantics(FloatSemantics Semantics) noexcept; -[[nodiscard]] std::optional -getFloatSemanticsBitWidth(FloatSemantics Semantics) noexcept; -[[nodiscard]] std::string_view getFloatSemanticsName(FloatSemantics Semantics) noexcept; -[[nodiscard]] std::string_view getFloatSemanticsSpelling(FloatSemantics Semantics) noexcept; - class LLT final { public: enum class Kind : std::uint8_t { diff --git a/backend/include/rcc/CodeGen/MachineIRBuilder.h b/backend/include/rcc/CodeGen/MachineIRBuilder.h index 2524c7a..b8ff248 100644 --- a/backend/include/rcc/CodeGen/MachineIRBuilder.h +++ b/backend/include/rcc/CodeGen/MachineIRBuilder.h @@ -52,10 +52,8 @@ public: std::uint32_t TargetFlags = 0); [[nodiscard]] Expected addImmediate(std::int64_t Value, std::uint32_t TargetFlags = 0); - [[nodiscard]] Expected addIntegerImmediate(IntegerImmediate Value, - std::uint32_t TargetFlags = 0); - [[nodiscard]] Expected addFloatingImmediate(FloatingPointBits Bits, - std::uint32_t TargetFlags = 0); + [[nodiscard]] Expected addIntegerImmediate(APInt Value, std::uint32_t TargetFlags = 0); + [[nodiscard]] Expected addFloatingImmediate(APFloat Bits, std::uint32_t TargetFlags = 0); [[nodiscard]] Expected addBasicBlock(MachineBasicBlock &Block, std::uint32_t TargetFlags = 0); [[nodiscard]] Expected addFrameIndex(FrameIndex Index, std::int64_t Offset = 0, diff --git a/backend/include/rcc/CodeGen/MachineOperand.h b/backend/include/rcc/CodeGen/MachineOperand.h index a7feafa..ef14638 100644 --- a/backend/include/rcc/CodeGen/MachineOperand.h +++ b/backend/include/rcc/CodeGen/MachineOperand.h @@ -3,6 +3,8 @@ #ifndef RCC_CODEGEN_MACHINEOPERAND_H #define RCC_CODEGEN_MACHINEOPERAND_H +#include "rcc/ADT/APFloat.h" +#include "rcc/ADT/APInt.h" #include "rcc/CodeGen/LowLevelType.h" #include "rcc/CodeGen/MachineDebugInfo.h" #include "rcc/CodeGen/MachineIRTypes.h" @@ -10,7 +12,6 @@ #include "rcc/CodeGen/RegisterMask.h" #include "rcc/Support/Error.h" -#include #include #include #include @@ -30,72 +31,6 @@ class MachineInstr; class MachineRegisterInfo; class RegOperandIterator; -class FloatingPointBits final { -public: - [[nodiscard]] static Expected create(FloatSemantics Semantics, - std::span Words); - - [[nodiscard]] FloatSemantics semantics() const noexcept { - return Semantics; - } - - [[nodiscard]] std::uint32_t bitWidth() const noexcept { - return getFloatSemanticsBitWidth(Semantics).value_or(0); - } - - [[nodiscard]] std::span words() const noexcept { - return std::span(Words).first(WordCount); - } - - friend bool operator==(const FloatingPointBits &Left, const FloatingPointBits &Right) = default; - -private: - FloatingPointBits(FloatSemantics Semantics, std::array Words, - std::uint8_t WordCount) noexcept - : Semantics(Semantics), Words(Words), WordCount(WordCount) {} - - FloatSemantics Semantics; - std::array Words; - std::uint8_t WordCount; -}; - -class IntegerImmediate final { -public: - static constexpr std::uint32_t MaxBitWidth = std::uint32_t{1} << 23U; - - [[nodiscard]] static Expected create(std::uint32_t BitWidth, - std::span Words); - [[nodiscard]] static Expected fromUnsigned(std::uint32_t BitWidth, - std::uint64_t Value); - [[nodiscard]] static Expected fromSigned(std::uint32_t BitWidth, - std::int64_t Value); - [[nodiscard]] static Expected parseDecimal(std::uint32_t BitWidth, - std::string_view Text); - - [[nodiscard]] std::uint32_t bitWidth() const noexcept { - return BitWidth; - } - - [[nodiscard]] std::span words() const noexcept { - return Words; - } - - [[nodiscard]] bool isZero() const noexcept; - [[nodiscard]] bool isNegative() const noexcept; - [[nodiscard]] std::string toUnsignedDecimal() const; - [[nodiscard]] std::string toSignedDecimal() const; - [[nodiscard]] Expected verify() const; - - friend bool operator==(const IntegerImmediate &Left, const IntegerImmediate &Right) = default; - -private: - IntegerImmediate(std::uint32_t BitWidth, std::vector Words) - : BitWidth(BitWidth), Words(std::move(Words)) {} - - std::uint32_t BitWidth; - std::vector Words; -}; - enum class RegisterOperandFlag : std::uint8_t { Define, Use, @@ -147,14 +82,14 @@ private: }; struct FloatingImmediateOperand final { - FloatingPointBits Bits; + APFloat Bits; friend bool operator==(const FloatingImmediateOperand &Left, const FloatingImmediateOperand &Right) = default; }; struct IntegerImmediateOperand final { - IntegerImmediate Value; + APInt Value; friend bool operator==(const IntegerImmediateOperand &Left, const IntegerImmediateOperand &Right) = default; @@ -382,9 +317,8 @@ public: SubRegIndex SubReg = {}, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand immediate(std::int64_t Value, std::uint32_t TargetFlags = 0); - [[nodiscard]] static MachineOperand integerImmediate(IntegerImmediate Value, - std::uint32_t TargetFlags = 0); - [[nodiscard]] static MachineOperand floatingImmediate(FloatingPointBits Bits, + [[nodiscard]] static MachineOperand integerImmediate(APInt Value, std::uint32_t TargetFlags = 0); + [[nodiscard]] static MachineOperand floatingImmediate(APFloat Bits, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand basicBlock(MachineBasicBlock &Block, std::uint32_t TargetFlags = 0); diff --git a/backend/include/rcc/MIR/LLVMConstantSyntax.h b/backend/include/rcc/MIR/LLVMConstantSyntax.h index a47da54..7e18d60 100644 --- a/backend/include/rcc/MIR/LLVMConstantSyntax.h +++ b/backend/include/rcc/MIR/LLVMConstantSyntax.h @@ -4,6 +4,7 @@ #define RCC_MIR_LLVMCONSTANTSYNTAX_H #include "rcc/CodeGen/GenericConstant.h" +#include "rcc/CodeGen/MachineIRTypes.h" #include "rcc/Support/Error.h" #include -- cgit v1.2.3