aboutsummaryrefslogtreecommitdiff
path: root/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'backend/utils')
-rw-r--r--backend/utils/TableGen/Common/CodeGenSelection.cpp38
-rw-r--r--backend/utils/TableGen/Common/CodeGenTarget.h3
-rw-r--r--backend/utils/TableGen/GlobalISelEmitter.cpp12
3 files changed, 38 insertions, 15 deletions
diff --git a/backend/utils/TableGen/Common/CodeGenSelection.cpp b/backend/utils/TableGen/Common/CodeGenSelection.cpp
index 5093f67..077a95f 100644
--- a/backend/utils/TableGen/Common/CodeGenSelection.cpp
+++ b/backend/utils/TableGen/Common/CodeGenSelection.cpp
@@ -481,21 +481,36 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) {
for (const SourceSelectionTemporary &Temporary : Rule.Temporaries) {
if (!isIdentifier(Temporary.Symbol) ||
!TemporaryIDs.emplace(Temporary.Symbol, TemporaryIDs.size() + 1U).second ||
- (MatchInstruction != nullptr &&
- !isRegisterOperand(*MatchInstruction, Temporary.TypeFromOperand))) {
- fail(Temporary.Range,
- "selection temporary requires a unique identifier and a register type source");
+ (Temporary.TypeFromOperand.has_value() == Temporary.Type.has_value())) {
+ fail(Temporary.Range, "selection temporary requires a unique identifier and one type");
return false;
}
- Normalized.Temporaries.push_back({
+ NormalizedSelectionTemporary NormalizedTemporary{
.ID = TemporaryIDs.at(Temporary.Symbol),
- .TypeFromOperand = Temporary.TypeFromOperand,
- });
+ .TypeFromOperand = std::nullopt,
+ .Type = std::nullopt,
+ };
+ if (Temporary.TypeFromOperand) {
+ if (MatchInstruction != nullptr &&
+ !isRegisterOperand(*MatchInstruction, *Temporary.TypeFromOperand)) {
+ fail(Temporary.Range,
+ "selection temporary type source must be a matched register operand");
+ return false;
+ }
+ NormalizedTemporary.TypeFromOperand = *Temporary.TypeFromOperand;
+ } else {
+ auto Type = NormalizeType(*Temporary.Type);
+ if (!Type || Type->Kind != NormalizedSelectionTypeKind::Scalar) {
+ fail(Temporary.Range, "selection temporary explicit type must be a scalar");
+ return false;
+ }
+ NormalizedTemporary.Type = *Type;
+ }
+ Normalized.Temporaries.push_back(std::move(NormalizedTemporary));
}
bool HasRootAction = false;
- for (std::size_t ActionIndex = 0; ActionIndex < Rule.Actions.size(); ++ActionIndex) {
- const SourceSelectionAction &Action = Rule.Actions[ActionIndex];
+ for (const SourceSelectionAction &Action : Rule.Actions) {
const auto ResultOpcode = resolveOpcode(Result, Action.ResultOpcodeSymbol);
const NormalizedInstruction *ResultInstruction =
findInstructionBySymbol(Result, Action.ResultOpcodeSymbol);
@@ -509,9 +524,8 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) {
"selection instruction opcode must name a declared target instruction or core pseudo");
return false;
}
- if (Action.ReplacesRoot == HasRootAction || (Action.ReplacesRoot && ActionIndex != 0)) {
- fail(Action.Range,
- "selection instructions require exactly one root replacement as their first action");
+ if (Action.ReplacesRoot && HasRootAction) {
+ fail(Action.Range, "selection instructions require exactly one root replacement");
return false;
}
HasRootAction |= Action.ReplacesRoot;
diff --git a/backend/utils/TableGen/Common/CodeGenTarget.h b/backend/utils/TableGen/Common/CodeGenTarget.h
index 43c7383..2ab6db1 100644
--- a/backend/utils/TableGen/Common/CodeGenTarget.h
+++ b/backend/utils/TableGen/Common/CodeGenTarget.h
@@ -298,7 +298,8 @@ struct NormalizedSelectionDefUsePredicate final {
struct NormalizedSelectionTemporary final {
std::uint32_t ID = 0;
- std::uint32_t TypeFromOperand = 0;
+ std::optional<std::uint32_t> TypeFromOperand;
+ std::optional<NormalizedSelectionTypePredicate> Type;
};
enum class NormalizedSelectionImmediateTransform : std::uint8_t {
diff --git a/backend/utils/TableGen/GlobalISelEmitter.cpp b/backend/utils/TableGen/GlobalISelEmitter.cpp
index 092969d..3ce9411 100644
--- a/backend/utils/TableGen/GlobalISelEmitter.cpp
+++ b/backend/utils/TableGen/GlobalISelEmitter.cpp
@@ -162,8 +162,16 @@ std::string emitGlobalISel(const NormalizedTargetModel &Model, std::string_view
emitInstruction(Output, "CaptureDefOperand", DefUse.RootOperandIndex, Capture.ID,
std::to_string(Capture.OperandIndex));
}
- for (const NormalizedSelectionTemporary &Temporary : Rule.Temporaries)
- emitInstruction(Output, "CreateTemporary", Temporary.TypeFromOperand, Temporary.ID);
+ for (const NormalizedSelectionTemporary &Temporary : Rule.Temporaries) {
+ if (Temporary.TypeFromOperand) {
+ emitInstruction(Output, "CreateTemporary", *Temporary.TypeFromOperand, Temporary.ID);
+ continue;
+ }
+ emitInstruction(Output, "CreateTemporaryType", 0, Temporary.ID,
+ "static_cast<std::uint32_t>(GIMatchTypeKind::" +
+ std::string(typeKindName(Temporary.Type->Kind)) + ")",
+ Temporary.Type->Bits);
+ }
for (const NormalizedSelectionAction &Action : Rule.Actions) {
emitInstruction(Output, Action.ReplacesRoot ? "MutateOpcode" : "BuildInstruction", 0,
Action.ResultOpcode);