diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-28 23:56:19 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-28 23:56:19 +0800 |
| commit | 7ee5d1913c7cfd0261f86b0ff7be6968b8c07d84 (patch) | |
| tree | 446dafb95e2f792fee922602b74709c5b9e0777c | |
| parent | f0cfb240d80cb9f4444fb996350c1f88bc69a142 (diff) | |
| download | rcc-project-7ee5d1913c7cfd0261f86b0ff7be6968b8c07d84.tar.gz rcc-project-7ee5d1913c7cfd0261f86b0ff7be6968b8c07d84.tar.xz | |
[Support] Use standard power-of-two checks
| -rw-r--r-- | backend/lib/CodeGen/TargetRegisterInfo.cpp | 8 | ||||
| -rw-r--r-- | backend/lib/MC/ELFObjectWriter.cpp | 13 | ||||
| -rw-r--r-- | backend/lib/MC/MCAssembler.cpp | 11 | ||||
| -rw-r--r-- | backend/lib/MC/MCSection.cpp | 7 | ||||
| -rw-r--r-- | backend/lib/MC/MCStreamer.cpp | 7 | ||||
| -rw-r--r-- | backend/utils/TableGen/Common/CodeGenInstruction.cpp | 3 | ||||
| -rw-r--r-- | backend/utils/TableGen/Common/CodeGenTarget.cpp | 9 | ||||
| -rw-r--r-- | backend/utils/TableGen/Common/CodeGenTarget.h | 1 |
8 files changed, 20 insertions, 39 deletions
diff --git a/backend/lib/CodeGen/TargetRegisterInfo.cpp b/backend/lib/CodeGen/TargetRegisterInfo.cpp index 7ddf676..b6631eb 100644 --- a/backend/lib/CodeGen/TargetRegisterInfo.cpp +++ b/backend/lib/CodeGen/TargetRegisterInfo.cpp @@ -22,10 +22,6 @@ namespace { "target register description: " + std::move(Message)); } -[[nodiscard]] bool isPowerOfTwo(std::uint32_t Value) noexcept { - return Value != 0 && std::has_single_bit(Value); -} - [[nodiscard]] std::string lowerASCII(std::string_view Name) { std::string Result(Name); for (char &Character : Result) { @@ -274,8 +270,8 @@ Expected<TargetRegisterInfo> TargetRegisterInfo::create(TargetRegisterInfoDesc D for (const RegisterClassDesc &Class : Result.Description.RegisterClasses) { if (Class.Registers.empty() || Class.SizeInBits == 0 || - Class.SpillSizeInBits < Class.SizeInBits || !isPowerOfTwo(Class.SpillAlignmentInBits) || - Class.Lanes.empty()) { + Class.SpillSizeInBits < Class.SizeInBits || + !std::has_single_bit(Class.SpillAlignmentInBits) || Class.Lanes.empty()) { return invalidDescription( "register class requires members, sizes, power-of-two spill alignment, and lanes"); } diff --git a/backend/lib/MC/ELFObjectWriter.cpp b/backend/lib/MC/ELFObjectWriter.cpp index 730ef72..96ec234 100644 --- a/backend/lib/MC/ELFObjectWriter.cpp +++ b/backend/lib/MC/ELFObjectWriter.cpp @@ -3,6 +3,7 @@ #include "rcc/MC/ELFObjectWriter.h" #include <algorithm> +#include <bit> #include <cstddef> #include <cstdint> #include <limits> @@ -98,10 +99,6 @@ struct OutputSection final { MCSymbolRef GroupSignature; }; -[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept { - return Value != 0 && (Value & (Value - 1U)) == 0; -} - [[nodiscard]] bool isWriterManagedSectionType(std::uint32_t Type) noexcept { switch (Type) { case SHTNull: @@ -127,7 +124,7 @@ struct OutputSection final { } [[nodiscard]] Expected<std::uint64_t> alignTo(std::uint64_t Value, std::uint64_t Alignment) { - if (!isPowerOfTwo(Alignment)) + if (!std::has_single_bit(Alignment)) return makeUnexpected(ErrorCode::ObjectWritingFailed, "ELF alignment is not a power of two"); auto Adjusted = checkedAdd(Value, Alignment - 1U, "ELF file offset overflows"); if (!Adjusted) @@ -290,7 +287,7 @@ ELF64LEObjectWriter::writeObject(const MCAssembledObject &Object) const { return std::unexpected(DescriptionVerification.error()); const bool NoBits = Description.Kind == MCSectionKind::BSS || Description.Kind == MCSectionKind::TLSBSS; - if (!isPowerOfTwo(Input.Alignment) || Input.Alignment < Description.Alignment) { + if (!std::has_single_bit(Input.Alignment) || Input.Alignment < Description.Alignment) { return makeUnexpected(ErrorCode::ObjectWritingFailed, "ELF input section has an invalid effective alignment"); } @@ -324,7 +321,7 @@ ELF64LEObjectWriter::writeObject(const MCAssembledObject &Object) const { for (const ELFExtraSection &Extra : Target.ExtraSections) { if (Extra.Name.empty() || isWriterManagedSectionType(Extra.Type) || - !isPowerOfTwo(Extra.Alignment) || (Extra.Flags & (SHFInfoLink | SHFGroup)) != 0 || + !std::has_single_bit(Extra.Alignment) || (Extra.Flags & (SHFInfoLink | SHFGroup)) != 0 || (Extra.EntrySize != 0 && Extra.Contents.size() % Extra.EntrySize != 0)) { return makeUnexpected(ErrorCode::ObjectWritingFailed, "ELF extra section has an invalid description"); @@ -365,7 +362,7 @@ ELF64LEObjectWriter::writeObject(const MCAssembledObject &Object) const { std::uint16_t Section = SHNUndefined; std::uint64_t Value = Input.Value; if (Input.CommonAlignment != 0) { - if (!isPowerOfTwo(Input.CommonAlignment) || Input.Size == 0 || Input.SectionIndex || + if (!std::has_single_bit(Input.CommonAlignment) || Input.Size == 0 || Input.SectionIndex || Input.Binding == MCObjectSymbolBinding::Local || Input.Value != Input.CommonAlignment) { return makeUnexpected(ErrorCode::ObjectWritingFailed, "ELF common symbol has an invalid definition"); diff --git a/backend/lib/MC/MCAssembler.cpp b/backend/lib/MC/MCAssembler.cpp index 0f92edb..e1eb8e0 100644 --- a/backend/lib/MC/MCAssembler.cpp +++ b/backend/lib/MC/MCAssembler.cpp @@ -3,6 +3,7 @@ #include "rcc/MC/MCAssembler.h" #include <algorithm> +#include <bit> #include <cstddef> #include <cstdint> #include <limits> @@ -12,10 +13,6 @@ namespace rcc::mc { namespace { -[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept { - return Value != 0 && (Value & (Value - 1U)) == 0; -} - [[nodiscard]] Expected<std::uint64_t> checkedAdd(std::uint64_t Left, std::uint64_t Right, std::string_view Message) { std::uint64_t Result = 0; @@ -48,7 +45,7 @@ namespace { [[nodiscard]] Expected<std::uint64_t> alignmentPadding(std::uint64_t Offset, std::uint64_t Alignment) { - if (!isPowerOfTwo(Alignment)) + if (!std::has_single_bit(Alignment)) return makeUnexpected(ErrorCode::InvalidArgument, "MC alignment is not a power of two"); const std::uint64_t Mask = Alignment - 1U; auto Adjusted = checkedAdd(Offset, Mask, "MC section alignment overflows"); @@ -230,7 +227,7 @@ Expected<void> MCAssembler::emitAlignment(std::uint64_t Alignment, std::uint8_t auto SectionIndex = currentSectionIndex(); if (!SectionIndex) return std::unexpected(SectionIndex.error()); - if (!isPowerOfTwo(Alignment)) + if (!std::has_single_bit(Alignment)) return makeUnexpected(ErrorCode::InvalidArgument, "MC alignment is not a power of two"); Sections[*SectionIndex].Fragments.push_back(Fragment{ .Payload = @@ -296,7 +293,7 @@ Expected<void> MCAssembler::emitCommonSymbol(MCSymbolRef Symbol, std::uint64_t S std::uint64_t Alignment) { if (WasAssembled) return makeUnexpected(ErrorCode::ObjectWritingFailed, "MC assembler is already finalized"); - if (!Symbol || Size == 0 || !isPowerOfTwo(Alignment)) { + if (!Symbol || Size == 0 || !std::has_single_bit(Alignment)) { return makeUnexpected(ErrorCode::InvalidArgument, "common symbol requires a size and power-of-two alignment"); } diff --git a/backend/lib/MC/MCSection.cpp b/backend/lib/MC/MCSection.cpp index 21ba410..464dcc6 100644 --- a/backend/lib/MC/MCSection.cpp +++ b/backend/lib/MC/MCSection.cpp @@ -2,6 +2,7 @@ #include "rcc/MC/MCSection.h" +#include <bit> #include <cstdint> #include <string_view> @@ -19,16 +20,12 @@ namespace { return true; } -[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept { - return Value != 0 && (Value & (Value - 1U)) == 0; -} - } // namespace Expected<void> MCSectionDesc::verify() const { if (!isValidAssemblyName(Name)) return makeUnexpected(ErrorCode::InvalidArgument, "MC section has an invalid name"); - if (!isPowerOfTwo(Alignment)) { + if (!std::has_single_bit(Alignment)) { return makeUnexpected(ErrorCode::InvalidArgument, "MC section alignment must be a nonzero power of two"); } diff --git a/backend/lib/MC/MCStreamer.cpp b/backend/lib/MC/MCStreamer.cpp index 56c3f96..709dccc 100644 --- a/backend/lib/MC/MCStreamer.cpp +++ b/backend/lib/MC/MCStreamer.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <array> +#include <bit> #include <cctype> #include <cstddef> #include <cstdint> @@ -23,10 +24,6 @@ namespace { Text.find('\r') != std::string_view::npos; } -[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept { - return Value != 0 && (Value & (Value - 1U)) == 0; -} - [[nodiscard]] unsigned log2Exact(std::uint64_t Value) noexcept { unsigned Result = 0; while (Value > 1) { @@ -282,7 +279,7 @@ Expected<void> AsmTextStreamer::emitAlignment(std::uint64_t Alignment, std::uint auto Active = requireActiveSection(); if (!Active) return std::unexpected(Active.error()); - if (!isPowerOfTwo(Alignment)) { + if (!std::has_single_bit(Alignment)) { return makeUnexpected(ErrorCode::InvalidArgument, "assembly alignment must be a nonzero power of two"); } diff --git a/backend/utils/TableGen/Common/CodeGenInstruction.cpp b/backend/utils/TableGen/Common/CodeGenInstruction.cpp index a34f5ab..e7f5ddc 100644 --- a/backend/utils/TableGen/Common/CodeGenInstruction.cpp +++ b/backend/utils/TableGen/Common/CodeGenInstruction.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <array> +#include <bit> #include <cstdint> #include <limits> #include <ranges> @@ -218,7 +219,7 @@ pipelineStageEnumerator(std::string_view Value) noexcept { const bool IsUnsigned = Predicate.Kind == "unsigned"; if (Predicate.ID == 0 || !isIdentifier(Predicate.Symbol) || Predicate.Name.empty() || (!IsSigned && !IsUnsigned) || Predicate.Bits == 0 || Predicate.Bits > 63 || - !isPowerOfTwo(Predicate.Alignment) || !IDs.insert(Predicate.ID).second || + !std::has_single_bit(Predicate.Alignment) || !IDs.insert(Predicate.ID).second || !Symbols.insert(Predicate.Symbol).second || !Names.insert(Predicate.Name).second) { fail(Predicate.Range, "immediate predicates require nonzero unique IDs, symbols, names, a signed or " diff --git a/backend/utils/TableGen/Common/CodeGenTarget.cpp b/backend/utils/TableGen/Common/CodeGenTarget.cpp index d4c9795..478457c 100644 --- a/backend/utils/TableGen/Common/CodeGenTarget.cpp +++ b/backend/utils/TableGen/Common/CodeGenTarget.cpp @@ -6,6 +6,7 @@ #include "rcc/TableGen/Parser.h" #include <algorithm> +#include <bit> #include <cstddef> #include <ranges> #include <string> @@ -15,10 +16,6 @@ namespace rcc::targetgen { -[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept { - return Value != 0 && (Value & (Value - 1U)) == 0; -} - CodeGenTarget::CodeGenTarget(const DescriptionAST &Input, std::string SourceName) : Input(Input), SourceName(std::move(SourceName)) {} @@ -105,8 +102,8 @@ void CodeGenTarget::fail(TextRange Range, std::string Message) { IntegerClass == ClassBySymbol.end() || FloatingClass == ClassBySymbol.end() || PreservedMask == Result.RegisterMasks.end() || Convention.StackAlignmentBytes == 0 || Convention.StackArgumentAlignmentBytes == 0 || - !isPowerOfTwo(Convention.StackAlignmentBytes) || - !isPowerOfTwo(Convention.StackArgumentAlignmentBytes) || + !std::has_single_bit(Convention.StackAlignmentBytes) || + !std::has_single_bit(Convention.StackArgumentAlignmentBytes) || Convention.StackAlignmentBytes % Convention.StackArgumentAlignmentBytes != 0 || Convention.ShadowSpaceBytes % Convention.StackArgumentAlignmentBytes != 0 || !IDs.insert(Convention.ID).second || !Symbols.insert(Convention.Symbol).second || diff --git a/backend/utils/TableGen/Common/CodeGenTarget.h b/backend/utils/TableGen/Common/CodeGenTarget.h index 2ab6db1..a2aed7c 100644 --- a/backend/utils/TableGen/Common/CodeGenTarget.h +++ b/backend/utils/TableGen/Common/CodeGenTarget.h @@ -426,7 +426,6 @@ instructionFlagEnumerator(std::string_view Value) noexcept; pseudoOwnerEnumerator(std::string_view Value) noexcept; [[nodiscard]] std::optional<std::string_view> pipelineStageEnumerator(std::string_view Value) noexcept; -[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept; class CodeGenTarget final { public: |
