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