From 3b14bd4d5324b5a280c1ee5567b5526b59e60c5b Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Thu, 27 Aug 2026 17:13:36 +0800 Subject: [GlobalISel] Generate floating memory selection --- backend/utils/TableGen/Common/CodeGenSelection.cpp | 38 +++++++++++++++------- backend/utils/TableGen/Common/CodeGenTarget.h | 3 +- backend/utils/TableGen/GlobalISelEmitter.cpp | 12 +++++-- 3 files changed, 38 insertions(+), 15 deletions(-) (limited to 'backend/utils/TableGen') 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 TypeFromOperand; + std::optional 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(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); -- cgit v1.2.3