1 //===- GlobalCombinerEmitter.cpp - Generate a combiner --------------------===// 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 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "CodeGenTarget.h" 15 #include "GlobalISel/CodeExpander.h" 16 #include "GlobalISel/CodeExpansions.h" 17 #include "GlobalISel/GIMatchDag.h" 18 #include "GlobalISel/GIMatchDagPredicate.h" 19 #include "GlobalISel/GIMatchTree.h" 20 #include "llvm/ADT/SmallSet.h" 21 #include "llvm/ADT/Statistic.h" 22 #include "llvm/ADT/StringSet.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/ScopedPrinter.h" 26 #include "llvm/Support/Timer.h" 27 #include "llvm/TableGen/Error.h" 28 #include "llvm/TableGen/StringMatcher.h" 29 #include "llvm/TableGen/TableGenBackend.h" 30 #include <cstdint> 31 32 using namespace llvm; 33 34 #define DEBUG_TYPE "gicombiner-emitter" 35 36 // FIXME: Use ALWAYS_ENABLED_STATISTIC once it's available. 37 unsigned NumPatternTotal = 0; 38 STATISTIC(NumPatternTotalStatistic, "Total number of patterns"); 39 40 cl::OptionCategory 41 GICombinerEmitterCat("Options for -gen-global-isel-combiner"); 42 static cl::list<std::string> 43 SelectedCombiners("combiners", cl::desc("Emit the specified combiners"), 44 cl::cat(GICombinerEmitterCat), cl::CommaSeparated); 45 static cl::opt<bool> ShowExpansions( 46 "gicombiner-show-expansions", 47 cl::desc("Use C++ comments to indicate occurence of code expansion"), 48 cl::cat(GICombinerEmitterCat)); 49 static cl::opt<bool> StopAfterParse( 50 "gicombiner-stop-after-parse", 51 cl::desc("Stop processing after parsing rules and dump state"), 52 cl::cat(GICombinerEmitterCat)); 53 static cl::opt<bool> StopAfterBuild( 54 "gicombiner-stop-after-build", 55 cl::desc("Stop processing after building the match tree"), 56 cl::cat(GICombinerEmitterCat)); 57 58 namespace { 59 typedef uint64_t RuleID; 60 61 // We're going to be referencing the same small strings quite a lot for operand 62 // names and the like. Make their lifetime management simple with a global 63 // string table. 64 StringSet<> StrTab; 65 66 StringRef insertStrTab(StringRef S) { 67 if (S.empty()) 68 return S; 69 return StrTab.insert(S).first->first(); 70 } 71 72 class format_partition_name { 73 const GIMatchTree &Tree; 74 unsigned Idx; 75 76 public: 77 format_partition_name(const GIMatchTree &Tree, unsigned Idx) 78 : Tree(Tree), Idx(Idx) {} 79 void print(raw_ostream &OS) const { 80 Tree.getPartitioner()->emitPartitionName(OS, Idx); 81 } 82 }; 83 raw_ostream &operator<<(raw_ostream &OS, const format_partition_name &Fmt) { 84 Fmt.print(OS); 85 return OS; 86 } 87 88 /// Declares data that is passed from the match stage to the apply stage. 89 class MatchDataInfo { 90 /// The symbol used in the tablegen patterns 91 StringRef PatternSymbol; 92 /// The data type for the variable 93 StringRef Type; 94 /// The name of the variable as declared in the generated matcher. 95 std::string VariableName; 96 97 public: 98 MatchDataInfo(StringRef PatternSymbol, StringRef Type, StringRef VariableName) 99 : PatternSymbol(PatternSymbol), Type(Type), VariableName(VariableName) {} 100 101 StringRef getPatternSymbol() const { return PatternSymbol; }; 102 StringRef getType() const { return Type; }; 103 StringRef getVariableName() const { return VariableName; }; 104 }; 105 106 class RootInfo { 107 StringRef PatternSymbol; 108 109 public: 110 RootInfo(StringRef PatternSymbol) : PatternSymbol(PatternSymbol) {} 111 112 StringRef getPatternSymbol() const { return PatternSymbol; } 113 }; 114 115 class CombineRule { 116 public: 117 118 using const_matchdata_iterator = std::vector<MatchDataInfo>::const_iterator; 119 120 struct VarInfo { 121 const GIMatchDagInstr *N; 122 const GIMatchDagOperand *Op; 123 const DagInit *Matcher; 124 125 public: 126 VarInfo(const GIMatchDagInstr *N, const GIMatchDagOperand *Op, 127 const DagInit *Matcher) 128 : N(N), Op(Op), Matcher(Matcher) {} 129 }; 130 131 protected: 132 /// A unique ID for this rule 133 /// ID's are used for debugging and run-time disabling of rules among other 134 /// things. 135 RuleID ID; 136 137 /// A unique ID that can be used for anonymous objects belonging to this rule. 138 /// Used to create unique names in makeNameForAnon*() without making tests 139 /// overly fragile. 140 unsigned UID = 0; 141 142 /// The record defining this rule. 143 const Record &TheDef; 144 145 /// The roots of a match. These are the leaves of the DAG that are closest to 146 /// the end of the function. I.e. the nodes that are encountered without 147 /// following any edges of the DAG described by the pattern as we work our way 148 /// from the bottom of the function to the top. 149 std::vector<RootInfo> Roots; 150 151 GIMatchDag MatchDag; 152 153 /// A block of arbitrary C++ to finish testing the match. 154 /// FIXME: This is a temporary measure until we have actual pattern matching 155 const StringInit *MatchingFixupCode = nullptr; 156 157 /// The MatchData defined by the match stage and required by the apply stage. 158 /// This allows the plumbing of arbitrary data from C++ predicates between the 159 /// stages. 160 /// 161 /// For example, suppose you have: 162 /// %A = <some-constant-expr> 163 /// %0 = G_ADD %1, %A 164 /// you could define a GIMatchPredicate that walks %A, constant folds as much 165 /// as possible and returns an APInt containing the discovered constant. You 166 /// could then declare: 167 /// def apint : GIDefMatchData<"APInt">; 168 /// add it to the rule with: 169 /// (defs root:$root, apint:$constant) 170 /// evaluate it in the pattern with a C++ function that takes a 171 /// MachineOperand& and an APInt& with: 172 /// (match [{MIR %root = G_ADD %0, %A }], 173 /// (constantfold operand:$A, apint:$constant)) 174 /// and finally use it in the apply stage with: 175 /// (apply (create_operand 176 /// [{ MachineOperand::CreateImm(${constant}.getZExtValue()); 177 /// ]}, apint:$constant), 178 /// [{MIR %root = FOO %0, %constant }]) 179 std::vector<MatchDataInfo> MatchDataDecls; 180 181 void declareMatchData(StringRef PatternSymbol, StringRef Type, 182 StringRef VarName); 183 184 bool parseInstructionMatcher(const CodeGenTarget &Target, StringInit *ArgName, 185 const Init &Arg, 186 StringMap<std::vector<VarInfo>> &NamedEdgeDefs, 187 StringMap<std::vector<VarInfo>> &NamedEdgeUses); 188 bool parseWipMatchOpcodeMatcher(const CodeGenTarget &Target, 189 StringInit *ArgName, const Init &Arg); 190 191 public: 192 CombineRule(const CodeGenTarget &Target, GIMatchDagContext &Ctx, RuleID ID, 193 const Record &R) 194 : ID(ID), TheDef(R), MatchDag(Ctx) {} 195 CombineRule(const CombineRule &) = delete; 196 197 bool parseDefs(); 198 bool parseMatcher(const CodeGenTarget &Target); 199 200 RuleID getID() const { return ID; } 201 unsigned allocUID() { return UID++; } 202 StringRef getName() const { return TheDef.getName(); } 203 const Record &getDef() const { return TheDef; } 204 const StringInit *getMatchingFixupCode() const { return MatchingFixupCode; } 205 size_t getNumRoots() const { return Roots.size(); } 206 207 GIMatchDag &getMatchDag() { return MatchDag; } 208 const GIMatchDag &getMatchDag() const { return MatchDag; } 209 210 using const_root_iterator = std::vector<RootInfo>::const_iterator; 211 const_root_iterator roots_begin() const { return Roots.begin(); } 212 const_root_iterator roots_end() const { return Roots.end(); } 213 iterator_range<const_root_iterator> roots() const { 214 return llvm::make_range(Roots.begin(), Roots.end()); 215 } 216 217 iterator_range<const_matchdata_iterator> matchdata_decls() const { 218 return make_range(MatchDataDecls.begin(), MatchDataDecls.end()); 219 } 220 221 /// Export expansions for this rule 222 void declareExpansions(CodeExpansions &Expansions) const { 223 for (const auto &I : matchdata_decls()) 224 Expansions.declare(I.getPatternSymbol(), I.getVariableName()); 225 } 226 227 /// The matcher will begin from the roots and will perform the match by 228 /// traversing the edges to cover the whole DAG. This function reverses DAG 229 /// edges such that everything is reachable from a root. This is part of the 230 /// preparation work for flattening the DAG into a tree. 231 void reorientToRoots() { 232 SmallSet<const GIMatchDagInstr *, 5> Roots; 233 SmallSet<const GIMatchDagInstr *, 5> Visited; 234 SmallSet<GIMatchDagEdge *, 20> EdgesRemaining; 235 236 for (auto &I : MatchDag.roots()) { 237 Roots.insert(I); 238 Visited.insert(I); 239 } 240 for (auto &I : MatchDag.edges()) 241 EdgesRemaining.insert(I); 242 243 bool Progressed = false; 244 SmallSet<GIMatchDagEdge *, 20> EdgesToRemove; 245 while (!EdgesRemaining.empty()) { 246 for (auto *EI : EdgesRemaining) { 247 if (Visited.count(EI->getFromMI())) { 248 if (Roots.count(EI->getToMI())) 249 PrintError(TheDef.getLoc(), "One or more roots are unnecessary"); 250 Visited.insert(EI->getToMI()); 251 EdgesToRemove.insert(EI); 252 Progressed = true; 253 } 254 } 255 for (GIMatchDagEdge *ToRemove : EdgesToRemove) 256 EdgesRemaining.erase(ToRemove); 257 EdgesToRemove.clear(); 258 259 for (auto EI = EdgesRemaining.begin(), EE = EdgesRemaining.end(); 260 EI != EE; ++EI) { 261 if (Visited.count((*EI)->getToMI())) { 262 (*EI)->reverse(); 263 Visited.insert((*EI)->getToMI()); 264 EdgesToRemove.insert(*EI); 265 Progressed = true; 266 } 267 for (GIMatchDagEdge *ToRemove : EdgesToRemove) 268 EdgesRemaining.erase(ToRemove); 269 EdgesToRemove.clear(); 270 } 271 272 if (!Progressed) { 273 LLVM_DEBUG(dbgs() << "No progress\n"); 274 return; 275 } 276 Progressed = false; 277 } 278 } 279 }; 280 281 /// A convenience function to check that an Init refers to a specific def. This 282 /// is primarily useful for testing for defs and similar in DagInit's since 283 /// DagInit's support any type inside them. 284 static bool isSpecificDef(const Init &N, StringRef Def) { 285 if (const DefInit *OpI = dyn_cast<DefInit>(&N)) 286 if (OpI->getDef()->getName() == Def) 287 return true; 288 return false; 289 } 290 291 /// A convenience function to check that an Init refers to a def that is a 292 /// subclass of the given class and coerce it to a def if it is. This is 293 /// primarily useful for testing for subclasses of GIMatchKind and similar in 294 /// DagInit's since DagInit's support any type inside them. 295 static Record *getDefOfSubClass(const Init &N, StringRef Cls) { 296 if (const DefInit *OpI = dyn_cast<DefInit>(&N)) 297 if (OpI->getDef()->isSubClassOf(Cls)) 298 return OpI->getDef(); 299 return nullptr; 300 } 301 302 /// A convenience function to check that an Init refers to a dag whose operator 303 /// is a specific def and coerce it to a dag if it is. This is primarily useful 304 /// for testing for subclasses of GIMatchKind and similar in DagInit's since 305 /// DagInit's support any type inside them. 306 static const DagInit *getDagWithSpecificOperator(const Init &N, 307 StringRef Name) { 308 if (const DagInit *I = dyn_cast<DagInit>(&N)) 309 if (I->getNumArgs() > 0) 310 if (const DefInit *OpI = dyn_cast<DefInit>(I->getOperator())) 311 if (OpI->getDef()->getName() == Name) 312 return I; 313 return nullptr; 314 } 315 316 /// A convenience function to check that an Init refers to a dag whose operator 317 /// is a def that is a subclass of the given class and coerce it to a dag if it 318 /// is. This is primarily useful for testing for subclasses of GIMatchKind and 319 /// similar in DagInit's since DagInit's support any type inside them. 320 static const DagInit *getDagWithOperatorOfSubClass(const Init &N, 321 StringRef Cls) { 322 if (const DagInit *I = dyn_cast<DagInit>(&N)) 323 if (I->getNumArgs() > 0) 324 if (const DefInit *OpI = dyn_cast<DefInit>(I->getOperator())) 325 if (OpI->getDef()->isSubClassOf(Cls)) 326 return I; 327 return nullptr; 328 } 329 330 StringRef makeNameForAnonInstr(CombineRule &Rule) { 331 return insertStrTab(to_string( 332 format("__anon%" PRIu64 "_%u", Rule.getID(), Rule.allocUID()))); 333 } 334 335 StringRef makeDebugName(CombineRule &Rule, StringRef Name) { 336 return insertStrTab(Name.empty() ? makeNameForAnonInstr(Rule) : StringRef(Name)); 337 } 338 339 StringRef makeNameForAnonPredicate(CombineRule &Rule) { 340 return insertStrTab(to_string( 341 format("__anonpred%" PRIu64 "_%u", Rule.getID(), Rule.allocUID()))); 342 } 343 344 void CombineRule::declareMatchData(StringRef PatternSymbol, StringRef Type, 345 StringRef VarName) { 346 MatchDataDecls.emplace_back(PatternSymbol, Type, VarName); 347 } 348 349 bool CombineRule::parseDefs() { 350 DagInit *Defs = TheDef.getValueAsDag("Defs"); 351 352 if (Defs->getOperatorAsDef(TheDef.getLoc())->getName() != "defs") { 353 PrintError(TheDef.getLoc(), "Expected defs operator"); 354 return false; 355 } 356 357 for (unsigned I = 0, E = Defs->getNumArgs(); I < E; ++I) { 358 // Roots should be collected into Roots 359 if (isSpecificDef(*Defs->getArg(I), "root")) { 360 Roots.emplace_back(Defs->getArgNameStr(I)); 361 continue; 362 } 363 364 // Subclasses of GIDefMatchData should declare that this rule needs to pass 365 // data from the match stage to the apply stage, and ensure that the 366 // generated matcher has a suitable variable for it to do so. 367 if (Record *MatchDataRec = 368 getDefOfSubClass(*Defs->getArg(I), "GIDefMatchData")) { 369 declareMatchData(Defs->getArgNameStr(I), 370 MatchDataRec->getValueAsString("Type"), 371 llvm::to_string(llvm::format("MatchData%" PRIu64, ID))); 372 continue; 373 } 374 375 // Otherwise emit an appropriate error message. 376 if (getDefOfSubClass(*Defs->getArg(I), "GIDefKind")) 377 PrintError(TheDef.getLoc(), 378 "This GIDefKind not implemented in tablegen"); 379 else if (getDefOfSubClass(*Defs->getArg(I), "GIDefKindWithArgs")) 380 PrintError(TheDef.getLoc(), 381 "This GIDefKindWithArgs not implemented in tablegen"); 382 else 383 PrintError(TheDef.getLoc(), 384 "Expected a subclass of GIDefKind or a sub-dag whose " 385 "operator is of type GIDefKindWithArgs"); 386 return false; 387 } 388 389 if (Roots.empty()) { 390 PrintError(TheDef.getLoc(), "Combine rules must have at least one root"); 391 return false; 392 } 393 return true; 394 } 395 396 // Parse an (Instruction $a:Arg1, $b:Arg2, ...) matcher. Edges are formed 397 // between matching operand names between different matchers. 398 bool CombineRule::parseInstructionMatcher( 399 const CodeGenTarget &Target, StringInit *ArgName, const Init &Arg, 400 StringMap<std::vector<VarInfo>> &NamedEdgeDefs, 401 StringMap<std::vector<VarInfo>> &NamedEdgeUses) { 402 if (const DagInit *Matcher = 403 getDagWithOperatorOfSubClass(Arg, "Instruction")) { 404 auto &Instr = 405 Target.getInstruction(Matcher->getOperatorAsDef(TheDef.getLoc())); 406 407 StringRef Name = ArgName ? ArgName->getValue() : ""; 408 409 GIMatchDagInstr *N = 410 MatchDag.addInstrNode(makeDebugName(*this, Name), insertStrTab(Name), 411 MatchDag.getContext().makeOperandList(Instr)); 412 413 N->setOpcodeAnnotation(&Instr); 414 const auto &P = MatchDag.addPredicateNode<GIMatchDagOpcodePredicate>( 415 makeNameForAnonPredicate(*this), Instr); 416 MatchDag.addPredicateDependency(N, nullptr, P, &P->getOperandInfo()["mi"]); 417 unsigned OpIdx = 0; 418 for (const auto &NameInit : Matcher->getArgNames()) { 419 StringRef Name = insertStrTab(NameInit->getAsUnquotedString()); 420 if (Name.empty()) 421 continue; 422 N->assignNameToOperand(OpIdx, Name); 423 424 // Record the endpoints of any named edges. We'll add the cartesian 425 // product of edges later. 426 const auto &InstrOperand = N->getOperandInfo()[OpIdx]; 427 if (InstrOperand.isDef()) { 428 NamedEdgeDefs.try_emplace(Name); 429 NamedEdgeDefs[Name].emplace_back(N, &InstrOperand, Matcher); 430 } else { 431 NamedEdgeUses.try_emplace(Name); 432 NamedEdgeUses[Name].emplace_back(N, &InstrOperand, Matcher); 433 } 434 435 if (InstrOperand.isDef()) { 436 if (any_of(Roots, [&](const RootInfo &X) { 437 return X.getPatternSymbol() == Name; 438 })) { 439 N->setMatchRoot(); 440 } 441 } 442 443 OpIdx++; 444 } 445 446 return true; 447 } 448 return false; 449 } 450 451 // Parse the wip_match_opcode placeholder that's temporarily present in lieu of 452 // implementing macros or choices between two matchers. 453 bool CombineRule::parseWipMatchOpcodeMatcher(const CodeGenTarget &Target, 454 StringInit *ArgName, 455 const Init &Arg) { 456 if (const DagInit *Matcher = 457 getDagWithSpecificOperator(Arg, "wip_match_opcode")) { 458 StringRef Name = ArgName ? ArgName->getValue() : ""; 459 460 GIMatchDagInstr *N = 461 MatchDag.addInstrNode(makeDebugName(*this, Name), insertStrTab(Name), 462 MatchDag.getContext().makeEmptyOperandList()); 463 464 if (any_of(Roots, [&](const RootInfo &X) { 465 return ArgName && X.getPatternSymbol() == ArgName->getValue(); 466 })) { 467 N->setMatchRoot(); 468 } 469 470 const auto &P = MatchDag.addPredicateNode<GIMatchDagOneOfOpcodesPredicate>( 471 makeNameForAnonPredicate(*this)); 472 MatchDag.addPredicateDependency(N, nullptr, P, &P->getOperandInfo()["mi"]); 473 // Each argument is an opcode that will pass this predicate. Add them all to 474 // the predicate implementation 475 for (const auto &Arg : Matcher->getArgs()) { 476 Record *OpcodeDef = getDefOfSubClass(*Arg, "Instruction"); 477 if (OpcodeDef) { 478 P->addOpcode(&Target.getInstruction(OpcodeDef)); 479 continue; 480 } 481 PrintError(TheDef.getLoc(), 482 "Arguments to wip_match_opcode must be instructions"); 483 return false; 484 } 485 return true; 486 } 487 return false; 488 } 489 bool CombineRule::parseMatcher(const CodeGenTarget &Target) { 490 StringMap<std::vector<VarInfo>> NamedEdgeDefs; 491 StringMap<std::vector<VarInfo>> NamedEdgeUses; 492 DagInit *Matchers = TheDef.getValueAsDag("Match"); 493 494 if (Matchers->getOperatorAsDef(TheDef.getLoc())->getName() != "match") { 495 PrintError(TheDef.getLoc(), "Expected match operator"); 496 return false; 497 } 498 499 if (Matchers->getNumArgs() == 0) { 500 PrintError(TheDef.getLoc(), "Matcher is empty"); 501 return false; 502 } 503 504 // The match section consists of a list of matchers and predicates. Parse each 505 // one and add the equivalent GIMatchDag nodes, predicates, and edges. 506 for (unsigned I = 0; I < Matchers->getNumArgs(); ++I) { 507 if (parseInstructionMatcher(Target, Matchers->getArgName(I), 508 *Matchers->getArg(I), NamedEdgeDefs, 509 NamedEdgeUses)) 510 continue; 511 512 if (parseWipMatchOpcodeMatcher(Target, Matchers->getArgName(I), 513 *Matchers->getArg(I))) 514 continue; 515 516 517 // Parse arbitrary C++ code we have in lieu of supporting MIR matching 518 if (const StringInit *StringI = dyn_cast<StringInit>(Matchers->getArg(I))) { 519 assert(!MatchingFixupCode && 520 "Only one block of arbitrary code is currently permitted"); 521 MatchingFixupCode = StringI; 522 MatchDag.setHasPostMatchPredicate(true); 523 continue; 524 } 525 526 PrintError(TheDef.getLoc(), 527 "Expected a subclass of GIMatchKind or a sub-dag whose " 528 "operator is either of a GIMatchKindWithArgs or Instruction"); 529 PrintNote("Pattern was `" + Matchers->getArg(I)->getAsString() + "'"); 530 return false; 531 } 532 533 // Add the cartesian product of use -> def edges. 534 bool FailedToAddEdges = false; 535 for (const auto &NameAndDefs : NamedEdgeDefs) { 536 if (NameAndDefs.getValue().size() > 1) { 537 PrintError(TheDef.getLoc(), 538 "Two different MachineInstrs cannot def the same vreg"); 539 for (const auto &NameAndDefOp : NameAndDefs.getValue()) 540 PrintNote("in " + to_string(*NameAndDefOp.N) + " created from " + 541 to_string(*NameAndDefOp.Matcher) + ""); 542 FailedToAddEdges = true; 543 } 544 const auto &Uses = NamedEdgeUses[NameAndDefs.getKey()]; 545 for (const VarInfo &DefVar : NameAndDefs.getValue()) { 546 for (const VarInfo &UseVar : Uses) { 547 MatchDag.addEdge(insertStrTab(NameAndDefs.getKey()), UseVar.N, UseVar.Op, 548 DefVar.N, DefVar.Op); 549 } 550 } 551 } 552 if (FailedToAddEdges) 553 return false; 554 555 // If a variable is referenced in multiple use contexts then we need a 556 // predicate to confirm they are the same operand. We can elide this if it's 557 // also referenced in a def context and we're traversing the def-use chain 558 // from the def to the uses but we can't know which direction we're going 559 // until after reorientToRoots(). 560 for (const auto &NameAndUses : NamedEdgeUses) { 561 const auto &Uses = NameAndUses.getValue(); 562 if (Uses.size() > 1) { 563 const auto &LeadingVar = Uses.front(); 564 for (const auto &Var : ArrayRef<VarInfo>(Uses).drop_front()) { 565 // Add a predicate for each pair until we've covered the whole 566 // equivalence set. We could test the whole set in a single predicate 567 // but that means we can't test any equivalence until all the MO's are 568 // available which can lead to wasted work matching the DAG when this 569 // predicate can already be seen to have failed. 570 // 571 // We have a similar problem due to the need to wait for a particular MO 572 // before being able to test any of them. However, that is mitigated by 573 // the order in which we build the DAG. We build from the roots outwards 574 // so by using the first recorded use in all the predicates, we are 575 // making the dependency on one of the earliest visited references in 576 // the DAG. It's not guaranteed once the generated matcher is optimized 577 // (because the factoring the common portions of rules might change the 578 // visit order) but this should mean that these predicates depend on the 579 // first MO to become available. 580 const auto &P = MatchDag.addPredicateNode<GIMatchDagSameMOPredicate>( 581 makeNameForAnonPredicate(*this)); 582 MatchDag.addPredicateDependency(LeadingVar.N, LeadingVar.Op, P, 583 &P->getOperandInfo()["mi0"]); 584 MatchDag.addPredicateDependency(Var.N, Var.Op, P, 585 &P->getOperandInfo()["mi1"]); 586 } 587 } 588 } 589 return true; 590 } 591 592 class GICombinerEmitter { 593 RecordKeeper &Records; 594 StringRef Name; 595 const CodeGenTarget &Target; 596 Record *Combiner; 597 std::vector<std::unique_ptr<CombineRule>> Rules; 598 GIMatchDagContext MatchDagCtx; 599 600 std::unique_ptr<CombineRule> makeCombineRule(const Record &R); 601 602 void gatherRules(std::vector<std::unique_ptr<CombineRule>> &ActiveRules, 603 const std::vector<Record *> &&RulesAndGroups); 604 605 public: 606 explicit GICombinerEmitter(RecordKeeper &RK, const CodeGenTarget &Target, 607 StringRef Name, Record *Combiner); 608 ~GICombinerEmitter() {} 609 610 StringRef getClassName() const { 611 return Combiner->getValueAsString("Classname"); 612 } 613 void run(raw_ostream &OS); 614 615 /// Emit the name matcher (guarded by #ifndef NDEBUG) used to disable rules in 616 /// response to the generated cl::opt. 617 void emitNameMatcher(raw_ostream &OS) const; 618 619 void generateCodeForTree(raw_ostream &OS, const GIMatchTree &Tree, 620 StringRef Indent) const; 621 }; 622 623 GICombinerEmitter::GICombinerEmitter(RecordKeeper &RK, 624 const CodeGenTarget &Target, 625 StringRef Name, Record *Combiner) 626 : Records(RK), Name(Name), Target(Target), Combiner(Combiner) {} 627 628 void GICombinerEmitter::emitNameMatcher(raw_ostream &OS) const { 629 std::vector<std::pair<std::string, std::string>> Cases; 630 Cases.reserve(Rules.size()); 631 632 for (const CombineRule &EnumeratedRule : make_pointee_range(Rules)) { 633 std::string Code; 634 raw_string_ostream SS(Code); 635 SS << "return " << EnumeratedRule.getID() << ";\n"; 636 Cases.push_back( 637 std::make_pair(std::string(EnumeratedRule.getName()), Code)); 638 } 639 640 OS << "static Optional<uint64_t> getRuleIdxForIdentifier(StringRef " 641 "RuleIdentifier) {\n" 642 << " uint64_t I;\n" 643 << " // getAtInteger(...) returns false on success\n" 644 << " bool Parsed = !RuleIdentifier.getAsInteger(0, I);\n" 645 << " if (Parsed)\n" 646 << " return I;\n\n" 647 << "#ifndef NDEBUG\n"; 648 StringMatcher Matcher("RuleIdentifier", Cases, OS); 649 Matcher.Emit(); 650 OS << "#endif // ifndef NDEBUG\n\n" 651 << " return None;\n" 652 << "}\n"; 653 } 654 655 std::unique_ptr<CombineRule> 656 GICombinerEmitter::makeCombineRule(const Record &TheDef) { 657 std::unique_ptr<CombineRule> Rule = 658 std::make_unique<CombineRule>(Target, MatchDagCtx, NumPatternTotal, TheDef); 659 660 if (!Rule->parseDefs()) 661 return nullptr; 662 if (!Rule->parseMatcher(Target)) 663 return nullptr; 664 665 Rule->reorientToRoots(); 666 667 LLVM_DEBUG({ 668 dbgs() << "Parsed rule defs/match for '" << Rule->getName() << "'\n"; 669 Rule->getMatchDag().dump(); 670 Rule->getMatchDag().writeDOTGraph(dbgs(), Rule->getName()); 671 }); 672 if (StopAfterParse) 673 return Rule; 674 675 // For now, don't support traversing from def to use. We'll come back to 676 // this later once we have the algorithm changes to support it. 677 bool EmittedDefToUseError = false; 678 for (const auto &E : Rule->getMatchDag().edges()) { 679 if (E->isDefToUse()) { 680 if (!EmittedDefToUseError) { 681 PrintError( 682 TheDef.getLoc(), 683 "Generated state machine cannot lookup uses from a def (yet)"); 684 EmittedDefToUseError = true; 685 } 686 PrintNote("Node " + to_string(*E->getFromMI())); 687 PrintNote("Node " + to_string(*E->getToMI())); 688 PrintNote("Edge " + to_string(*E)); 689 } 690 } 691 if (EmittedDefToUseError) 692 return nullptr; 693 694 // For now, don't support multi-root rules. We'll come back to this later 695 // once we have the algorithm changes to support it. 696 if (Rule->getNumRoots() > 1) { 697 PrintError(TheDef.getLoc(), "Multi-root matches are not supported (yet)"); 698 return nullptr; 699 } 700 return Rule; 701 } 702 703 /// Recurse into GICombineGroup's and flatten the ruleset into a simple list. 704 void GICombinerEmitter::gatherRules( 705 std::vector<std::unique_ptr<CombineRule>> &ActiveRules, 706 const std::vector<Record *> &&RulesAndGroups) { 707 for (Record *R : RulesAndGroups) { 708 if (R->isValueUnset("Rules")) { 709 std::unique_ptr<CombineRule> Rule = makeCombineRule(*R); 710 if (Rule == nullptr) { 711 PrintError(R->getLoc(), "Failed to parse rule"); 712 continue; 713 } 714 ActiveRules.emplace_back(std::move(Rule)); 715 ++NumPatternTotal; 716 } else 717 gatherRules(ActiveRules, R->getValueAsListOfDefs("Rules")); 718 } 719 } 720 721 void GICombinerEmitter::generateCodeForTree(raw_ostream &OS, 722 const GIMatchTree &Tree, 723 StringRef Indent) const { 724 if (Tree.getPartitioner() != nullptr) { 725 Tree.getPartitioner()->generatePartitionSelectorCode(OS, Indent); 726 for (const auto &EnumChildren : enumerate(Tree.children())) { 727 OS << Indent << "if (Partition == " << EnumChildren.index() << " /* " 728 << format_partition_name(Tree, EnumChildren.index()) << " */) {\n"; 729 generateCodeForTree(OS, EnumChildren.value(), (Indent + " ").str()); 730 OS << Indent << "}\n"; 731 } 732 return; 733 } 734 735 bool AnyFullyTested = false; 736 for (const auto &Leaf : Tree.possible_leaves()) { 737 OS << Indent << "// Leaf name: " << Leaf.getName() << "\n"; 738 739 const CombineRule *Rule = Leaf.getTargetData<CombineRule>(); 740 const Record &RuleDef = Rule->getDef(); 741 742 OS << Indent << "// Rule: " << RuleDef.getName() << "\n" 743 << Indent << "if (!RuleConfig->isRuleDisabled(" << Rule->getID() 744 << ")) {\n"; 745 746 CodeExpansions Expansions; 747 for (const auto &VarBinding : Leaf.var_bindings()) { 748 if (VarBinding.isInstr()) 749 Expansions.declare(VarBinding.getName(), 750 "MIs[" + to_string(VarBinding.getInstrID()) + "]"); 751 else 752 Expansions.declare(VarBinding.getName(), 753 "MIs[" + to_string(VarBinding.getInstrID()) + 754 "]->getOperand(" + 755 to_string(VarBinding.getOpIdx()) + ")"); 756 } 757 Rule->declareExpansions(Expansions); 758 759 DagInit *Applyer = RuleDef.getValueAsDag("Apply"); 760 if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() != 761 "apply") { 762 PrintError(RuleDef.getLoc(), "Expected 'apply' operator in Apply DAG"); 763 return; 764 } 765 766 OS << Indent << " if (1\n"; 767 768 // Attempt to emit code for any untested predicates left over. Note that 769 // isFullyTested() will remain false even if we succeed here and therefore 770 // combine rule elision will not be performed. This is because we do not 771 // know if there's any connection between the predicates for each leaf and 772 // therefore can't tell if one makes another unreachable. Ideally, the 773 // partitioner(s) would be sufficiently complete to prevent us from having 774 // untested predicates left over. 775 for (const GIMatchDagPredicate *Predicate : Leaf.untested_predicates()) { 776 if (Predicate->generateCheckCode(OS, (Indent + " ").str(), 777 Expansions)) 778 continue; 779 PrintError(RuleDef.getLoc(), 780 "Unable to test predicate used in rule"); 781 PrintNote(SMLoc(), 782 "This indicates an incomplete implementation in tablegen"); 783 Predicate->print(errs()); 784 errs() << "\n"; 785 OS << Indent 786 << "llvm_unreachable(\"TableGen did not emit complete code for this " 787 "path\");\n"; 788 break; 789 } 790 791 if (Rule->getMatchingFixupCode() && 792 !Rule->getMatchingFixupCode()->getValue().empty()) { 793 // FIXME: Single-use lambda's like this are a serious compile-time 794 // performance and memory issue. It's convenient for this early stage to 795 // defer some work to successive patches but we need to eliminate this 796 // before the ruleset grows to small-moderate size. Last time, it became 797 // a big problem for low-mem systems around the 500 rule mark but by the 798 // time we grow that large we should have merged the ISel match table 799 // mechanism with the Combiner. 800 OS << Indent << " && [&]() {\n" 801 << Indent << " " 802 << CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions, 803 RuleDef.getLoc(), ShowExpansions) 804 << "\n" 805 << Indent << " return true;\n" 806 << Indent << " }()"; 807 } 808 OS << ") {\n" << Indent << " "; 809 810 if (const StringInit *Code = dyn_cast<StringInit>(Applyer->getArg(0))) { 811 OS << CodeExpander(Code->getAsUnquotedString(), Expansions, 812 RuleDef.getLoc(), ShowExpansions) 813 << "\n" 814 << Indent << " return true;\n" 815 << Indent << " }\n"; 816 } else { 817 PrintError(RuleDef.getLoc(), "Expected apply code block"); 818 return; 819 } 820 821 OS << Indent << "}\n"; 822 823 assert(Leaf.isFullyTraversed()); 824 825 // If we didn't have any predicates left over and we're not using the 826 // trap-door we have to support arbitrary C++ code while we're migrating to 827 // the declarative style then we know that subsequent leaves are 828 // unreachable. 829 if (Leaf.isFullyTested() && 830 (!Rule->getMatchingFixupCode() || 831 Rule->getMatchingFixupCode()->getValue().empty())) { 832 AnyFullyTested = true; 833 OS << Indent 834 << "llvm_unreachable(\"Combine rule elision was incorrect\");\n" 835 << Indent << "return false;\n"; 836 } 837 } 838 if (!AnyFullyTested) 839 OS << Indent << "return false;\n"; 840 } 841 842 static void emitAdditionalHelperMethodArguments(raw_ostream &OS, 843 Record *Combiner) { 844 for (Record *Arg : Combiner->getValueAsListOfDefs("AdditionalArguments")) 845 OS << ",\n " << Arg->getValueAsString("Type") 846 << Arg->getValueAsString("Name"); 847 } 848 849 void GICombinerEmitter::run(raw_ostream &OS) { 850 Records.startTimer("Gather rules"); 851 gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules")); 852 if (StopAfterParse) { 853 MatchDagCtx.print(errs()); 854 PrintNote(Combiner->getLoc(), 855 "Terminating due to -gicombiner-stop-after-parse"); 856 return; 857 } 858 if (ErrorsPrinted) 859 PrintFatalError(Combiner->getLoc(), "Failed to parse one or more rules"); 860 LLVM_DEBUG(dbgs() << "Optimizing tree for " << Rules.size() << " rules\n"); 861 std::unique_ptr<GIMatchTree> Tree; 862 Records.startTimer("Optimize combiner"); 863 { 864 GIMatchTreeBuilder TreeBuilder(0); 865 for (const auto &Rule : Rules) { 866 bool HadARoot = false; 867 for (const auto &Root : enumerate(Rule->getMatchDag().roots())) { 868 TreeBuilder.addLeaf(Rule->getName(), Root.index(), Rule->getMatchDag(), 869 Rule.get()); 870 HadARoot = true; 871 } 872 if (!HadARoot) 873 PrintFatalError(Rule->getDef().getLoc(), "All rules must have a root"); 874 } 875 876 Tree = TreeBuilder.run(); 877 } 878 if (StopAfterBuild) { 879 Tree->writeDOTGraph(outs()); 880 PrintNote(Combiner->getLoc(), 881 "Terminating due to -gicombiner-stop-after-build"); 882 return; 883 } 884 885 Records.startTimer("Emit combiner"); 886 OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n" 887 << "#include \"llvm/ADT/SparseBitVector.h\"\n" 888 << "namespace llvm {\n" 889 << "extern cl::OptionCategory GICombinerOptionCategory;\n" 890 << "} // end namespace llvm\n" 891 << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n\n"; 892 893 OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n" 894 << "class " << getClassName() << "RuleConfig {\n" 895 << " SparseBitVector<> DisabledRules;\n" 896 << "\n" 897 << "public:\n" 898 << " bool parseCommandLineOption();\n" 899 << " bool isRuleDisabled(unsigned ID) const;\n" 900 << " bool setRuleEnabled(StringRef RuleIdentifier);\n" 901 << " bool setRuleDisabled(StringRef RuleIdentifier);\n" 902 << "};\n" 903 << "\n" 904 << "class " << getClassName(); 905 StringRef StateClass = Combiner->getValueAsString("StateClass"); 906 if (!StateClass.empty()) 907 OS << " : public " << StateClass; 908 OS << " {\n" 909 << " const " << getClassName() << "RuleConfig *RuleConfig;\n" 910 << "\n" 911 << "public:\n" 912 << " template <typename... Args>" << getClassName() << "(const " 913 << getClassName() << "RuleConfig &RuleConfig, Args &&... args) : "; 914 if (!StateClass.empty()) 915 OS << StateClass << "(std::forward<Args>(args)...), "; 916 OS << "RuleConfig(&RuleConfig) {}\n" 917 << "\n" 918 << " bool tryCombineAll(\n" 919 << " GISelChangeObserver &Observer,\n" 920 << " MachineInstr &MI,\n" 921 << " MachineIRBuilder &B"; 922 emitAdditionalHelperMethodArguments(OS, Combiner); 923 OS << ") const;\n"; 924 OS << "};\n\n"; 925 926 emitNameMatcher(OS); 927 928 OS << "static Optional<std::pair<uint64_t, uint64_t>> " 929 "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n" 930 << " std::pair<StringRef, StringRef> RangePair = " 931 "RuleIdentifier.split('-');\n" 932 << " if (!RangePair.second.empty()) {\n" 933 << " const auto First = " 934 "getRuleIdxForIdentifier(RangePair.first);\n" 935 << " const auto Last = " 936 "getRuleIdxForIdentifier(RangePair.second);\n" 937 << " if (!First.hasValue() || !Last.hasValue())\n" 938 << " return None;\n" 939 << " if (First >= Last)\n" 940 << " report_fatal_error(\"Beginning of range should be before " 941 "end of range\");\n" 942 << " return {{*First, *Last + 1}};\n" 943 << " } else if (RangePair.first == \"*\") {\n" 944 << " return {{0, " << Rules.size() << "}};\n" 945 << " } else {\n" 946 << " const auto I = getRuleIdxForIdentifier(RangePair.first);\n" 947 << " if (!I.hasValue())\n" 948 << " return None;\n" 949 << " return {{*I, *I + 1}};\n" 950 << " }\n" 951 << " return None;\n" 952 << "}\n\n"; 953 954 for (bool Enabled : {true, false}) { 955 OS << "bool " << getClassName() << "RuleConfig::setRule" 956 << (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n" 957 << " auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n" 958 << " if (!MaybeRange.hasValue())\n" 959 << " return false;\n" 960 << " for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n" 961 << " DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n" 962 << " return true;\n" 963 << "}\n\n"; 964 } 965 966 OS << "bool " << getClassName() 967 << "RuleConfig::isRuleDisabled(unsigned RuleID) const {\n" 968 << " return DisabledRules.test(RuleID);\n" 969 << "}\n"; 970 OS << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n\n"; 971 972 OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n" 973 << "\n" 974 << "std::vector<std::string> " << Name << "Option;\n" 975 << "cl::list<std::string> " << Name << "DisableOption(\n" 976 << " \"" << Name.lower() << "-disable-rule\",\n" 977 << " cl::desc(\"Disable one or more combiner rules temporarily in " 978 << "the " << Name << " pass\"),\n" 979 << " cl::CommaSeparated,\n" 980 << " cl::Hidden,\n" 981 << " cl::cat(GICombinerOptionCategory),\n" 982 << " cl::callback([](const std::string &Str) {\n" 983 << " " << Name << "Option.push_back(Str);\n" 984 << " }));\n" 985 << "cl::list<std::string> " << Name << "OnlyEnableOption(\n" 986 << " \"" << Name.lower() << "-only-enable-rule\",\n" 987 << " cl::desc(\"Disable all rules in the " << Name 988 << " pass then re-enable the specified ones\"),\n" 989 << " cl::Hidden,\n" 990 << " cl::cat(GICombinerOptionCategory),\n" 991 << " cl::callback([](const std::string &CommaSeparatedArg) {\n" 992 << " StringRef Str = CommaSeparatedArg;\n" 993 << " " << Name << "Option.push_back(\"*\");\n" 994 << " do {\n" 995 << " auto X = Str.split(\",\");\n" 996 << " " << Name << "Option.push_back((\"!\" + X.first).str());\n" 997 << " Str = X.second;\n" 998 << " } while (!Str.empty());\n" 999 << " }));\n" 1000 << "\n" 1001 << "bool " << getClassName() << "RuleConfig::parseCommandLineOption() {\n" 1002 << " for (StringRef Identifier : " << Name << "Option) {\n" 1003 << " bool Enabled = Identifier.consume_front(\"!\");\n" 1004 << " if (Enabled && !setRuleEnabled(Identifier))\n" 1005 << " return false;\n" 1006 << " if (!Enabled && !setRuleDisabled(Identifier))\n" 1007 << " return false;\n" 1008 << " }\n" 1009 << " return true;\n" 1010 << "}\n\n"; 1011 1012 OS << "bool " << getClassName() << "::tryCombineAll(\n" 1013 << " GISelChangeObserver &Observer,\n" 1014 << " MachineInstr &MI,\n" 1015 << " MachineIRBuilder &B"; 1016 emitAdditionalHelperMethodArguments(OS, Combiner); 1017 OS << ") const {\n" 1018 << " MachineBasicBlock *MBB = MI.getParent();\n" 1019 << " MachineFunction *MF = MBB->getParent();\n" 1020 << " MachineRegisterInfo &MRI = MF->getRegInfo();\n" 1021 << " SmallVector<MachineInstr *, 8> MIs = {&MI};\n\n" 1022 << " (void)MBB; (void)MF; (void)MRI; (void)RuleConfig;\n\n"; 1023 1024 OS << " // Match data\n"; 1025 for (const auto &Rule : Rules) 1026 for (const auto &I : Rule->matchdata_decls()) 1027 OS << " " << I.getType() << " " << I.getVariableName() << ";\n"; 1028 OS << "\n"; 1029 1030 OS << " int Partition = -1;\n"; 1031 generateCodeForTree(OS, *Tree, " "); 1032 OS << "\n return false;\n" 1033 << "}\n" 1034 << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n"; 1035 } 1036 1037 } // end anonymous namespace 1038 1039 //===----------------------------------------------------------------------===// 1040 1041 namespace llvm { 1042 void EmitGICombiner(RecordKeeper &RK, raw_ostream &OS) { 1043 CodeGenTarget Target(RK); 1044 emitSourceFileHeader("Global Combiner", OS); 1045 1046 if (SelectedCombiners.empty()) 1047 PrintFatalError("No combiners selected with -combiners"); 1048 for (const auto &Combiner : SelectedCombiners) { 1049 Record *CombinerDef = RK.getDef(Combiner); 1050 if (!CombinerDef) 1051 PrintFatalError("Could not find " + Combiner); 1052 GICombinerEmitter(RK, Target, Combiner, CombinerDef).run(OS); 1053 } 1054 NumPatternTotalStatistic = NumPatternTotal; 1055 } 1056 1057 } // namespace llvm 1058