GIMatchTree.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. //===- GIMatchTree.h - A decision tree to match GIMatchDag's --------------===//
  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. #ifndef LLVM_UTILS_TABLEGEN_GIMATCHTREE_H
  9. #define LLVM_UTILS_TABLEGEN_GIMATCHTREE_H
  10. #include "GIMatchDag.h"
  11. #include "llvm/ADT/BitVector.h"
  12. namespace llvm {
  13. class raw_ostream;
  14. class GIMatchTreeBuilder;
  15. class GIMatchTreePartitioner;
  16. /// Describes the binding of a variable to the matched MIR
  17. class GIMatchTreeVariableBinding {
  18. /// The name of the variable described by this binding.
  19. StringRef Name;
  20. // The matched instruction it is bound to.
  21. unsigned InstrID;
  22. // The matched operand (if appropriate) it is bound to.
  23. std::optional<unsigned> OpIdx;
  24. public:
  25. GIMatchTreeVariableBinding(StringRef Name, unsigned InstrID,
  26. std::optional<unsigned> OpIdx = std::nullopt)
  27. : Name(Name), InstrID(InstrID), OpIdx(OpIdx) {}
  28. bool isInstr() const { return !OpIdx; }
  29. StringRef getName() const { return Name; }
  30. unsigned getInstrID() const { return InstrID; }
  31. unsigned getOpIdx() const {
  32. assert(OpIdx && "Is not an operand binding");
  33. return *OpIdx;
  34. }
  35. };
  36. /// Associates a matchable with a leaf of the decision tree.
  37. class GIMatchTreeLeafInfo {
  38. public:
  39. using const_var_binding_iterator =
  40. std::vector<GIMatchTreeVariableBinding>::const_iterator;
  41. using UntestedPredicatesTy = SmallVector<const GIMatchDagPredicate *, 1>;
  42. using const_untested_predicates_iterator = UntestedPredicatesTy::const_iterator;
  43. protected:
  44. /// A name for the matchable. This is primarily for debugging.
  45. StringRef Name;
  46. /// Where rules have multiple roots, this is which root we're starting from.
  47. unsigned RootIdx;
  48. /// Opaque data the caller of the tree building code understands.
  49. void *Data;
  50. /// Has the decision tree covered every edge traversal? If it hasn't then this
  51. /// is an unrecoverable error indicating there's something wrong with the
  52. /// partitioners.
  53. bool IsFullyTraversed;
  54. /// Has the decision tree covered every predicate test? If it has, then
  55. /// subsequent matchables on the same leaf are unreachable. If it hasn't, the
  56. /// code that requested the GIMatchTree is responsible for finishing off any
  57. /// remaining predicates.
  58. bool IsFullyTested;
  59. /// The variable bindings associated with this leaf so far.
  60. std::vector<GIMatchTreeVariableBinding> VarBindings;
  61. /// Any predicates left untested by the time we reach this leaf.
  62. UntestedPredicatesTy UntestedPredicates;
  63. public:
  64. GIMatchTreeLeafInfo() { llvm_unreachable("Cannot default-construct"); }
  65. GIMatchTreeLeafInfo(StringRef Name, unsigned RootIdx, void *Data)
  66. : Name(Name), RootIdx(RootIdx), Data(Data), IsFullyTraversed(false),
  67. IsFullyTested(false) {}
  68. StringRef getName() const { return Name; }
  69. unsigned getRootIdx() const { return RootIdx; }
  70. template <class Ty> Ty *getTargetData() const {
  71. return static_cast<Ty *>(Data);
  72. }
  73. bool isFullyTraversed() const { return IsFullyTraversed; }
  74. void setIsFullyTraversed(bool V) { IsFullyTraversed = V; }
  75. bool isFullyTested() const { return IsFullyTested; }
  76. void setIsFullyTested(bool V) { IsFullyTested = V; }
  77. void bindInstrVariable(StringRef Name, unsigned InstrID) {
  78. VarBindings.emplace_back(Name, InstrID);
  79. }
  80. void bindOperandVariable(StringRef Name, unsigned InstrID, unsigned OpIdx) {
  81. VarBindings.emplace_back(Name, InstrID, OpIdx);
  82. }
  83. const_var_binding_iterator var_bindings_begin() const {
  84. return VarBindings.begin();
  85. }
  86. const_var_binding_iterator var_bindings_end() const {
  87. return VarBindings.end();
  88. }
  89. iterator_range<const_var_binding_iterator> var_bindings() const {
  90. return make_range(VarBindings.begin(), VarBindings.end());
  91. }
  92. iterator_range<const_untested_predicates_iterator> untested_predicates() const {
  93. return make_range(UntestedPredicates.begin(), UntestedPredicates.end());
  94. }
  95. void addUntestedPredicate(const GIMatchDagPredicate *P) {
  96. UntestedPredicates.push_back(P);
  97. }
  98. };
  99. /// The nodes of a decision tree used to perform the match.
  100. /// This will be used to generate the C++ code or state machine equivalent.
  101. ///
  102. /// It should be noted that some nodes of this tree (most notably nodes handling
  103. /// def -> use edges) will need to iterate over several possible matches. As
  104. /// such, code generated from this will sometimes need to support backtracking.
  105. class GIMatchTree {
  106. using LeafVector = std::vector<GIMatchTreeLeafInfo>;
  107. /// The partitioner that has been chosen for this node. This may be nullptr if
  108. /// a partitioner hasn't been chosen yet or if the node is a leaf.
  109. std::unique_ptr<GIMatchTreePartitioner> Partitioner;
  110. /// All the leaves that are possible for this node of the tree.
  111. /// Note: This should be emptied after the tree is built when there are
  112. /// children but this currently isn't done to aid debuggability of the DOT
  113. /// graph for the decision tree.
  114. LeafVector PossibleLeaves;
  115. /// The children of this node. The index into this array must match the index
  116. /// chosen by the partitioner.
  117. std::vector<GIMatchTree> Children;
  118. void writeDOTGraphNode(raw_ostream &OS) const;
  119. void writeDOTGraphEdges(raw_ostream &OS) const;
  120. public:
  121. void writeDOTGraph(raw_ostream &OS) const;
  122. void setNumChildren(unsigned Num) { Children.resize(Num); }
  123. void addPossibleLeaf(const GIMatchTreeLeafInfo &V, bool IsFullyTraversed,
  124. bool IsFullyTested) {
  125. PossibleLeaves.push_back(V);
  126. PossibleLeaves.back().setIsFullyTraversed(IsFullyTraversed);
  127. PossibleLeaves.back().setIsFullyTested(IsFullyTested);
  128. }
  129. void dropLeavesAfter(size_t Length) {
  130. if (PossibleLeaves.size() > Length)
  131. PossibleLeaves.resize(Length);
  132. }
  133. void setPartitioner(std::unique_ptr<GIMatchTreePartitioner> &&V) {
  134. Partitioner = std::move(V);
  135. }
  136. GIMatchTreePartitioner *getPartitioner() const { return Partitioner.get(); }
  137. std::vector<GIMatchTree>::iterator children_begin() {
  138. return Children.begin();
  139. }
  140. std::vector<GIMatchTree>::iterator children_end() { return Children.end(); }
  141. iterator_range<std::vector<GIMatchTree>::iterator> children() {
  142. return make_range(children_begin(), children_end());
  143. }
  144. std::vector<GIMatchTree>::const_iterator children_begin() const {
  145. return Children.begin();
  146. }
  147. std::vector<GIMatchTree>::const_iterator children_end() const {
  148. return Children.end();
  149. }
  150. iterator_range<std::vector<GIMatchTree>::const_iterator> children() const {
  151. return make_range(children_begin(), children_end());
  152. }
  153. LeafVector::const_iterator possible_leaves_begin() const {
  154. return PossibleLeaves.begin();
  155. }
  156. LeafVector::const_iterator possible_leaves_end() const {
  157. return PossibleLeaves.end();
  158. }
  159. iterator_range<LeafVector::const_iterator>
  160. possible_leaves() const {
  161. return make_range(possible_leaves_begin(), possible_leaves_end());
  162. }
  163. LeafVector::iterator possible_leaves_begin() {
  164. return PossibleLeaves.begin();
  165. }
  166. LeafVector::iterator possible_leaves_end() {
  167. return PossibleLeaves.end();
  168. }
  169. iterator_range<LeafVector::iterator> possible_leaves() {
  170. return make_range(possible_leaves_begin(), possible_leaves_end());
  171. }
  172. };
  173. /// Record information that is known about the instruction bound to this ID and
  174. /// GIMatchDagInstrNode. Every rule gets its own set of
  175. /// GIMatchTreeInstrInfo to bind the shared IDs to an instr node in its
  176. /// DAG.
  177. ///
  178. /// For example, if we know that there are 3 operands. We can record it here to
  179. /// elide duplicate checks.
  180. class GIMatchTreeInstrInfo {
  181. /// The instruction ID for the matched instruction.
  182. unsigned ID;
  183. /// The corresponding instruction node in the MatchDAG.
  184. const GIMatchDagInstr *InstrNode;
  185. public:
  186. GIMatchTreeInstrInfo(unsigned ID, const GIMatchDagInstr *InstrNode)
  187. : ID(ID), InstrNode(InstrNode) {}
  188. unsigned getID() const { return ID; }
  189. const GIMatchDagInstr *getInstrNode() const { return InstrNode; }
  190. };
  191. /// Record information that is known about the operand bound to this ID, OpIdx,
  192. /// and GIMatchDagInstrNode. Every rule gets its own set of
  193. /// GIMatchTreeOperandInfo to bind the shared IDs to an operand of an
  194. /// instr node from its DAG.
  195. ///
  196. /// For example, if we know that there the operand is a register. We can record
  197. /// it here to elide duplicate checks.
  198. class GIMatchTreeOperandInfo {
  199. /// The corresponding instruction node in the MatchDAG that the operand
  200. /// belongs to.
  201. const GIMatchDagInstr *InstrNode;
  202. unsigned OpIdx;
  203. public:
  204. GIMatchTreeOperandInfo(const GIMatchDagInstr *InstrNode, unsigned OpIdx)
  205. : InstrNode(InstrNode), OpIdx(OpIdx) {}
  206. const GIMatchDagInstr *getInstrNode() const { return InstrNode; }
  207. unsigned getOpIdx() const { return OpIdx; }
  208. };
  209. /// Represent a leaf of the match tree and any working data we need to build the
  210. /// tree.
  211. ///
  212. /// It's important to note that each rule can have multiple
  213. /// GIMatchTreeBuilderLeafInfo's since the partitioners do not always partition
  214. /// into mutually-exclusive partitions. For example:
  215. /// R1: (FOO ..., ...)
  216. /// R2: (oneof(FOO, BAR) ..., ...)
  217. /// will partition by opcode into two partitions FOO=>[R1, R2], and BAR=>[R2]
  218. ///
  219. /// As an optimization, all instructions, edges, and predicates in the DAGs are
  220. /// numbered and tracked in BitVectors. As such, the GIMatchDAG must not be
  221. /// modified once construction of the tree has begun.
  222. class GIMatchTreeBuilderLeafInfo {
  223. protected:
  224. GIMatchTreeBuilder &Builder;
  225. GIMatchTreeLeafInfo Info;
  226. const GIMatchDag &MatchDag;
  227. /// The association between GIMatchDagInstr* and GIMatchTreeInstrInfo.
  228. /// The primary reason for this members existence is to allow the use of
  229. /// InstrIDToInfo.lookup() since that requires that the value is
  230. /// default-constructible.
  231. DenseMap<const GIMatchDagInstr *, GIMatchTreeInstrInfo> InstrNodeToInfo;
  232. /// The instruction information for a given ID in the context of this
  233. /// particular leaf.
  234. DenseMap<unsigned, GIMatchTreeInstrInfo *> InstrIDToInfo;
  235. /// The operand information for a given ID and OpIdx in the context of this
  236. /// particular leaf.
  237. DenseMap<std::pair<unsigned, unsigned>, GIMatchTreeOperandInfo>
  238. OperandIDToInfo;
  239. public:
  240. /// The remaining instrs/edges/predicates to visit
  241. BitVector RemainingInstrNodes;
  242. BitVector RemainingEdges;
  243. BitVector RemainingPredicates;
  244. // The remaining predicate dependencies for each predicate
  245. std::vector<BitVector> UnsatisfiedPredDepsForPred;
  246. /// The edges/predicates we can visit as a result of the declare*() calls we
  247. /// have already made. We don't need an instrs version since edges imply the
  248. /// instr.
  249. BitVector TraversableEdges;
  250. BitVector TestablePredicates;
  251. /// Map predicates from the DAG to their position in the DAG predicate
  252. /// iterators.
  253. DenseMap<GIMatchDagPredicate *, unsigned> PredicateIDs;
  254. /// Map predicate dependency edges from the DAG to their position in the DAG
  255. /// predicate dependency iterators.
  256. DenseMap<GIMatchDagPredicateDependencyEdge *, unsigned> PredicateDepIDs;
  257. public:
  258. GIMatchTreeBuilderLeafInfo(GIMatchTreeBuilder &Builder, StringRef Name,
  259. unsigned RootIdx, const GIMatchDag &MatchDag,
  260. void *Data);
  261. StringRef getName() const { return Info.getName(); }
  262. GIMatchTreeLeafInfo &getInfo() { return Info; }
  263. const GIMatchTreeLeafInfo &getInfo() const { return Info; }
  264. const GIMatchDag &getMatchDag() const { return MatchDag; }
  265. unsigned getRootIdx() const { return Info.getRootIdx(); }
  266. /// Has this DAG been fully traversed. This must be true by the time the tree
  267. /// builder finishes.
  268. bool isFullyTraversed() const {
  269. // We don't need UnsatisfiedPredDepsForPred because RemainingPredicates
  270. // can't be all-zero without satisfying all the dependencies. The same is
  271. // almost true for Edges and Instrs but it's possible to have Instrs without
  272. // Edges.
  273. return RemainingInstrNodes.none() && RemainingEdges.none();
  274. }
  275. /// Has this DAG been fully tested. This hould be true by the time the tree
  276. /// builder finishes but clients can finish any untested predicates left over
  277. /// if it's not true.
  278. bool isFullyTested() const {
  279. // We don't need UnsatisfiedPredDepsForPred because RemainingPredicates
  280. // can't be all-zero without satisfying all the dependencies. The same is
  281. // almost true for Edges and Instrs but it's possible to have Instrs without
  282. // Edges.
  283. return RemainingInstrNodes.none() && RemainingEdges.none() &&
  284. RemainingPredicates.none();
  285. }
  286. const GIMatchDagInstr *getInstr(unsigned Idx) const {
  287. return *(MatchDag.instr_nodes_begin() + Idx);
  288. }
  289. const GIMatchDagEdge *getEdge(unsigned Idx) const {
  290. return *(MatchDag.edges_begin() + Idx);
  291. }
  292. GIMatchDagEdge *getEdge(unsigned Idx) {
  293. return *(MatchDag.edges_begin() + Idx);
  294. }
  295. const GIMatchDagPredicate *getPredicate(unsigned Idx) const {
  296. return *(MatchDag.predicates_begin() + Idx);
  297. }
  298. iterator_range<llvm::BitVector::const_set_bits_iterator>
  299. untested_instrs() const {
  300. return RemainingInstrNodes.set_bits();
  301. }
  302. iterator_range<llvm::BitVector::const_set_bits_iterator>
  303. untested_edges() const {
  304. return RemainingEdges.set_bits();
  305. }
  306. iterator_range<llvm::BitVector::const_set_bits_iterator>
  307. untested_predicates() const {
  308. return RemainingPredicates.set_bits();
  309. }
  310. /// Bind an instr node to the given ID and clear any blocking dependencies
  311. /// that were waiting for it.
  312. void declareInstr(const GIMatchDagInstr *Instr, unsigned ID);
  313. /// Bind an operand to the given ID and OpIdx and clear any blocking
  314. /// dependencies that were waiting for it.
  315. void declareOperand(unsigned InstrID, unsigned OpIdx);
  316. GIMatchTreeInstrInfo *getInstrInfo(unsigned ID) const {
  317. return InstrIDToInfo.lookup(ID);
  318. }
  319. void dump(raw_ostream &OS) const {
  320. OS << "Leaf " << getName() << " for root #" << getRootIdx() << "\n";
  321. MatchDag.print(OS);
  322. for (const auto &I : InstrIDToInfo)
  323. OS << "Declared Instr #" << I.first << "\n";
  324. for (const auto &I : OperandIDToInfo)
  325. OS << "Declared Instr #" << I.first.first << ", Op #" << I.first.second
  326. << "\n";
  327. OS << RemainingInstrNodes.count() << " untested instrs of "
  328. << RemainingInstrNodes.size() << "\n";
  329. OS << RemainingEdges.count() << " untested edges of "
  330. << RemainingEdges.size() << "\n";
  331. OS << RemainingPredicates.count() << " untested predicates of "
  332. << RemainingPredicates.size() << "\n";
  333. OS << TraversableEdges.count() << " edges could be traversed\n";
  334. OS << TestablePredicates.count() << " predicates could be tested\n";
  335. }
  336. };
  337. /// The tree builder has a fairly tough job. It's purpose is to merge all the
  338. /// DAGs from the ruleset into a decision tree that walks all of them
  339. /// simultaneously and identifies the rule that was matched. In addition to
  340. /// that, it also needs to find the most efficient order to make decisions
  341. /// without violating any dependencies and ensure that every DAG covers every
  342. /// instr/edge/predicate.
  343. class GIMatchTreeBuilder {
  344. public:
  345. using LeafVec = std::vector<GIMatchTreeBuilderLeafInfo>;
  346. protected:
  347. /// The leaves that the resulting decision tree will distinguish.
  348. LeafVec Leaves;
  349. /// The tree node being constructed.
  350. GIMatchTree *TreeNode;
  351. /// The builders for each subtree resulting from the current decision.
  352. std::vector<GIMatchTreeBuilder> SubtreeBuilders;
  353. /// The possible partitioners we could apply right now.
  354. std::vector<std::unique_ptr<GIMatchTreePartitioner>> Partitioners;
  355. /// The next instruction ID to allocate when requested by the chosen
  356. /// Partitioner.
  357. unsigned NextInstrID;
  358. /// Use any context we have stored to cull partitioners that only test things
  359. /// we already know. At the time of writing, there's no need to do anything
  360. /// here but it will become important once, for example, there is a
  361. /// num-operands and an opcode partitioner. This is because applying an opcode
  362. /// partitioner (usually) makes the number of operands known which makes
  363. /// additional checking pointless.
  364. void filterRedundantPartitioners();
  365. /// Evaluate the available partioners and select the best one at the moment.
  366. void evaluatePartitioners();
  367. /// Construct the current tree node.
  368. void runStep();
  369. public:
  370. GIMatchTreeBuilder(unsigned NextInstrID) : NextInstrID(NextInstrID) {}
  371. GIMatchTreeBuilder(GIMatchTree *TreeNode, unsigned NextInstrID)
  372. : TreeNode(TreeNode), NextInstrID(NextInstrID) {}
  373. void addLeaf(StringRef Name, unsigned RootIdx, const GIMatchDag &MatchDag,
  374. void *Data) {
  375. Leaves.emplace_back(*this, Name, RootIdx, MatchDag, Data);
  376. }
  377. void addLeaf(const GIMatchTreeBuilderLeafInfo &L) { Leaves.push_back(L); }
  378. void addPartitioner(std::unique_ptr<GIMatchTreePartitioner> P) {
  379. Partitioners.push_back(std::move(P));
  380. }
  381. void addPartitionersForInstr(unsigned InstrIdx);
  382. void addPartitionersForOperand(unsigned InstrID, unsigned OpIdx);
  383. LeafVec &getPossibleLeaves() { return Leaves; }
  384. unsigned allocInstrID() { return NextInstrID++; }
  385. /// Construct the decision tree.
  386. std::unique_ptr<GIMatchTree> run();
  387. };
  388. /// Partitioners are the core of the tree builder and are unfortunately rather
  389. /// tricky to write.
  390. class GIMatchTreePartitioner {
  391. protected:
  392. /// The partitions resulting from applying the partitioner to the possible
  393. /// leaves. The keys must be consecutive integers starting from 0. This can
  394. /// lead to some unfortunate situations where partitioners test a predicate
  395. /// and use 0 for success and 1 for failure if the ruleset encounters a
  396. /// success case first but is necessary to assign the partition to one of the
  397. /// tree nodes children. As a result, you usually need some kind of
  398. /// indirection to map the natural keys (e.g. ptrs/bools) to this linear
  399. /// sequence. The values are a bitvector indicating which leaves belong to
  400. /// this partition.
  401. DenseMap<unsigned, BitVector> Partitions;
  402. public:
  403. virtual ~GIMatchTreePartitioner() {}
  404. virtual std::unique_ptr<GIMatchTreePartitioner> clone() const = 0;
  405. /// Determines which partitions the given leaves belong to. A leaf may belong
  406. /// to multiple partitions in which case it will be duplicated during
  407. /// applyForPartition().
  408. ///
  409. /// This function can be rather complicated. A few particular things to be
  410. /// aware of include:
  411. /// * One leaf can be assigned to multiple partitions when there's some
  412. /// ambiguity.
  413. /// * Not all DAG's for the leaves may be able to perform the test. For
  414. /// example, the opcode partitiioner must account for one DAG being a
  415. /// superset of another such as [(ADD ..., ..., ...)], and [(MUL t, ...,
  416. /// ...), (ADD ..., t, ...)]
  417. /// * Attaching meaning to a particular partition index will generally not
  418. /// work due to the '0, 1, ..., n' requirement. You might encounter cases
  419. /// where only partition 1 is seen, leaving a missing 0.
  420. /// * Finding a specific predicate such as the opcode predicate for a specific
  421. /// instruction is non-trivial. It's often O(NumPredicates), leading to
  422. /// O(NumPredicates*NumRules) when applied to the whole ruleset. The good
  423. /// news there is that n is typically small thanks to predicate dependencies
  424. /// limiting how many are testable at once. Also, with opcode and type
  425. /// predicates being so frequent the value of m drops very fast too. It
  426. /// wouldn't be terribly surprising to see a 10k ruleset drop down to an
  427. /// average of 100 leaves per partition after a single opcode partitioner.
  428. /// * The same goes for finding specific edges. The need to traverse them in
  429. /// dependency order dramatically limits the search space at any given
  430. /// moment.
  431. /// * If you need to add a leaf to all partitions, make sure you don't forget
  432. /// them when adding partitions later.
  433. virtual void repartition(GIMatchTreeBuilder::LeafVec &Leaves) = 0;
  434. /// Delegate the leaves for a given partition to the corresponding subbuilder,
  435. /// update any recorded context for this partition (e.g. allocate instr id's
  436. /// for instrs recorder by the current node), and clear any blocking
  437. /// dependencies this partitioner resolved.
  438. virtual void applyForPartition(unsigned PartitionIdx,
  439. GIMatchTreeBuilder &Builder,
  440. GIMatchTreeBuilder &SubBuilder) = 0;
  441. /// Return a BitVector indicating which leaves should be transferred to the
  442. /// specified partition. Note that the same leaf can be indicated for multiple
  443. /// partitions.
  444. BitVector getPossibleLeavesForPartition(unsigned Idx) {
  445. const auto &I = Partitions.find(Idx);
  446. assert(I != Partitions.end() && "Requested non-existant partition");
  447. return I->second;
  448. }
  449. size_t getNumPartitions() const { return Partitions.size(); }
  450. size_t getNumLeavesWithDupes() const {
  451. size_t S = 0;
  452. for (const auto &P : Partitions)
  453. S += P.second.size();
  454. return S;
  455. }
  456. /// Emit a brief description of the partitioner suitable for debug printing or
  457. /// use in a DOT graph.
  458. virtual void emitDescription(raw_ostream &OS) const = 0;
  459. /// Emit a label for the given partition suitable for debug printing or use in
  460. /// a DOT graph.
  461. virtual void emitPartitionName(raw_ostream &OS, unsigned Idx) const = 0;
  462. /// Emit a long description of how the partitioner partitions the leaves.
  463. virtual void emitPartitionResults(raw_ostream &OS) const = 0;
  464. /// Generate code to select between partitions based on the MIR being matched.
  465. /// This is typically a switch statement that picks a partition index.
  466. virtual void generatePartitionSelectorCode(raw_ostream &OS,
  467. StringRef Indent) const = 0;
  468. };
  469. /// Partition according to the opcode of the instruction.
  470. ///
  471. /// Numbers CodeGenInstr ptrs for use as partition ID's. One special partition,
  472. /// nullptr, represents the case where the instruction isn't known.
  473. ///
  474. /// * If the opcode can be tested and is a single opcode, create the partition
  475. /// for that opcode and assign the leaf to it. This partition no longer needs
  476. /// to test the opcode, and many details about the instruction will usually
  477. /// become known (e.g. number of operands for non-variadic instrs) via the
  478. /// CodeGenInstr ptr.
  479. /// * (not implemented yet) If the opcode can be tested and is a choice of
  480. /// opcodes, then the leaf can be treated like the single-opcode case but must
  481. /// be added to all relevant partitions and not quite as much becomes known as
  482. /// a result. That said, multiple-choice opcodes are likely similar enough
  483. /// (because if they aren't then handling them together makes little sense)
  484. /// that plenty still becomes known. The main implementation issue with this
  485. /// is having a description to represent the commonality between instructions.
  486. /// * If the opcode is not tested, the leaf must be added to all partitions
  487. /// including the wildcard nullptr partition. What becomes known as a result
  488. /// varies between partitions.
  489. /// * If the instruction to be tested is not declared then add the leaf to all
  490. /// partitions. This occurs when we encounter one rule that is a superset of
  491. /// the other and we are still matching the remainder of the superset. The
  492. /// result is that the cases that don't match the superset will match the
  493. /// subset rule, while the ones that do match the superset will match either
  494. /// (which one is algorithm dependent but will usually be the superset).
  495. class GIMatchTreeOpcodePartitioner : public GIMatchTreePartitioner {
  496. unsigned InstrID;
  497. DenseMap<const CodeGenInstruction *, unsigned> InstrToPartition;
  498. std::vector<const CodeGenInstruction *> PartitionToInstr;
  499. std::vector<BitVector> TestedPredicates;
  500. public:
  501. GIMatchTreeOpcodePartitioner(unsigned InstrID) : InstrID(InstrID) {}
  502. std::unique_ptr<GIMatchTreePartitioner> clone() const override {
  503. return std::make_unique<GIMatchTreeOpcodePartitioner>(*this);
  504. }
  505. void emitDescription(raw_ostream &OS) const override {
  506. OS << "MI[" << InstrID << "].getOpcode()";
  507. }
  508. void emitPartitionName(raw_ostream &OS, unsigned Idx) const override;
  509. void repartition(GIMatchTreeBuilder::LeafVec &Leaves) override;
  510. void applyForPartition(unsigned Idx, GIMatchTreeBuilder &SubBuilder,
  511. GIMatchTreeBuilder &Builder) override;
  512. void emitPartitionResults(raw_ostream &OS) const override;
  513. void generatePartitionSelectorCode(raw_ostream &OS,
  514. StringRef Indent) const override;
  515. };
  516. class GIMatchTreeVRegDefPartitioner : public GIMatchTreePartitioner {
  517. unsigned NewInstrID = -1;
  518. unsigned InstrID;
  519. unsigned OpIdx;
  520. std::vector<BitVector> TraversedEdges;
  521. DenseMap<unsigned, unsigned> ResultToPartition;
  522. BitVector PartitionToResult;
  523. void addToPartition(bool Result, unsigned LeafIdx);
  524. public:
  525. GIMatchTreeVRegDefPartitioner(unsigned InstrID, unsigned OpIdx)
  526. : InstrID(InstrID), OpIdx(OpIdx) {}
  527. std::unique_ptr<GIMatchTreePartitioner> clone() const override {
  528. return std::make_unique<GIMatchTreeVRegDefPartitioner>(*this);
  529. }
  530. void emitDescription(raw_ostream &OS) const override {
  531. OS << "MI[" << NewInstrID << "] = getVRegDef(MI[" << InstrID
  532. << "].getOperand(" << OpIdx << "))";
  533. }
  534. void emitPartitionName(raw_ostream &OS, unsigned Idx) const override {
  535. bool Result = PartitionToResult[Idx];
  536. if (Result)
  537. OS << "true";
  538. else
  539. OS << "false";
  540. }
  541. void repartition(GIMatchTreeBuilder::LeafVec &Leaves) override;
  542. void applyForPartition(unsigned PartitionIdx, GIMatchTreeBuilder &Builder,
  543. GIMatchTreeBuilder &SubBuilder) override;
  544. void emitPartitionResults(raw_ostream &OS) const override;
  545. void generatePartitionSelectorCode(raw_ostream &OS,
  546. StringRef Indent) const override;
  547. };
  548. } // end namespace llvm
  549. #endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHTREE_H