[Frontend] Remove unused includes (NFC) (#116927)
[llvm-project.git] / llvm / utils / TableGen / GlobalISelCombinerEmitter.cpp
blob149ba7a1d9032d33bfb91928d55552d89a81d77e
1 //===- GlobalISelCombinerMatchTableEmitter.cpp - --------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file Generate a combiner implementation for GlobalISel from a declarative
10 /// syntax using GlobalISelMatchTable.
11 ///
12 /// Usually, TableGen backends use "assert is an error" as a means to report
13 /// invalid input. They try to diagnose common case but don't try very hard and
14 /// crashes can be common. This backend aims to behave closer to how a language
15 /// compiler frontend would behave: we try extra hard to diagnose invalid inputs
16 /// early, and any crash should be considered a bug (= a feature or diagnostic
17 /// is missing).
18 ///
19 /// While this can make the backend a bit more complex than it needs to be, it
20 /// pays off because MIR patterns can get complicated. Giving useful error
21 /// messages to combine writers can help boost their productivity.
22 ///
23 /// As with anything, a good balance has to be found. We also don't want to
24 /// write hundreds of lines of code to detect edge cases. In practice, crashing
25 /// very occasionally, or giving poor errors in some rare instances, is fine.
26 ///
27 //===----------------------------------------------------------------------===//
29 #include "Basic/CodeGenIntrinsics.h"
30 #include "Common/CodeGenInstruction.h"
31 #include "Common/CodeGenTarget.h"
32 #include "Common/GlobalISel/CXXPredicates.h"
33 #include "Common/GlobalISel/CodeExpander.h"
34 #include "Common/GlobalISel/CodeExpansions.h"
35 #include "Common/GlobalISel/CombinerUtils.h"
36 #include "Common/GlobalISel/GlobalISelMatchTable.h"
37 #include "Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h"
38 #include "Common/GlobalISel/PatternParser.h"
39 #include "Common/GlobalISel/Patterns.h"
40 #include "Common/SubtargetFeatureInfo.h"
41 #include "llvm/ADT/APInt.h"
42 #include "llvm/ADT/EquivalenceClasses.h"
43 #include "llvm/ADT/MapVector.h"
44 #include "llvm/ADT/Statistic.h"
45 #include "llvm/ADT/StringExtras.h"
46 #include "llvm/ADT/StringSet.h"
47 #include "llvm/Support/CommandLine.h"
48 #include "llvm/Support/Debug.h"
49 #include "llvm/Support/PrettyStackTrace.h"
50 #include "llvm/Support/ScopedPrinter.h"
51 #include "llvm/TableGen/Error.h"
52 #include "llvm/TableGen/Record.h"
53 #include "llvm/TableGen/StringMatcher.h"
54 #include "llvm/TableGen/TGTimer.h"
55 #include "llvm/TableGen/TableGenBackend.h"
56 #include <cstdint>
58 using namespace llvm;
59 using namespace llvm::gi;
61 #define DEBUG_TYPE "gicombiner-emitter"
63 namespace {
64 cl::OptionCategory
65 GICombinerEmitterCat("Options for -gen-global-isel-combiner");
66 cl::opt<bool> StopAfterParse(
67 "gicombiner-stop-after-parse",
68 cl::desc("Stop processing after parsing rules and dump state"),
69 cl::cat(GICombinerEmitterCat));
70 cl::list<std::string>
71 SelectedCombiners("combiners", cl::desc("Emit the specified combiners"),
72 cl::cat(GICombinerEmitterCat), cl::CommaSeparated);
73 cl::opt<bool> DebugCXXPreds(
74 "gicombiner-debug-cxxpreds",
75 cl::desc("Add Contextual/Debug comments to all C++ predicates"),
76 cl::cat(GICombinerEmitterCat));
77 cl::opt<bool> DebugTypeInfer("gicombiner-debug-typeinfer",
78 cl::desc("Print type inference debug logs"),
79 cl::cat(GICombinerEmitterCat));
81 constexpr StringLiteral CXXCustomActionPrefix = "GICXXCustomAction_";
82 constexpr StringLiteral CXXPredPrefix = "GICXXPred_MI_Predicate_";
83 constexpr StringLiteral MatchDataClassName = "GIDefMatchData";
85 //===- CodeExpansions Helpers --------------------------------------------===//
87 void declareInstExpansion(CodeExpansions &CE, const InstructionMatcher &IM,
88 StringRef Name) {
89 CE.declare(Name, "State.MIs[" + to_string(IM.getInsnVarID()) + "]");
92 void declareInstExpansion(CodeExpansions &CE, const BuildMIAction &A,
93 StringRef Name) {
94 // Note: we use redeclare here because this may overwrite a matcher inst
95 // expansion.
96 CE.redeclare(Name, "OutMIs[" + to_string(A.getInsnID()) + "]");
99 void declareOperandExpansion(CodeExpansions &CE, const OperandMatcher &OM,
100 StringRef Name) {
101 if (OM.isVariadic()) {
102 CE.declare(Name, "getRemainingOperands(*State.MIs[" +
103 to_string(OM.getInsnVarID()) + "], " +
104 to_string(OM.getOpIdx()) + ")");
105 } else {
106 CE.declare(Name, "State.MIs[" + to_string(OM.getInsnVarID()) +
107 "]->getOperand(" + to_string(OM.getOpIdx()) + ")");
111 void declareTempRegExpansion(CodeExpansions &CE, unsigned TempRegID,
112 StringRef Name) {
113 CE.declare(Name, "State.TempRegisters[" + to_string(TempRegID) + "]");
116 //===- Misc. Helpers -----------------------------------------------------===//
118 template <typename Container> auto keys(Container &&C) {
119 return map_range(C, [](auto &Entry) -> auto & { return Entry.first; });
122 template <typename Container> auto values(Container &&C) {
123 return map_range(C, [](auto &Entry) -> auto & { return Entry.second; });
126 std::string getIsEnabledPredicateEnumName(unsigned CombinerRuleID) {
127 return "GICXXPred_Simple_IsRule" + to_string(CombinerRuleID) + "Enabled";
130 //===- MatchTable Helpers ------------------------------------------------===//
132 LLTCodeGen getLLTCodeGen(const PatternType &PT) {
133 return *MVTToLLT(getValueType(PT.getLLTRecord()));
136 //===- PrettyStackTrace Helpers ------------------------------------------===//
138 class PrettyStackTraceParse : public PrettyStackTraceEntry {
139 const Record &Def;
141 public:
142 PrettyStackTraceParse(const Record &Def) : Def(Def) {}
144 void print(raw_ostream &OS) const override {
145 if (Def.isSubClassOf("GICombineRule"))
146 OS << "Parsing GICombineRule '" << Def.getName() << "'";
147 else if (Def.isSubClassOf(PatFrag::ClassName))
148 OS << "Parsing " << PatFrag::ClassName << " '" << Def.getName() << "'";
149 else
150 OS << "Parsing '" << Def.getName() << "'";
151 OS << '\n';
155 class PrettyStackTraceEmit : public PrettyStackTraceEntry {
156 const Record &Def;
157 const Pattern *Pat = nullptr;
159 public:
160 PrettyStackTraceEmit(const Record &Def, const Pattern *Pat = nullptr)
161 : Def(Def), Pat(Pat) {}
163 void print(raw_ostream &OS) const override {
164 if (Def.isSubClassOf("GICombineRule"))
165 OS << "Emitting GICombineRule '" << Def.getName() << "'";
166 else if (Def.isSubClassOf(PatFrag::ClassName))
167 OS << "Emitting " << PatFrag::ClassName << " '" << Def.getName() << "'";
168 else
169 OS << "Emitting '" << Def.getName() << "'";
171 if (Pat)
172 OS << " [" << Pat->getKindName() << " '" << Pat->getName() << "']";
173 OS << '\n';
177 //===- CombineRuleOperandTypeChecker --------------------------------------===//
179 /// This is a wrapper around OperandTypeChecker specialized for Combiner Rules.
180 /// On top of doing the same things as OperandTypeChecker, this also attempts to
181 /// infer as many types as possible for temporary register defs & immediates in
182 /// apply patterns.
184 /// The inference is trivial and leverages the MCOI OperandTypes encoded in
185 /// CodeGenInstructions to infer types across patterns in a CombineRule. It's
186 /// thus very limited and only supports CodeGenInstructions (but that's the main
187 /// use case so it's fine).
189 /// We only try to infer untyped operands in apply patterns when they're temp
190 /// reg defs, or immediates. Inference always outputs a `TypeOf<$x>` where $x is
191 /// a named operand from a match pattern.
192 class CombineRuleOperandTypeChecker : private OperandTypeChecker {
193 public:
194 CombineRuleOperandTypeChecker(const Record &RuleDef,
195 const OperandTable &MatchOpTable)
196 : OperandTypeChecker(RuleDef.getLoc()), RuleDef(RuleDef),
197 MatchOpTable(MatchOpTable) {}
199 /// Records and checks a 'match' pattern.
200 bool processMatchPattern(InstructionPattern &P);
202 /// Records and checks an 'apply' pattern.
203 bool processApplyPattern(InstructionPattern &P);
205 /// Propagates types, then perform type inference and do a second round of
206 /// propagation in the apply patterns only if any types were inferred.
207 void propagateAndInferTypes();
209 private:
210 /// TypeEquivalenceClasses are groups of operands of an instruction that share
211 /// a common type.
213 /// e.g. [[a, b], [c, d]] means a and b have the same type, and c and
214 /// d have the same type too. b/c and a/d don't have to have the same type,
215 /// though.
216 using TypeEquivalenceClasses = EquivalenceClasses<StringRef>;
218 /// \returns true for `OPERAND_GENERIC_` 0 through 5.
219 /// These are the MCOI types that can be registers. The other MCOI types are
220 /// either immediates, or fancier operands used only post-ISel, so we don't
221 /// care about them for combiners.
222 static bool canMCOIOperandTypeBeARegister(StringRef MCOIType) {
223 // Assume OPERAND_GENERIC_0 through 5 can be registers. The other MCOI
224 // OperandTypes are either never used in gMIR, or not relevant (e.g.
225 // OPERAND_GENERIC_IMM, which is definitely never a register).
226 return MCOIType.drop_back(1).ends_with("OPERAND_GENERIC_");
229 /// Finds the "MCOI::"" operand types for each operand of \p CGP.
231 /// This is a bit trickier than it looks because we need to handle variadic
232 /// in/outs.
234 /// e.g. for
235 /// (G_BUILD_VECTOR $vec, $x, $y) ->
236 /// [MCOI::OPERAND_GENERIC_0, MCOI::OPERAND_GENERIC_1,
237 /// MCOI::OPERAND_GENERIC_1]
239 /// For unknown types (which can happen in variadics where varargs types are
240 /// inconsistent), a unique name is given, e.g. "unknown_type_0".
241 static std::vector<std::string>
242 getMCOIOperandTypes(const CodeGenInstructionPattern &CGP);
244 /// Adds the TypeEquivalenceClasses for \p P in \p OutTECs.
245 void getInstEqClasses(const InstructionPattern &P,
246 TypeEquivalenceClasses &OutTECs) const;
248 /// Calls `getInstEqClasses` on all patterns of the rule to produce the whole
249 /// rule's TypeEquivalenceClasses.
250 TypeEquivalenceClasses getRuleEqClasses() const;
252 /// Tries to infer the type of the \p ImmOpIdx -th operand of \p IP using \p
253 /// TECs.
255 /// This is achieved by trying to find a named operand in \p IP that shares
256 /// the same type as \p ImmOpIdx, and using \ref inferNamedOperandType on that
257 /// operand instead.
259 /// \returns the inferred type or an empty PatternType if inference didn't
260 /// succeed.
261 PatternType inferImmediateType(const InstructionPattern &IP,
262 unsigned ImmOpIdx,
263 const TypeEquivalenceClasses &TECs) const;
265 /// Looks inside \p TECs to infer \p OpName's type.
267 /// \returns the inferred type or an empty PatternType if inference didn't
268 /// succeed.
269 PatternType inferNamedOperandType(const InstructionPattern &IP,
270 StringRef OpName,
271 const TypeEquivalenceClasses &TECs,
272 bool AllowSelf = false) const;
274 const Record &RuleDef;
275 SmallVector<InstructionPattern *, 8> MatchPats;
276 SmallVector<InstructionPattern *, 8> ApplyPats;
278 const OperandTable &MatchOpTable;
281 bool CombineRuleOperandTypeChecker::processMatchPattern(InstructionPattern &P) {
282 MatchPats.push_back(&P);
283 return check(P, /*CheckTypeOf*/ [](const auto &) {
284 // GITypeOf in 'match' is currently always rejected by the
285 // CombineRuleBuilder after inference is done.
286 return true;
290 bool CombineRuleOperandTypeChecker::processApplyPattern(InstructionPattern &P) {
291 ApplyPats.push_back(&P);
292 return check(P, /*CheckTypeOf*/ [&](const PatternType &Ty) {
293 // GITypeOf<"$x"> can only be used if "$x" is a matched operand.
294 const auto OpName = Ty.getTypeOfOpName();
295 if (MatchOpTable.lookup(OpName).Found)
296 return true;
298 PrintError(RuleDef.getLoc(), "'" + OpName + "' ('" + Ty.str() +
299 "') does not refer to a matched operand!");
300 return false;
304 void CombineRuleOperandTypeChecker::propagateAndInferTypes() {
305 /// First step here is to propagate types using the OperandTypeChecker. That
306 /// way we ensure all uses of a given register have consistent types.
307 propagateTypes();
309 /// Build the TypeEquivalenceClasses for the whole rule.
310 const TypeEquivalenceClasses TECs = getRuleEqClasses();
312 /// Look at the apply patterns and find operands that need to be
313 /// inferred. We then try to find an equivalence class that they're a part of
314 /// and select the best operand to use for the `GITypeOf` type. We prioritize
315 /// defs of matched instructions because those are guaranteed to be registers.
316 bool InferredAny = false;
317 for (auto *Pat : ApplyPats) {
318 for (unsigned K = 0; K < Pat->operands_size(); ++K) {
319 auto &Op = Pat->getOperand(K);
321 // We only want to take a look at untyped defs or immediates.
322 if ((!Op.isDef() && !Op.hasImmValue()) || Op.getType())
323 continue;
325 // Infer defs & named immediates.
326 if (Op.isDef() || Op.isNamedImmediate()) {
327 // Check it's not a redefinition of a matched operand.
328 // In such cases, inference is not necessary because we just copy
329 // operands and don't create temporary registers.
330 if (MatchOpTable.lookup(Op.getOperandName()).Found)
331 continue;
333 // Inference is needed here, so try to do it.
334 if (PatternType Ty =
335 inferNamedOperandType(*Pat, Op.getOperandName(), TECs)) {
336 if (DebugTypeInfer)
337 errs() << "INFER: " << Op.describe() << " -> " << Ty.str() << '\n';
338 Op.setType(Ty);
339 InferredAny = true;
342 continue;
345 // Infer immediates
346 if (Op.hasImmValue()) {
347 if (PatternType Ty = inferImmediateType(*Pat, K, TECs)) {
348 if (DebugTypeInfer)
349 errs() << "INFER: " << Op.describe() << " -> " << Ty.str() << '\n';
350 Op.setType(Ty);
351 InferredAny = true;
353 continue;
358 // If we've inferred any types, we want to propagate them across the apply
359 // patterns. Type inference only adds GITypeOf types that point to Matched
360 // operands, so we definitely don't want to propagate types into the match
361 // patterns as well, otherwise bad things happen.
362 if (InferredAny) {
363 OperandTypeChecker OTC(RuleDef.getLoc());
364 for (auto *Pat : ApplyPats) {
365 if (!OTC.check(*Pat, [&](const auto &) { return true; }))
366 PrintFatalError(RuleDef.getLoc(),
367 "OperandTypeChecker unexpectedly failed on '" +
368 Pat->getName() + "' during Type Inference");
370 OTC.propagateTypes();
372 if (DebugTypeInfer) {
373 errs() << "Apply patterns for rule " << RuleDef.getName()
374 << " after inference:\n";
375 for (auto *Pat : ApplyPats) {
376 errs() << " ";
377 Pat->print(errs(), /*PrintName*/ true);
378 errs() << '\n';
380 errs() << '\n';
385 PatternType CombineRuleOperandTypeChecker::inferImmediateType(
386 const InstructionPattern &IP, unsigned ImmOpIdx,
387 const TypeEquivalenceClasses &TECs) const {
388 // We can only infer CGPs (except intrinsics).
389 const auto *CGP = dyn_cast<CodeGenInstructionPattern>(&IP);
390 if (!CGP || CGP->isIntrinsic())
391 return {};
393 // For CGPs, we try to infer immediates by trying to infer another named
394 // operand that shares its type.
396 // e.g.
397 // Pattern: G_BUILD_VECTOR $x, $y, 0
398 // MCOIs: [MCOI::OPERAND_GENERIC_0, MCOI::OPERAND_GENERIC_1,
399 // MCOI::OPERAND_GENERIC_1]
400 // $y has the same type as 0, so we can infer $y and get the type 0 should
401 // have.
403 // We infer immediates by looking for a named operand that shares the same
404 // MCOI type.
405 const auto MCOITypes = getMCOIOperandTypes(*CGP);
406 StringRef ImmOpTy = MCOITypes[ImmOpIdx];
408 for (const auto &[Idx, Ty] : enumerate(MCOITypes)) {
409 if (Idx != ImmOpIdx && Ty == ImmOpTy) {
410 const auto &Op = IP.getOperand(Idx);
411 if (!Op.isNamedOperand())
412 continue;
414 // Named operand with the same name, try to infer that.
415 if (PatternType InferTy = inferNamedOperandType(IP, Op.getOperandName(),
416 TECs, /*AllowSelf=*/true))
417 return InferTy;
421 return {};
424 PatternType CombineRuleOperandTypeChecker::inferNamedOperandType(
425 const InstructionPattern &IP, StringRef OpName,
426 const TypeEquivalenceClasses &TECs, bool AllowSelf) const {
427 // This is the simplest possible case, we just need to find a TEC that
428 // contains OpName. Look at all operands in equivalence class and try to
429 // find a suitable one. If `AllowSelf` is true, the operand itself is also
430 // considered suitable.
432 // Check for a def of a matched pattern. This is guaranteed to always
433 // be a register so we can blindly use that.
434 StringRef GoodOpName;
435 for (auto It = TECs.findLeader(OpName); It != TECs.member_end(); ++It) {
436 if (!AllowSelf && *It == OpName)
437 continue;
439 const auto LookupRes = MatchOpTable.lookup(*It);
440 if (LookupRes.Def) // Favor defs
441 return PatternType::getTypeOf(*It);
443 // Otherwise just save this in case we don't find any def.
444 if (GoodOpName.empty() && LookupRes.Found)
445 GoodOpName = *It;
448 if (!GoodOpName.empty())
449 return PatternType::getTypeOf(GoodOpName);
451 // No good operand found, give up.
452 return {};
455 std::vector<std::string> CombineRuleOperandTypeChecker::getMCOIOperandTypes(
456 const CodeGenInstructionPattern &CGP) {
457 // FIXME?: Should we cache this? We call it twice when inferring immediates.
459 static unsigned UnknownTypeIdx = 0;
461 std::vector<std::string> OpTypes;
462 auto &CGI = CGP.getInst();
463 const Record *VarArgsTy =
464 CGI.TheDef->isSubClassOf("GenericInstruction")
465 ? CGI.TheDef->getValueAsOptionalDef("variadicOpsType")
466 : nullptr;
467 std::string VarArgsTyName =
468 VarArgsTy ? ("MCOI::" + VarArgsTy->getValueAsString("OperandType")).str()
469 : ("unknown_type_" + Twine(UnknownTypeIdx++)).str();
471 // First, handle defs.
472 for (unsigned K = 0; K < CGI.Operands.NumDefs; ++K)
473 OpTypes.push_back(CGI.Operands[K].OperandType);
475 // Then, handle variadic defs if there are any.
476 if (CGP.hasVariadicDefs()) {
477 for (unsigned K = CGI.Operands.NumDefs; K < CGP.getNumInstDefs(); ++K)
478 OpTypes.push_back(VarArgsTyName);
481 // If we had variadic defs, the op idx in the pattern won't match the op idx
482 // in the CGI anymore.
483 int CGIOpOffset = int(CGI.Operands.NumDefs) - CGP.getNumInstDefs();
484 assert(CGP.hasVariadicDefs() ? (CGIOpOffset <= 0) : (CGIOpOffset == 0));
486 // Handle all remaining use operands, including variadic ones.
487 for (unsigned K = CGP.getNumInstDefs(); K < CGP.getNumInstOperands(); ++K) {
488 unsigned CGIOpIdx = K + CGIOpOffset;
489 if (CGIOpIdx >= CGI.Operands.size()) {
490 assert(CGP.isVariadic());
491 OpTypes.push_back(VarArgsTyName);
492 } else {
493 OpTypes.push_back(CGI.Operands[CGIOpIdx].OperandType);
497 assert(OpTypes.size() == CGP.operands_size());
498 return OpTypes;
501 void CombineRuleOperandTypeChecker::getInstEqClasses(
502 const InstructionPattern &P, TypeEquivalenceClasses &OutTECs) const {
503 // Determine the TypeEquivalenceClasses by:
504 // - Getting the MCOI Operand Types.
505 // - Creating a Map of MCOI Type -> [Operand Indexes]
506 // - Iterating over the map, filtering types we don't like, and just adding
507 // the array of Operand Indexes to \p OutTECs.
509 // We can only do this on CodeGenInstructions that aren't intrinsics. Other
510 // InstructionPatterns have no type inference information associated with
511 // them.
512 // TODO: We could try to extract some info from CodeGenIntrinsic to
513 // guide inference.
515 // TODO: Could we add some inference information to builtins at least? e.g.
516 // ReplaceReg should always replace with a reg of the same type, for instance.
517 // Though, those patterns are often used alone so it might not be worth the
518 // trouble to infer their types.
519 auto *CGP = dyn_cast<CodeGenInstructionPattern>(&P);
520 if (!CGP || CGP->isIntrinsic())
521 return;
523 const auto MCOITypes = getMCOIOperandTypes(*CGP);
524 assert(MCOITypes.size() == P.operands_size());
526 MapVector<StringRef, SmallVector<unsigned, 0>> TyToOpIdx;
527 for (const auto &[Idx, Ty] : enumerate(MCOITypes))
528 TyToOpIdx[Ty].push_back(Idx);
530 if (DebugTypeInfer)
531 errs() << "\tGroups for " << P.getName() << ":\t";
533 for (const auto &[Ty, Idxs] : TyToOpIdx) {
534 if (!canMCOIOperandTypeBeARegister(Ty))
535 continue;
537 if (DebugTypeInfer)
538 errs() << '[';
539 StringRef Sep = "";
541 // We only collect named operands.
542 StringRef Leader;
543 for (unsigned Idx : Idxs) {
544 const auto &Op = P.getOperand(Idx);
545 if (!Op.isNamedOperand())
546 continue;
548 const auto OpName = Op.getOperandName();
549 if (DebugTypeInfer) {
550 errs() << Sep << OpName;
551 Sep = ", ";
554 if (Leader.empty())
555 OutTECs.insert((Leader = OpName));
556 else
557 OutTECs.unionSets(Leader, OpName);
560 if (DebugTypeInfer)
561 errs() << "] ";
564 if (DebugTypeInfer)
565 errs() << '\n';
568 CombineRuleOperandTypeChecker::TypeEquivalenceClasses
569 CombineRuleOperandTypeChecker::getRuleEqClasses() const {
570 StringMap<unsigned> OpNameToEqClassIdx;
571 TypeEquivalenceClasses TECs;
573 if (DebugTypeInfer)
574 errs() << "Rule Operand Type Equivalence Classes for " << RuleDef.getName()
575 << ":\n";
577 for (const auto *Pat : MatchPats)
578 getInstEqClasses(*Pat, TECs);
579 for (const auto *Pat : ApplyPats)
580 getInstEqClasses(*Pat, TECs);
582 if (DebugTypeInfer) {
583 errs() << "Final Type Equivalence Classes: ";
584 for (auto ClassIt = TECs.begin(); ClassIt != TECs.end(); ++ClassIt) {
585 // only print non-empty classes.
586 if (auto MembIt = TECs.member_begin(ClassIt);
587 MembIt != TECs.member_end()) {
588 errs() << '[';
589 StringRef Sep = "";
590 for (; MembIt != TECs.member_end(); ++MembIt) {
591 errs() << Sep << *MembIt;
592 Sep = ", ";
594 errs() << "] ";
597 errs() << '\n';
600 return TECs;
603 //===- MatchData Handling -------------------------------------------------===//
604 struct MatchDataDef {
605 MatchDataDef(StringRef Symbol, StringRef Type) : Symbol(Symbol), Type(Type) {}
607 StringRef Symbol;
608 StringRef Type;
610 /// \returns the desired variable name for this MatchData.
611 std::string getVarName() const {
612 // Add a prefix in case the symbol name is very generic and conflicts with
613 // something else.
614 return "GIMatchData_" + Symbol.str();
618 //===- CombineRuleBuilder -------------------------------------------------===//
620 /// Parses combine rule and builds a small intermediate representation to tie
621 /// patterns together and emit RuleMatchers to match them. This may emit more
622 /// than one RuleMatcher, e.g. for `wip_match_opcode`.
624 /// Memory management for `Pattern` objects is done through `std::unique_ptr`.
625 /// In most cases, there are two stages to a pattern's lifetime:
626 /// - Creation in a `parse` function
627 /// - The unique_ptr is stored in a variable, and may be destroyed if the
628 /// pattern is found to be semantically invalid.
629 /// - Ownership transfer into a `PatternMap`
630 /// - Once a pattern is moved into either the map of Match or Apply
631 /// patterns, it is known to be valid and it never moves back.
632 class CombineRuleBuilder {
633 public:
634 using PatternMap = MapVector<StringRef, std::unique_ptr<Pattern>>;
635 using PatternAlternatives = DenseMap<const Pattern *, unsigned>;
637 CombineRuleBuilder(const CodeGenTarget &CGT,
638 SubtargetFeatureInfoMap &SubtargetFeatures,
639 const Record &RuleDef, unsigned ID,
640 std::vector<RuleMatcher> &OutRMs)
641 : Parser(CGT, RuleDef.getLoc()), CGT(CGT),
642 SubtargetFeatures(SubtargetFeatures), RuleDef(RuleDef), RuleID(ID),
643 OutRMs(OutRMs) {}
645 /// Parses all fields in the RuleDef record.
646 bool parseAll();
648 /// Emits all RuleMatchers into the vector of RuleMatchers passed in the
649 /// constructor.
650 bool emitRuleMatchers();
652 void print(raw_ostream &OS) const;
653 void dump() const { print(dbgs()); }
655 /// Debug-only verification of invariants.
656 #ifndef NDEBUG
657 void verify() const;
658 #endif
660 private:
661 const CodeGenInstruction &getGConstant() const {
662 return CGT.getInstruction(RuleDef.getRecords().getDef("G_CONSTANT"));
665 std::optional<LLTCodeGenOrTempType>
666 getLLTCodeGenOrTempType(const PatternType &PT, RuleMatcher &RM);
668 void PrintError(Twine Msg) const { ::PrintError(&RuleDef, Msg); }
669 void PrintWarning(Twine Msg) const { ::PrintWarning(RuleDef.getLoc(), Msg); }
670 void PrintNote(Twine Msg) const { ::PrintNote(RuleDef.getLoc(), Msg); }
672 void print(raw_ostream &OS, const PatternAlternatives &Alts) const;
674 bool addApplyPattern(std::unique_ptr<Pattern> Pat);
675 bool addMatchPattern(std::unique_ptr<Pattern> Pat);
677 /// Adds the expansions from \see MatchDatas to \p CE.
678 void declareAllMatchDatasExpansions(CodeExpansions &CE) const;
680 /// Adds a matcher \p P to \p IM, expanding its code using \p CE.
681 /// Note that the predicate is added on the last InstructionMatcher.
683 /// \p Alts is only used if DebugCXXPreds is enabled.
684 void addCXXPredicate(RuleMatcher &M, const CodeExpansions &CE,
685 const CXXPattern &P, const PatternAlternatives &Alts);
687 bool hasOnlyCXXApplyPatterns() const;
688 bool hasEraseRoot() const;
690 // Infer machine operand types and check their consistency.
691 bool typecheckPatterns();
693 /// For all PatFragPatterns, add a new entry in PatternAlternatives for each
694 /// PatternList it contains. This is multiplicative, so if we have 2
695 /// PatFrags with 3 alternatives each, we get 2*3 permutations added to
696 /// PermutationsToEmit. The "MaxPermutations" field controls how many
697 /// permutations are allowed before an error is emitted and this function
698 /// returns false. This is a simple safeguard to prevent combination of
699 /// PatFrags from generating enormous amounts of rules.
700 bool buildPermutationsToEmit();
702 /// Checks additional semantics of the Patterns.
703 bool checkSemantics();
705 /// Creates a new RuleMatcher with some boilerplate
706 /// settings/actions/predicates, and and adds it to \p OutRMs.
707 /// \see addFeaturePredicates too.
709 /// \param Alts Current set of alternatives, for debug comment.
710 /// \param AdditionalComment Comment string to be added to the
711 /// `DebugCommentAction`.
712 RuleMatcher &addRuleMatcher(const PatternAlternatives &Alts,
713 Twine AdditionalComment = "");
714 bool addFeaturePredicates(RuleMatcher &M);
716 bool findRoots();
717 bool buildRuleOperandsTable();
719 bool parseDefs(const DagInit &Def);
721 bool emitMatchPattern(CodeExpansions &CE, const PatternAlternatives &Alts,
722 const InstructionPattern &IP);
723 bool emitMatchPattern(CodeExpansions &CE, const PatternAlternatives &Alts,
724 const AnyOpcodePattern &AOP);
726 bool emitPatFragMatchPattern(CodeExpansions &CE,
727 const PatternAlternatives &Alts, RuleMatcher &RM,
728 InstructionMatcher *IM,
729 const PatFragPattern &PFP,
730 DenseSet<const Pattern *> &SeenPats);
732 bool emitApplyPatterns(CodeExpansions &CE, RuleMatcher &M);
733 bool emitCXXMatchApply(CodeExpansions &CE, RuleMatcher &M,
734 ArrayRef<CXXPattern *> Matchers);
736 // Recursively visits InstructionPatterns from P to build up the
737 // RuleMatcher actions.
738 bool emitInstructionApplyPattern(CodeExpansions &CE, RuleMatcher &M,
739 const InstructionPattern &P,
740 DenseSet<const Pattern *> &SeenPats,
741 StringMap<unsigned> &OperandToTempRegID);
743 bool emitCodeGenInstructionApplyImmOperand(RuleMatcher &M,
744 BuildMIAction &DstMI,
745 const CodeGenInstructionPattern &P,
746 const InstructionOperand &O);
748 bool emitBuiltinApplyPattern(CodeExpansions &CE, RuleMatcher &M,
749 const BuiltinPattern &P,
750 StringMap<unsigned> &OperandToTempRegID);
752 // Recursively visits CodeGenInstructionPattern from P to build up the
753 // RuleMatcher/InstructionMatcher. May create new InstructionMatchers as
754 // needed.
755 using OperandMapperFnRef =
756 function_ref<InstructionOperand(const InstructionOperand &)>;
757 using OperandDefLookupFn =
758 function_ref<const InstructionPattern *(StringRef)>;
759 bool emitCodeGenInstructionMatchPattern(
760 CodeExpansions &CE, const PatternAlternatives &Alts, RuleMatcher &M,
761 InstructionMatcher &IM, const CodeGenInstructionPattern &P,
762 DenseSet<const Pattern *> &SeenPats, OperandDefLookupFn LookupOperandDef,
763 OperandMapperFnRef OperandMapper = [](const auto &O) { return O; });
765 PatternParser Parser;
766 const CodeGenTarget &CGT;
767 SubtargetFeatureInfoMap &SubtargetFeatures;
768 const Record &RuleDef;
769 const unsigned RuleID;
770 std::vector<RuleMatcher> &OutRMs;
772 // For InstructionMatcher::addOperand
773 unsigned AllocatedTemporariesBaseID = 0;
775 /// The root of the pattern.
776 StringRef RootName;
778 /// These maps have ownership of the actual Pattern objects.
779 /// They both map a Pattern's name to the Pattern instance.
780 PatternMap MatchPats;
781 PatternMap ApplyPats;
783 /// Operand tables to tie match/apply patterns together.
784 OperandTable MatchOpTable;
785 OperandTable ApplyOpTable;
787 /// Set by findRoots.
788 Pattern *MatchRoot = nullptr;
789 SmallDenseSet<InstructionPattern *, 2> ApplyRoots;
791 SmallVector<MatchDataDef, 2> MatchDatas;
792 SmallVector<PatternAlternatives, 1> PermutationsToEmit;
795 bool CombineRuleBuilder::parseAll() {
796 auto StackTrace = PrettyStackTraceParse(RuleDef);
798 if (!parseDefs(*RuleDef.getValueAsDag("Defs")))
799 return false;
801 if (!Parser.parsePatternList(
802 *RuleDef.getValueAsDag("Match"),
803 [this](auto Pat) { return addMatchPattern(std::move(Pat)); }, "match",
804 (RuleDef.getName() + "_match").str()))
805 return false;
807 if (!Parser.parsePatternList(
808 *RuleDef.getValueAsDag("Apply"),
809 [this](auto Pat) { return addApplyPattern(std::move(Pat)); }, "apply",
810 (RuleDef.getName() + "_apply").str()))
811 return false;
813 if (!buildRuleOperandsTable() || !typecheckPatterns() || !findRoots() ||
814 !checkSemantics() || !buildPermutationsToEmit())
815 return false;
816 LLVM_DEBUG(verify());
817 return true;
820 bool CombineRuleBuilder::emitRuleMatchers() {
821 auto StackTrace = PrettyStackTraceEmit(RuleDef);
823 assert(MatchRoot);
824 CodeExpansions CE;
826 assert(!PermutationsToEmit.empty());
827 for (const auto &Alts : PermutationsToEmit) {
828 switch (MatchRoot->getKind()) {
829 case Pattern::K_AnyOpcode: {
830 if (!emitMatchPattern(CE, Alts, *cast<AnyOpcodePattern>(MatchRoot)))
831 return false;
832 break;
834 case Pattern::K_PatFrag:
835 case Pattern::K_Builtin:
836 case Pattern::K_CodeGenInstruction:
837 if (!emitMatchPattern(CE, Alts, *cast<InstructionPattern>(MatchRoot)))
838 return false;
839 break;
840 case Pattern::K_CXX:
841 PrintError("C++ code cannot be the root of a rule!");
842 return false;
843 default:
844 llvm_unreachable("unknown pattern kind!");
848 return true;
851 void CombineRuleBuilder::print(raw_ostream &OS) const {
852 OS << "(CombineRule name:" << RuleDef.getName() << " id:" << RuleID
853 << " root:" << RootName << '\n';
855 if (!MatchDatas.empty()) {
856 OS << " (MatchDatas\n";
857 for (const auto &MD : MatchDatas) {
858 OS << " (MatchDataDef symbol:" << MD.Symbol << " type:" << MD.Type
859 << ")\n";
861 OS << " )\n";
864 const auto &SeenPFs = Parser.getSeenPatFrags();
865 if (!SeenPFs.empty()) {
866 OS << " (PatFrags\n";
867 for (const auto *PF : Parser.getSeenPatFrags()) {
868 PF->print(OS, /*Indent=*/" ");
869 OS << '\n';
871 OS << " )\n";
874 const auto DumpPats = [&](StringRef Name, const PatternMap &Pats) {
875 OS << " (" << Name << " ";
876 if (Pats.empty()) {
877 OS << "<empty>)\n";
878 return;
881 OS << '\n';
882 for (const auto &[Name, Pat] : Pats) {
883 OS << " ";
884 if (Pat.get() == MatchRoot)
885 OS << "<match_root>";
886 if (isa<InstructionPattern>(Pat.get()) &&
887 ApplyRoots.contains(cast<InstructionPattern>(Pat.get())))
888 OS << "<apply_root>";
889 OS << Name << ":";
890 Pat->print(OS, /*PrintName=*/false);
891 OS << '\n';
893 OS << " )\n";
896 DumpPats("MatchPats", MatchPats);
897 DumpPats("ApplyPats", ApplyPats);
899 MatchOpTable.print(OS, "MatchPats", /*Indent*/ " ");
900 ApplyOpTable.print(OS, "ApplyPats", /*Indent*/ " ");
902 if (PermutationsToEmit.size() > 1) {
903 OS << " (PermutationsToEmit\n";
904 for (const auto &Perm : PermutationsToEmit) {
905 OS << " ";
906 print(OS, Perm);
907 OS << ",\n";
909 OS << " )\n";
912 OS << ")\n";
915 #ifndef NDEBUG
916 void CombineRuleBuilder::verify() const {
917 const auto VerifyPats = [&](const PatternMap &Pats) {
918 for (const auto &[Name, Pat] : Pats) {
919 if (!Pat)
920 PrintFatalError("null pattern in pattern map!");
922 if (Name != Pat->getName()) {
923 Pat->dump();
924 PrintFatalError("Pattern name mismatch! Map name: " + Name +
925 ", Pat name: " + Pat->getName());
928 // Sanity check: the map should point to the same data as the Pattern.
929 // Both strings are allocated in the pool using insertStrRef.
930 if (Name.data() != Pat->getName().data()) {
931 dbgs() << "Map StringRef: '" << Name << "' @ "
932 << (const void *)Name.data() << '\n';
933 dbgs() << "Pat String: '" << Pat->getName() << "' @ "
934 << (const void *)Pat->getName().data() << '\n';
935 PrintFatalError("StringRef stored in the PatternMap is not referencing "
936 "the same string as its Pattern!");
941 VerifyPats(MatchPats);
942 VerifyPats(ApplyPats);
944 // Check there are no wip_match_opcode patterns in the "apply" patterns.
945 if (any_of(ApplyPats,
946 [&](auto &E) { return isa<AnyOpcodePattern>(E.second.get()); })) {
947 dump();
948 PrintFatalError(
949 "illegal wip_match_opcode pattern in the 'apply' patterns!");
952 // Check there are no nullptrs in ApplyRoots.
953 if (ApplyRoots.contains(nullptr)) {
954 PrintFatalError(
955 "CombineRuleBuilder's ApplyRoots set contains a null pointer!");
958 #endif
960 std::optional<LLTCodeGenOrTempType>
961 CombineRuleBuilder::getLLTCodeGenOrTempType(const PatternType &PT,
962 RuleMatcher &RM) {
963 assert(!PT.isNone());
965 if (PT.isLLT())
966 return getLLTCodeGen(PT);
968 assert(PT.isTypeOf());
969 auto &OM = RM.getOperandMatcher(PT.getTypeOfOpName());
970 if (OM.isVariadic()) {
971 PrintError("type '" + PT.str() + "' is ill-formed: '" +
972 OM.getSymbolicName() + "' is a variadic pack operand");
973 return std::nullopt;
975 return OM.getTempTypeIdx(RM);
978 void CombineRuleBuilder::print(raw_ostream &OS,
979 const PatternAlternatives &Alts) const {
980 SmallVector<std::string, 1> Strings(
981 map_range(Alts, [](const auto &PatAndPerm) {
982 return PatAndPerm.first->getName().str() + "[" +
983 to_string(PatAndPerm.second) + "]";
984 }));
985 // Sort so output is deterministic for tests. Otherwise it's sorted by pointer
986 // values.
987 sort(Strings);
988 OS << "[" << join(Strings, ", ") << "]";
991 bool CombineRuleBuilder::addApplyPattern(std::unique_ptr<Pattern> Pat) {
992 StringRef Name = Pat->getName();
993 if (ApplyPats.contains(Name)) {
994 PrintError("'" + Name + "' apply pattern defined more than once!");
995 return false;
998 if (isa<AnyOpcodePattern>(Pat.get())) {
999 PrintError("'" + Name +
1000 "': wip_match_opcode is not supported in apply patterns");
1001 return false;
1004 if (isa<PatFragPattern>(Pat.get())) {
1005 PrintError("'" + Name + "': using " + PatFrag::ClassName +
1006 " is not supported in apply patterns");
1007 return false;
1010 if (auto *CXXPat = dyn_cast<CXXPattern>(Pat.get()))
1011 CXXPat->setIsApply();
1013 ApplyPats[Name] = std::move(Pat);
1014 return true;
1017 bool CombineRuleBuilder::addMatchPattern(std::unique_ptr<Pattern> Pat) {
1018 StringRef Name = Pat->getName();
1019 if (MatchPats.contains(Name)) {
1020 PrintError("'" + Name + "' match pattern defined more than once!");
1021 return false;
1024 // For now, none of the builtins can appear in 'match'.
1025 if (const auto *BP = dyn_cast<BuiltinPattern>(Pat.get())) {
1026 PrintError("'" + BP->getInstName() +
1027 "' cannot be used in a 'match' pattern");
1028 return false;
1031 MatchPats[Name] = std::move(Pat);
1032 return true;
1035 void CombineRuleBuilder::declareAllMatchDatasExpansions(
1036 CodeExpansions &CE) const {
1037 for (const auto &MD : MatchDatas)
1038 CE.declare(MD.Symbol, MD.getVarName());
1041 void CombineRuleBuilder::addCXXPredicate(RuleMatcher &M,
1042 const CodeExpansions &CE,
1043 const CXXPattern &P,
1044 const PatternAlternatives &Alts) {
1045 // FIXME: Hack so C++ code is executed last. May not work for more complex
1046 // patterns.
1047 auto &IM = *std::prev(M.insnmatchers().end());
1048 auto Loc = RuleDef.getLoc();
1049 const auto AddComment = [&](raw_ostream &OS) {
1050 OS << "// Pattern Alternatives: ";
1051 print(OS, Alts);
1052 OS << '\n';
1054 const auto &ExpandedCode =
1055 DebugCXXPreds ? P.expandCode(CE, Loc, AddComment) : P.expandCode(CE, Loc);
1056 IM->addPredicate<GenericInstructionPredicateMatcher>(
1057 ExpandedCode.getEnumNameWithPrefix(CXXPredPrefix));
1060 bool CombineRuleBuilder::hasOnlyCXXApplyPatterns() const {
1061 return all_of(ApplyPats, [&](auto &Entry) {
1062 return isa<CXXPattern>(Entry.second.get());
1066 bool CombineRuleBuilder::hasEraseRoot() const {
1067 return any_of(ApplyPats, [&](auto &Entry) {
1068 if (const auto *BP = dyn_cast<BuiltinPattern>(Entry.second.get()))
1069 return BP->getBuiltinKind() == BI_EraseRoot;
1070 return false;
1074 bool CombineRuleBuilder::typecheckPatterns() {
1075 CombineRuleOperandTypeChecker OTC(RuleDef, MatchOpTable);
1077 for (auto &Pat : values(MatchPats)) {
1078 if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1079 if (!OTC.processMatchPattern(*IP))
1080 return false;
1084 for (auto &Pat : values(ApplyPats)) {
1085 if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1086 if (!OTC.processApplyPattern(*IP))
1087 return false;
1091 OTC.propagateAndInferTypes();
1093 // Always check this after in case inference adds some special types to the
1094 // match patterns.
1095 for (auto &Pat : values(MatchPats)) {
1096 if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1097 bool HasDiag = false;
1098 for (const auto &[Idx, Op] : enumerate(IP->operands())) {
1099 if (Op.getType().isTypeOf()) {
1100 PrintError(PatternType::TypeOfClassName +
1101 " is not supported in 'match' patterns");
1102 PrintNote("operand " + Twine(Idx) + " of '" + IP->getName() +
1103 "' has type '" + Op.getType().str() + "'");
1104 HasDiag = true;
1107 if (HasDiag)
1108 return false;
1111 return true;
1114 bool CombineRuleBuilder::buildPermutationsToEmit() {
1115 PermutationsToEmit.clear();
1117 // Start with one empty set of alternatives.
1118 PermutationsToEmit.emplace_back();
1119 for (const auto &Pat : values(MatchPats)) {
1120 unsigned NumAlts = 0;
1121 // Note: technically, AnyOpcodePattern also needs permutations, but:
1122 // - We only allow a single one of them in the root.
1123 // - They cannot be mixed with any other pattern other than C++ code.
1124 // So we don't really need to take them into account here. We could, but
1125 // that pattern is a hack anyway and the less it's involved, the better.
1126 if (const auto *PFP = dyn_cast<PatFragPattern>(Pat.get()))
1127 NumAlts = PFP->getPatFrag().num_alternatives();
1128 else
1129 continue;
1131 // For each pattern that needs permutations, multiply the current set of
1132 // alternatives.
1133 auto CurPerms = PermutationsToEmit;
1134 PermutationsToEmit.clear();
1136 for (const auto &Perm : CurPerms) {
1137 assert(!Perm.count(Pat.get()) && "Pattern already emitted?");
1138 for (unsigned K = 0; K < NumAlts; ++K) {
1139 PatternAlternatives NewPerm = Perm;
1140 NewPerm[Pat.get()] = K;
1141 PermutationsToEmit.emplace_back(std::move(NewPerm));
1146 if (int64_t MaxPerms = RuleDef.getValueAsInt("MaxPermutations");
1147 MaxPerms > 0) {
1148 if ((int64_t)PermutationsToEmit.size() > MaxPerms) {
1149 PrintError("cannot emit rule '" + RuleDef.getName() + "'; " +
1150 Twine(PermutationsToEmit.size()) +
1151 " permutations would be emitted, but the max is " +
1152 Twine(MaxPerms));
1153 return false;
1157 // Ensure we always have a single empty entry, it simplifies the emission
1158 // logic so it doesn't need to handle the case where there are no perms.
1159 if (PermutationsToEmit.empty()) {
1160 PermutationsToEmit.emplace_back();
1161 return true;
1164 return true;
1167 bool CombineRuleBuilder::checkSemantics() {
1168 assert(MatchRoot && "Cannot call this before findRoots()");
1170 const auto CheckVariadicOperands = [&](const InstructionPattern &IP,
1171 bool IsMatch) {
1172 bool HasVariadic = false;
1173 for (auto &Op : IP.operands()) {
1174 if (!Op.getType().isVariadicPack())
1175 continue;
1177 HasVariadic = true;
1179 if (IsMatch && &Op != &IP.operands_back()) {
1180 PrintError("'" + IP.getInstName() +
1181 "': " + PatternType::VariadicClassName +
1182 " can only be used on the last operand");
1183 return false;
1186 if (Op.isDef()) {
1187 PrintError("'" + IP.getInstName() + "': " +
1188 PatternType::VariadicClassName + " cannot be used on defs");
1189 return false;
1193 if (HasVariadic && !IP.isVariadic()) {
1194 PrintError("cannot use a " + PatternType::VariadicClassName +
1195 " operand on non-variadic instruction '" + IP.getInstName() +
1196 "'");
1197 return false;
1200 return true;
1203 bool UsesWipMatchOpcode = false;
1204 for (const auto &Match : MatchPats) {
1205 const auto *Pat = Match.second.get();
1207 if (const auto *CXXPat = dyn_cast<CXXPattern>(Pat)) {
1208 if (!CXXPat->getRawCode().contains("return "))
1209 PrintWarning("'match' C++ code does not seem to return!");
1210 continue;
1213 if (const auto IP = dyn_cast<InstructionPattern>(Pat)) {
1214 if (!CheckVariadicOperands(*IP, /*IsMatch=*/true))
1215 return false;
1217 // MIFlags in match cannot use the following syntax: (MIFlags $mi)
1218 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(Pat)) {
1219 if (auto *FI = CGP->getMIFlagsInfo()) {
1220 if (!FI->copy_flags().empty()) {
1221 PrintError("'match' patterns cannot refer to flags from other "
1222 "instructions");
1223 PrintNote("MIFlags in '" + CGP->getName() +
1224 "' refer to: " + join(FI->copy_flags(), ", "));
1225 return false;
1229 continue;
1232 const auto *AOP = dyn_cast<AnyOpcodePattern>(Pat);
1233 if (!AOP)
1234 continue;
1236 if (UsesWipMatchOpcode) {
1237 PrintError("wip_opcode_match can only be present once");
1238 return false;
1241 UsesWipMatchOpcode = true;
1244 std::optional<bool> IsUsingCXXPatterns;
1245 for (const auto &Apply : ApplyPats) {
1246 Pattern *Pat = Apply.second.get();
1247 if (IsUsingCXXPatterns) {
1248 if (*IsUsingCXXPatterns != isa<CXXPattern>(Pat)) {
1249 PrintError("'apply' patterns cannot mix C++ code with other types of "
1250 "patterns");
1251 return false;
1253 } else
1254 IsUsingCXXPatterns = isa<CXXPattern>(Pat);
1256 assert(Pat);
1257 const auto *IP = dyn_cast<InstructionPattern>(Pat);
1258 if (!IP)
1259 continue;
1261 if (!CheckVariadicOperands(*IP, /*IsMatch=*/false))
1262 return false;
1264 if (UsesWipMatchOpcode) {
1265 PrintError("cannot use wip_match_opcode in combination with apply "
1266 "instruction patterns!");
1267 return false;
1270 // Check that the insts mentioned in copy_flags exist.
1271 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(IP)) {
1272 if (auto *FI = CGP->getMIFlagsInfo()) {
1273 for (auto InstName : FI->copy_flags()) {
1274 auto It = MatchPats.find(InstName);
1275 if (It == MatchPats.end()) {
1276 PrintError("unknown instruction '$" + InstName +
1277 "' referenced in MIFlags of '" + CGP->getName() + "'");
1278 return false;
1281 if (!isa<CodeGenInstructionPattern>(It->second.get())) {
1282 PrintError(
1283 "'$" + InstName +
1284 "' does not refer to a CodeGenInstruction in MIFlags of '" +
1285 CGP->getName() + "'");
1286 return false;
1292 const auto *BIP = dyn_cast<BuiltinPattern>(IP);
1293 if (!BIP)
1294 continue;
1295 StringRef Name = BIP->getInstName();
1297 // (GIEraseInst) has to be the only apply pattern, or it can not be used at
1298 // all. The root cannot have any defs either.
1299 switch (BIP->getBuiltinKind()) {
1300 case BI_EraseRoot: {
1301 if (ApplyPats.size() > 1) {
1302 PrintError(Name + " must be the only 'apply' pattern");
1303 return false;
1306 const auto *IRoot = dyn_cast<CodeGenInstructionPattern>(MatchRoot);
1307 if (!IRoot) {
1308 PrintError(Name + " can only be used if the root is a "
1309 "CodeGenInstruction or Intrinsic");
1310 return false;
1313 if (IRoot->getNumInstDefs() != 0) {
1314 PrintError(Name + " can only be used if on roots that do "
1315 "not have any output operand");
1316 PrintNote("'" + IRoot->getInstName() + "' has " +
1317 Twine(IRoot->getNumInstDefs()) + " output operands");
1318 return false;
1320 break;
1322 case BI_ReplaceReg: {
1323 // (GIReplaceReg can only be used on the root instruction)
1324 // TODO: When we allow rewriting non-root instructions, also allow this.
1325 StringRef OldRegName = BIP->getOperand(0).getOperandName();
1326 auto *Def = MatchOpTable.getDef(OldRegName);
1327 if (!Def) {
1328 PrintError(Name + " cannot find a matched pattern that defines '" +
1329 OldRegName + "'");
1330 return false;
1332 if (MatchOpTable.getDef(OldRegName) != MatchRoot) {
1333 PrintError(Name + " cannot replace '" + OldRegName +
1334 "': this builtin can only replace a register defined by the "
1335 "match root");
1336 return false;
1338 break;
1343 if (!hasOnlyCXXApplyPatterns() && !MatchDatas.empty()) {
1344 PrintError(MatchDataClassName +
1345 " can only be used if 'apply' in entirely written in C++");
1346 return false;
1349 return true;
1352 RuleMatcher &CombineRuleBuilder::addRuleMatcher(const PatternAlternatives &Alts,
1353 Twine AdditionalComment) {
1354 auto &RM = OutRMs.emplace_back(RuleDef.getLoc());
1355 addFeaturePredicates(RM);
1356 RM.setPermanentGISelFlags(GISF_IgnoreCopies);
1357 RM.addRequiredSimplePredicate(getIsEnabledPredicateEnumName(RuleID));
1359 std::string Comment;
1360 raw_string_ostream CommentOS(Comment);
1361 CommentOS << "Combiner Rule #" << RuleID << ": " << RuleDef.getName();
1362 if (!Alts.empty()) {
1363 CommentOS << " @ ";
1364 print(CommentOS, Alts);
1366 if (!AdditionalComment.isTriviallyEmpty())
1367 CommentOS << "; " << AdditionalComment;
1368 RM.addAction<DebugCommentAction>(Comment);
1369 return RM;
1372 bool CombineRuleBuilder::addFeaturePredicates(RuleMatcher &M) {
1373 if (!RuleDef.getValue("Predicates"))
1374 return true;
1376 const ListInit *Preds = RuleDef.getValueAsListInit("Predicates");
1377 for (const Init *PI : Preds->getValues()) {
1378 const DefInit *Pred = dyn_cast<DefInit>(PI);
1379 if (!Pred)
1380 continue;
1382 const Record *Def = Pred->getDef();
1383 if (!Def->isSubClassOf("Predicate")) {
1384 ::PrintError(Def, "Unknown 'Predicate' Type");
1385 return false;
1388 if (Def->getValueAsString("CondString").empty())
1389 continue;
1391 if (SubtargetFeatures.count(Def) == 0) {
1392 SubtargetFeatures.emplace(
1393 Def, SubtargetFeatureInfo(Def, SubtargetFeatures.size()));
1396 M.addRequiredFeature(Def);
1399 return true;
1402 bool CombineRuleBuilder::findRoots() {
1403 const auto Finish = [&]() {
1404 assert(MatchRoot);
1406 if (hasOnlyCXXApplyPatterns() || hasEraseRoot())
1407 return true;
1409 auto *IPRoot = dyn_cast<InstructionPattern>(MatchRoot);
1410 if (!IPRoot)
1411 return true;
1413 if (IPRoot->getNumInstDefs() == 0) {
1414 // No defs to work with -> find the root using the pattern name.
1415 auto It = ApplyPats.find(RootName);
1416 if (It == ApplyPats.end()) {
1417 PrintError("Cannot find root '" + RootName + "' in apply patterns!");
1418 return false;
1421 auto *ApplyRoot = dyn_cast<InstructionPattern>(It->second.get());
1422 if (!ApplyRoot) {
1423 PrintError("apply pattern root '" + RootName +
1424 "' must be an instruction pattern");
1425 return false;
1428 ApplyRoots.insert(ApplyRoot);
1429 return true;
1432 // Collect all redefinitions of the MatchRoot's defs and put them in
1433 // ApplyRoots.
1434 const auto DefsNeeded = IPRoot->getApplyDefsNeeded();
1435 for (auto &Op : DefsNeeded) {
1436 assert(Op.isDef() && Op.isNamedOperand());
1437 StringRef Name = Op.getOperandName();
1439 auto *ApplyRedef = ApplyOpTable.getDef(Name);
1440 if (!ApplyRedef) {
1441 PrintError("'" + Name + "' must be redefined in the 'apply' pattern");
1442 return false;
1445 ApplyRoots.insert((InstructionPattern *)ApplyRedef);
1448 if (auto It = ApplyPats.find(RootName); It != ApplyPats.end()) {
1449 if (find(ApplyRoots, It->second.get()) == ApplyRoots.end()) {
1450 PrintError("apply pattern '" + RootName +
1451 "' is supposed to be a root but it does not redefine any of "
1452 "the defs of the match root");
1453 return false;
1457 return true;
1460 // Look by pattern name, e.g.
1461 // (G_FNEG $x, $y):$root
1462 if (auto MatchPatIt = MatchPats.find(RootName);
1463 MatchPatIt != MatchPats.end()) {
1464 MatchRoot = MatchPatIt->second.get();
1465 return Finish();
1468 // Look by def:
1469 // (G_FNEG $root, $y)
1470 auto LookupRes = MatchOpTable.lookup(RootName);
1471 if (!LookupRes.Found) {
1472 PrintError("Cannot find root '" + RootName + "' in match patterns!");
1473 return false;
1476 MatchRoot = LookupRes.Def;
1477 if (!MatchRoot) {
1478 PrintError("Cannot use live-in operand '" + RootName +
1479 "' as match pattern root!");
1480 return false;
1483 return Finish();
1486 bool CombineRuleBuilder::buildRuleOperandsTable() {
1487 const auto DiagnoseRedefMatch = [&](StringRef OpName) {
1488 PrintError("Operand '" + OpName +
1489 "' is defined multiple times in the 'match' patterns");
1492 const auto DiagnoseRedefApply = [&](StringRef OpName) {
1493 PrintError("Operand '" + OpName +
1494 "' is defined multiple times in the 'apply' patterns");
1497 for (auto &Pat : values(MatchPats)) {
1498 auto *IP = dyn_cast<InstructionPattern>(Pat.get());
1499 if (IP && !MatchOpTable.addPattern(IP, DiagnoseRedefMatch))
1500 return false;
1503 for (auto &Pat : values(ApplyPats)) {
1504 auto *IP = dyn_cast<InstructionPattern>(Pat.get());
1505 if (IP && !ApplyOpTable.addPattern(IP, DiagnoseRedefApply))
1506 return false;
1509 return true;
1512 bool CombineRuleBuilder::parseDefs(const DagInit &Def) {
1513 if (Def.getOperatorAsDef(RuleDef.getLoc())->getName() != "defs") {
1514 PrintError("Expected defs operator");
1515 return false;
1518 SmallVector<StringRef> Roots;
1519 for (unsigned I = 0, E = Def.getNumArgs(); I < E; ++I) {
1520 if (isSpecificDef(*Def.getArg(I), "root")) {
1521 Roots.emplace_back(Def.getArgNameStr(I));
1522 continue;
1525 // Subclasses of GIDefMatchData should declare that this rule needs to pass
1526 // data from the match stage to the apply stage, and ensure that the
1527 // generated matcher has a suitable variable for it to do so.
1528 if (const Record *MatchDataRec =
1529 getDefOfSubClass(*Def.getArg(I), MatchDataClassName)) {
1530 MatchDatas.emplace_back(Def.getArgNameStr(I),
1531 MatchDataRec->getValueAsString("Type"));
1532 continue;
1535 // Otherwise emit an appropriate error message.
1536 if (getDefOfSubClass(*Def.getArg(I), "GIDefKind"))
1537 PrintError("This GIDefKind not implemented in tablegen");
1538 else if (getDefOfSubClass(*Def.getArg(I), "GIDefKindWithArgs"))
1539 PrintError("This GIDefKindWithArgs not implemented in tablegen");
1540 else
1541 PrintError("Expected a subclass of GIDefKind or a sub-dag whose "
1542 "operator is of type GIDefKindWithArgs");
1543 return false;
1546 if (Roots.size() != 1) {
1547 PrintError("Combine rules must have exactly one root");
1548 return false;
1551 RootName = Roots.front();
1552 return true;
1555 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions &CE,
1556 const PatternAlternatives &Alts,
1557 const InstructionPattern &IP) {
1558 auto StackTrace = PrettyStackTraceEmit(RuleDef, &IP);
1560 auto &M = addRuleMatcher(Alts);
1561 InstructionMatcher &IM = M.addInstructionMatcher(IP.getName());
1562 declareInstExpansion(CE, IM, IP.getName());
1564 DenseSet<const Pattern *> SeenPats;
1566 const auto FindOperandDef = [&](StringRef Op) -> InstructionPattern * {
1567 return MatchOpTable.getDef(Op);
1570 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(&IP)) {
1571 if (!emitCodeGenInstructionMatchPattern(CE, Alts, M, IM, *CGP, SeenPats,
1572 FindOperandDef))
1573 return false;
1574 } else if (const auto *PFP = dyn_cast<PatFragPattern>(&IP)) {
1575 if (!PFP->getPatFrag().canBeMatchRoot()) {
1576 PrintError("cannot use '" + PFP->getInstName() + " as match root");
1577 return false;
1580 if (!emitPatFragMatchPattern(CE, Alts, M, &IM, *PFP, SeenPats))
1581 return false;
1582 } else if (isa<BuiltinPattern>(&IP)) {
1583 llvm_unreachable("No match builtins known!");
1584 } else
1585 llvm_unreachable("Unknown kind of InstructionPattern!");
1587 // Emit remaining patterns
1588 const bool IsUsingCustomCXXAction = hasOnlyCXXApplyPatterns();
1589 SmallVector<CXXPattern *, 2> CXXMatchers;
1590 for (auto &Pat : values(MatchPats)) {
1591 if (SeenPats.contains(Pat.get()))
1592 continue;
1594 switch (Pat->getKind()) {
1595 case Pattern::K_AnyOpcode:
1596 PrintError("wip_match_opcode can not be used with instruction patterns!");
1597 return false;
1598 case Pattern::K_PatFrag: {
1599 if (!emitPatFragMatchPattern(CE, Alts, M, /*IM*/ nullptr,
1600 *cast<PatFragPattern>(Pat.get()), SeenPats))
1601 return false;
1602 continue;
1604 case Pattern::K_Builtin:
1605 PrintError("No known match builtins");
1606 return false;
1607 case Pattern::K_CodeGenInstruction:
1608 cast<InstructionPattern>(Pat.get())->reportUnreachable(RuleDef.getLoc());
1609 return false;
1610 case Pattern::K_CXX: {
1611 // Delay emission for top-level C++ matchers (which can use MatchDatas).
1612 if (IsUsingCustomCXXAction)
1613 CXXMatchers.push_back(cast<CXXPattern>(Pat.get()));
1614 else
1615 addCXXPredicate(M, CE, *cast<CXXPattern>(Pat.get()), Alts);
1616 continue;
1618 default:
1619 llvm_unreachable("unknown pattern kind!");
1623 return IsUsingCustomCXXAction ? emitCXXMatchApply(CE, M, CXXMatchers)
1624 : emitApplyPatterns(CE, M);
1627 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions &CE,
1628 const PatternAlternatives &Alts,
1629 const AnyOpcodePattern &AOP) {
1630 auto StackTrace = PrettyStackTraceEmit(RuleDef, &AOP);
1632 const bool IsUsingCustomCXXAction = hasOnlyCXXApplyPatterns();
1633 for (const CodeGenInstruction *CGI : AOP.insts()) {
1634 auto &M = addRuleMatcher(Alts, "wip_match_opcode '" +
1635 CGI->TheDef->getName() + "'");
1637 InstructionMatcher &IM = M.addInstructionMatcher(AOP.getName());
1638 declareInstExpansion(CE, IM, AOP.getName());
1639 // declareInstExpansion needs to be identical, otherwise we need to create a
1640 // CodeExpansions object here instead.
1641 assert(IM.getInsnVarID() == 0);
1643 IM.addPredicate<InstructionOpcodeMatcher>(CGI);
1645 // Emit remaining patterns.
1646 SmallVector<CXXPattern *, 2> CXXMatchers;
1647 for (auto &Pat : values(MatchPats)) {
1648 if (Pat.get() == &AOP)
1649 continue;
1651 switch (Pat->getKind()) {
1652 case Pattern::K_AnyOpcode:
1653 PrintError("wip_match_opcode can only be present once!");
1654 return false;
1655 case Pattern::K_PatFrag: {
1656 DenseSet<const Pattern *> SeenPats;
1657 if (!emitPatFragMatchPattern(CE, Alts, M, /*IM*/ nullptr,
1658 *cast<PatFragPattern>(Pat.get()),
1659 SeenPats))
1660 return false;
1661 continue;
1663 case Pattern::K_Builtin:
1664 PrintError("No known match builtins");
1665 return false;
1666 case Pattern::K_CodeGenInstruction:
1667 cast<InstructionPattern>(Pat.get())->reportUnreachable(
1668 RuleDef.getLoc());
1669 return false;
1670 case Pattern::K_CXX: {
1671 // Delay emission for top-level C++ matchers (which can use MatchDatas).
1672 if (IsUsingCustomCXXAction)
1673 CXXMatchers.push_back(cast<CXXPattern>(Pat.get()));
1674 else
1675 addCXXPredicate(M, CE, *cast<CXXPattern>(Pat.get()), Alts);
1676 break;
1678 default:
1679 llvm_unreachable("unknown pattern kind!");
1683 const bool Res = IsUsingCustomCXXAction
1684 ? emitCXXMatchApply(CE, M, CXXMatchers)
1685 : emitApplyPatterns(CE, M);
1686 if (!Res)
1687 return false;
1690 return true;
1693 bool CombineRuleBuilder::emitPatFragMatchPattern(
1694 CodeExpansions &CE, const PatternAlternatives &Alts, RuleMatcher &RM,
1695 InstructionMatcher *IM, const PatFragPattern &PFP,
1696 DenseSet<const Pattern *> &SeenPats) {
1697 auto StackTrace = PrettyStackTraceEmit(RuleDef, &PFP);
1699 if (!SeenPats.insert(&PFP).second)
1700 return true;
1702 const auto &PF = PFP.getPatFrag();
1704 if (!IM) {
1705 // When we don't have an IM, this means this PatFrag isn't reachable from
1706 // the root. This is only acceptable if it doesn't define anything (e.g. a
1707 // pure C++ PatFrag).
1708 if (PF.num_out_params() != 0) {
1709 PFP.reportUnreachable(RuleDef.getLoc());
1710 return false;
1712 } else {
1713 // When an IM is provided, this is reachable from the root, and we're
1714 // expecting to have output operands.
1715 // TODO: If we want to allow for multiple roots we'll need a map of IMs
1716 // then, and emission becomes a bit more complicated.
1717 assert(PF.num_roots() == 1);
1720 CodeExpansions PatFragCEs;
1721 if (!PFP.mapInputCodeExpansions(CE, PatFragCEs, RuleDef.getLoc()))
1722 return false;
1724 // List of {ParamName, ArgName}.
1725 // When all patterns have been emitted, find expansions in PatFragCEs named
1726 // ArgName and add their expansion to CE using ParamName as the key.
1727 SmallVector<std::pair<std::string, std::string>, 4> CEsToImport;
1729 // Map parameter names to the actual argument.
1730 const auto OperandMapper =
1731 [&](const InstructionOperand &O) -> InstructionOperand {
1732 if (!O.isNamedOperand())
1733 return O;
1735 StringRef ParamName = O.getOperandName();
1737 // Not sure what to do with those tbh. They should probably never be here.
1738 assert(!O.isNamedImmediate() && "TODO: handle named imms");
1739 unsigned PIdx = PF.getParamIdx(ParamName);
1741 // Map parameters to the argument values.
1742 if (PIdx == (unsigned)-1) {
1743 // This is a temp of the PatFragPattern, prefix the name to avoid
1744 // conflicts.
1745 return O.withNewName(
1746 insertStrRef((PFP.getName() + "." + ParamName).str()));
1749 // The operand will be added to PatFragCEs's code expansions using the
1750 // parameter's name. If it's bound to some operand during emission of the
1751 // patterns, we'll want to add it to CE.
1752 auto ArgOp = PFP.getOperand(PIdx);
1753 if (ArgOp.isNamedOperand())
1754 CEsToImport.emplace_back(ArgOp.getOperandName().str(), ParamName);
1756 if (ArgOp.getType() && O.getType() && ArgOp.getType() != O.getType()) {
1757 StringRef PFName = PF.getName();
1758 PrintWarning("impossible type constraints: operand " + Twine(PIdx) +
1759 " of '" + PFP.getName() + "' has type '" +
1760 ArgOp.getType().str() + "', but '" + PFName +
1761 "' constrains it to '" + O.getType().str() + "'");
1762 if (ArgOp.isNamedOperand())
1763 PrintNote("operand " + Twine(PIdx) + " of '" + PFP.getName() +
1764 "' is '" + ArgOp.getOperandName() + "'");
1765 if (O.isNamedOperand())
1766 PrintNote("argument " + Twine(PIdx) + " of '" + PFName + "' is '" +
1767 ParamName + "'");
1770 return ArgOp;
1773 // PatFragPatterns are only made of InstructionPatterns or CXXPatterns.
1774 // Emit instructions from the root.
1775 const auto &FragAlt = PF.getAlternative(Alts.lookup(&PFP));
1776 const auto &FragAltOT = FragAlt.OpTable;
1777 const auto LookupOperandDef =
1778 [&](StringRef Op) -> const InstructionPattern * {
1779 return FragAltOT.getDef(Op);
1782 DenseSet<const Pattern *> PatFragSeenPats;
1783 for (const auto &[Idx, InOp] : enumerate(PF.out_params())) {
1784 if (InOp.Kind != PatFrag::PK_Root)
1785 continue;
1787 StringRef ParamName = InOp.Name;
1788 const auto *Def = FragAltOT.getDef(ParamName);
1789 assert(Def && "PatFrag::checkSemantics should have emitted an error if "
1790 "an out operand isn't defined!");
1791 assert(isa<CodeGenInstructionPattern>(Def) &&
1792 "Nested PatFrags not supported yet");
1794 if (!emitCodeGenInstructionMatchPattern(
1795 PatFragCEs, Alts, RM, *IM, *cast<CodeGenInstructionPattern>(Def),
1796 PatFragSeenPats, LookupOperandDef, OperandMapper))
1797 return false;
1800 // Emit leftovers.
1801 for (const auto &Pat : FragAlt.Pats) {
1802 if (PatFragSeenPats.contains(Pat.get()))
1803 continue;
1805 if (const auto *CXXPat = dyn_cast<CXXPattern>(Pat.get())) {
1806 addCXXPredicate(RM, PatFragCEs, *CXXPat, Alts);
1807 continue;
1810 if (const auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1811 IP->reportUnreachable(PF.getLoc());
1812 return false;
1815 llvm_unreachable("Unexpected pattern kind in PatFrag");
1818 for (const auto &[ParamName, ArgName] : CEsToImport) {
1819 // Note: we're find if ParamName already exists. It just means it's been
1820 // bound before, so we prefer to keep the first binding.
1821 CE.declare(ParamName, PatFragCEs.lookup(ArgName));
1824 return true;
1827 bool CombineRuleBuilder::emitApplyPatterns(CodeExpansions &CE, RuleMatcher &M) {
1828 assert(MatchDatas.empty());
1830 DenseSet<const Pattern *> SeenPats;
1831 StringMap<unsigned> OperandToTempRegID;
1833 for (auto *ApplyRoot : ApplyRoots) {
1834 assert(isa<InstructionPattern>(ApplyRoot) &&
1835 "Root can only be a InstructionPattern!");
1836 if (!emitInstructionApplyPattern(CE, M,
1837 cast<InstructionPattern>(*ApplyRoot),
1838 SeenPats, OperandToTempRegID))
1839 return false;
1842 for (auto &Pat : values(ApplyPats)) {
1843 if (SeenPats.contains(Pat.get()))
1844 continue;
1846 switch (Pat->getKind()) {
1847 case Pattern::K_AnyOpcode:
1848 llvm_unreachable("Unexpected pattern in apply!");
1849 case Pattern::K_PatFrag:
1850 // TODO: We could support pure C++ PatFrags as a temporary thing.
1851 llvm_unreachable("Unexpected pattern in apply!");
1852 case Pattern::K_Builtin:
1853 if (!emitInstructionApplyPattern(CE, M, cast<BuiltinPattern>(*Pat),
1854 SeenPats, OperandToTempRegID))
1855 return false;
1856 break;
1857 case Pattern::K_CodeGenInstruction:
1858 cast<CodeGenInstructionPattern>(*Pat).reportUnreachable(RuleDef.getLoc());
1859 return false;
1860 case Pattern::K_CXX: {
1861 llvm_unreachable(
1862 "CXX Pattern Emission should have been handled earlier!");
1864 default:
1865 llvm_unreachable("unknown pattern kind!");
1869 // Erase the root.
1870 unsigned RootInsnID =
1871 M.getInsnVarID(M.getInstructionMatcher(MatchRoot->getName()));
1872 M.addAction<EraseInstAction>(RootInsnID);
1874 return true;
1877 bool CombineRuleBuilder::emitCXXMatchApply(CodeExpansions &CE, RuleMatcher &M,
1878 ArrayRef<CXXPattern *> Matchers) {
1879 assert(hasOnlyCXXApplyPatterns());
1880 declareAllMatchDatasExpansions(CE);
1882 std::string CodeStr;
1883 raw_string_ostream OS(CodeStr);
1885 for (auto &MD : MatchDatas)
1886 OS << MD.Type << " " << MD.getVarName() << ";\n";
1888 if (!Matchers.empty()) {
1889 OS << "// Match Patterns\n";
1890 for (auto *M : Matchers) {
1891 OS << "if(![&](){";
1892 CodeExpander Expander(M->getRawCode(), CE, RuleDef.getLoc(),
1893 /*ShowExpansions=*/false);
1894 Expander.emit(OS);
1895 OS << "}()) {\n"
1896 << " return false;\n}\n";
1900 OS << "// Apply Patterns\n";
1901 ListSeparator LS("\n");
1902 for (auto &Pat : ApplyPats) {
1903 auto *CXXPat = cast<CXXPattern>(Pat.second.get());
1904 CodeExpander Expander(CXXPat->getRawCode(), CE, RuleDef.getLoc(),
1905 /*ShowExpansions=*/false);
1906 OS << LS;
1907 Expander.emit(OS);
1910 const auto &Code = CXXPredicateCode::getCustomActionCode(CodeStr);
1911 M.setCustomCXXAction(Code.getEnumNameWithPrefix(CXXCustomActionPrefix));
1912 return true;
1915 bool CombineRuleBuilder::emitInstructionApplyPattern(
1916 CodeExpansions &CE, RuleMatcher &M, const InstructionPattern &P,
1917 DenseSet<const Pattern *> &SeenPats,
1918 StringMap<unsigned> &OperandToTempRegID) {
1919 auto StackTrace = PrettyStackTraceEmit(RuleDef, &P);
1921 if (!SeenPats.insert(&P).second)
1922 return true;
1924 // First, render the uses.
1925 for (auto &Op : P.named_operands()) {
1926 if (Op.isDef())
1927 continue;
1929 StringRef OpName = Op.getOperandName();
1930 if (const auto *DefPat = ApplyOpTable.getDef(OpName)) {
1931 if (!emitInstructionApplyPattern(CE, M, *DefPat, SeenPats,
1932 OperandToTempRegID))
1933 return false;
1934 } else {
1935 // If we have no def, check this exists in the MatchRoot.
1936 if (!Op.isNamedImmediate() && !MatchOpTable.lookup(OpName).Found) {
1937 PrintError("invalid output operand '" + OpName +
1938 "': operand is not a live-in of the match pattern, and it "
1939 "has no definition");
1940 return false;
1945 if (const auto *BP = dyn_cast<BuiltinPattern>(&P))
1946 return emitBuiltinApplyPattern(CE, M, *BP, OperandToTempRegID);
1948 if (isa<PatFragPattern>(&P))
1949 llvm_unreachable("PatFragPatterns is not supported in 'apply'!");
1951 auto &CGIP = cast<CodeGenInstructionPattern>(P);
1953 // Now render this inst.
1954 auto &DstMI =
1955 M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &CGIP.getInst());
1957 bool HasEmittedIntrinsicID = false;
1958 const auto EmitIntrinsicID = [&]() {
1959 assert(CGIP.isIntrinsic());
1960 DstMI.addRenderer<IntrinsicIDRenderer>(CGIP.getIntrinsic());
1961 HasEmittedIntrinsicID = true;
1964 for (auto &Op : P.operands()) {
1965 // Emit the intrinsic ID after the last def.
1966 if (CGIP.isIntrinsic() && !Op.isDef() && !HasEmittedIntrinsicID)
1967 EmitIntrinsicID();
1969 if (Op.isNamedImmediate()) {
1970 PrintError("invalid output operand '" + Op.getOperandName() +
1971 "': output immediates cannot be named");
1972 PrintNote("while emitting pattern '" + P.getName() + "' (" +
1973 P.getInstName() + ")");
1974 return false;
1977 if (Op.hasImmValue()) {
1978 if (!emitCodeGenInstructionApplyImmOperand(M, DstMI, CGIP, Op))
1979 return false;
1980 continue;
1983 StringRef OpName = Op.getOperandName();
1985 // Uses of operand.
1986 if (!Op.isDef()) {
1987 if (auto It = OperandToTempRegID.find(OpName);
1988 It != OperandToTempRegID.end()) {
1989 assert(!MatchOpTable.lookup(OpName).Found &&
1990 "Temp reg is also from match pattern?");
1991 DstMI.addRenderer<TempRegRenderer>(It->second);
1992 } else {
1993 // This should be a match live in or a redef of a matched instr.
1994 // If it's a use of a temporary register, then we messed up somewhere -
1995 // the previous condition should have passed.
1996 assert(MatchOpTable.lookup(OpName).Found &&
1997 !ApplyOpTable.getDef(OpName) && "Temp reg not emitted yet!");
1998 DstMI.addRenderer<CopyRenderer>(OpName);
2000 continue;
2003 // Determine what we're dealing with. Are we replacing a matched
2004 // instruction? Creating a new one?
2005 auto OpLookupRes = MatchOpTable.lookup(OpName);
2006 if (OpLookupRes.Found) {
2007 if (OpLookupRes.isLiveIn()) {
2008 // live-in of the match pattern.
2009 PrintError("Cannot define live-in operand '" + OpName +
2010 "' in the 'apply' pattern");
2011 return false;
2013 assert(OpLookupRes.Def);
2015 // TODO: Handle this. We need to mutate the instr, or delete the old
2016 // one.
2017 // Likewise, we also need to ensure we redef everything, if the
2018 // instr has more than one def, we need to redef all or nothing.
2019 if (OpLookupRes.Def != MatchRoot) {
2020 PrintError("redefining an instruction other than the root is not "
2021 "supported (operand '" +
2022 OpName + "')");
2023 return false;
2025 // redef of a match
2026 DstMI.addRenderer<CopyRenderer>(OpName);
2027 continue;
2030 // Define a new register unique to the apply patterns (AKA a "temp"
2031 // register).
2032 unsigned TempRegID;
2033 if (auto It = OperandToTempRegID.find(OpName);
2034 It != OperandToTempRegID.end()) {
2035 TempRegID = It->second;
2036 } else {
2037 // This is a brand new register.
2038 TempRegID = M.allocateTempRegID();
2039 OperandToTempRegID[OpName] = TempRegID;
2040 const auto Ty = Op.getType();
2041 if (!Ty) {
2042 PrintError("def of a new register '" + OpName +
2043 "' in the apply patterns must have a type");
2044 return false;
2047 declareTempRegExpansion(CE, TempRegID, OpName);
2048 // Always insert the action at the beginning, otherwise we may end up
2049 // using the temp reg before it's available.
2050 auto Result = getLLTCodeGenOrTempType(Ty, M);
2051 if (!Result)
2052 return false;
2053 M.insertAction<MakeTempRegisterAction>(M.actions_begin(), *Result,
2054 TempRegID);
2057 DstMI.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true);
2060 // Some intrinsics have no in operands, ensure the ID is still emitted in such
2061 // cases.
2062 if (CGIP.isIntrinsic() && !HasEmittedIntrinsicID)
2063 EmitIntrinsicID();
2065 // Render MIFlags
2066 if (const auto *FI = CGIP.getMIFlagsInfo()) {
2067 for (StringRef InstName : FI->copy_flags())
2068 DstMI.addCopiedMIFlags(M.getInstructionMatcher(InstName));
2069 for (StringRef F : FI->set_flags())
2070 DstMI.addSetMIFlags(F);
2071 for (StringRef F : FI->unset_flags())
2072 DstMI.addUnsetMIFlags(F);
2075 // Don't allow mutating opcodes for GISel combiners. We want a more precise
2076 // handling of MIFlags so we require them to be explicitly preserved.
2078 // TODO: We don't mutate very often, if at all in combiners, but it'd be nice
2079 // to re-enable this. We'd then need to always clear MIFlags when mutating
2080 // opcodes, and never mutate an inst that we copy flags from.
2081 // DstMI.chooseInsnToMutate(M);
2082 declareInstExpansion(CE, DstMI, P.getName());
2084 return true;
2087 bool CombineRuleBuilder::emitCodeGenInstructionApplyImmOperand(
2088 RuleMatcher &M, BuildMIAction &DstMI, const CodeGenInstructionPattern &P,
2089 const InstructionOperand &O) {
2090 // If we have a type, we implicitly emit a G_CONSTANT, except for G_CONSTANT
2091 // itself where we emit a CImm.
2093 // No type means we emit a simple imm.
2094 // G_CONSTANT is a special case and needs a CImm though so this is likely a
2095 // mistake.
2096 const bool isGConstant = P.is("G_CONSTANT");
2097 const auto Ty = O.getType();
2098 if (!Ty) {
2099 if (isGConstant) {
2100 PrintError("'G_CONSTANT' immediate must be typed!");
2101 PrintNote("while emitting pattern '" + P.getName() + "' (" +
2102 P.getInstName() + ")");
2103 return false;
2106 DstMI.addRenderer<ImmRenderer>(O.getImmValue());
2107 return true;
2110 auto ImmTy = getLLTCodeGenOrTempType(Ty, M);
2111 if (!ImmTy)
2112 return false;
2114 if (isGConstant) {
2115 DstMI.addRenderer<ImmRenderer>(O.getImmValue(), *ImmTy);
2116 return true;
2119 unsigned TempRegID = M.allocateTempRegID();
2120 // Ensure MakeTempReg & the BuildConstantAction occur at the beginning.
2121 auto InsertIt = M.insertAction<MakeTempRegisterAction>(M.actions_begin(),
2122 *ImmTy, TempRegID);
2123 M.insertAction<BuildConstantAction>(++InsertIt, TempRegID, O.getImmValue());
2124 DstMI.addRenderer<TempRegRenderer>(TempRegID);
2125 return true;
2128 bool CombineRuleBuilder::emitBuiltinApplyPattern(
2129 CodeExpansions &CE, RuleMatcher &M, const BuiltinPattern &P,
2130 StringMap<unsigned> &OperandToTempRegID) {
2131 const auto Error = [&](Twine Reason) {
2132 PrintError("cannot emit '" + P.getInstName() + "' builtin: " + Reason);
2133 return false;
2136 switch (P.getBuiltinKind()) {
2137 case BI_EraseRoot: {
2138 // Root is always inst 0.
2139 M.addAction<EraseInstAction>(/*InsnID*/ 0);
2140 return true;
2142 case BI_ReplaceReg: {
2143 StringRef Old = P.getOperand(0).getOperandName();
2144 StringRef New = P.getOperand(1).getOperandName();
2146 if (!ApplyOpTable.lookup(New).Found && !MatchOpTable.lookup(New).Found)
2147 return Error("unknown operand '" + Old + "'");
2149 auto &OldOM = M.getOperandMatcher(Old);
2150 if (auto It = OperandToTempRegID.find(New);
2151 It != OperandToTempRegID.end()) {
2152 // Replace with temp reg.
2153 M.addAction<ReplaceRegAction>(OldOM.getInsnVarID(), OldOM.getOpIdx(),
2154 It->second);
2155 } else {
2156 // Replace with matched reg.
2157 auto &NewOM = M.getOperandMatcher(New);
2158 M.addAction<ReplaceRegAction>(OldOM.getInsnVarID(), OldOM.getOpIdx(),
2159 NewOM.getInsnVarID(), NewOM.getOpIdx());
2161 // checkSemantics should have ensured that we can only rewrite the root.
2162 // Ensure we're deleting it.
2163 assert(MatchOpTable.getDef(Old) == MatchRoot);
2164 return true;
2168 llvm_unreachable("Unknown BuiltinKind!");
2171 bool isLiteralImm(const InstructionPattern &P, unsigned OpIdx) {
2172 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(&P)) {
2173 StringRef InstName = CGP->getInst().TheDef->getName();
2174 return (InstName == "G_CONSTANT" || InstName == "G_FCONSTANT") &&
2175 OpIdx == 1;
2178 llvm_unreachable("TODO");
2181 bool CombineRuleBuilder::emitCodeGenInstructionMatchPattern(
2182 CodeExpansions &CE, const PatternAlternatives &Alts, RuleMatcher &M,
2183 InstructionMatcher &IM, const CodeGenInstructionPattern &P,
2184 DenseSet<const Pattern *> &SeenPats, OperandDefLookupFn LookupOperandDef,
2185 OperandMapperFnRef OperandMapper) {
2186 auto StackTrace = PrettyStackTraceEmit(RuleDef, &P);
2188 if (!SeenPats.insert(&P).second)
2189 return true;
2191 IM.addPredicate<InstructionOpcodeMatcher>(&P.getInst());
2192 declareInstExpansion(CE, IM, P.getName());
2194 // If this is an intrinsic, check the intrinsic ID.
2195 if (P.isIntrinsic()) {
2196 // The IntrinsicID's operand is the first operand after the defs.
2197 OperandMatcher &OM = IM.addOperand(P.getNumInstDefs(), "$intrinsic_id",
2198 AllocatedTemporariesBaseID++);
2199 OM.addPredicate<IntrinsicIDOperandMatcher>(P.getIntrinsic());
2202 // Check flags if needed.
2203 if (const auto *FI = P.getMIFlagsInfo()) {
2204 assert(FI->copy_flags().empty());
2206 if (const auto &SetF = FI->set_flags(); !SetF.empty())
2207 IM.addPredicate<MIFlagsInstructionPredicateMatcher>(SetF.getArrayRef());
2208 if (const auto &UnsetF = FI->unset_flags(); !UnsetF.empty())
2209 IM.addPredicate<MIFlagsInstructionPredicateMatcher>(UnsetF.getArrayRef(),
2210 /*CheckNot=*/true);
2213 for (auto [Idx, OriginalO] : enumerate(P.operands())) {
2214 // Remap the operand. This is used when emitting InstructionPatterns inside
2215 // PatFrags, so it can remap them to the arguments passed to the pattern.
2217 // We use the remapped operand to emit immediates, and for the symbolic
2218 // operand names (in IM.addOperand). CodeExpansions and OperandTable lookups
2219 // still use the original name.
2221 // The "def" flag on the remapped operand is always ignored.
2222 auto RemappedO = OperandMapper(OriginalO);
2223 assert(RemappedO.isNamedOperand() == OriginalO.isNamedOperand() &&
2224 "Cannot remap an unnamed operand to a named one!");
2226 const auto Ty = RemappedO.getType();
2228 const auto OpName =
2229 RemappedO.isNamedOperand() ? RemappedO.getOperandName().str() : "";
2231 // For intrinsics, the first use operand is the intrinsic id, so the true
2232 // operand index is shifted by 1.
2234 // From now on:
2235 // Idx = index in the pattern operand list.
2236 // RealIdx = expected index in the MachineInstr.
2237 const unsigned RealIdx =
2238 (P.isIntrinsic() && !OriginalO.isDef()) ? (Idx + 1) : Idx;
2240 if (Ty.isVariadicPack() && M.hasOperand(OpName)) {
2241 // TODO: We could add some CheckIsSameOperand opcode variant that checks
2242 // all operands. We could also just emit a C++ code snippet lazily to do
2243 // the check since it's probably fairly rare that we need to do it.
2245 // I'm just not sure it's worth the effort at this stage.
2246 PrintError("each instance of a " + PatternType::VariadicClassName +
2247 " operand must have a unique name within the match patterns");
2248 PrintNote("'" + OpName + "' is used multiple times");
2249 return false;
2252 OperandMatcher &OM =
2253 IM.addOperand(RealIdx, OpName, AllocatedTemporariesBaseID++,
2254 /*IsVariadic=*/Ty.isVariadicPack());
2255 if (!OpName.empty())
2256 declareOperandExpansion(CE, OM, OriginalO.getOperandName());
2258 if (Ty.isVariadicPack()) {
2259 // In the presence of variadics, the InstructionMatcher won't insert a
2260 // InstructionNumOperandsMatcher implicitly, so we have to emit our own.
2261 assert((Idx + 1) == P.operands_size() &&
2262 "VariadicPack isn't last operand!");
2263 auto VPTI = Ty.getVariadicPackTypeInfo();
2264 assert(VPTI.Min > 0 && (VPTI.Max == 0 || VPTI.Max > VPTI.Min));
2265 IM.addPredicate<InstructionNumOperandsMatcher>(
2266 RealIdx + VPTI.Min, InstructionNumOperandsMatcher::CheckKind::GE);
2267 if (VPTI.Max) {
2268 IM.addPredicate<InstructionNumOperandsMatcher>(
2269 RealIdx + VPTI.Max, InstructionNumOperandsMatcher::CheckKind::LE);
2271 break;
2274 // Handle immediates.
2275 if (RemappedO.hasImmValue()) {
2276 if (isLiteralImm(P, Idx))
2277 OM.addPredicate<LiteralIntOperandMatcher>(RemappedO.getImmValue());
2278 else
2279 OM.addPredicate<ConstantIntOperandMatcher>(RemappedO.getImmValue());
2282 // Handle typed operands, but only bother to check if it hasn't been done
2283 // before.
2285 // getOperandMatcher will always return the first OM to have been created
2286 // for that Operand. "OM" here is always a new OperandMatcher.
2288 // Always emit a check for unnamed operands.
2289 if (Ty && (OpName.empty() ||
2290 !M.getOperandMatcher(OpName).contains<LLTOperandMatcher>())) {
2291 // TODO: We could support GITypeOf here on the condition that the
2292 // OperandMatcher exists already. Though it's clunky to make this work
2293 // and isn't all that useful so it's just rejected in typecheckPatterns
2294 // at this time.
2295 assert(Ty.isLLT());
2296 OM.addPredicate<LLTOperandMatcher>(getLLTCodeGen(Ty));
2299 // Stop here if the operand is a def, or if it had no name.
2300 if (OriginalO.isDef() || !OriginalO.isNamedOperand())
2301 continue;
2303 const auto *DefPat = LookupOperandDef(OriginalO.getOperandName());
2304 if (!DefPat)
2305 continue;
2307 if (OriginalO.hasImmValue()) {
2308 assert(!OpName.empty());
2309 // This is a named immediate that also has a def, that's not okay.
2310 // e.g.
2311 // (G_SEXT $y, (i32 0))
2312 // (COPY $x, 42:$y)
2313 PrintError("'" + OpName +
2314 "' is a named immediate, it cannot be defined by another "
2315 "instruction");
2316 PrintNote("'" + OpName + "' is defined by '" + DefPat->getName() + "'");
2317 return false;
2320 // From here we know that the operand defines an instruction, and we need to
2321 // emit it.
2322 auto InstOpM =
2323 OM.addPredicate<InstructionOperandMatcher>(M, DefPat->getName());
2324 if (!InstOpM) {
2325 // TODO: copy-pasted from GlobalISelEmitter.cpp. Is it still relevant
2326 // here?
2327 PrintError("Nested instruction '" + DefPat->getName() +
2328 "' cannot be the same as another operand '" +
2329 OriginalO.getOperandName() + "'");
2330 return false;
2333 auto &IM = (*InstOpM)->getInsnMatcher();
2334 if (const auto *CGIDef = dyn_cast<CodeGenInstructionPattern>(DefPat)) {
2335 if (!emitCodeGenInstructionMatchPattern(CE, Alts, M, IM, *CGIDef,
2336 SeenPats, LookupOperandDef,
2337 OperandMapper))
2338 return false;
2339 continue;
2342 if (const auto *PFPDef = dyn_cast<PatFragPattern>(DefPat)) {
2343 if (!emitPatFragMatchPattern(CE, Alts, M, &IM, *PFPDef, SeenPats))
2344 return false;
2345 continue;
2348 llvm_unreachable("unknown type of InstructionPattern");
2351 return true;
2354 //===- GICombinerEmitter --------------------------------------------------===//
2356 /// Main implementation class. This emits the tablegenerated output.
2358 /// It collects rules, uses `CombineRuleBuilder` to parse them and accumulate
2359 /// RuleMatchers, then takes all the necessary state/data from the various
2360 /// static storage pools and wires them together to emit the match table &
2361 /// associated function/data structures.
2362 class GICombinerEmitter final : public GlobalISelMatchTableExecutorEmitter {
2363 const RecordKeeper &Records;
2364 StringRef Name;
2365 const CodeGenTarget &Target;
2366 const Record *Combiner;
2367 unsigned NextRuleID = 0;
2369 // List all combine rules (ID, name) imported.
2370 // Note that the combiner rule ID is different from the RuleMatcher ID. The
2371 // latter is internal to the MatchTable, the former is the canonical ID of the
2372 // combine rule used to disable/enable it.
2373 std::vector<std::pair<unsigned, std::string>> AllCombineRules;
2375 // Keep track of all rules we've seen so far to ensure we don't process
2376 // the same rule twice.
2377 StringSet<> RulesSeen;
2379 MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules);
2381 void emitRuleConfigImpl(raw_ostream &OS);
2383 void emitAdditionalImpl(raw_ostream &OS) override;
2385 void emitMIPredicateFns(raw_ostream &OS) override;
2386 void emitI64ImmPredicateFns(raw_ostream &OS) override;
2387 void emitAPFloatImmPredicateFns(raw_ostream &OS) override;
2388 void emitAPIntImmPredicateFns(raw_ostream &OS) override;
2389 void emitTestSimplePredicate(raw_ostream &OS) override;
2390 void emitRunCustomAction(raw_ostream &OS) override;
2392 const CodeGenTarget &getTarget() const override { return Target; }
2393 StringRef getClassName() const override {
2394 return Combiner->getValueAsString("Classname");
2397 StringRef getCombineAllMethodName() const {
2398 return Combiner->getValueAsString("CombineAllMethodName");
2401 std::string getRuleConfigClassName() const {
2402 return getClassName().str() + "RuleConfig";
2405 void gatherRules(std::vector<RuleMatcher> &Rules,
2406 ArrayRef<const Record *> RulesAndGroups);
2408 public:
2409 explicit GICombinerEmitter(const RecordKeeper &RK,
2410 const CodeGenTarget &Target, StringRef Name,
2411 const Record *Combiner);
2412 ~GICombinerEmitter() {}
2414 void run(raw_ostream &OS);
2417 void GICombinerEmitter::emitRuleConfigImpl(raw_ostream &OS) {
2418 OS << "struct " << getRuleConfigClassName() << " {\n"
2419 << " SparseBitVector<> DisabledRules;\n\n"
2420 << " bool isRuleEnabled(unsigned RuleID) const;\n"
2421 << " bool parseCommandLineOption();\n"
2422 << " bool setRuleEnabled(StringRef RuleIdentifier);\n"
2423 << " bool setRuleDisabled(StringRef RuleIdentifier);\n"
2424 << "};\n\n";
2426 std::vector<std::pair<std::string, std::string>> Cases;
2427 Cases.reserve(AllCombineRules.size());
2429 for (const auto &[ID, Name] : AllCombineRules)
2430 Cases.emplace_back(Name, "return " + to_string(ID) + ";\n");
2432 OS << "static std::optional<uint64_t> getRuleIdxForIdentifier(StringRef "
2433 "RuleIdentifier) {\n"
2434 << " uint64_t I;\n"
2435 << " // getAtInteger(...) returns false on success\n"
2436 << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n"
2437 << " if (Parsed)\n"
2438 << " return I;\n\n"
2439 << "#ifndef NDEBUG\n";
2440 StringMatcher Matcher("RuleIdentifier", Cases, OS);
2441 Matcher.Emit();
2442 OS << "#endif // ifndef NDEBUG\n\n"
2443 << " return std::nullopt;\n"
2444 << "}\n";
2446 OS << "static std::optional<std::pair<uint64_t, uint64_t>> "
2447 "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
2448 << " std::pair<StringRef, StringRef> RangePair = "
2449 "RuleIdentifier.split('-');\n"
2450 << " if (!RangePair.second.empty()) {\n"
2451 << " const auto First = "
2452 "getRuleIdxForIdentifier(RangePair.first);\n"
2453 << " const auto Last = "
2454 "getRuleIdxForIdentifier(RangePair.second);\n"
2455 << " if (!First || !Last)\n"
2456 << " return std::nullopt;\n"
2457 << " if (First >= Last)\n"
2458 << " report_fatal_error(\"Beginning of range should be before "
2459 "end of range\");\n"
2460 << " return {{*First, *Last + 1}};\n"
2461 << " }\n"
2462 << " if (RangePair.first == \"*\") {\n"
2463 << " return {{0, " << AllCombineRules.size() << "}};\n"
2464 << " }\n"
2465 << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
2466 << " if (!I)\n"
2467 << " return std::nullopt;\n"
2468 << " return {{*I, *I + 1}};\n"
2469 << "}\n\n";
2471 for (bool Enabled : {true, false}) {
2472 OS << "bool " << getRuleConfigClassName() << "::setRule"
2473 << (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
2474 << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
2475 << " if (!MaybeRange)\n"
2476 << " return false;\n"
2477 << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
2478 << " DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n"
2479 << " return true;\n"
2480 << "}\n\n";
2483 OS << "static std::vector<std::string> " << Name << "Option;\n"
2484 << "static cl::list<std::string> " << Name << "DisableOption(\n"
2485 << " \"" << Name.lower() << "-disable-rule\",\n"
2486 << " cl::desc(\"Disable one or more combiner rules temporarily in "
2487 << "the " << Name << " pass\"),\n"
2488 << " cl::CommaSeparated,\n"
2489 << " cl::Hidden,\n"
2490 << " cl::cat(GICombinerOptionCategory),\n"
2491 << " cl::callback([](const std::string &Str) {\n"
2492 << " " << Name << "Option.push_back(Str);\n"
2493 << " }));\n"
2494 << "static cl::list<std::string> " << Name << "OnlyEnableOption(\n"
2495 << " \"" << Name.lower() << "-only-enable-rule\",\n"
2496 << " cl::desc(\"Disable all rules in the " << Name
2497 << " pass then re-enable the specified ones\"),\n"
2498 << " cl::Hidden,\n"
2499 << " cl::cat(GICombinerOptionCategory),\n"
2500 << " cl::callback([](const std::string &CommaSeparatedArg) {\n"
2501 << " StringRef Str = CommaSeparatedArg;\n"
2502 << " " << Name << "Option.push_back(\"*\");\n"
2503 << " do {\n"
2504 << " auto X = Str.split(\",\");\n"
2505 << " " << Name << "Option.push_back((\"!\" + X.first).str());\n"
2506 << " Str = X.second;\n"
2507 << " } while (!Str.empty());\n"
2508 << " }));\n"
2509 << "\n\n"
2510 << "bool " << getRuleConfigClassName()
2511 << "::isRuleEnabled(unsigned RuleID) const {\n"
2512 << " return !DisabledRules.test(RuleID);\n"
2513 << "}\n"
2514 << "bool " << getRuleConfigClassName() << "::parseCommandLineOption() {\n"
2515 << " for (StringRef Identifier : " << Name << "Option) {\n"
2516 << " bool Enabled = Identifier.consume_front(\"!\");\n"
2517 << " if (Enabled && !setRuleEnabled(Identifier))\n"
2518 << " return false;\n"
2519 << " if (!Enabled && !setRuleDisabled(Identifier))\n"
2520 << " return false;\n"
2521 << " }\n"
2522 << " return true;\n"
2523 << "}\n\n";
2526 void GICombinerEmitter::emitAdditionalImpl(raw_ostream &OS) {
2527 OS << "bool " << getClassName() << "::" << getCombineAllMethodName()
2528 << "(MachineInstr &I) const {\n"
2529 << " const TargetSubtargetInfo &ST = MF.getSubtarget();\n"
2530 << " const PredicateBitset AvailableFeatures = "
2531 "getAvailableFeatures();\n"
2532 << " B.setInstrAndDebugLoc(I);\n"
2533 << " State.MIs.clear();\n"
2534 << " State.MIs.push_back(&I);\n"
2535 << " if (executeMatchTable(*this, State, ExecInfo, B"
2536 << ", getMatchTable(), *ST.getInstrInfo(), MRI, "
2537 "*MRI.getTargetRegisterInfo(), *ST.getRegBankInfo(), AvailableFeatures"
2538 << ", /*CoverageInfo*/ nullptr)) {\n"
2539 << " return true;\n"
2540 << " }\n\n"
2541 << " return false;\n"
2542 << "}\n\n";
2545 void GICombinerEmitter::emitMIPredicateFns(raw_ostream &OS) {
2546 auto MatchCode = CXXPredicateCode::getAllMatchCode();
2547 emitMIPredicateFnsImpl<const CXXPredicateCode *>(
2548 OS, "", ArrayRef<const CXXPredicateCode *>(MatchCode),
2549 [](const CXXPredicateCode *C) -> StringRef { return C->BaseEnumName; },
2550 [](const CXXPredicateCode *C) -> StringRef { return C->Code; });
2553 void GICombinerEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {
2554 // Unused, but still needs to be called.
2555 emitImmPredicateFnsImpl<unsigned>(
2556 OS, "I64", "int64_t", {}, [](unsigned) { return ""; },
2557 [](unsigned) { return ""; });
2560 void GICombinerEmitter::emitAPFloatImmPredicateFns(raw_ostream &OS) {
2561 // Unused, but still needs to be called.
2562 emitImmPredicateFnsImpl<unsigned>(
2563 OS, "APFloat", "const APFloat &", {}, [](unsigned) { return ""; },
2564 [](unsigned) { return ""; });
2567 void GICombinerEmitter::emitAPIntImmPredicateFns(raw_ostream &OS) {
2568 // Unused, but still needs to be called.
2569 emitImmPredicateFnsImpl<unsigned>(
2570 OS, "APInt", "const APInt &", {}, [](unsigned) { return ""; },
2571 [](unsigned) { return ""; });
2574 void GICombinerEmitter::emitTestSimplePredicate(raw_ostream &OS) {
2575 if (!AllCombineRules.empty()) {
2576 OS << "enum {\n";
2577 std::string EnumeratorSeparator = " = GICXXPred_Invalid + 1,\n";
2578 // To avoid emitting a switch, we expect that all those rules are in order.
2579 // That way we can just get the RuleID from the enum by subtracting
2580 // (GICXXPred_Invalid + 1).
2581 unsigned ExpectedID = 0;
2582 (void)ExpectedID;
2583 for (const auto &ID : keys(AllCombineRules)) {
2584 assert(ExpectedID++ == ID && "combine rules are not ordered!");
2585 OS << " " << getIsEnabledPredicateEnumName(ID) << EnumeratorSeparator;
2586 EnumeratorSeparator = ",\n";
2588 OS << "};\n\n";
2591 OS << "bool " << getClassName()
2592 << "::testSimplePredicate(unsigned Predicate) const {\n"
2593 << " return RuleConfig.isRuleEnabled(Predicate - "
2594 "GICXXPred_Invalid - "
2595 "1);\n"
2596 << "}\n";
2599 void GICombinerEmitter::emitRunCustomAction(raw_ostream &OS) {
2600 const auto CustomActionsCode = CXXPredicateCode::getAllCustomActionsCode();
2602 if (!CustomActionsCode.empty()) {
2603 OS << "enum {\n";
2604 std::string EnumeratorSeparator = " = GICXXCustomAction_Invalid + 1,\n";
2605 for (const auto &CA : CustomActionsCode) {
2606 OS << " " << CA->getEnumNameWithPrefix(CXXCustomActionPrefix)
2607 << EnumeratorSeparator;
2608 EnumeratorSeparator = ",\n";
2610 OS << "};\n";
2613 OS << "bool " << getClassName()
2614 << "::runCustomAction(unsigned ApplyID, const MatcherState &State, "
2615 "NewMIVector &OutMIs) const "
2616 "{\n Helper.getBuilder().setInstrAndDebugLoc(*State.MIs[0]);\n";
2617 if (!CustomActionsCode.empty()) {
2618 OS << " switch(ApplyID) {\n";
2619 for (const auto &CA : CustomActionsCode) {
2620 OS << " case " << CA->getEnumNameWithPrefix(CXXCustomActionPrefix)
2621 << ":{\n"
2622 << " " << join(split(CA->Code, '\n'), "\n ") << '\n'
2623 << " return true;\n";
2624 OS << " }\n";
2626 OS << " }\n";
2628 OS << " llvm_unreachable(\"Unknown Apply Action\");\n"
2629 << "}\n";
2632 GICombinerEmitter::GICombinerEmitter(const RecordKeeper &RK,
2633 const CodeGenTarget &Target,
2634 StringRef Name, const Record *Combiner)
2635 : Records(RK), Name(Name), Target(Target), Combiner(Combiner) {}
2637 MatchTable
2638 GICombinerEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules) {
2639 std::vector<Matcher *> InputRules;
2640 for (Matcher &Rule : Rules)
2641 InputRules.push_back(&Rule);
2643 unsigned CurrentOrdering = 0;
2644 StringMap<unsigned> OpcodeOrder;
2645 for (RuleMatcher &Rule : Rules) {
2646 const StringRef Opcode = Rule.getOpcode();
2647 assert(!Opcode.empty() && "Didn't expect an undefined opcode");
2648 if (OpcodeOrder.count(Opcode) == 0)
2649 OpcodeOrder[Opcode] = CurrentOrdering++;
2652 llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,
2653 const Matcher *B) {
2654 auto *L = static_cast<const RuleMatcher *>(A);
2655 auto *R = static_cast<const RuleMatcher *>(B);
2656 return std::make_tuple(OpcodeOrder[L->getOpcode()],
2657 L->insnmatchers_front().getNumOperandMatchers()) <
2658 std::make_tuple(OpcodeOrder[R->getOpcode()],
2659 R->insnmatchers_front().getNumOperandMatchers());
2662 for (Matcher *Rule : InputRules)
2663 Rule->optimize();
2665 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
2666 std::vector<Matcher *> OptRules =
2667 optimizeRules<GroupMatcher>(InputRules, MatcherStorage);
2669 for (Matcher *Rule : OptRules)
2670 Rule->optimize();
2672 OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);
2674 return MatchTable::buildTable(OptRules, /*WithCoverage*/ false,
2675 /*IsCombiner*/ true);
2678 /// Recurse into GICombineGroup's and flatten the ruleset into a simple list.
2679 void GICombinerEmitter::gatherRules(std::vector<RuleMatcher> &ActiveRules,
2680 ArrayRef<const Record *> RulesAndGroups) {
2681 for (const Record *Rec : RulesAndGroups) {
2682 if (!Rec->isValueUnset("Rules")) {
2683 gatherRules(ActiveRules, Rec->getValueAsListOfDefs("Rules"));
2684 continue;
2687 StringRef RuleName = Rec->getName();
2688 if (!RulesSeen.insert(RuleName).second) {
2689 PrintWarning(Rec->getLoc(),
2690 "skipping rule '" + Rec->getName() +
2691 "' because it has already been processed");
2692 continue;
2695 AllCombineRules.emplace_back(NextRuleID, Rec->getName().str());
2696 CombineRuleBuilder CRB(Target, SubtargetFeatures, *Rec, NextRuleID++,
2697 ActiveRules);
2699 if (!CRB.parseAll()) {
2700 assert(ErrorsPrinted && "Parsing failed without errors!");
2701 continue;
2704 if (StopAfterParse) {
2705 CRB.print(outs());
2706 continue;
2709 if (!CRB.emitRuleMatchers()) {
2710 assert(ErrorsPrinted && "Emission failed without errors!");
2711 continue;
2716 void GICombinerEmitter::run(raw_ostream &OS) {
2717 InstructionOpcodeMatcher::initOpcodeValuesMap(Target);
2718 LLTOperandMatcher::initTypeIDValuesMap();
2720 TGTimer &Timer = Records.getTimer();
2721 Timer.startTimer("Gather rules");
2722 std::vector<RuleMatcher> Rules;
2723 gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules"));
2724 if (ErrorsPrinted)
2725 PrintFatalError(Combiner->getLoc(), "Failed to parse one or more rules");
2727 if (StopAfterParse)
2728 return;
2730 Timer.startTimer("Creating Match Table");
2731 unsigned MaxTemporaries = 0;
2732 for (const auto &Rule : Rules)
2733 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
2735 llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
2736 if (A.isHigherPriorityThan(B)) {
2737 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
2738 "and less important at "
2739 "the same time");
2740 return true;
2742 return false;
2745 const MatchTable Table = buildMatchTable(Rules);
2747 Timer.startTimer("Emit combiner");
2749 emitSourceFileHeader(getClassName().str() + " Combiner Match Table", OS);
2751 SmallVector<LLTCodeGen, 16> TypeObjects;
2752 append_range(TypeObjects, KnownTypes);
2753 llvm::sort(TypeObjects);
2755 // Hack: Avoid empty declarator.
2756 if (TypeObjects.empty())
2757 TypeObjects.push_back(LLT::scalar(1));
2759 // GET_GICOMBINER_DEPS, which pulls in extra dependencies.
2760 OS << "#ifdef GET_GICOMBINER_DEPS\n"
2761 << "#include \"llvm/ADT/SparseBitVector.h\"\n"
2762 << "namespace llvm {\n"
2763 << "extern cl::OptionCategory GICombinerOptionCategory;\n"
2764 << "} // end namespace llvm\n"
2765 << "#endif // ifdef GET_GICOMBINER_DEPS\n\n";
2767 // GET_GICOMBINER_TYPES, which needs to be included before the declaration of
2768 // the class.
2769 OS << "#ifdef GET_GICOMBINER_TYPES\n";
2770 emitRuleConfigImpl(OS);
2771 OS << "#endif // ifdef GET_GICOMBINER_TYPES\n\n";
2772 emitPredicateBitset(OS, "GET_GICOMBINER_TYPES");
2774 // GET_GICOMBINER_CLASS_MEMBERS, which need to be included inside the class.
2775 emitPredicatesDecl(OS, "GET_GICOMBINER_CLASS_MEMBERS");
2776 emitTemporariesDecl(OS, "GET_GICOMBINER_CLASS_MEMBERS");
2778 // GET_GICOMBINER_IMPL, which needs to be included outside the class.
2779 emitExecutorImpl(OS, Table, TypeObjects, Rules, {}, {},
2780 "GET_GICOMBINER_IMPL");
2782 // GET_GICOMBINER_CONSTRUCTOR_INITS, which are in the constructor's
2783 // initializer list.
2784 emitPredicatesInit(OS, "GET_GICOMBINER_CONSTRUCTOR_INITS");
2785 emitTemporariesInit(OS, MaxTemporaries, "GET_GICOMBINER_CONSTRUCTOR_INITS");
2788 } // end anonymous namespace
2790 //===----------------------------------------------------------------------===//
2792 static void EmitGICombiner(const RecordKeeper &RK, raw_ostream &OS) {
2793 EnablePrettyStackTrace();
2794 const CodeGenTarget Target(RK);
2796 if (SelectedCombiners.empty())
2797 PrintFatalError("No combiners selected with -combiners");
2798 for (const auto &Combiner : SelectedCombiners) {
2799 const Record *CombinerDef = RK.getDef(Combiner);
2800 if (!CombinerDef)
2801 PrintFatalError("Could not find " + Combiner);
2802 GICombinerEmitter(RK, Target, Combiner, CombinerDef).run(OS);
2806 static TableGen::Emitter::Opt X("gen-global-isel-combiner", EmitGICombiner,
2807 "Generate GlobalISel Combiner");