diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-17 02:22:27 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-17 02:22:27 +0800 |
| commit | f6a3a06de3d32eaeba1f3c8bbc5faa5ffaeb1128 (patch) | |
| tree | 709c80bac56fb9c18f795ab77185da6132d35ff8 /backend/utils/TableGen/Common | |
| parent | fb5c47bd2cb9ba5b201dfaa8d4918d122c4a624d (diff) | |
| download | rcc-project-f6a3a06de3d32eaeba1f3c8bbc5faa5ffaeb1128.tar.gz rcc-project-f6a3a06de3d32eaeba1f3c8bbc5faa5ffaeb1128.tar.xz | |
[RISCV][GlobalISel] Generate integer extension selections
Diffstat (limited to 'backend/utils/TableGen/Common')
| -rw-r--r-- | backend/utils/TableGen/Common/CodeGenSelection.cpp | 134 | ||||
| -rw-r--r-- | backend/utils/TableGen/Common/CodeGenTarget.h | 19 |
2 files changed, 89 insertions, 64 deletions
diff --git a/backend/utils/TableGen/Common/CodeGenSelection.cpp b/backend/utils/TableGen/Common/CodeGenSelection.cpp index 88f85f7..d3bc299 100644 --- a/backend/utils/TableGen/Common/CodeGenSelection.cpp +++ b/backend/utils/TableGen/Common/CodeGenSelection.cpp @@ -170,6 +170,36 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) { } return NormalizedSelectionTypePredicate{.Kind = Kind, .Bits = Source.Bits}; }; + const auto NormalizeRanges = [this](const std::vector<SourceSelectionConstantRange> &Ranges, + TextRange PredicateRange, std::string_view PredicateName) + -> std::optional<std::vector<NormalizedSelectionConstantRange>> { + if (Ranges.empty()) { + fail(PredicateRange, std::string(PredicateName) + " requires at least one range"); + return std::nullopt; + } + std::vector<NormalizedSelectionConstantRange> NormalizedRanges; + NormalizedRanges.reserve(Ranges.size()); + for (const SourceSelectionConstantRange &Range : Ranges) { + if (Range.Minimum > Range.Maximum) { + fail(Range.SourceRange, std::string(PredicateName) + " range is invalid"); + return std::nullopt; + } + NormalizedRanges.push_back({ + .Minimum = Range.Minimum, + .Maximum = Range.Maximum, + }); + } + std::ranges::sort(NormalizedRanges, {}, &NormalizedSelectionConstantRange::Minimum); + for (std::size_t Index = 1; Index < NormalizedRanges.size(); ++Index) { + const auto &Previous = NormalizedRanges[Index - 1]; + const auto &Current = NormalizedRanges[Index]; + if (Current.Minimum <= Previous.Maximum) { + fail(PredicateRange, std::string(PredicateName) + " ranges overlap"); + return std::nullopt; + } + } + return NormalizedRanges; + }; NormalizedSelectionRule Normalized; Normalized.Symbol = Rule.Symbol; @@ -213,6 +243,17 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) { ++Normalized.Specificity; } + std::unordered_set<std::string> TargetPredicateSymbols; + for (const SourceSelectionTargetPredicate &Predicate : Rule.TargetPredicates) { + if (!isIdentifier(Predicate.Symbol) || + !TargetPredicateSymbols.insert(Predicate.Symbol).second) { + fail(Predicate.Range, "selection target predicates require distinct identifiers"); + return false; + } + Normalized.TargetPredicates.push_back(Predicate.Symbol); + ++Normalized.Specificity; + } + std::unordered_set<std::uint32_t> TypeOperands; for (const SourceSelectionOperandTypePredicate &Predicate : Rule.OperandTypes) { auto Type = NormalizeType(Predicate.Type); @@ -261,43 +302,40 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) { ++Normalized.Specificity; } + std::unordered_set<std::uint32_t> ImmediateOperands; + for (const SourceSelectionOperandImmediatePredicate &Predicate : Rule.OperandImmediates) { + if (!ImmediateOperands.insert(Predicate.OperandIndex).second) { + fail(Predicate.Range, "selection operand immediate predicates require distinct operands"); + return false; + } + auto Ranges = NormalizeRanges(Predicate.Ranges, Predicate.Range, + "selection operand immediate predicate"); + if (!Ranges) + return false; + Normalized.OperandImmediates.push_back({ + .OperandIndex = Predicate.OperandIndex, + .Ranges = std::move(*Ranges), + }); + ++Normalized.Specificity; + } + std::unordered_set<std::uint32_t> ConstantOperands; for (const SourceSelectionOperandDefConstantPredicate &Predicate : Rule.OperandDefConstants) { if (!ConstantOperands.insert(Predicate.OperandIndex).second || (MatchInstruction != nullptr && - !isRegisterOperand(*MatchInstruction, Predicate.OperandIndex)) || - Predicate.Ranges.empty()) { + !isRegisterOperand(*MatchInstruction, Predicate.OperandIndex))) { fail(Predicate.Range, - "selection operand definition constant predicates require distinct register " - "operands and at least one range"); + "selection operand definition constant predicates require distinct register operands"); return false; } - NormalizedSelectionOperandDefConstantPredicate NormalizedPredicate{ + auto Ranges = NormalizeRanges(Predicate.Ranges, Predicate.Range, + "selection operand definition constant predicate"); + if (!Ranges) + return false; + Normalized.OperandDefConstants.push_back({ .OperandIndex = Predicate.OperandIndex, - .Ranges = {}, - }; - for (const SourceSelectionOperandDefConstantPredicate::ConstantRange &Range : - Predicate.Ranges) { - if (Range.Minimum > Range.Maximum) { - fail(Range.SourceRange, "selection operand definition constant range is invalid"); - return false; - } - NormalizedPredicate.Ranges.push_back({ - .Minimum = Range.Minimum, - .Maximum = Range.Maximum, - }); - } - std::ranges::sort(NormalizedPredicate.Ranges, {}, - &NormalizedSelectionOperandDefConstantPredicate::Range::Minimum); - for (std::size_t Index = 1; Index < NormalizedPredicate.Ranges.size(); ++Index) { - const auto &Previous = NormalizedPredicate.Ranges[Index - 1]; - const auto &Current = NormalizedPredicate.Ranges[Index]; - if (Current.Minimum <= Previous.Maximum) { - fail(Predicate.Range, "selection operand definition constant ranges overlap"); - return false; - } - } - Normalized.OperandDefConstants.push_back(std::move(NormalizedPredicate)); + .Ranges = std::move(*Ranges), + }); ++Normalized.Specificity; } @@ -338,38 +376,18 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) { std::unordered_set<std::uint32_t> ConstantOperandsInDef; for (const SourceSelectionOperandDefConstantPredicate &Constant : Predicate.OperandDefConstants) { - if (!ConstantOperandsInDef.insert(Constant.OperandIndex).second || - Constant.Ranges.empty()) { - fail(Constant.Range, "selection def-use constant predicates require distinct operands " - "and at least one range"); + if (!ConstantOperandsInDef.insert(Constant.OperandIndex).second) { + fail(Constant.Range, "selection def-use constant predicates require distinct operands"); return false; } - NormalizedSelectionOperandDefConstantPredicate NormalizedConstant{ + auto Ranges = NormalizeRanges(Constant.Ranges, Constant.Range, + "selection def-use constant predicate"); + if (!Ranges) + return false; + NormalizedPredicate.OperandDefConstants.push_back({ .OperandIndex = Constant.OperandIndex, - .Ranges = {}, - }; - for (const SourceSelectionOperandDefConstantPredicate::ConstantRange &Range : - Constant.Ranges) { - if (Range.Minimum > Range.Maximum) { - fail(Range.SourceRange, "selection def-use constant range is invalid"); - return false; - } - NormalizedConstant.Ranges.push_back({ - .Minimum = Range.Minimum, - .Maximum = Range.Maximum, - }); - } - std::ranges::sort(NormalizedConstant.Ranges, {}, - &NormalizedSelectionOperandDefConstantPredicate::Range::Minimum); - for (std::size_t Index = 1; Index < NormalizedConstant.Ranges.size(); ++Index) { - const auto &Previous = NormalizedConstant.Ranges[Index - 1]; - const auto &Current = NormalizedConstant.Ranges[Index]; - if (Current.Minimum <= Previous.Maximum) { - fail(Constant.Range, "selection def-use constant ranges overlap"); - return false; - } - } - NormalizedPredicate.OperandDefConstants.push_back(std::move(NormalizedConstant)); + .Ranges = std::move(*Ranges), + }); } Normalized.DefUsePredicates.push_back(std::move(NormalizedPredicate)); Normalized.Specificity += 1U + static_cast<std::uint32_t>(Predicate.Captures.size()) + diff --git a/backend/utils/TableGen/Common/CodeGenTarget.h b/backend/utils/TableGen/Common/CodeGenTarget.h index 47dd598..d66cfee 100644 --- a/backend/utils/TableGen/Common/CodeGenTarget.h +++ b/backend/utils/TableGen/Common/CodeGenTarget.h @@ -194,14 +194,19 @@ struct NormalizedSelectionIntegerPredicate final { std::uint32_t Predicate = 0; }; -struct NormalizedSelectionOperandDefConstantPredicate final { - struct Range final { - std::int64_t Minimum = 0; - std::int64_t Maximum = 0; - }; +struct NormalizedSelectionConstantRange final { + std::int64_t Minimum = 0; + std::int64_t Maximum = 0; +}; +struct NormalizedSelectionOperandImmediatePredicate final { + std::uint32_t OperandIndex = 0; + std::vector<NormalizedSelectionConstantRange> Ranges; +}; + +struct NormalizedSelectionOperandDefConstantPredicate final { std::uint32_t OperandIndex = 0; - std::vector<Range> Ranges; + std::vector<NormalizedSelectionConstantRange> Ranges; }; struct NormalizedSelectionDefUseCapture final { @@ -259,9 +264,11 @@ struct NormalizedSelectionRule final { std::uint32_t MatchOpcode = 0; std::optional<NormalizedSelectionTypePredicate> ResultType; std::optional<NormalizedSelectionIntegerPredicate> IntegerPredicate; + std::vector<std::string> TargetPredicates; std::vector<NormalizedSelectionOperandTypePredicate> OperandTypes; std::vector<NormalizedSelectionOperandBankPredicate> OperandBanks; std::vector<NormalizedSelectionOperandClassPredicate> OperandClasses; + std::vector<NormalizedSelectionOperandImmediatePredicate> OperandImmediates; std::vector<NormalizedSelectionOperandDefConstantPredicate> OperandDefConstants; std::vector<NormalizedSelectionDefUsePredicate> DefUsePredicates; std::vector<NormalizedSelectionTemporary> Temporaries; |
