aboutsummaryrefslogtreecommitdiff
path: root/backend/utils/TableGen/Common
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-17 02:22:27 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-17 02:22:27 +0800
commitf6a3a06de3d32eaeba1f3c8bbc5faa5ffaeb1128 (patch)
tree709c80bac56fb9c18f795ab77185da6132d35ff8 /backend/utils/TableGen/Common
parentfb5c47bd2cb9ba5b201dfaa8d4918d122c4a624d (diff)
downloadrcc-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.cpp134
-rw-r--r--backend/utils/TableGen/Common/CodeGenTarget.h19
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;