[llvm-objdump] --disassemble-symbols: skip inline relocs from symbols that are not...
[llvm-project.git] / llvm / utils / TableGen / GlobalISelCombinerEmitter.cpp
blob89aca87a28ec0dc89c7fb4ba2b693b18650da223
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 "CodeGenInstruction.h"
30 #include "CodeGenTarget.h"
31 #include "GlobalISel/CXXPredicates.h"
32 #include "GlobalISel/CodeExpander.h"
33 #include "GlobalISel/CodeExpansions.h"
34 #include "GlobalISel/CombinerUtils.h"
35 #include "GlobalISel/MatchDataInfo.h"
36 #include "GlobalISel/Patterns.h"
37 #include "GlobalISelMatchTable.h"
38 #include "GlobalISelMatchTableExecutorEmitter.h"
39 #include "SubtargetFeatureInfo.h"
40 #include "llvm/ADT/APInt.h"
41 #include "llvm/ADT/EquivalenceClasses.h"
42 #include "llvm/ADT/Hashing.h"
43 #include "llvm/ADT/MapVector.h"
44 #include "llvm/ADT/SetVector.h"
45 #include "llvm/ADT/Statistic.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/TableGenBackend.h"
55 #include <cstdint>
57 using namespace llvm;
58 using namespace llvm::gi;
60 #define DEBUG_TYPE "gicombiner-emitter"
62 namespace {
63 cl::OptionCategory
64 GICombinerEmitterCat("Options for -gen-global-isel-combiner");
65 cl::opt<bool> StopAfterParse(
66 "gicombiner-stop-after-parse",
67 cl::desc("Stop processing after parsing rules and dump state"),
68 cl::cat(GICombinerEmitterCat));
69 cl::list<std::string>
70 SelectedCombiners("combiners", cl::desc("Emit the specified combiners"),
71 cl::cat(GICombinerEmitterCat), cl::CommaSeparated);
72 cl::opt<bool> DebugCXXPreds(
73 "gicombiner-debug-cxxpreds",
74 cl::desc("Add Contextual/Debug comments to all C++ predicates"),
75 cl::cat(GICombinerEmitterCat));
76 cl::opt<bool> DebugTypeInfer("gicombiner-debug-typeinfer",
77 cl::desc("Print type inference debug logs"),
78 cl::cat(GICombinerEmitterCat));
80 constexpr StringLiteral CXXApplyPrefix = "GICXXCustomAction_CombineApply";
81 constexpr StringLiteral CXXPredPrefix = "GICXXPred_MI_Predicate_";
82 constexpr StringLiteral MIFlagsEnumClassName = "MIFlagEnum";
84 //===- CodeExpansions Helpers --------------------------------------------===//
86 void declareInstExpansion(CodeExpansions &CE, const InstructionMatcher &IM,
87 StringRef Name) {
88 CE.declare(Name, "State.MIs[" + to_string(IM.getInsnVarID()) + "]");
91 void declareInstExpansion(CodeExpansions &CE, const BuildMIAction &A,
92 StringRef Name) {
93 // Note: we use redeclare here because this may overwrite a matcher inst
94 // expansion.
95 CE.redeclare(Name, "OutMIs[" + to_string(A.getInsnID()) + "]");
98 void declareOperandExpansion(CodeExpansions &CE, const OperandMatcher &OM,
99 StringRef Name) {
100 CE.declare(Name, "State.MIs[" + to_string(OM.getInsnVarID()) +
101 "]->getOperand(" + to_string(OM.getOpIdx()) + ")");
104 void declareTempRegExpansion(CodeExpansions &CE, unsigned TempRegID,
105 StringRef Name) {
106 CE.declare(Name, "State.TempRegisters[" + to_string(TempRegID) + "]");
109 //===- Misc. Helpers -----------------------------------------------------===//
111 /// Copies a StringRef into a static pool to preserve it.
112 /// Most Pattern classes use StringRef so we need this.
113 StringRef insertStrRef(StringRef S) {
114 if (S.empty())
115 return {};
117 static StringSet<> Pool;
118 auto [It, Inserted] = Pool.insert(S);
119 return It->getKey();
122 template <typename Container> auto keys(Container &&C) {
123 return map_range(C, [](auto &Entry) -> auto & { return Entry.first; });
126 template <typename Container> auto values(Container &&C) {
127 return map_range(C, [](auto &Entry) -> auto & { return Entry.second; });
130 std::string getIsEnabledPredicateEnumName(unsigned CombinerRuleID) {
131 return "GICXXPred_Simple_IsRule" + to_string(CombinerRuleID) + "Enabled";
134 //===- MatchTable Helpers ------------------------------------------------===//
136 LLTCodeGen getLLTCodeGen(const PatternType &PT) {
137 return *MVTToLLT(getValueType(PT.getLLTRecord()));
140 LLTCodeGenOrTempType getLLTCodeGenOrTempType(const PatternType &PT,
141 RuleMatcher &RM) {
142 assert(!PT.isNone());
144 if (PT.isLLT())
145 return getLLTCodeGen(PT);
147 assert(PT.isTypeOf());
148 auto &OM = RM.getOperandMatcher(PT.getTypeOfOpName());
149 return OM.getTempTypeIdx(RM);
152 //===- PrettyStackTrace Helpers ------------------------------------------===//
154 class PrettyStackTraceParse : public PrettyStackTraceEntry {
155 const Record &Def;
157 public:
158 PrettyStackTraceParse(const Record &Def) : Def(Def) {}
160 void print(raw_ostream &OS) const override {
161 if (Def.isSubClassOf("GICombineRule"))
162 OS << "Parsing GICombineRule '" << Def.getName() << "'";
163 else if (Def.isSubClassOf(PatFrag::ClassName))
164 OS << "Parsing " << PatFrag::ClassName << " '" << Def.getName() << "'";
165 else
166 OS << "Parsing '" << Def.getName() << "'";
167 OS << '\n';
171 class PrettyStackTraceEmit : public PrettyStackTraceEntry {
172 const Record &Def;
173 const Pattern *Pat = nullptr;
175 public:
176 PrettyStackTraceEmit(const Record &Def, const Pattern *Pat = nullptr)
177 : Def(Def), Pat(Pat) {}
179 void print(raw_ostream &OS) const override {
180 if (Def.isSubClassOf("GICombineRule"))
181 OS << "Emitting GICombineRule '" << Def.getName() << "'";
182 else if (Def.isSubClassOf(PatFrag::ClassName))
183 OS << "Emitting " << PatFrag::ClassName << " '" << Def.getName() << "'";
184 else
185 OS << "Emitting '" << Def.getName() << "'";
187 if (Pat)
188 OS << " [" << Pat->getKindName() << " '" << Pat->getName() << "']";
189 OS << '\n';
193 //===- CombineRuleOperandTypeChecker --------------------------------------===//
195 /// This is a wrapper around OperandTypeChecker specialized for Combiner Rules.
196 /// On top of doing the same things as OperandTypeChecker, this also attempts to
197 /// infer as many types as possible for temporary register defs & immediates in
198 /// apply patterns.
200 /// The inference is trivial and leverages the MCOI OperandTypes encoded in
201 /// CodeGenInstructions to infer types across patterns in a CombineRule. It's
202 /// thus very limited and only supports CodeGenInstructions (but that's the main
203 /// use case so it's fine).
205 /// We only try to infer untyped operands in apply patterns when they're temp
206 /// reg defs, or immediates. Inference always outputs a `TypeOf<$x>` where $x is
207 /// a named operand from a match pattern.
208 class CombineRuleOperandTypeChecker : private OperandTypeChecker {
209 public:
210 CombineRuleOperandTypeChecker(const Record &RuleDef,
211 const OperandTable &MatchOpTable)
212 : OperandTypeChecker(RuleDef.getLoc()), RuleDef(RuleDef),
213 MatchOpTable(MatchOpTable) {}
215 /// Records and checks a 'match' pattern.
216 bool processMatchPattern(InstructionPattern &P);
218 /// Records and checks an 'apply' pattern.
219 bool processApplyPattern(InstructionPattern &P);
221 /// Propagates types, then perform type inference and do a second round of
222 /// propagation in the apply patterns only if any types were inferred.
223 void propagateAndInferTypes();
225 private:
226 /// TypeEquivalenceClasses are groups of operands of an instruction that share
227 /// a common type.
229 /// e.g. [[a, b], [c, d]] means a and b have the same type, and c and
230 /// d have the same type too. b/c and a/d don't have to have the same type,
231 /// though.
232 using TypeEquivalenceClasses = EquivalenceClasses<StringRef>;
234 /// \returns true for `OPERAND_GENERIC_` 0 through 5.
235 /// These are the MCOI types that can be registers. The other MCOI types are
236 /// either immediates, or fancier operands used only post-ISel, so we don't
237 /// care about them for combiners.
238 static bool canMCOIOperandTypeBeARegister(StringRef MCOIType) {
239 // Assume OPERAND_GENERIC_0 through 5 can be registers. The other MCOI
240 // OperandTypes are either never used in gMIR, or not relevant (e.g.
241 // OPERAND_GENERIC_IMM, which is definitely never a register).
242 return MCOIType.drop_back(1).ends_with("OPERAND_GENERIC_");
245 /// Finds the "MCOI::"" operand types for each operand of \p CGP.
247 /// This is a bit trickier than it looks because we need to handle variadic
248 /// in/outs.
250 /// e.g. for
251 /// (G_BUILD_VECTOR $vec, $x, $y) ->
252 /// [MCOI::OPERAND_GENERIC_0, MCOI::OPERAND_GENERIC_1,
253 /// MCOI::OPERAND_GENERIC_1]
255 /// For unknown types (which can happen in variadics where varargs types are
256 /// inconsistent), a unique name is given, e.g. "unknown_type_0".
257 static std::vector<std::string>
258 getMCOIOperandTypes(const CodeGenInstructionPattern &CGP);
260 /// Adds the TypeEquivalenceClasses for \p P in \p OutTECs.
261 void getInstEqClasses(const InstructionPattern &P,
262 TypeEquivalenceClasses &OutTECs) const;
264 /// Calls `getInstEqClasses` on all patterns of the rule to produce the whole
265 /// rule's TypeEquivalenceClasses.
266 TypeEquivalenceClasses getRuleEqClasses() const;
268 /// Tries to infer the type of the \p ImmOpIdx -th operand of \p IP using \p
269 /// TECs.
271 /// This is achieved by trying to find a named operand in \p IP that shares
272 /// the same type as \p ImmOpIdx, and using \ref inferNamedOperandType on that
273 /// operand instead.
275 /// \returns the inferred type or an empty PatternType if inference didn't
276 /// succeed.
277 PatternType inferImmediateType(const InstructionPattern &IP,
278 unsigned ImmOpIdx,
279 const TypeEquivalenceClasses &TECs) const;
281 /// Looks inside \p TECs to infer \p OpName's type.
283 /// \returns the inferred type or an empty PatternType if inference didn't
284 /// succeed.
285 PatternType inferNamedOperandType(const InstructionPattern &IP,
286 StringRef OpName,
287 const TypeEquivalenceClasses &TECs) const;
289 const Record &RuleDef;
290 SmallVector<InstructionPattern *, 8> MatchPats;
291 SmallVector<InstructionPattern *, 8> ApplyPats;
293 const OperandTable &MatchOpTable;
296 bool CombineRuleOperandTypeChecker::processMatchPattern(InstructionPattern &P) {
297 MatchPats.push_back(&P);
298 return check(P, /*CheckTypeOf*/ [](const auto &) {
299 // GITypeOf in 'match' is currently always rejected by the
300 // CombineRuleBuilder after inference is done.
301 return true;
305 bool CombineRuleOperandTypeChecker::processApplyPattern(InstructionPattern &P) {
306 ApplyPats.push_back(&P);
307 return check(P, /*CheckTypeOf*/ [&](const PatternType &Ty) {
308 // GITypeOf<"$x"> can only be used if "$x" is a matched operand.
309 const auto OpName = Ty.getTypeOfOpName();
310 if (MatchOpTable.lookup(OpName).Found)
311 return true;
313 PrintError(RuleDef.getLoc(), "'" + OpName + "' ('" + Ty.str() +
314 "') does not refer to a matched operand!");
315 return false;
319 void CombineRuleOperandTypeChecker::propagateAndInferTypes() {
320 /// First step here is to propagate types using the OperandTypeChecker. That
321 /// way we ensure all uses of a given register have consistent types.
322 propagateTypes();
324 /// Build the TypeEquivalenceClasses for the whole rule.
325 const TypeEquivalenceClasses TECs = getRuleEqClasses();
327 /// Look at the apply patterns and find operands that need to be
328 /// inferred. We then try to find an equivalence class that they're a part of
329 /// and select the best operand to use for the `GITypeOf` type. We prioritize
330 /// defs of matched instructions because those are guaranteed to be registers.
331 bool InferredAny = false;
332 for (auto *Pat : ApplyPats) {
333 for (unsigned K = 0; K < Pat->operands_size(); ++K) {
334 auto &Op = Pat->getOperand(K);
336 // We only want to take a look at untyped defs or immediates.
337 if ((!Op.isDef() && !Op.hasImmValue()) || Op.getType())
338 continue;
340 // Infer defs & named immediates.
341 if (Op.isDef() || Op.isNamedImmediate()) {
342 // Check it's not a redefinition of a matched operand.
343 // In such cases, inference is not necessary because we just copy
344 // operands and don't create temporary registers.
345 if (MatchOpTable.lookup(Op.getOperandName()).Found)
346 continue;
348 // Inference is needed here, so try to do it.
349 if (PatternType Ty =
350 inferNamedOperandType(*Pat, Op.getOperandName(), TECs)) {
351 if (DebugTypeInfer)
352 errs() << "INFER: " << Op.describe() << " -> " << Ty.str() << '\n';
353 Op.setType(Ty);
354 InferredAny = true;
357 continue;
360 // Infer immediates
361 if (Op.hasImmValue()) {
362 if (PatternType Ty = inferImmediateType(*Pat, K, TECs)) {
363 if (DebugTypeInfer)
364 errs() << "INFER: " << Op.describe() << " -> " << Ty.str() << '\n';
365 Op.setType(Ty);
366 InferredAny = true;
368 continue;
373 // If we've inferred any types, we want to propagate them across the apply
374 // patterns. Type inference only adds GITypeOf types that point to Matched
375 // operands, so we definitely don't want to propagate types into the match
376 // patterns as well, otherwise bad things happen.
377 if (InferredAny) {
378 OperandTypeChecker OTC(RuleDef.getLoc());
379 for (auto *Pat : ApplyPats) {
380 if (!OTC.check(*Pat, [&](const auto &) { return true; }))
381 PrintFatalError(RuleDef.getLoc(),
382 "OperandTypeChecker unexpectedly failed on '" +
383 Pat->getName() + "' during Type Inference");
385 OTC.propagateTypes();
387 if (DebugTypeInfer) {
388 errs() << "Apply patterns for rule " << RuleDef.getName()
389 << " after inference:\n";
390 for (auto *Pat : ApplyPats) {
391 errs() << " ";
392 Pat->print(errs(), /*PrintName*/ true);
393 errs() << '\n';
395 errs() << '\n';
400 PatternType CombineRuleOperandTypeChecker::inferImmediateType(
401 const InstructionPattern &IP, unsigned ImmOpIdx,
402 const TypeEquivalenceClasses &TECs) const {
403 // We can only infer CGPs.
404 const auto *CGP = dyn_cast<CodeGenInstructionPattern>(&IP);
405 if (!CGP)
406 return {};
408 // For CGPs, we try to infer immediates by trying to infer another named
409 // operand that shares its type.
411 // e.g.
412 // Pattern: G_BUILD_VECTOR $x, $y, 0
413 // MCOIs: [MCOI::OPERAND_GENERIC_0, MCOI::OPERAND_GENERIC_1,
414 // MCOI::OPERAND_GENERIC_1]
415 // $y has the same type as 0, so we can infer $y and get the type 0 should
416 // have.
418 // We infer immediates by looking for a named operand that shares the same
419 // MCOI type.
420 const auto MCOITypes = getMCOIOperandTypes(*CGP);
421 StringRef ImmOpTy = MCOITypes[ImmOpIdx];
423 for (const auto &[Idx, Ty] : enumerate(MCOITypes)) {
424 if (Idx != ImmOpIdx && Ty == ImmOpTy) {
425 const auto &Op = IP.getOperand(Idx);
426 if (!Op.isNamedOperand())
427 continue;
429 // Named operand with the same name, try to infer that.
430 if (PatternType InferTy =
431 inferNamedOperandType(IP, Op.getOperandName(), TECs))
432 return InferTy;
436 return {};
439 PatternType CombineRuleOperandTypeChecker::inferNamedOperandType(
440 const InstructionPattern &IP, StringRef OpName,
441 const TypeEquivalenceClasses &TECs) const {
442 // This is the simplest possible case, we just need to find a TEC that
443 // contains OpName. Look at all other operands in equivalence class and try to
444 // find a suitable one.
446 // Check for a def of a matched pattern. This is guaranteed to always
447 // be a register so we can blindly use that.
448 StringRef GoodOpName;
449 for (auto It = TECs.findLeader(OpName); It != TECs.member_end(); ++It) {
450 if (*It == OpName)
451 continue;
453 const auto LookupRes = MatchOpTable.lookup(*It);
454 if (LookupRes.Def) // Favor defs
455 return PatternType::getTypeOf(*It);
457 // Otherwise just save this in case we don't find any def.
458 if (GoodOpName.empty() && LookupRes.Found)
459 GoodOpName = *It;
462 if (!GoodOpName.empty())
463 return PatternType::getTypeOf(GoodOpName);
465 // No good operand found, give up.
466 return {};
469 std::vector<std::string> CombineRuleOperandTypeChecker::getMCOIOperandTypes(
470 const CodeGenInstructionPattern &CGP) {
471 // FIXME?: Should we cache this? We call it twice when inferring immediates.
473 static unsigned UnknownTypeIdx = 0;
475 std::vector<std::string> OpTypes;
476 auto &CGI = CGP.getInst();
477 Record *VarArgsTy = CGI.TheDef->isSubClassOf("GenericInstruction")
478 ? CGI.TheDef->getValueAsOptionalDef("variadicOpsType")
479 : nullptr;
480 std::string VarArgsTyName =
481 VarArgsTy ? ("MCOI::" + VarArgsTy->getValueAsString("OperandType")).str()
482 : ("unknown_type_" + Twine(UnknownTypeIdx++)).str();
484 // First, handle defs.
485 for (unsigned K = 0; K < CGI.Operands.NumDefs; ++K)
486 OpTypes.push_back(CGI.Operands[K].OperandType);
488 // Then, handle variadic defs if there are any.
489 if (CGP.hasVariadicDefs()) {
490 for (unsigned K = CGI.Operands.NumDefs; K < CGP.getNumInstDefs(); ++K)
491 OpTypes.push_back(VarArgsTyName);
494 // If we had variadic defs, the op idx in the pattern won't match the op idx
495 // in the CGI anymore.
496 int CGIOpOffset = int(CGI.Operands.NumDefs) - CGP.getNumInstDefs();
497 assert(CGP.hasVariadicDefs() ? (CGIOpOffset <= 0) : (CGIOpOffset == 0));
499 // Handle all remaining use operands, including variadic ones.
500 for (unsigned K = CGP.getNumInstDefs(); K < CGP.getNumInstOperands(); ++K) {
501 unsigned CGIOpIdx = K + CGIOpOffset;
502 if (CGIOpIdx >= CGI.Operands.size()) {
503 assert(CGP.isVariadic());
504 OpTypes.push_back(VarArgsTyName);
505 } else {
506 OpTypes.push_back(CGI.Operands[CGIOpIdx].OperandType);
510 assert(OpTypes.size() == CGP.operands_size());
511 return OpTypes;
514 void CombineRuleOperandTypeChecker::getInstEqClasses(
515 const InstructionPattern &P, TypeEquivalenceClasses &OutTECs) const {
516 // Determine the TypeEquivalenceClasses by:
517 // - Getting the MCOI Operand Types.
518 // - Creating a Map of MCOI Type -> [Operand Indexes]
519 // - Iterating over the map, filtering types we don't like, and just adding
520 // the array of Operand Indexes to \p OutTECs.
522 // We can only do this on CodeGenInstructions. Other InstructionPatterns have
523 // no type inference information associated with them.
524 // TODO: Could we add some inference information to builtins at least? e.g.
525 // ReplaceReg should always replace with a reg of the same type, for instance.
526 // Though, those patterns are often used alone so it might not be worth the
527 // trouble to infer their types.
528 auto *CGP = dyn_cast<CodeGenInstructionPattern>(&P);
529 if (!CGP)
530 return;
532 const auto MCOITypes = getMCOIOperandTypes(*CGP);
533 assert(MCOITypes.size() == P.operands_size());
535 DenseMap<StringRef, std::vector<unsigned>> TyToOpIdx;
536 for (const auto &[Idx, Ty] : enumerate(MCOITypes))
537 TyToOpIdx[Ty].push_back(Idx);
539 if (DebugTypeInfer)
540 errs() << "\tGroups for " << P.getName() << ":\t";
542 for (const auto &[Ty, Idxs] : TyToOpIdx) {
543 if (!canMCOIOperandTypeBeARegister(Ty))
544 continue;
546 if (DebugTypeInfer)
547 errs() << '[';
548 StringRef Sep = "";
550 // We only collect named operands.
551 StringRef Leader;
552 for (unsigned Idx : Idxs) {
553 const auto &Op = P.getOperand(Idx);
554 if (!Op.isNamedOperand())
555 continue;
557 const auto OpName = Op.getOperandName();
558 if (DebugTypeInfer) {
559 errs() << Sep << OpName;
560 Sep = ", ";
563 if (Leader.empty())
564 OutTECs.insert((Leader = OpName));
565 else
566 OutTECs.unionSets(Leader, OpName);
569 if (DebugTypeInfer)
570 errs() << "] ";
573 if (DebugTypeInfer)
574 errs() << '\n';
577 CombineRuleOperandTypeChecker::TypeEquivalenceClasses
578 CombineRuleOperandTypeChecker::getRuleEqClasses() const {
579 StringMap<unsigned> OpNameToEqClassIdx;
580 TypeEquivalenceClasses TECs;
582 if (DebugTypeInfer)
583 errs() << "Rule Operand Type Equivalence Classes for " << RuleDef.getName()
584 << ":\n";
586 for (const auto *Pat : MatchPats)
587 getInstEqClasses(*Pat, TECs);
588 for (const auto *Pat : ApplyPats)
589 getInstEqClasses(*Pat, TECs);
591 if (DebugTypeInfer) {
592 errs() << "Final Type Equivalence Classes: ";
593 for (auto ClassIt = TECs.begin(); ClassIt != TECs.end(); ++ClassIt) {
594 // only print non-empty classes.
595 if (auto MembIt = TECs.member_begin(ClassIt);
596 MembIt != TECs.member_end()) {
597 errs() << '[';
598 StringRef Sep = "";
599 for (; MembIt != TECs.member_end(); ++MembIt) {
600 errs() << Sep << *MembIt;
601 Sep = ", ";
603 errs() << "] ";
606 errs() << '\n';
609 return TECs;
612 //===- CombineRuleBuilder -------------------------------------------------===//
614 /// Parses combine rule and builds a small intermediate representation to tie
615 /// patterns together and emit RuleMatchers to match them. This may emit more
616 /// than one RuleMatcher, e.g. for `wip_match_opcode`.
618 /// Memory management for `Pattern` objects is done through `std::unique_ptr`.
619 /// In most cases, there are two stages to a pattern's lifetime:
620 /// - Creation in a `parse` function
621 /// - The unique_ptr is stored in a variable, and may be destroyed if the
622 /// pattern is found to be semantically invalid.
623 /// - Ownership transfer into a `PatternMap`
624 /// - Once a pattern is moved into either the map of Match or Apply
625 /// patterns, it is known to be valid and it never moves back.
626 class CombineRuleBuilder {
627 public:
628 using PatternMap = MapVector<StringRef, std::unique_ptr<Pattern>>;
629 using PatternAlternatives = DenseMap<const Pattern *, unsigned>;
631 CombineRuleBuilder(const CodeGenTarget &CGT,
632 SubtargetFeatureInfoMap &SubtargetFeatures,
633 Record &RuleDef, unsigned ID,
634 std::vector<RuleMatcher> &OutRMs)
635 : CGT(CGT), SubtargetFeatures(SubtargetFeatures), RuleDef(RuleDef),
636 RuleID(ID), OutRMs(OutRMs) {}
638 /// Parses all fields in the RuleDef record.
639 bool parseAll();
641 /// Emits all RuleMatchers into the vector of RuleMatchers passed in the
642 /// constructor.
643 bool emitRuleMatchers();
645 void print(raw_ostream &OS) const;
646 void dump() const { print(dbgs()); }
648 /// Debug-only verification of invariants.
649 #ifndef NDEBUG
650 void verify() const;
651 #endif
653 private:
654 const CodeGenInstruction &getGConstant() const {
655 return CGT.getInstruction(RuleDef.getRecords().getDef("G_CONSTANT"));
658 void PrintError(Twine Msg) const { ::PrintError(&RuleDef, Msg); }
659 void PrintWarning(Twine Msg) const { ::PrintWarning(RuleDef.getLoc(), Msg); }
660 void PrintNote(Twine Msg) const { ::PrintNote(RuleDef.getLoc(), Msg); }
662 void print(raw_ostream &OS, const PatternAlternatives &Alts) const;
664 bool addApplyPattern(std::unique_ptr<Pattern> Pat);
665 bool addMatchPattern(std::unique_ptr<Pattern> Pat);
667 /// Adds the expansions from \see MatchDatas to \p CE.
668 void declareAllMatchDatasExpansions(CodeExpansions &CE) const;
670 /// Adds a matcher \p P to \p IM, expanding its code using \p CE.
671 /// Note that the predicate is added on the last InstructionMatcher.
673 /// \p Alts is only used if DebugCXXPreds is enabled.
674 void addCXXPredicate(RuleMatcher &M, const CodeExpansions &CE,
675 const CXXPattern &P, const PatternAlternatives &Alts);
677 /// Adds an apply \p P to \p IM, expanding its code using \p CE.
678 void addCXXAction(RuleMatcher &M, const CodeExpansions &CE,
679 const CXXPattern &P);
681 bool hasOnlyCXXApplyPatterns() const;
682 bool hasEraseRoot() const;
684 // Infer machine operand types and check their consistency.
685 bool typecheckPatterns();
687 /// For all PatFragPatterns, add a new entry in PatternAlternatives for each
688 /// PatternList it contains. This is multiplicative, so if we have 2
689 /// PatFrags with 3 alternatives each, we get 2*3 permutations added to
690 /// PermutationsToEmit. The "MaxPermutations" field controls how many
691 /// permutations are allowed before an error is emitted and this function
692 /// returns false. This is a simple safeguard to prevent combination of
693 /// PatFrags from generating enormous amounts of rules.
694 bool buildPermutationsToEmit();
696 /// Checks additional semantics of the Patterns.
697 bool checkSemantics();
699 /// Creates a new RuleMatcher with some boilerplate
700 /// settings/actions/predicates, and and adds it to \p OutRMs.
701 /// \see addFeaturePredicates too.
703 /// \param Alts Current set of alternatives, for debug comment.
704 /// \param AdditionalComment Comment string to be added to the
705 /// `DebugCommentAction`.
706 RuleMatcher &addRuleMatcher(const PatternAlternatives &Alts,
707 Twine AdditionalComment = "");
708 bool addFeaturePredicates(RuleMatcher &M);
710 bool findRoots();
711 bool buildRuleOperandsTable();
713 bool parseDefs(const DagInit &Def);
714 bool
715 parsePatternList(const DagInit &List,
716 function_ref<bool(std::unique_ptr<Pattern>)> ParseAction,
717 StringRef Operator, ArrayRef<SMLoc> DiagLoc,
718 StringRef AnonPatNamePrefix) const;
720 std::unique_ptr<Pattern> parseInstructionPattern(const Init &Arg,
721 StringRef PatName) const;
722 std::unique_ptr<Pattern> parseWipMatchOpcodeMatcher(const Init &Arg,
723 StringRef PatName) const;
724 bool parseInstructionPatternOperand(InstructionPattern &IP,
725 const Init *OpInit,
726 const StringInit *OpName) const;
727 bool parseInstructionPatternMIFlags(InstructionPattern &IP,
728 const DagInit *Op) const;
729 std::unique_ptr<PatFrag> parsePatFragImpl(const Record *Def) const;
730 bool parsePatFragParamList(
731 ArrayRef<SMLoc> DiagLoc, const DagInit &OpsList,
732 function_ref<bool(StringRef, PatFrag::ParamKind)> ParseAction) const;
733 const PatFrag *parsePatFrag(const Record *Def) const;
735 bool emitMatchPattern(CodeExpansions &CE, const PatternAlternatives &Alts,
736 const InstructionPattern &IP);
737 bool emitMatchPattern(CodeExpansions &CE, const PatternAlternatives &Alts,
738 const AnyOpcodePattern &AOP);
740 bool emitPatFragMatchPattern(CodeExpansions &CE,
741 const PatternAlternatives &Alts, RuleMatcher &RM,
742 InstructionMatcher *IM,
743 const PatFragPattern &PFP,
744 DenseSet<const Pattern *> &SeenPats);
746 bool emitApplyPatterns(CodeExpansions &CE, RuleMatcher &M);
748 // Recursively visits InstructionPatterns from P to build up the
749 // RuleMatcher actions.
750 bool emitInstructionApplyPattern(CodeExpansions &CE, RuleMatcher &M,
751 const InstructionPattern &P,
752 DenseSet<const Pattern *> &SeenPats,
753 StringMap<unsigned> &OperandToTempRegID);
755 bool emitCodeGenInstructionApplyImmOperand(RuleMatcher &M,
756 BuildMIAction &DstMI,
757 const CodeGenInstructionPattern &P,
758 const InstructionOperand &O);
760 bool emitBuiltinApplyPattern(CodeExpansions &CE, RuleMatcher &M,
761 const BuiltinPattern &P,
762 StringMap<unsigned> &OperandToTempRegID);
764 // Recursively visits CodeGenInstructionPattern from P to build up the
765 // RuleMatcher/InstructionMatcher. May create new InstructionMatchers as
766 // needed.
767 using OperandMapperFnRef =
768 function_ref<InstructionOperand(const InstructionOperand &)>;
769 using OperandDefLookupFn =
770 function_ref<const InstructionPattern *(StringRef)>;
771 bool emitCodeGenInstructionMatchPattern(
772 CodeExpansions &CE, const PatternAlternatives &Alts, RuleMatcher &M,
773 InstructionMatcher &IM, const CodeGenInstructionPattern &P,
774 DenseSet<const Pattern *> &SeenPats, OperandDefLookupFn LookupOperandDef,
775 OperandMapperFnRef OperandMapper = [](const auto &O) { return O; });
777 const CodeGenTarget &CGT;
778 SubtargetFeatureInfoMap &SubtargetFeatures;
779 Record &RuleDef;
780 const unsigned RuleID;
781 std::vector<RuleMatcher> &OutRMs;
783 // For InstructionMatcher::addOperand
784 unsigned AllocatedTemporariesBaseID = 0;
786 /// The root of the pattern.
787 StringRef RootName;
789 /// These maps have ownership of the actual Pattern objects.
790 /// They both map a Pattern's name to the Pattern instance.
791 PatternMap MatchPats;
792 PatternMap ApplyPats;
794 /// Operand tables to tie match/apply patterns together.
795 OperandTable MatchOpTable;
796 OperandTable ApplyOpTable;
798 /// Set by findRoots.
799 Pattern *MatchRoot = nullptr;
800 SmallDenseSet<InstructionPattern *, 2> ApplyRoots;
802 SmallVector<MatchDataInfo, 2> MatchDatas;
803 SmallVector<PatternAlternatives, 1> PermutationsToEmit;
805 // print()/debug-only members.
806 mutable SmallPtrSet<const PatFrag *, 2> SeenPatFrags;
809 bool CombineRuleBuilder::parseAll() {
810 auto StackTrace = PrettyStackTraceParse(RuleDef);
812 if (!parseDefs(*RuleDef.getValueAsDag("Defs")))
813 return false;
815 if (!parsePatternList(
816 *RuleDef.getValueAsDag("Match"),
817 [this](auto Pat) { return addMatchPattern(std::move(Pat)); }, "match",
818 RuleDef.getLoc(), (RuleDef.getName() + "_match").str()))
819 return false;
821 if (!parsePatternList(
822 *RuleDef.getValueAsDag("Apply"),
823 [this](auto Pat) { return addApplyPattern(std::move(Pat)); }, "apply",
824 RuleDef.getLoc(), (RuleDef.getName() + "_apply").str()))
825 return false;
827 if (!buildRuleOperandsTable() || !typecheckPatterns() || !findRoots() ||
828 !checkSemantics() || !buildPermutationsToEmit())
829 return false;
830 LLVM_DEBUG(verify());
831 return true;
834 bool CombineRuleBuilder::emitRuleMatchers() {
835 auto StackTrace = PrettyStackTraceEmit(RuleDef);
837 assert(MatchRoot);
838 CodeExpansions CE;
839 declareAllMatchDatasExpansions(CE);
841 assert(!PermutationsToEmit.empty());
842 for (const auto &Alts : PermutationsToEmit) {
843 switch (MatchRoot->getKind()) {
844 case Pattern::K_AnyOpcode: {
845 if (!emitMatchPattern(CE, Alts, *cast<AnyOpcodePattern>(MatchRoot)))
846 return false;
847 break;
849 case Pattern::K_PatFrag:
850 case Pattern::K_Builtin:
851 case Pattern::K_CodeGenInstruction:
852 if (!emitMatchPattern(CE, Alts, *cast<InstructionPattern>(MatchRoot)))
853 return false;
854 break;
855 case Pattern::K_CXX:
856 PrintError("C++ code cannot be the root of a rule!");
857 return false;
858 default:
859 llvm_unreachable("unknown pattern kind!");
863 return true;
866 void CombineRuleBuilder::print(raw_ostream &OS) const {
867 OS << "(CombineRule name:" << RuleDef.getName() << " id:" << RuleID
868 << " root:" << RootName << '\n';
870 if (!MatchDatas.empty()) {
871 OS << " (MatchDatas\n";
872 for (const auto &MD : MatchDatas) {
873 OS << " ";
874 MD.print(OS);
875 OS << '\n';
877 OS << " )\n";
880 if (!SeenPatFrags.empty()) {
881 OS << " (PatFrags\n";
882 for (const auto *PF : SeenPatFrags) {
883 PF->print(OS, /*Indent=*/" ");
884 OS << '\n';
886 OS << " )\n";
889 const auto DumpPats = [&](StringRef Name, const PatternMap &Pats) {
890 OS << " (" << Name << " ";
891 if (Pats.empty()) {
892 OS << "<empty>)\n";
893 return;
896 OS << '\n';
897 for (const auto &[Name, Pat] : Pats) {
898 OS << " ";
899 if (Pat.get() == MatchRoot)
900 OS << "<match_root>";
901 if (isa<InstructionPattern>(Pat.get()) &&
902 ApplyRoots.contains(cast<InstructionPattern>(Pat.get())))
903 OS << "<apply_root>";
904 OS << Name << ":";
905 Pat->print(OS, /*PrintName=*/false);
906 OS << '\n';
908 OS << " )\n";
911 DumpPats("MatchPats", MatchPats);
912 DumpPats("ApplyPats", ApplyPats);
914 MatchOpTable.print(OS, "MatchPats", /*Indent*/ " ");
915 ApplyOpTable.print(OS, "ApplyPats", /*Indent*/ " ");
917 if (PermutationsToEmit.size() > 1) {
918 OS << " (PermutationsToEmit\n";
919 for (const auto &Perm : PermutationsToEmit) {
920 OS << " ";
921 print(OS, Perm);
922 OS << ",\n";
924 OS << " )\n";
927 OS << ")\n";
930 #ifndef NDEBUG
931 void CombineRuleBuilder::verify() const {
932 const auto VerifyPats = [&](const PatternMap &Pats) {
933 for (const auto &[Name, Pat] : Pats) {
934 if (!Pat)
935 PrintFatalError("null pattern in pattern map!");
937 if (Name != Pat->getName()) {
938 Pat->dump();
939 PrintFatalError("Pattern name mismatch! Map name: " + Name +
940 ", Pat name: " + Pat->getName());
943 // Sanity check: the map should point to the same data as the Pattern.
944 // Both strings are allocated in the pool using insertStrRef.
945 if (Name.data() != Pat->getName().data()) {
946 dbgs() << "Map StringRef: '" << Name << "' @ "
947 << (const void *)Name.data() << '\n';
948 dbgs() << "Pat String: '" << Pat->getName() << "' @ "
949 << (const void *)Pat->getName().data() << '\n';
950 PrintFatalError("StringRef stored in the PatternMap is not referencing "
951 "the same string as its Pattern!");
956 VerifyPats(MatchPats);
957 VerifyPats(ApplyPats);
959 // Check there are no wip_match_opcode patterns in the "apply" patterns.
960 if (any_of(ApplyPats,
961 [&](auto &E) { return isa<AnyOpcodePattern>(E.second.get()); })) {
962 dump();
963 PrintFatalError(
964 "illegal wip_match_opcode pattern in the 'apply' patterns!");
967 // Check there are no nullptrs in ApplyRoots.
968 if (ApplyRoots.contains(nullptr)) {
969 PrintFatalError(
970 "CombineRuleBuilder's ApplyRoots set contains a null pointer!");
973 #endif
975 void CombineRuleBuilder::print(raw_ostream &OS,
976 const PatternAlternatives &Alts) const {
977 SmallVector<std::string, 1> Strings(
978 map_range(Alts, [](const auto &PatAndPerm) {
979 return PatAndPerm.first->getName().str() + "[" +
980 to_string(PatAndPerm.second) + "]";
981 }));
982 // Sort so output is deterministic for tests. Otherwise it's sorted by pointer
983 // values.
984 sort(Strings);
985 OS << "[" << join(Strings, ", ") << "]";
988 bool CombineRuleBuilder::addApplyPattern(std::unique_ptr<Pattern> Pat) {
989 StringRef Name = Pat->getName();
990 if (ApplyPats.contains(Name)) {
991 PrintError("'" + Name + "' apply pattern defined more than once!");
992 return false;
995 if (isa<AnyOpcodePattern>(Pat.get())) {
996 PrintError("'" + Name +
997 "': wip_match_opcode is not supported in apply patterns");
998 return false;
1001 if (isa<PatFragPattern>(Pat.get())) {
1002 PrintError("'" + Name + "': using " + PatFrag::ClassName +
1003 " is not supported in apply patterns");
1004 return false;
1007 if (auto *CXXPat = dyn_cast<CXXPattern>(Pat.get()))
1008 CXXPat->setIsApply();
1010 ApplyPats[Name] = std::move(Pat);
1011 return true;
1014 bool CombineRuleBuilder::addMatchPattern(std::unique_ptr<Pattern> Pat) {
1015 StringRef Name = Pat->getName();
1016 if (MatchPats.contains(Name)) {
1017 PrintError("'" + Name + "' match pattern defined more than once!");
1018 return false;
1021 // For now, none of the builtins can appear in 'match'.
1022 if (const auto *BP = dyn_cast<BuiltinPattern>(Pat.get())) {
1023 PrintError("'" + BP->getInstName() +
1024 "' cannot be used in a 'match' pattern");
1025 return false;
1028 MatchPats[Name] = std::move(Pat);
1029 return true;
1032 void CombineRuleBuilder::declareAllMatchDatasExpansions(
1033 CodeExpansions &CE) const {
1034 for (const auto &MD : MatchDatas)
1035 CE.declare(MD.getPatternSymbol(), MD.getQualifiedVariableName());
1038 void CombineRuleBuilder::addCXXPredicate(RuleMatcher &M,
1039 const CodeExpansions &CE,
1040 const CXXPattern &P,
1041 const PatternAlternatives &Alts) {
1042 // FIXME: Hack so C++ code is executed last. May not work for more complex
1043 // patterns.
1044 auto &IM = *std::prev(M.insnmatchers().end());
1045 auto Loc = RuleDef.getLoc();
1046 const auto AddComment = [&](raw_ostream &OS) {
1047 OS << "// Pattern Alternatives: ";
1048 print(OS, Alts);
1049 OS << '\n';
1051 const auto &ExpandedCode =
1052 DebugCXXPreds ? P.expandCode(CE, Loc, AddComment) : P.expandCode(CE, Loc);
1053 IM->addPredicate<GenericInstructionPredicateMatcher>(
1054 ExpandedCode.getEnumNameWithPrefix(CXXPredPrefix));
1057 void CombineRuleBuilder::addCXXAction(RuleMatcher &M, const CodeExpansions &CE,
1058 const CXXPattern &P) {
1059 const auto &ExpandedCode = P.expandCode(CE, RuleDef.getLoc());
1060 M.addAction<CustomCXXAction>(
1061 ExpandedCode.getEnumNameWithPrefix(CXXApplyPrefix));
1064 bool CombineRuleBuilder::hasOnlyCXXApplyPatterns() const {
1065 return all_of(ApplyPats, [&](auto &Entry) {
1066 return isa<CXXPattern>(Entry.second.get());
1070 bool CombineRuleBuilder::hasEraseRoot() const {
1071 return any_of(ApplyPats, [&](auto &Entry) {
1072 if (const auto *BP = dyn_cast<BuiltinPattern>(Entry.second.get()))
1073 return BP->getBuiltinKind() == BI_EraseRoot;
1074 return false;
1078 bool CombineRuleBuilder::typecheckPatterns() {
1079 CombineRuleOperandTypeChecker OTC(RuleDef, MatchOpTable);
1081 for (auto &Pat : values(MatchPats)) {
1082 if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1083 if (!OTC.processMatchPattern(*IP))
1084 return false;
1088 for (auto &Pat : values(ApplyPats)) {
1089 if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1090 if (!OTC.processApplyPattern(*IP))
1091 return false;
1095 OTC.propagateAndInferTypes();
1097 // Always check this after in case inference adds some special types to the
1098 // match patterns.
1099 for (auto &Pat : values(MatchPats)) {
1100 if (auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
1101 if (IP->diagnoseAllSpecialTypes(
1102 RuleDef.getLoc(), PatternType::SpecialTyClassName +
1103 " is not supported in 'match' patterns")) {
1104 return false;
1108 return true;
1111 bool CombineRuleBuilder::buildPermutationsToEmit() {
1112 PermutationsToEmit.clear();
1114 // Start with one empty set of alternatives.
1115 PermutationsToEmit.emplace_back();
1116 for (const auto &Pat : values(MatchPats)) {
1117 unsigned NumAlts = 0;
1118 // Note: technically, AnyOpcodePattern also needs permutations, but:
1119 // - We only allow a single one of them in the root.
1120 // - They cannot be mixed with any other pattern other than C++ code.
1121 // So we don't really need to take them into account here. We could, but
1122 // that pattern is a hack anyway and the less it's involved, the better.
1123 if (const auto *PFP = dyn_cast<PatFragPattern>(Pat.get()))
1124 NumAlts = PFP->getPatFrag().num_alternatives();
1125 else
1126 continue;
1128 // For each pattern that needs permutations, multiply the current set of
1129 // alternatives.
1130 auto CurPerms = PermutationsToEmit;
1131 PermutationsToEmit.clear();
1133 for (const auto &Perm : CurPerms) {
1134 assert(!Perm.count(Pat.get()) && "Pattern already emitted?");
1135 for (unsigned K = 0; K < NumAlts; ++K) {
1136 PatternAlternatives NewPerm = Perm;
1137 NewPerm[Pat.get()] = K;
1138 PermutationsToEmit.emplace_back(std::move(NewPerm));
1143 if (int64_t MaxPerms = RuleDef.getValueAsInt("MaxPermutations");
1144 MaxPerms > 0) {
1145 if ((int64_t)PermutationsToEmit.size() > MaxPerms) {
1146 PrintError("cannot emit rule '" + RuleDef.getName() + "'; " +
1147 Twine(PermutationsToEmit.size()) +
1148 " permutations would be emitted, but the max is " +
1149 Twine(MaxPerms));
1150 return false;
1154 // Ensure we always have a single empty entry, it simplifies the emission
1155 // logic so it doesn't need to handle the case where there are no perms.
1156 if (PermutationsToEmit.empty()) {
1157 PermutationsToEmit.emplace_back();
1158 return true;
1161 return true;
1164 bool CombineRuleBuilder::checkSemantics() {
1165 assert(MatchRoot && "Cannot call this before findRoots()");
1167 bool UsesWipMatchOpcode = false;
1168 for (const auto &Match : MatchPats) {
1169 const auto *Pat = Match.second.get();
1171 if (const auto *CXXPat = dyn_cast<CXXPattern>(Pat)) {
1172 if (!CXXPat->getRawCode().contains("return "))
1173 PrintWarning("'match' C++ code does not seem to return!");
1174 continue;
1177 // MIFlags in match cannot use the following syntax: (MIFlags $mi)
1178 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(Pat)) {
1179 if (auto *FI = CGP->getMIFlagsInfo()) {
1180 if (!FI->copy_flags().empty()) {
1181 PrintError(
1182 "'match' patterns cannot refer to flags from other instructions");
1183 PrintNote("MIFlags in '" + CGP->getName() +
1184 "' refer to: " + join(FI->copy_flags(), ", "));
1185 return false;
1190 const auto *AOP = dyn_cast<AnyOpcodePattern>(Pat);
1191 if (!AOP)
1192 continue;
1194 if (UsesWipMatchOpcode) {
1195 PrintError("wip_opcode_match can only be present once");
1196 return false;
1199 UsesWipMatchOpcode = true;
1202 for (const auto &Apply : ApplyPats) {
1203 assert(Apply.second.get());
1204 const auto *IP = dyn_cast<InstructionPattern>(Apply.second.get());
1205 if (!IP)
1206 continue;
1208 if (UsesWipMatchOpcode) {
1209 PrintError("cannot use wip_match_opcode in combination with apply "
1210 "instruction patterns!");
1211 return false;
1214 // Check that the insts mentioned in copy_flags exist.
1215 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(IP)) {
1216 if (auto *FI = CGP->getMIFlagsInfo()) {
1217 for (auto InstName : FI->copy_flags()) {
1218 auto It = MatchPats.find(InstName);
1219 if (It == MatchPats.end()) {
1220 PrintError("unknown instruction '$" + InstName +
1221 "' referenced in MIFlags of '" + CGP->getName() + "'");
1222 return false;
1225 if (!isa<CodeGenInstructionPattern>(It->second.get())) {
1226 PrintError(
1227 "'$" + InstName +
1228 "' does not refer to a CodeGenInstruction in MIFlags of '" +
1229 CGP->getName() + "'");
1230 return false;
1236 const auto *BIP = dyn_cast<BuiltinPattern>(IP);
1237 if (!BIP)
1238 continue;
1239 StringRef Name = BIP->getInstName();
1241 // (GIEraseInst) has to be the only apply pattern, or it can not be used at
1242 // all. The root cannot have any defs either.
1243 switch (BIP->getBuiltinKind()) {
1244 case BI_EraseRoot: {
1245 if (ApplyPats.size() > 1) {
1246 PrintError(Name + " must be the only 'apply' pattern");
1247 return false;
1250 const auto *IRoot = dyn_cast<CodeGenInstructionPattern>(MatchRoot);
1251 if (!IRoot) {
1252 PrintError(Name +
1253 " can only be used if the root is a CodeGenInstruction");
1254 return false;
1257 if (IRoot->getNumInstDefs() != 0) {
1258 PrintError(Name + " can only be used if on roots that do "
1259 "not have any output operand");
1260 PrintNote("'" + IRoot->getInstName() + "' has " +
1261 Twine(IRoot->getNumInstDefs()) + " output operands");
1262 return false;
1264 break;
1266 case BI_ReplaceReg: {
1267 // (GIReplaceReg can only be used on the root instruction)
1268 // TODO: When we allow rewriting non-root instructions, also allow this.
1269 StringRef OldRegName = BIP->getOperand(0).getOperandName();
1270 auto *Def = MatchOpTable.getDef(OldRegName);
1271 if (!Def) {
1272 PrintError(Name + " cannot find a matched pattern that defines '" +
1273 OldRegName + "'");
1274 return false;
1276 if (MatchOpTable.getDef(OldRegName) != MatchRoot) {
1277 PrintError(Name + " cannot replace '" + OldRegName +
1278 "': this builtin can only replace a register defined by the "
1279 "match root");
1280 return false;
1282 break;
1287 return true;
1290 RuleMatcher &CombineRuleBuilder::addRuleMatcher(const PatternAlternatives &Alts,
1291 Twine AdditionalComment) {
1292 auto &RM = OutRMs.emplace_back(RuleDef.getLoc());
1293 addFeaturePredicates(RM);
1294 RM.setPermanentGISelFlags(GISF_IgnoreCopies);
1295 RM.addRequiredSimplePredicate(getIsEnabledPredicateEnumName(RuleID));
1297 std::string Comment;
1298 raw_string_ostream CommentOS(Comment);
1299 CommentOS << "Combiner Rule #" << RuleID << ": " << RuleDef.getName();
1300 if (!Alts.empty()) {
1301 CommentOS << " @ ";
1302 print(CommentOS, Alts);
1304 if (!AdditionalComment.isTriviallyEmpty())
1305 CommentOS << "; " << AdditionalComment;
1306 RM.addAction<DebugCommentAction>(Comment);
1307 return RM;
1310 bool CombineRuleBuilder::addFeaturePredicates(RuleMatcher &M) {
1311 if (!RuleDef.getValue("Predicates"))
1312 return true;
1314 ListInit *Preds = RuleDef.getValueAsListInit("Predicates");
1315 for (Init *PI : Preds->getValues()) {
1316 DefInit *Pred = dyn_cast<DefInit>(PI);
1317 if (!Pred)
1318 continue;
1320 Record *Def = Pred->getDef();
1321 if (!Def->isSubClassOf("Predicate")) {
1322 ::PrintError(Def, "Unknown 'Predicate' Type");
1323 return false;
1326 if (Def->getValueAsString("CondString").empty())
1327 continue;
1329 if (SubtargetFeatures.count(Def) == 0) {
1330 SubtargetFeatures.emplace(
1331 Def, SubtargetFeatureInfo(Def, SubtargetFeatures.size()));
1334 M.addRequiredFeature(Def);
1337 return true;
1340 bool CombineRuleBuilder::findRoots() {
1341 const auto Finish = [&]() {
1342 assert(MatchRoot);
1344 if (hasOnlyCXXApplyPatterns() || hasEraseRoot())
1345 return true;
1347 auto *IPRoot = dyn_cast<InstructionPattern>(MatchRoot);
1348 if (!IPRoot)
1349 return true;
1351 if (IPRoot->getNumInstDefs() == 0) {
1352 // No defs to work with -> find the root using the pattern name.
1353 auto It = ApplyPats.find(RootName);
1354 if (It == ApplyPats.end()) {
1355 PrintError("Cannot find root '" + RootName + "' in apply patterns!");
1356 return false;
1359 auto *ApplyRoot = dyn_cast<InstructionPattern>(It->second.get());
1360 if (!ApplyRoot) {
1361 PrintError("apply pattern root '" + RootName +
1362 "' must be an instruction pattern");
1363 return false;
1366 ApplyRoots.insert(ApplyRoot);
1367 return true;
1370 // Collect all redefinitions of the MatchRoot's defs and put them in
1371 // ApplyRoots.
1372 const auto DefsNeeded = IPRoot->getApplyDefsNeeded();
1373 for (auto &Op : DefsNeeded) {
1374 assert(Op.isDef() && Op.isNamedOperand());
1375 StringRef Name = Op.getOperandName();
1377 auto *ApplyRedef = ApplyOpTable.getDef(Name);
1378 if (!ApplyRedef) {
1379 PrintError("'" + Name + "' must be redefined in the 'apply' pattern");
1380 return false;
1383 ApplyRoots.insert((InstructionPattern *)ApplyRedef);
1386 if (auto It = ApplyPats.find(RootName); It != ApplyPats.end()) {
1387 if (find(ApplyRoots, It->second.get()) == ApplyRoots.end()) {
1388 PrintError("apply pattern '" + RootName +
1389 "' is supposed to be a root but it does not redefine any of "
1390 "the defs of the match root");
1391 return false;
1395 return true;
1398 // Look by pattern name, e.g.
1399 // (G_FNEG $x, $y):$root
1400 if (auto MatchPatIt = MatchPats.find(RootName);
1401 MatchPatIt != MatchPats.end()) {
1402 MatchRoot = MatchPatIt->second.get();
1403 return Finish();
1406 // Look by def:
1407 // (G_FNEG $root, $y)
1408 auto LookupRes = MatchOpTable.lookup(RootName);
1409 if (!LookupRes.Found) {
1410 PrintError("Cannot find root '" + RootName + "' in match patterns!");
1411 return false;
1414 MatchRoot = LookupRes.Def;
1415 if (!MatchRoot) {
1416 PrintError("Cannot use live-in operand '" + RootName +
1417 "' as match pattern root!");
1418 return false;
1421 return Finish();
1424 bool CombineRuleBuilder::buildRuleOperandsTable() {
1425 const auto DiagnoseRedefMatch = [&](StringRef OpName) {
1426 PrintError("Operand '" + OpName +
1427 "' is defined multiple times in the 'match' patterns");
1430 const auto DiagnoseRedefApply = [&](StringRef OpName) {
1431 PrintError("Operand '" + OpName +
1432 "' is defined multiple times in the 'apply' patterns");
1435 for (auto &Pat : values(MatchPats)) {
1436 auto *IP = dyn_cast<InstructionPattern>(Pat.get());
1437 if (IP && !MatchOpTable.addPattern(IP, DiagnoseRedefMatch))
1438 return false;
1441 for (auto &Pat : values(ApplyPats)) {
1442 auto *IP = dyn_cast<InstructionPattern>(Pat.get());
1443 if (IP && !ApplyOpTable.addPattern(IP, DiagnoseRedefApply))
1444 return false;
1447 return true;
1450 bool CombineRuleBuilder::parseDefs(const DagInit &Def) {
1451 if (Def.getOperatorAsDef(RuleDef.getLoc())->getName() != "defs") {
1452 PrintError("Expected defs operator");
1453 return false;
1456 SmallVector<StringRef> Roots;
1457 for (unsigned I = 0, E = Def.getNumArgs(); I < E; ++I) {
1458 if (isSpecificDef(*Def.getArg(I), "root")) {
1459 Roots.emplace_back(Def.getArgNameStr(I));
1460 continue;
1463 // Subclasses of GIDefMatchData should declare that this rule needs to pass
1464 // data from the match stage to the apply stage, and ensure that the
1465 // generated matcher has a suitable variable for it to do so.
1466 if (Record *MatchDataRec =
1467 getDefOfSubClass(*Def.getArg(I), "GIDefMatchData")) {
1468 MatchDatas.emplace_back(Def.getArgNameStr(I),
1469 MatchDataRec->getValueAsString("Type"));
1470 continue;
1473 // Otherwise emit an appropriate error message.
1474 if (getDefOfSubClass(*Def.getArg(I), "GIDefKind"))
1475 PrintError("This GIDefKind not implemented in tablegen");
1476 else if (getDefOfSubClass(*Def.getArg(I), "GIDefKindWithArgs"))
1477 PrintError("This GIDefKindWithArgs not implemented in tablegen");
1478 else
1479 PrintError("Expected a subclass of GIDefKind or a sub-dag whose "
1480 "operator is of type GIDefKindWithArgs");
1481 return false;
1484 if (Roots.size() != 1) {
1485 PrintError("Combine rules must have exactly one root");
1486 return false;
1489 RootName = Roots.front();
1491 // Assign variables to all MatchDatas.
1492 AssignMatchDataVariables(MatchDatas);
1493 return true;
1496 bool CombineRuleBuilder::parsePatternList(
1497 const DagInit &List,
1498 function_ref<bool(std::unique_ptr<Pattern>)> ParseAction,
1499 StringRef Operator, ArrayRef<SMLoc> DiagLoc,
1500 StringRef AnonPatNamePrefix) const {
1501 if (List.getOperatorAsDef(RuleDef.getLoc())->getName() != Operator) {
1502 ::PrintError(DiagLoc, "Expected " + Operator + " operator");
1503 return false;
1506 if (List.getNumArgs() == 0) {
1507 ::PrintError(DiagLoc, Operator + " pattern list is empty");
1508 return false;
1511 // The match section consists of a list of matchers and predicates. Parse each
1512 // one and add the equivalent GIMatchDag nodes, predicates, and edges.
1513 for (unsigned I = 0; I < List.getNumArgs(); ++I) {
1514 Init *Arg = List.getArg(I);
1515 std::string Name = List.getArgName(I)
1516 ? List.getArgName(I)->getValue().str()
1517 : ("__" + AnonPatNamePrefix + "_" + Twine(I)).str();
1519 if (auto Pat = parseInstructionPattern(*Arg, Name)) {
1520 if (!ParseAction(std::move(Pat)))
1521 return false;
1522 continue;
1525 if (auto Pat = parseWipMatchOpcodeMatcher(*Arg, Name)) {
1526 if (!ParseAction(std::move(Pat)))
1527 return false;
1528 continue;
1531 // Parse arbitrary C++ code
1532 if (const auto *StringI = dyn_cast<StringInit>(Arg)) {
1533 auto CXXPat = std::make_unique<CXXPattern>(*StringI, insertStrRef(Name));
1534 if (!ParseAction(std::move(CXXPat)))
1535 return false;
1536 continue;
1539 ::PrintError(DiagLoc,
1540 "Failed to parse pattern: '" + Arg->getAsString() + "'");
1541 return false;
1544 return true;
1547 std::unique_ptr<Pattern>
1548 CombineRuleBuilder::parseInstructionPattern(const Init &Arg,
1549 StringRef Name) const {
1550 const DagInit *DagPat = dyn_cast<DagInit>(&Arg);
1551 if (!DagPat)
1552 return nullptr;
1554 std::unique_ptr<InstructionPattern> Pat;
1555 if (const DagInit *IP = getDagWithOperatorOfSubClass(Arg, "Instruction")) {
1556 auto &Instr = CGT.getInstruction(IP->getOperatorAsDef(RuleDef.getLoc()));
1557 Pat =
1558 std::make_unique<CodeGenInstructionPattern>(Instr, insertStrRef(Name));
1559 } else if (const DagInit *PFP =
1560 getDagWithOperatorOfSubClass(Arg, PatFrag::ClassName)) {
1561 const Record *Def = PFP->getOperatorAsDef(RuleDef.getLoc());
1562 const PatFrag *PF = parsePatFrag(Def);
1563 if (!PF)
1564 return nullptr; // Already diagnosed by parsePatFrag
1565 Pat = std::make_unique<PatFragPattern>(*PF, insertStrRef(Name));
1566 } else if (const DagInit *BP =
1567 getDagWithOperatorOfSubClass(Arg, BuiltinPattern::ClassName)) {
1568 Pat = std::make_unique<BuiltinPattern>(
1569 *BP->getOperatorAsDef(RuleDef.getLoc()), insertStrRef(Name));
1570 } else {
1571 return nullptr;
1574 for (unsigned K = 0; K < DagPat->getNumArgs(); ++K) {
1575 Init *Arg = DagPat->getArg(K);
1576 if (auto *DagArg = getDagWithSpecificOperator(*Arg, "MIFlags")) {
1577 if (!parseInstructionPatternMIFlags(*Pat, DagArg))
1578 return nullptr;
1579 continue;
1582 if (!parseInstructionPatternOperand(*Pat, Arg, DagPat->getArgName(K)))
1583 return nullptr;
1586 if (!Pat->checkSemantics(RuleDef.getLoc()))
1587 return nullptr;
1589 return std::move(Pat);
1592 std::unique_ptr<Pattern>
1593 CombineRuleBuilder::parseWipMatchOpcodeMatcher(const Init &Arg,
1594 StringRef Name) const {
1595 const DagInit *Matcher = getDagWithSpecificOperator(Arg, "wip_match_opcode");
1596 if (!Matcher)
1597 return nullptr;
1599 if (Matcher->getNumArgs() == 0) {
1600 PrintError("Empty wip_match_opcode");
1601 return nullptr;
1604 // Each argument is an opcode that can match.
1605 auto Result = std::make_unique<AnyOpcodePattern>(insertStrRef(Name));
1606 for (const auto &Arg : Matcher->getArgs()) {
1607 Record *OpcodeDef = getDefOfSubClass(*Arg, "Instruction");
1608 if (OpcodeDef) {
1609 Result->addOpcode(&CGT.getInstruction(OpcodeDef));
1610 continue;
1613 PrintError("Arguments to wip_match_opcode must be instructions");
1614 return nullptr;
1617 return std::move(Result);
1620 bool CombineRuleBuilder::parseInstructionPatternOperand(
1621 InstructionPattern &IP, const Init *OpInit,
1622 const StringInit *OpName) const {
1623 const auto ParseErr = [&]() {
1624 PrintError("cannot parse operand '" + OpInit->getAsUnquotedString() + "' ");
1625 if (OpName)
1626 PrintNote("operand name is '" + OpName->getAsUnquotedString() + "'");
1627 return false;
1630 // untyped immediate, e.g. 0
1631 if (const auto *IntImm = dyn_cast<IntInit>(OpInit)) {
1632 std::string Name = OpName ? OpName->getAsUnquotedString() : "";
1633 IP.addOperand(IntImm->getValue(), insertStrRef(Name), PatternType());
1634 return true;
1637 // typed immediate, e.g. (i32 0)
1638 if (const auto *DagOp = dyn_cast<DagInit>(OpInit)) {
1639 if (DagOp->getNumArgs() != 1)
1640 return ParseErr();
1642 const Record *TyDef = DagOp->getOperatorAsDef(RuleDef.getLoc());
1643 auto ImmTy = PatternType::get(RuleDef.getLoc(), TyDef,
1644 "cannot parse immediate '" +
1645 DagOp->getAsUnquotedString() + "'");
1646 if (!ImmTy)
1647 return false;
1649 if (!IP.hasAllDefs()) {
1650 PrintError("out operand of '" + IP.getInstName() +
1651 "' cannot be an immediate");
1652 return false;
1655 const auto *Val = dyn_cast<IntInit>(DagOp->getArg(0));
1656 if (!Val)
1657 return ParseErr();
1659 std::string Name = OpName ? OpName->getAsUnquotedString() : "";
1660 IP.addOperand(Val->getValue(), insertStrRef(Name), *ImmTy);
1661 return true;
1664 // Typed operand e.g. $x/$z in (G_FNEG $x, $z)
1665 if (auto *DefI = dyn_cast<DefInit>(OpInit)) {
1666 if (!OpName) {
1667 PrintError("expected an operand name after '" + OpInit->getAsString() +
1668 "'");
1669 return false;
1671 const Record *Def = DefI->getDef();
1672 auto Ty =
1673 PatternType::get(RuleDef.getLoc(), Def, "cannot parse operand type");
1674 if (!Ty)
1675 return false;
1676 IP.addOperand(insertStrRef(OpName->getAsUnquotedString()), *Ty);
1677 return true;
1680 // Untyped operand e.g. $x/$z in (G_FNEG $x, $z)
1681 if (isa<UnsetInit>(OpInit)) {
1682 assert(OpName && "Unset w/ no OpName?");
1683 IP.addOperand(insertStrRef(OpName->getAsUnquotedString()), PatternType());
1684 return true;
1687 return ParseErr();
1690 bool CombineRuleBuilder::parseInstructionPatternMIFlags(
1691 InstructionPattern &IP, const DagInit *Op) const {
1692 auto *CGIP = dyn_cast<CodeGenInstructionPattern>(&IP);
1693 if (!CGIP) {
1694 PrintError("matching/writing MIFlags is only allowed on CodeGenInstruction "
1695 "patterns");
1696 return false;
1699 const auto CheckFlagEnum = [&](const Record *R) {
1700 if (!R->isSubClassOf(MIFlagsEnumClassName)) {
1701 PrintError("'" + R->getName() + "' is not a subclass of '" +
1702 MIFlagsEnumClassName + "'");
1703 return false;
1706 return true;
1709 if (CGIP->getMIFlagsInfo()) {
1710 PrintError("MIFlags can only be present once on an instruction");
1711 return false;
1714 auto &FI = CGIP->getOrCreateMIFlagsInfo();
1715 for (unsigned K = 0; K < Op->getNumArgs(); ++K) {
1716 const Init *Arg = Op->getArg(K);
1718 // Match/set a flag: (MIFlags FmNoNans)
1719 if (const auto *Def = dyn_cast<DefInit>(Arg)) {
1720 const Record *R = Def->getDef();
1721 if (!CheckFlagEnum(R))
1722 return false;
1724 FI.addSetFlag(R);
1725 continue;
1728 // Do not match a flag/unset a flag: (MIFlags (not FmNoNans))
1729 if (const DagInit *NotDag = getDagWithSpecificOperator(*Arg, "not")) {
1730 for (const Init *NotArg : NotDag->getArgs()) {
1731 const DefInit *DefArg = dyn_cast<DefInit>(NotArg);
1732 if (!DefArg) {
1733 PrintError("cannot parse '" + NotArg->getAsUnquotedString() +
1734 "': expected a '" + MIFlagsEnumClassName + "'");
1735 return false;
1738 const Record *R = DefArg->getDef();
1739 if (!CheckFlagEnum(R))
1740 return false;
1742 FI.addUnsetFlag(R);
1743 continue;
1746 continue;
1749 // Copy flags from a matched instruction: (MIFlags $mi)
1750 if (isa<UnsetInit>(Arg)) {
1751 FI.addCopyFlag(insertStrRef(Op->getArgName(K)->getAsUnquotedString()));
1752 continue;
1756 return true;
1759 std::unique_ptr<PatFrag>
1760 CombineRuleBuilder::parsePatFragImpl(const Record *Def) const {
1761 auto StackTrace = PrettyStackTraceParse(*Def);
1762 if (!Def->isSubClassOf(PatFrag::ClassName))
1763 return nullptr;
1765 const DagInit *Ins = Def->getValueAsDag("InOperands");
1766 if (Ins->getOperatorAsDef(Def->getLoc())->getName() != "ins") {
1767 ::PrintError(Def, "expected 'ins' operator for " + PatFrag::ClassName +
1768 " in operands list");
1769 return nullptr;
1772 const DagInit *Outs = Def->getValueAsDag("OutOperands");
1773 if (Outs->getOperatorAsDef(Def->getLoc())->getName() != "outs") {
1774 ::PrintError(Def, "expected 'outs' operator for " + PatFrag::ClassName +
1775 " out operands list");
1776 return nullptr;
1779 auto Result = std::make_unique<PatFrag>(*Def);
1780 if (!parsePatFragParamList(Def->getLoc(), *Outs,
1781 [&](StringRef Name, PatFrag::ParamKind Kind) {
1782 Result->addOutParam(insertStrRef(Name), Kind);
1783 return true;
1785 return nullptr;
1787 if (!parsePatFragParamList(Def->getLoc(), *Ins,
1788 [&](StringRef Name, PatFrag::ParamKind Kind) {
1789 Result->addInParam(insertStrRef(Name), Kind);
1790 return true;
1792 return nullptr;
1794 const ListInit *Alts = Def->getValueAsListInit("Alternatives");
1795 unsigned AltIdx = 0;
1796 for (const Init *Alt : *Alts) {
1797 const auto *PatDag = dyn_cast<DagInit>(Alt);
1798 if (!PatDag) {
1799 ::PrintError(Def, "expected dag init for PatFrag pattern alternative");
1800 return nullptr;
1803 PatFrag::Alternative &A = Result->addAlternative();
1804 const auto AddPat = [&](std::unique_ptr<Pattern> Pat) {
1805 A.Pats.push_back(std::move(Pat));
1806 return true;
1809 if (!parsePatternList(
1810 *PatDag, AddPat, "pattern", Def->getLoc(),
1811 /*AnonPatPrefix*/
1812 (Def->getName() + "_alt" + Twine(AltIdx++) + "_pattern").str()))
1813 return nullptr;
1816 if (!Result->buildOperandsTables() || !Result->checkSemantics())
1817 return nullptr;
1819 return Result;
1822 bool CombineRuleBuilder::parsePatFragParamList(
1823 ArrayRef<SMLoc> DiagLoc, const DagInit &OpsList,
1824 function_ref<bool(StringRef, PatFrag::ParamKind)> ParseAction) const {
1825 for (unsigned K = 0; K < OpsList.getNumArgs(); ++K) {
1826 const StringInit *Name = OpsList.getArgName(K);
1827 const Init *Ty = OpsList.getArg(K);
1829 if (!Name) {
1830 ::PrintError(DiagLoc, "all operands must be named'");
1831 return false;
1833 const std::string NameStr = Name->getAsUnquotedString();
1835 PatFrag::ParamKind OpKind;
1836 if (isSpecificDef(*Ty, "gi_imm"))
1837 OpKind = PatFrag::PK_Imm;
1838 else if (isSpecificDef(*Ty, "root"))
1839 OpKind = PatFrag::PK_Root;
1840 else if (isa<UnsetInit>(Ty) ||
1841 isSpecificDef(*Ty, "gi_mo")) // no type = gi_mo.
1842 OpKind = PatFrag::PK_MachineOperand;
1843 else {
1844 ::PrintError(
1845 DiagLoc,
1846 "'" + NameStr +
1847 "' operand type was expected to be 'root', 'gi_imm' or 'gi_mo'");
1848 return false;
1851 if (!ParseAction(NameStr, OpKind))
1852 return false;
1855 return true;
1858 const PatFrag *CombineRuleBuilder::parsePatFrag(const Record *Def) const {
1859 // Cache already parsed PatFrags to avoid doing extra work.
1860 static DenseMap<const Record *, std::unique_ptr<PatFrag>> ParsedPatFrags;
1862 auto It = ParsedPatFrags.find(Def);
1863 if (It != ParsedPatFrags.end()) {
1864 SeenPatFrags.insert(It->second.get());
1865 return It->second.get();
1868 std::unique_ptr<PatFrag> NewPatFrag = parsePatFragImpl(Def);
1869 if (!NewPatFrag) {
1870 ::PrintError(Def, "Could not parse " + PatFrag::ClassName + " '" +
1871 Def->getName() + "'");
1872 // Put a nullptr in the map so we don't attempt parsing this again.
1873 ParsedPatFrags[Def] = nullptr;
1874 return nullptr;
1877 const auto *Res = NewPatFrag.get();
1878 ParsedPatFrags[Def] = std::move(NewPatFrag);
1879 SeenPatFrags.insert(Res);
1880 return Res;
1883 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions &CE,
1884 const PatternAlternatives &Alts,
1885 const InstructionPattern &IP) {
1886 auto StackTrace = PrettyStackTraceEmit(RuleDef, &IP);
1888 auto &M = addRuleMatcher(Alts);
1889 InstructionMatcher &IM = M.addInstructionMatcher(IP.getName());
1890 declareInstExpansion(CE, IM, IP.getName());
1892 DenseSet<const Pattern *> SeenPats;
1894 const auto FindOperandDef = [&](StringRef Op) -> InstructionPattern * {
1895 return MatchOpTable.getDef(Op);
1898 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(&IP)) {
1899 if (!emitCodeGenInstructionMatchPattern(CE, Alts, M, IM, *CGP, SeenPats,
1900 FindOperandDef))
1901 return false;
1902 } else if (const auto *PFP = dyn_cast<PatFragPattern>(&IP)) {
1903 if (!PFP->getPatFrag().canBeMatchRoot()) {
1904 PrintError("cannot use '" + PFP->getInstName() + " as match root");
1905 return false;
1908 if (!emitPatFragMatchPattern(CE, Alts, M, &IM, *PFP, SeenPats))
1909 return false;
1910 } else if (isa<BuiltinPattern>(&IP)) {
1911 llvm_unreachable("No match builtins known!");
1912 } else
1913 llvm_unreachable("Unknown kind of InstructionPattern!");
1915 // Emit remaining patterns
1916 for (auto &Pat : values(MatchPats)) {
1917 if (SeenPats.contains(Pat.get()))
1918 continue;
1920 switch (Pat->getKind()) {
1921 case Pattern::K_AnyOpcode:
1922 PrintError("wip_match_opcode can not be used with instruction patterns!");
1923 return false;
1924 case Pattern::K_PatFrag: {
1925 if (!emitPatFragMatchPattern(CE, Alts, M, /*IM*/ nullptr,
1926 *cast<PatFragPattern>(Pat.get()), SeenPats))
1927 return false;
1928 continue;
1930 case Pattern::K_Builtin:
1931 PrintError("No known match builtins");
1932 return false;
1933 case Pattern::K_CodeGenInstruction:
1934 cast<InstructionPattern>(Pat.get())->reportUnreachable(RuleDef.getLoc());
1935 return false;
1936 case Pattern::K_CXX: {
1937 addCXXPredicate(M, CE, *cast<CXXPattern>(Pat.get()), Alts);
1938 continue;
1940 default:
1941 llvm_unreachable("unknown pattern kind!");
1945 return emitApplyPatterns(CE, M);
1948 bool CombineRuleBuilder::emitMatchPattern(CodeExpansions &CE,
1949 const PatternAlternatives &Alts,
1950 const AnyOpcodePattern &AOP) {
1951 auto StackTrace = PrettyStackTraceEmit(RuleDef, &AOP);
1953 for (const CodeGenInstruction *CGI : AOP.insts()) {
1954 auto &M = addRuleMatcher(Alts, "wip_match_opcode '" +
1955 CGI->TheDef->getName() + "'");
1957 InstructionMatcher &IM = M.addInstructionMatcher(AOP.getName());
1958 declareInstExpansion(CE, IM, AOP.getName());
1959 // declareInstExpansion needs to be identical, otherwise we need to create a
1960 // CodeExpansions object here instead.
1961 assert(IM.getInsnVarID() == 0);
1963 IM.addPredicate<InstructionOpcodeMatcher>(CGI);
1965 // Emit remaining patterns.
1966 for (auto &Pat : values(MatchPats)) {
1967 if (Pat.get() == &AOP)
1968 continue;
1970 switch (Pat->getKind()) {
1971 case Pattern::K_AnyOpcode:
1972 PrintError("wip_match_opcode can only be present once!");
1973 return false;
1974 case Pattern::K_PatFrag: {
1975 DenseSet<const Pattern *> SeenPats;
1976 if (!emitPatFragMatchPattern(CE, Alts, M, /*IM*/ nullptr,
1977 *cast<PatFragPattern>(Pat.get()),
1978 SeenPats))
1979 return false;
1980 continue;
1982 case Pattern::K_Builtin:
1983 PrintError("No known match builtins");
1984 return false;
1985 case Pattern::K_CodeGenInstruction:
1986 cast<InstructionPattern>(Pat.get())->reportUnreachable(
1987 RuleDef.getLoc());
1988 return false;
1989 case Pattern::K_CXX: {
1990 addCXXPredicate(M, CE, *cast<CXXPattern>(Pat.get()), Alts);
1991 break;
1993 default:
1994 llvm_unreachable("unknown pattern kind!");
1998 if (!emitApplyPatterns(CE, M))
1999 return false;
2002 return true;
2005 bool CombineRuleBuilder::emitPatFragMatchPattern(
2006 CodeExpansions &CE, const PatternAlternatives &Alts, RuleMatcher &RM,
2007 InstructionMatcher *IM, const PatFragPattern &PFP,
2008 DenseSet<const Pattern *> &SeenPats) {
2009 auto StackTrace = PrettyStackTraceEmit(RuleDef, &PFP);
2011 if (SeenPats.contains(&PFP))
2012 return true;
2013 SeenPats.insert(&PFP);
2015 const auto &PF = PFP.getPatFrag();
2017 if (!IM) {
2018 // When we don't have an IM, this means this PatFrag isn't reachable from
2019 // the root. This is only acceptable if it doesn't define anything (e.g. a
2020 // pure C++ PatFrag).
2021 if (PF.num_out_params() != 0) {
2022 PFP.reportUnreachable(RuleDef.getLoc());
2023 return false;
2025 } else {
2026 // When an IM is provided, this is reachable from the root, and we're
2027 // expecting to have output operands.
2028 // TODO: If we want to allow for multiple roots we'll need a map of IMs
2029 // then, and emission becomes a bit more complicated.
2030 assert(PF.num_roots() == 1);
2033 CodeExpansions PatFragCEs;
2034 if (!PFP.mapInputCodeExpansions(CE, PatFragCEs, RuleDef.getLoc()))
2035 return false;
2037 // List of {ParamName, ArgName}.
2038 // When all patterns have been emitted, find expansions in PatFragCEs named
2039 // ArgName and add their expansion to CE using ParamName as the key.
2040 SmallVector<std::pair<std::string, std::string>, 4> CEsToImport;
2042 // Map parameter names to the actual argument.
2043 const auto OperandMapper =
2044 [&](const InstructionOperand &O) -> InstructionOperand {
2045 if (!O.isNamedOperand())
2046 return O;
2048 StringRef ParamName = O.getOperandName();
2050 // Not sure what to do with those tbh. They should probably never be here.
2051 assert(!O.isNamedImmediate() && "TODO: handle named imms");
2052 unsigned PIdx = PF.getParamIdx(ParamName);
2054 // Map parameters to the argument values.
2055 if (PIdx == (unsigned)-1) {
2056 // This is a temp of the PatFragPattern, prefix the name to avoid
2057 // conflicts.
2058 return O.withNewName(
2059 insertStrRef((PFP.getName() + "." + ParamName).str()));
2062 // The operand will be added to PatFragCEs's code expansions using the
2063 // parameter's name. If it's bound to some operand during emission of the
2064 // patterns, we'll want to add it to CE.
2065 auto ArgOp = PFP.getOperand(PIdx);
2066 if (ArgOp.isNamedOperand())
2067 CEsToImport.emplace_back(ArgOp.getOperandName().str(), ParamName);
2069 if (ArgOp.getType() && O.getType() && ArgOp.getType() != O.getType()) {
2070 StringRef PFName = PF.getName();
2071 PrintWarning("impossible type constraints: operand " + Twine(PIdx) +
2072 " of '" + PFP.getName() + "' has type '" +
2073 ArgOp.getType().str() + "', but '" + PFName +
2074 "' constrains it to '" + O.getType().str() + "'");
2075 if (ArgOp.isNamedOperand())
2076 PrintNote("operand " + Twine(PIdx) + " of '" + PFP.getName() +
2077 "' is '" + ArgOp.getOperandName() + "'");
2078 if (O.isNamedOperand())
2079 PrintNote("argument " + Twine(PIdx) + " of '" + PFName + "' is '" +
2080 ParamName + "'");
2083 return ArgOp;
2086 // PatFragPatterns are only made of InstructionPatterns or CXXPatterns.
2087 // Emit instructions from the root.
2088 const auto &FragAlt = PF.getAlternative(Alts.lookup(&PFP));
2089 const auto &FragAltOT = FragAlt.OpTable;
2090 const auto LookupOperandDef =
2091 [&](StringRef Op) -> const InstructionPattern * {
2092 return FragAltOT.getDef(Op);
2095 DenseSet<const Pattern *> PatFragSeenPats;
2096 for (const auto &[Idx, InOp] : enumerate(PF.out_params())) {
2097 if (InOp.Kind != PatFrag::PK_Root)
2098 continue;
2100 StringRef ParamName = InOp.Name;
2101 const auto *Def = FragAltOT.getDef(ParamName);
2102 assert(Def && "PatFrag::checkSemantics should have emitted an error if "
2103 "an out operand isn't defined!");
2104 assert(isa<CodeGenInstructionPattern>(Def) &&
2105 "Nested PatFrags not supported yet");
2107 if (!emitCodeGenInstructionMatchPattern(
2108 PatFragCEs, Alts, RM, *IM, *cast<CodeGenInstructionPattern>(Def),
2109 PatFragSeenPats, LookupOperandDef, OperandMapper))
2110 return false;
2113 // Emit leftovers.
2114 for (const auto &Pat : FragAlt.Pats) {
2115 if (PatFragSeenPats.contains(Pat.get()))
2116 continue;
2118 if (const auto *CXXPat = dyn_cast<CXXPattern>(Pat.get())) {
2119 addCXXPredicate(RM, PatFragCEs, *CXXPat, Alts);
2120 continue;
2123 if (const auto *IP = dyn_cast<InstructionPattern>(Pat.get())) {
2124 IP->reportUnreachable(PF.getLoc());
2125 return false;
2128 llvm_unreachable("Unexpected pattern kind in PatFrag");
2131 for (const auto &[ParamName, ArgName] : CEsToImport) {
2132 // Note: we're find if ParamName already exists. It just means it's been
2133 // bound before, so we prefer to keep the first binding.
2134 CE.declare(ParamName, PatFragCEs.lookup(ArgName));
2137 return true;
2140 bool CombineRuleBuilder::emitApplyPatterns(CodeExpansions &CE, RuleMatcher &M) {
2141 if (hasOnlyCXXApplyPatterns()) {
2142 for (auto &Pat : values(ApplyPats))
2143 addCXXAction(M, CE, *cast<CXXPattern>(Pat.get()));
2144 return true;
2147 DenseSet<const Pattern *> SeenPats;
2148 StringMap<unsigned> OperandToTempRegID;
2150 for (auto *ApplyRoot : ApplyRoots) {
2151 assert(isa<InstructionPattern>(ApplyRoot) &&
2152 "Root can only be a InstructionPattern!");
2153 if (!emitInstructionApplyPattern(CE, M,
2154 cast<InstructionPattern>(*ApplyRoot),
2155 SeenPats, OperandToTempRegID))
2156 return false;
2159 for (auto &Pat : values(ApplyPats)) {
2160 if (SeenPats.contains(Pat.get()))
2161 continue;
2163 switch (Pat->getKind()) {
2164 case Pattern::K_AnyOpcode:
2165 llvm_unreachable("Unexpected pattern in apply!");
2166 case Pattern::K_PatFrag:
2167 // TODO: We could support pure C++ PatFrags as a temporary thing.
2168 llvm_unreachable("Unexpected pattern in apply!");
2169 case Pattern::K_Builtin:
2170 if (!emitInstructionApplyPattern(CE, M, cast<BuiltinPattern>(*Pat),
2171 SeenPats, OperandToTempRegID))
2172 return false;
2173 break;
2174 case Pattern::K_CodeGenInstruction:
2175 cast<CodeGenInstructionPattern>(*Pat).reportUnreachable(RuleDef.getLoc());
2176 return false;
2177 case Pattern::K_CXX: {
2178 addCXXAction(M, CE, *cast<CXXPattern>(Pat.get()));
2179 continue;
2181 default:
2182 llvm_unreachable("unknown pattern kind!");
2186 return true;
2189 bool CombineRuleBuilder::emitInstructionApplyPattern(
2190 CodeExpansions &CE, RuleMatcher &M, const InstructionPattern &P,
2191 DenseSet<const Pattern *> &SeenPats,
2192 StringMap<unsigned> &OperandToTempRegID) {
2193 auto StackTrace = PrettyStackTraceEmit(RuleDef, &P);
2195 if (SeenPats.contains(&P))
2196 return true;
2198 SeenPats.insert(&P);
2200 // First, render the uses.
2201 for (auto &Op : P.named_operands()) {
2202 if (Op.isDef())
2203 continue;
2205 StringRef OpName = Op.getOperandName();
2206 if (const auto *DefPat = ApplyOpTable.getDef(OpName)) {
2207 if (!emitInstructionApplyPattern(CE, M, *DefPat, SeenPats,
2208 OperandToTempRegID))
2209 return false;
2210 } else {
2211 // If we have no def, check this exists in the MatchRoot.
2212 if (!Op.isNamedImmediate() && !MatchOpTable.lookup(OpName).Found) {
2213 PrintError("invalid output operand '" + OpName +
2214 "': operand is not a live-in of the match pattern, and it "
2215 "has no definition");
2216 return false;
2221 if (const auto *BP = dyn_cast<BuiltinPattern>(&P))
2222 return emitBuiltinApplyPattern(CE, M, *BP, OperandToTempRegID);
2224 if (isa<PatFragPattern>(&P))
2225 llvm_unreachable("PatFragPatterns is not supported in 'apply'!");
2227 auto &CGIP = cast<CodeGenInstructionPattern>(P);
2229 // Now render this inst.
2230 auto &DstMI =
2231 M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &CGIP.getInst());
2233 for (auto &Op : P.operands()) {
2234 if (Op.isNamedImmediate()) {
2235 PrintError("invalid output operand '" + Op.getOperandName() +
2236 "': output immediates cannot be named");
2237 PrintNote("while emitting pattern '" + P.getName() + "' (" +
2238 P.getInstName() + ")");
2239 return false;
2242 if (Op.hasImmValue()) {
2243 if (!emitCodeGenInstructionApplyImmOperand(M, DstMI, CGIP, Op))
2244 return false;
2245 continue;
2248 StringRef OpName = Op.getOperandName();
2250 // Uses of operand.
2251 if (!Op.isDef()) {
2252 if (auto It = OperandToTempRegID.find(OpName);
2253 It != OperandToTempRegID.end()) {
2254 assert(!MatchOpTable.lookup(OpName).Found &&
2255 "Temp reg is also from match pattern?");
2256 DstMI.addRenderer<TempRegRenderer>(It->second);
2257 } else {
2258 // This should be a match live in or a redef of a matched instr.
2259 // If it's a use of a temporary register, then we messed up somewhere -
2260 // the previous condition should have passed.
2261 assert(MatchOpTable.lookup(OpName).Found &&
2262 !ApplyOpTable.getDef(OpName) && "Temp reg not emitted yet!");
2263 DstMI.addRenderer<CopyRenderer>(OpName);
2265 continue;
2268 // Determine what we're dealing with. Are we replace a matched instruction?
2269 // Creating a new one?
2270 auto OpLookupRes = MatchOpTable.lookup(OpName);
2271 if (OpLookupRes.Found) {
2272 if (OpLookupRes.isLiveIn()) {
2273 // live-in of the match pattern.
2274 PrintError("Cannot define live-in operand '" + OpName +
2275 "' in the 'apply' pattern");
2276 return false;
2278 assert(OpLookupRes.Def);
2280 // TODO: Handle this. We need to mutate the instr, or delete the old
2281 // one.
2282 // Likewise, we also need to ensure we redef everything, if the
2283 // instr has more than one def, we need to redef all or nothing.
2284 if (OpLookupRes.Def != MatchRoot) {
2285 PrintError("redefining an instruction other than the root is not "
2286 "supported (operand '" +
2287 OpName + "')");
2288 return false;
2290 // redef of a match
2291 DstMI.addRenderer<CopyRenderer>(OpName);
2292 continue;
2295 // Define a new register unique to the apply patterns (AKA a "temp"
2296 // register).
2297 unsigned TempRegID;
2298 if (auto It = OperandToTempRegID.find(OpName);
2299 It != OperandToTempRegID.end()) {
2300 TempRegID = It->second;
2301 } else {
2302 // This is a brand new register.
2303 TempRegID = M.allocateTempRegID();
2304 OperandToTempRegID[OpName] = TempRegID;
2305 const auto Ty = Op.getType();
2306 if (!Ty) {
2307 PrintError("def of a new register '" + OpName +
2308 "' in the apply patterns must have a type");
2309 return false;
2312 declareTempRegExpansion(CE, TempRegID, OpName);
2313 // Always insert the action at the beginning, otherwise we may end up
2314 // using the temp reg before it's available.
2315 M.insertAction<MakeTempRegisterAction>(
2316 M.actions_begin(), getLLTCodeGenOrTempType(Ty, M), TempRegID);
2319 DstMI.addRenderer<TempRegRenderer>(TempRegID);
2322 // Render MIFlags
2323 if (const auto *FI = CGIP.getMIFlagsInfo()) {
2324 for (StringRef InstName : FI->copy_flags())
2325 DstMI.addCopiedMIFlags(M.getInstructionMatcher(InstName));
2326 for (StringRef F : FI->set_flags())
2327 DstMI.addSetMIFlags(F);
2328 for (StringRef F : FI->unset_flags())
2329 DstMI.addUnsetMIFlags(F);
2332 // Don't allow mutating opcodes for GISel combiners. We want a more precise
2333 // handling of MIFlags so we require them to be explicitly preserved.
2335 // TODO: We don't mutate very often, if at all in combiners, but it'd be nice
2336 // to re-enable this. We'd then need to always clear MIFlags when mutating
2337 // opcodes, and never mutate an inst that we copy flags from.
2338 // DstMI.chooseInsnToMutate(M);
2339 declareInstExpansion(CE, DstMI, P.getName());
2341 return true;
2344 bool CombineRuleBuilder::emitCodeGenInstructionApplyImmOperand(
2345 RuleMatcher &M, BuildMIAction &DstMI, const CodeGenInstructionPattern &P,
2346 const InstructionOperand &O) {
2347 // If we have a type, we implicitly emit a G_CONSTANT, except for G_CONSTANT
2348 // itself where we emit a CImm.
2350 // No type means we emit a simple imm.
2351 // G_CONSTANT is a special case and needs a CImm though so this is likely a
2352 // mistake.
2353 const bool isGConstant = P.is("G_CONSTANT");
2354 const auto Ty = O.getType();
2355 if (!Ty) {
2356 if (isGConstant) {
2357 PrintError("'G_CONSTANT' immediate must be typed!");
2358 PrintNote("while emitting pattern '" + P.getName() + "' (" +
2359 P.getInstName() + ")");
2360 return false;
2363 DstMI.addRenderer<ImmRenderer>(O.getImmValue());
2364 return true;
2367 auto ImmTy = getLLTCodeGenOrTempType(Ty, M);
2369 if (isGConstant) {
2370 DstMI.addRenderer<ImmRenderer>(O.getImmValue(), ImmTy);
2371 return true;
2374 unsigned TempRegID = M.allocateTempRegID();
2375 // Ensure MakeTempReg & the BuildConstantAction occur at the beginning.
2376 auto InsertIt = M.insertAction<MakeTempRegisterAction>(M.actions_begin(),
2377 ImmTy, TempRegID);
2378 M.insertAction<BuildConstantAction>(++InsertIt, TempRegID, O.getImmValue());
2379 DstMI.addRenderer<TempRegRenderer>(TempRegID);
2380 return true;
2383 bool CombineRuleBuilder::emitBuiltinApplyPattern(
2384 CodeExpansions &CE, RuleMatcher &M, const BuiltinPattern &P,
2385 StringMap<unsigned> &OperandToTempRegID) {
2386 const auto Error = [&](Twine Reason) {
2387 PrintError("cannot emit '" + P.getInstName() + "' builtin: " + Reason);
2388 return false;
2391 switch (P.getBuiltinKind()) {
2392 case BI_EraseRoot: {
2393 // Root is always inst 0.
2394 M.addAction<EraseInstAction>(/*InsnID*/ 0);
2395 return true;
2397 case BI_ReplaceReg: {
2398 StringRef Old = P.getOperand(0).getOperandName();
2399 StringRef New = P.getOperand(1).getOperandName();
2401 if (!ApplyOpTable.lookup(New).Found && !MatchOpTable.lookup(New).Found)
2402 return Error("unknown operand '" + Old + "'");
2404 auto &OldOM = M.getOperandMatcher(Old);
2405 if (auto It = OperandToTempRegID.find(New);
2406 It != OperandToTempRegID.end()) {
2407 // Replace with temp reg.
2408 M.addAction<ReplaceRegAction>(OldOM.getInsnVarID(), OldOM.getOpIdx(),
2409 It->second);
2410 } else {
2411 // Replace with matched reg.
2412 auto &NewOM = M.getOperandMatcher(New);
2413 M.addAction<ReplaceRegAction>(OldOM.getInsnVarID(), OldOM.getOpIdx(),
2414 NewOM.getInsnVarID(), NewOM.getOpIdx());
2416 // checkSemantics should have ensured that we can only rewrite the root.
2417 // Ensure we're deleting it.
2418 assert(MatchOpTable.getDef(Old) == MatchRoot);
2419 // TODO: We could avoid adding the action again if it's already in. The
2420 // MatchTable is smart enough to only emit one opcode even if
2421 // EraseInstAction is present multiple times. I think searching for a copy
2422 // is more expensive than just blindly adding it though.
2423 M.addAction<EraseInstAction>(/*InsnID*/ 0);
2425 return true;
2429 llvm_unreachable("Unknown BuiltinKind!");
2432 bool isLiteralImm(const InstructionPattern &P, unsigned OpIdx) {
2433 if (const auto *CGP = dyn_cast<CodeGenInstructionPattern>(&P)) {
2434 StringRef InstName = CGP->getInst().TheDef->getName();
2435 return (InstName == "G_CONSTANT" || InstName == "G_FCONSTANT") &&
2436 OpIdx == 1;
2439 llvm_unreachable("TODO");
2442 bool CombineRuleBuilder::emitCodeGenInstructionMatchPattern(
2443 CodeExpansions &CE, const PatternAlternatives &Alts, RuleMatcher &M,
2444 InstructionMatcher &IM, const CodeGenInstructionPattern &P,
2445 DenseSet<const Pattern *> &SeenPats, OperandDefLookupFn LookupOperandDef,
2446 OperandMapperFnRef OperandMapper) {
2447 auto StackTrace = PrettyStackTraceEmit(RuleDef, &P);
2449 if (SeenPats.contains(&P))
2450 return true;
2452 SeenPats.insert(&P);
2454 IM.addPredicate<InstructionOpcodeMatcher>(&P.getInst());
2455 declareInstExpansion(CE, IM, P.getName());
2457 // Check flags if needed.
2458 if (const auto *FI = P.getMIFlagsInfo()) {
2459 assert(FI->copy_flags().empty());
2461 if (const auto &SetF = FI->set_flags(); !SetF.empty())
2462 IM.addPredicate<MIFlagsInstructionPredicateMatcher>(SetF.getArrayRef());
2463 if (const auto &UnsetF = FI->unset_flags(); !UnsetF.empty())
2464 IM.addPredicate<MIFlagsInstructionPredicateMatcher>(UnsetF.getArrayRef(),
2465 /*CheckNot=*/true);
2468 for (const auto &[Idx, OriginalO] : enumerate(P.operands())) {
2469 // Remap the operand. This is used when emitting InstructionPatterns inside
2470 // PatFrags, so it can remap them to the arguments passed to the pattern.
2472 // We use the remapped operand to emit immediates, and for the symbolic
2473 // operand names (in IM.addOperand). CodeExpansions and OperandTable lookups
2474 // still use the original name.
2476 // The "def" flag on the remapped operand is always ignored.
2477 auto RemappedO = OperandMapper(OriginalO);
2478 assert(RemappedO.isNamedOperand() == OriginalO.isNamedOperand() &&
2479 "Cannot remap an unnamed operand to a named one!");
2481 const auto OpName =
2482 RemappedO.isNamedOperand() ? RemappedO.getOperandName().str() : "";
2483 OperandMatcher &OM =
2484 IM.addOperand(Idx, OpName, AllocatedTemporariesBaseID++);
2485 if (!OpName.empty())
2486 declareOperandExpansion(CE, OM, OriginalO.getOperandName());
2488 // Handle immediates.
2489 if (RemappedO.hasImmValue()) {
2490 if (isLiteralImm(P, Idx))
2491 OM.addPredicate<LiteralIntOperandMatcher>(RemappedO.getImmValue());
2492 else
2493 OM.addPredicate<ConstantIntOperandMatcher>(RemappedO.getImmValue());
2496 // Handle typed operands, but only bother to check if it hasn't been done
2497 // before.
2499 // getOperandMatcher will always return the first OM to have been created
2500 // for that Operand. "OM" here is always a new OperandMatcher.
2502 // Always emit a check for unnamed operands.
2503 if (OpName.empty() ||
2504 !M.getOperandMatcher(OpName).contains<LLTOperandMatcher>()) {
2505 if (const auto Ty = RemappedO.getType()) {
2506 // TODO: We could support GITypeOf here on the condition that the
2507 // OperandMatcher exists already. Though it's clunky to make this work
2508 // and isn't all that useful so it's just rejected in typecheckPatterns
2509 // at this time.
2510 assert(Ty.isLLT() && "Only LLTs are supported in match patterns!");
2511 OM.addPredicate<LLTOperandMatcher>(getLLTCodeGen(Ty));
2515 // Stop here if the operand is a def, or if it had no name.
2516 if (OriginalO.isDef() || !OriginalO.isNamedOperand())
2517 continue;
2519 const auto *DefPat = LookupOperandDef(OriginalO.getOperandName());
2520 if (!DefPat)
2521 continue;
2523 if (OriginalO.hasImmValue()) {
2524 assert(!OpName.empty());
2525 // This is a named immediate that also has a def, that's not okay.
2526 // e.g.
2527 // (G_SEXT $y, (i32 0))
2528 // (COPY $x, 42:$y)
2529 PrintError("'" + OpName +
2530 "' is a named immediate, it cannot be defined by another "
2531 "instruction");
2532 PrintNote("'" + OpName + "' is defined by '" + DefPat->getName() + "'");
2533 return false;
2536 // From here we know that the operand defines an instruction, and we need to
2537 // emit it.
2538 auto InstOpM =
2539 OM.addPredicate<InstructionOperandMatcher>(M, DefPat->getName());
2540 if (!InstOpM) {
2541 // TODO: copy-pasted from GlobalISelEmitter.cpp. Is it still relevant
2542 // here?
2543 PrintError("Nested instruction '" + DefPat->getName() +
2544 "' cannot be the same as another operand '" +
2545 OriginalO.getOperandName() + "'");
2546 return false;
2549 auto &IM = (*InstOpM)->getInsnMatcher();
2550 if (const auto *CGIDef = dyn_cast<CodeGenInstructionPattern>(DefPat)) {
2551 if (!emitCodeGenInstructionMatchPattern(CE, Alts, M, IM, *CGIDef,
2552 SeenPats, LookupOperandDef,
2553 OperandMapper))
2554 return false;
2555 continue;
2558 if (const auto *PFPDef = dyn_cast<PatFragPattern>(DefPat)) {
2559 if (!emitPatFragMatchPattern(CE, Alts, M, &IM, *PFPDef, SeenPats))
2560 return false;
2561 continue;
2564 llvm_unreachable("unknown type of InstructionPattern");
2567 return true;
2570 //===- GICombinerEmitter --------------------------------------------------===//
2572 /// Main implementation class. This emits the tablegenerated output.
2574 /// It collects rules, uses `CombineRuleBuilder` to parse them and accumulate
2575 /// RuleMatchers, then takes all the necessary state/data from the various
2576 /// static storage pools and wires them together to emit the match table &
2577 /// associated function/data structures.
2578 class GICombinerEmitter final : public GlobalISelMatchTableExecutorEmitter {
2579 RecordKeeper &Records;
2580 StringRef Name;
2581 const CodeGenTarget &Target;
2582 Record *Combiner;
2583 unsigned NextRuleID = 0;
2585 // List all combine rules (ID, name) imported.
2586 // Note that the combiner rule ID is different from the RuleMatcher ID. The
2587 // latter is internal to the MatchTable, the former is the canonical ID of the
2588 // combine rule used to disable/enable it.
2589 std::vector<std::pair<unsigned, std::string>> AllCombineRules;
2591 // Keep track of all rules we've seen so far to ensure we don't process
2592 // the same rule twice.
2593 StringSet<> RulesSeen;
2595 MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules);
2597 void emitRuleConfigImpl(raw_ostream &OS);
2599 void emitAdditionalImpl(raw_ostream &OS) override;
2601 void emitMIPredicateFns(raw_ostream &OS) override;
2602 void emitI64ImmPredicateFns(raw_ostream &OS) override;
2603 void emitAPFloatImmPredicateFns(raw_ostream &OS) override;
2604 void emitAPIntImmPredicateFns(raw_ostream &OS) override;
2605 void emitTestSimplePredicate(raw_ostream &OS) override;
2606 void emitRunCustomAction(raw_ostream &OS) override;
2608 void emitAdditionalTemporariesDecl(raw_ostream &OS,
2609 StringRef Indent) override;
2611 const CodeGenTarget &getTarget() const override { return Target; }
2612 StringRef getClassName() const override {
2613 return Combiner->getValueAsString("Classname");
2616 StringRef getCombineAllMethodName() const {
2617 return Combiner->getValueAsString("CombineAllMethodName");
2620 std::string getRuleConfigClassName() const {
2621 return getClassName().str() + "RuleConfig";
2624 void gatherRules(std::vector<RuleMatcher> &Rules,
2625 const std::vector<Record *> &&RulesAndGroups);
2627 public:
2628 explicit GICombinerEmitter(RecordKeeper &RK, const CodeGenTarget &Target,
2629 StringRef Name, Record *Combiner);
2630 ~GICombinerEmitter() {}
2632 void run(raw_ostream &OS);
2635 void GICombinerEmitter::emitRuleConfigImpl(raw_ostream &OS) {
2636 OS << "struct " << getRuleConfigClassName() << " {\n"
2637 << " SparseBitVector<> DisabledRules;\n\n"
2638 << " bool isRuleEnabled(unsigned RuleID) const;\n"
2639 << " bool parseCommandLineOption();\n"
2640 << " bool setRuleEnabled(StringRef RuleIdentifier);\n"
2641 << " bool setRuleDisabled(StringRef RuleIdentifier);\n"
2642 << "};\n\n";
2644 std::vector<std::pair<std::string, std::string>> Cases;
2645 Cases.reserve(AllCombineRules.size());
2647 for (const auto &[ID, Name] : AllCombineRules)
2648 Cases.emplace_back(Name, "return " + to_string(ID) + ";\n");
2650 OS << "static std::optional<uint64_t> getRuleIdxForIdentifier(StringRef "
2651 "RuleIdentifier) {\n"
2652 << " uint64_t I;\n"
2653 << " // getAtInteger(...) returns false on success\n"
2654 << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n"
2655 << " if (Parsed)\n"
2656 << " return I;\n\n"
2657 << "#ifndef NDEBUG\n";
2658 StringMatcher Matcher("RuleIdentifier", Cases, OS);
2659 Matcher.Emit();
2660 OS << "#endif // ifndef NDEBUG\n\n"
2661 << " return std::nullopt;\n"
2662 << "}\n";
2664 OS << "static std::optional<std::pair<uint64_t, uint64_t>> "
2665 "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
2666 << " std::pair<StringRef, StringRef> RangePair = "
2667 "RuleIdentifier.split('-');\n"
2668 << " if (!RangePair.second.empty()) {\n"
2669 << " const auto First = "
2670 "getRuleIdxForIdentifier(RangePair.first);\n"
2671 << " const auto Last = "
2672 "getRuleIdxForIdentifier(RangePair.second);\n"
2673 << " if (!First || !Last)\n"
2674 << " return std::nullopt;\n"
2675 << " if (First >= Last)\n"
2676 << " report_fatal_error(\"Beginning of range should be before "
2677 "end of range\");\n"
2678 << " return {{*First, *Last + 1}};\n"
2679 << " }\n"
2680 << " if (RangePair.first == \"*\") {\n"
2681 << " return {{0, " << AllCombineRules.size() << "}};\n"
2682 << " }\n"
2683 << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
2684 << " if (!I)\n"
2685 << " return std::nullopt;\n"
2686 << " return {{*I, *I + 1}};\n"
2687 << "}\n\n";
2689 for (bool Enabled : {true, false}) {
2690 OS << "bool " << getRuleConfigClassName() << "::setRule"
2691 << (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
2692 << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
2693 << " if (!MaybeRange)\n"
2694 << " return false;\n"
2695 << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
2696 << " DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n"
2697 << " return true;\n"
2698 << "}\n\n";
2701 OS << "static std::vector<std::string> " << Name << "Option;\n"
2702 << "static cl::list<std::string> " << Name << "DisableOption(\n"
2703 << " \"" << Name.lower() << "-disable-rule\",\n"
2704 << " cl::desc(\"Disable one or more combiner rules temporarily in "
2705 << "the " << Name << " pass\"),\n"
2706 << " cl::CommaSeparated,\n"
2707 << " cl::Hidden,\n"
2708 << " cl::cat(GICombinerOptionCategory),\n"
2709 << " cl::callback([](const std::string &Str) {\n"
2710 << " " << Name << "Option.push_back(Str);\n"
2711 << " }));\n"
2712 << "static cl::list<std::string> " << Name << "OnlyEnableOption(\n"
2713 << " \"" << Name.lower() << "-only-enable-rule\",\n"
2714 << " cl::desc(\"Disable all rules in the " << Name
2715 << " pass then re-enable the specified ones\"),\n"
2716 << " cl::Hidden,\n"
2717 << " cl::cat(GICombinerOptionCategory),\n"
2718 << " cl::callback([](const std::string &CommaSeparatedArg) {\n"
2719 << " StringRef Str = CommaSeparatedArg;\n"
2720 << " " << Name << "Option.push_back(\"*\");\n"
2721 << " do {\n"
2722 << " auto X = Str.split(\",\");\n"
2723 << " " << Name << "Option.push_back((\"!\" + X.first).str());\n"
2724 << " Str = X.second;\n"
2725 << " } while (!Str.empty());\n"
2726 << " }));\n"
2727 << "\n\n"
2728 << "bool " << getRuleConfigClassName()
2729 << "::isRuleEnabled(unsigned RuleID) const {\n"
2730 << " return !DisabledRules.test(RuleID);\n"
2731 << "}\n"
2732 << "bool " << getRuleConfigClassName() << "::parseCommandLineOption() {\n"
2733 << " for (StringRef Identifier : " << Name << "Option) {\n"
2734 << " bool Enabled = Identifier.consume_front(\"!\");\n"
2735 << " if (Enabled && !setRuleEnabled(Identifier))\n"
2736 << " return false;\n"
2737 << " if (!Enabled && !setRuleDisabled(Identifier))\n"
2738 << " return false;\n"
2739 << " }\n"
2740 << " return true;\n"
2741 << "}\n\n";
2744 void GICombinerEmitter::emitAdditionalImpl(raw_ostream &OS) {
2745 OS << "bool " << getClassName() << "::" << getCombineAllMethodName()
2746 << "(MachineInstr &I) const {\n"
2747 << " const TargetSubtargetInfo &ST = MF.getSubtarget();\n"
2748 << " const PredicateBitset AvailableFeatures = "
2749 "getAvailableFeatures();\n"
2750 << " B.setInstrAndDebugLoc(I);\n"
2751 << " State.MIs.clear();\n"
2752 << " State.MIs.push_back(&I);\n"
2753 << " " << MatchDataInfo::StructName << " = "
2754 << MatchDataInfo::StructTypeName << "();\n\n"
2755 << " if (executeMatchTable(*this, State, ExecInfo, B"
2756 << ", getMatchTable(), *ST.getInstrInfo(), MRI, "
2757 "*MRI.getTargetRegisterInfo(), *ST.getRegBankInfo(), AvailableFeatures"
2758 << ", /*CoverageInfo*/ nullptr)) {\n"
2759 << " return true;\n"
2760 << " }\n\n"
2761 << " return false;\n"
2762 << "}\n\n";
2765 void GICombinerEmitter::emitMIPredicateFns(raw_ostream &OS) {
2766 auto MatchCode = CXXPredicateCode::getAllMatchCode();
2767 emitMIPredicateFnsImpl<const CXXPredicateCode *>(
2768 OS, "", ArrayRef<const CXXPredicateCode *>(MatchCode),
2769 [](const CXXPredicateCode *C) -> StringRef { return C->BaseEnumName; },
2770 [](const CXXPredicateCode *C) -> StringRef { return C->Code; });
2773 void GICombinerEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {
2774 // Unused, but still needs to be called.
2775 emitImmPredicateFnsImpl<unsigned>(
2776 OS, "I64", "int64_t", {}, [](unsigned) { return ""; },
2777 [](unsigned) { return ""; });
2780 void GICombinerEmitter::emitAPFloatImmPredicateFns(raw_ostream &OS) {
2781 // Unused, but still needs to be called.
2782 emitImmPredicateFnsImpl<unsigned>(
2783 OS, "APFloat", "const APFloat &", {}, [](unsigned) { return ""; },
2784 [](unsigned) { return ""; });
2787 void GICombinerEmitter::emitAPIntImmPredicateFns(raw_ostream &OS) {
2788 // Unused, but still needs to be called.
2789 emitImmPredicateFnsImpl<unsigned>(
2790 OS, "APInt", "const APInt &", {}, [](unsigned) { return ""; },
2791 [](unsigned) { return ""; });
2794 void GICombinerEmitter::emitTestSimplePredicate(raw_ostream &OS) {
2795 if (!AllCombineRules.empty()) {
2796 OS << "enum {\n";
2797 std::string EnumeratorSeparator = " = GICXXPred_Invalid + 1,\n";
2798 // To avoid emitting a switch, we expect that all those rules are in order.
2799 // That way we can just get the RuleID from the enum by subtracting
2800 // (GICXXPred_Invalid + 1).
2801 unsigned ExpectedID = 0;
2802 (void)ExpectedID;
2803 for (const auto &ID : keys(AllCombineRules)) {
2804 assert(ExpectedID++ == ID && "combine rules are not ordered!");
2805 OS << " " << getIsEnabledPredicateEnumName(ID) << EnumeratorSeparator;
2806 EnumeratorSeparator = ",\n";
2808 OS << "};\n\n";
2811 OS << "bool " << getClassName()
2812 << "::testSimplePredicate(unsigned Predicate) const {\n"
2813 << " return RuleConfig.isRuleEnabled(Predicate - "
2814 "GICXXPred_Invalid - "
2815 "1);\n"
2816 << "}\n";
2819 void GICombinerEmitter::emitRunCustomAction(raw_ostream &OS) {
2820 const auto ApplyCode = CXXPredicateCode::getAllApplyCode();
2822 if (!ApplyCode.empty()) {
2823 OS << "enum {\n";
2824 std::string EnumeratorSeparator = " = GICXXCustomAction_Invalid + 1,\n";
2825 for (const auto &Apply : ApplyCode) {
2826 OS << " " << Apply->getEnumNameWithPrefix(CXXApplyPrefix)
2827 << EnumeratorSeparator;
2828 EnumeratorSeparator = ",\n";
2830 OS << "};\n";
2833 OS << "void " << getClassName()
2834 << "::runCustomAction(unsigned ApplyID, const MatcherState &State, "
2835 "NewMIVector &OutMIs) const "
2836 "{\n";
2837 if (!ApplyCode.empty()) {
2838 OS << " switch(ApplyID) {\n";
2839 for (const auto &Apply : ApplyCode) {
2840 OS << " case " << Apply->getEnumNameWithPrefix(CXXApplyPrefix) << ":{\n"
2841 << " " << join(split(Apply->Code, '\n'), "\n ") << '\n'
2842 << " return;\n";
2843 OS << " }\n";
2845 OS << "}\n";
2847 OS << " llvm_unreachable(\"Unknown Apply Action\");\n"
2848 << "}\n";
2851 void GICombinerEmitter::emitAdditionalTemporariesDecl(raw_ostream &OS,
2852 StringRef Indent) {
2853 OS << Indent << "struct " << MatchDataInfo::StructTypeName << " {\n";
2854 for (const auto &[Type, VarNames] : AllMatchDataVars) {
2855 assert(!VarNames.empty() && "Cannot have no vars for this type!");
2856 OS << Indent << " " << Type << " " << join(VarNames, ", ") << ";\n";
2858 OS << Indent << "};\n"
2859 << Indent << "mutable " << MatchDataInfo::StructTypeName << " "
2860 << MatchDataInfo::StructName << ";\n\n";
2863 GICombinerEmitter::GICombinerEmitter(RecordKeeper &RK,
2864 const CodeGenTarget &Target,
2865 StringRef Name, Record *Combiner)
2866 : Records(RK), Name(Name), Target(Target), Combiner(Combiner) {}
2868 MatchTable
2869 GICombinerEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules) {
2870 std::vector<Matcher *> InputRules;
2871 for (Matcher &Rule : Rules)
2872 InputRules.push_back(&Rule);
2874 unsigned CurrentOrdering = 0;
2875 StringMap<unsigned> OpcodeOrder;
2876 for (RuleMatcher &Rule : Rules) {
2877 const StringRef Opcode = Rule.getOpcode();
2878 assert(!Opcode.empty() && "Didn't expect an undefined opcode");
2879 if (OpcodeOrder.count(Opcode) == 0)
2880 OpcodeOrder[Opcode] = CurrentOrdering++;
2883 llvm::stable_sort(InputRules, [&OpcodeOrder](const Matcher *A,
2884 const Matcher *B) {
2885 auto *L = static_cast<const RuleMatcher *>(A);
2886 auto *R = static_cast<const RuleMatcher *>(B);
2887 return std::make_tuple(OpcodeOrder[L->getOpcode()], L->getNumOperands()) <
2888 std::make_tuple(OpcodeOrder[R->getOpcode()], R->getNumOperands());
2891 for (Matcher *Rule : InputRules)
2892 Rule->optimize();
2894 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
2895 std::vector<Matcher *> OptRules =
2896 optimizeRules<GroupMatcher>(InputRules, MatcherStorage);
2898 for (Matcher *Rule : OptRules)
2899 Rule->optimize();
2901 OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);
2903 return MatchTable::buildTable(OptRules, /*WithCoverage*/ false,
2904 /*IsCombiner*/ true);
2907 /// Recurse into GICombineGroup's and flatten the ruleset into a simple list.
2908 void GICombinerEmitter::gatherRules(
2909 std::vector<RuleMatcher> &ActiveRules,
2910 const std::vector<Record *> &&RulesAndGroups) {
2911 for (Record *Rec : RulesAndGroups) {
2912 if (!Rec->isValueUnset("Rules")) {
2913 gatherRules(ActiveRules, Rec->getValueAsListOfDefs("Rules"));
2914 continue;
2917 StringRef RuleName = Rec->getName();
2918 if (!RulesSeen.insert(RuleName).second) {
2919 PrintWarning(Rec->getLoc(),
2920 "skipping rule '" + Rec->getName() +
2921 "' because it has already been processed");
2922 continue;
2925 AllCombineRules.emplace_back(NextRuleID, Rec->getName().str());
2926 CombineRuleBuilder CRB(Target, SubtargetFeatures, *Rec, NextRuleID++,
2927 ActiveRules);
2929 if (!CRB.parseAll()) {
2930 assert(ErrorsPrinted && "Parsing failed without errors!");
2931 continue;
2934 if (StopAfterParse) {
2935 CRB.print(outs());
2936 continue;
2939 if (!CRB.emitRuleMatchers()) {
2940 assert(ErrorsPrinted && "Emission failed without errors!");
2941 continue;
2946 void GICombinerEmitter::run(raw_ostream &OS) {
2947 InstructionOpcodeMatcher::initOpcodeValuesMap(Target);
2948 LLTOperandMatcher::initTypeIDValuesMap();
2950 Records.startTimer("Gather rules");
2951 std::vector<RuleMatcher> Rules;
2952 gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules"));
2953 if (ErrorsPrinted)
2954 PrintFatalError(Combiner->getLoc(), "Failed to parse one or more rules");
2956 if (StopAfterParse)
2957 return;
2959 Records.startTimer("Creating Match Table");
2960 unsigned MaxTemporaries = 0;
2961 for (const auto &Rule : Rules)
2962 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
2964 llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
2965 if (A.isHigherPriorityThan(B)) {
2966 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
2967 "and less important at "
2968 "the same time");
2969 return true;
2971 return false;
2974 const MatchTable Table = buildMatchTable(Rules);
2976 Records.startTimer("Emit combiner");
2978 emitSourceFileHeader(getClassName().str() + " Combiner Match Table", OS);
2980 // Unused
2981 std::vector<StringRef> CustomRendererFns;
2982 // Unused
2983 std::vector<Record *> ComplexPredicates;
2985 SmallVector<LLTCodeGen, 16> TypeObjects;
2986 append_range(TypeObjects, KnownTypes);
2987 llvm::sort(TypeObjects);
2989 // Hack: Avoid empty declarator.
2990 if (TypeObjects.empty())
2991 TypeObjects.push_back(LLT::scalar(1));
2993 // GET_GICOMBINER_DEPS, which pulls in extra dependencies.
2994 OS << "#ifdef GET_GICOMBINER_DEPS\n"
2995 << "#include \"llvm/ADT/SparseBitVector.h\"\n"
2996 << "namespace llvm {\n"
2997 << "extern cl::OptionCategory GICombinerOptionCategory;\n"
2998 << "} // end namespace llvm\n"
2999 << "#endif // ifdef GET_GICOMBINER_DEPS\n\n";
3001 // GET_GICOMBINER_TYPES, which needs to be included before the declaration of
3002 // the class.
3003 OS << "#ifdef GET_GICOMBINER_TYPES\n";
3004 emitRuleConfigImpl(OS);
3005 OS << "#endif // ifdef GET_GICOMBINER_TYPES\n\n";
3006 emitPredicateBitset(OS, "GET_GICOMBINER_TYPES");
3008 // GET_GICOMBINER_CLASS_MEMBERS, which need to be included inside the class.
3009 emitPredicatesDecl(OS, "GET_GICOMBINER_CLASS_MEMBERS");
3010 emitTemporariesDecl(OS, "GET_GICOMBINER_CLASS_MEMBERS");
3012 // GET_GICOMBINER_IMPL, which needs to be included outside the class.
3013 emitExecutorImpl(OS, Table, TypeObjects, Rules, ComplexPredicates,
3014 CustomRendererFns, "GET_GICOMBINER_IMPL");
3016 // GET_GICOMBINER_CONSTRUCTOR_INITS, which are in the constructor's
3017 // initializer list.
3018 emitPredicatesInit(OS, "GET_GICOMBINER_CONSTRUCTOR_INITS");
3019 emitTemporariesInit(OS, MaxTemporaries, "GET_GICOMBINER_CONSTRUCTOR_INITS");
3022 } // end anonymous namespace
3024 //===----------------------------------------------------------------------===//
3026 static void EmitGICombiner(RecordKeeper &RK, raw_ostream &OS) {
3027 EnablePrettyStackTrace();
3028 CodeGenTarget Target(RK);
3030 if (SelectedCombiners.empty())
3031 PrintFatalError("No combiners selected with -combiners");
3032 for (const auto &Combiner : SelectedCombiners) {
3033 Record *CombinerDef = RK.getDef(Combiner);
3034 if (!CombinerDef)
3035 PrintFatalError("Could not find " + Combiner);
3036 GICombinerEmitter(RK, Target, Combiner, CombinerDef).run(OS);
3040 static TableGen::Emitter::Opt X("gen-global-isel-combiner", EmitGICombiner,
3041 "Generate GlobalISel Combiner");