1//===- GIMatchDagPredicate - Represent a predicate to check ---------------===//
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#ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H
10#define LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H
11
12#include "llvm/ADT/StringRef.h"
13#include "GIMatchDag.h"
14
15namespace llvm {
16class CodeExpansions;
17class CodeGenInstruction;
18class GIMatchDagOperandList;
19class GIMatchDagContext;
20class raw_ostream;
21
22/// Represents a predicate on the match DAG. This records the details of the
23/// predicate. The dependencies are stored in the GIMatchDag as edges.
24///
25/// Instances of this class objects are owned by the GIMatchDag and are not
26/// shareable between instances of GIMatchDag.
27class GIMatchDagPredicate {
28public:
29  enum GIMatchDagPredicateKind {
30    GIMatchDagPredicateKind_Opcode,
31    GIMatchDagPredicateKind_OneOfOpcodes,
32    GIMatchDagPredicateKind_SameMO,
33  };
34
35protected:
36  const GIMatchDagPredicateKind Kind;
37
38  /// The name of the predicate. For example:
39  ///     (FOO $a:s32, $b, $c)
40  /// will cause 's32' to be assigned to this member for the $a predicate.
41  /// Similarly, the opcode predicate will cause 'FOO' to be assigned to this
42  /// member. Anonymous instructions will have a name assigned for debugging
43  /// purposes.
44  StringRef Name;
45
46  /// The operand list for this predicate. This object may be shared with
47  /// other predicates of a similar 'shape'.
48  const GIMatchDagOperandList &OperandInfo;
49
50public:
51  GIMatchDagPredicate(GIMatchDagPredicateKind Kind, StringRef Name,
52                      const GIMatchDagOperandList &OperandInfo)
53      : Kind(Kind), Name(Name), OperandInfo(OperandInfo) {}
54  virtual ~GIMatchDagPredicate() {}
55
56  GIMatchDagPredicateKind getKind() const { return Kind; }
57
58  StringRef getName() const { return Name; }
59  const GIMatchDagOperandList &getOperandInfo() const { return OperandInfo; }
60
61  // Generate C++ code to check this predicate. If a partitioner has already
62  // tested this predicate then this function won't be called. If this function
63  // is called, it must emit code and return true to indicate that it did so. If
64  // it ever returns false, then the caller will abort due to an untested
65  // predicate.
66  virtual bool generateCheckCode(raw_ostream &OS, StringRef Indent,
67                                 const CodeExpansions &Expansions) const {
68    return false;
69  }
70
71  virtual void print(raw_ostream &OS) const;
72  virtual void printDescription(raw_ostream &OS) const;
73
74#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
75  virtual LLVM_DUMP_METHOD void dump() const { print(errs()); }
76#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
77};
78
79class GIMatchDagOpcodePredicate : public GIMatchDagPredicate {
80  const CodeGenInstruction &Instr;
81
82public:
83  GIMatchDagOpcodePredicate(GIMatchDagContext &Ctx, StringRef Name,
84                            const CodeGenInstruction &Instr);
85
86  static bool classof(const GIMatchDagPredicate *P) {
87    return P->getKind() == GIMatchDagPredicateKind_Opcode;
88  }
89
90  const CodeGenInstruction *getInstr() const { return &Instr; }
91
92  void printDescription(raw_ostream &OS) const override;
93
94#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
95  virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); }
96#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
97};
98
99class GIMatchDagOneOfOpcodesPredicate : public GIMatchDagPredicate {
100  SmallVector<const CodeGenInstruction *, 4> Instrs;
101
102public:
103  GIMatchDagOneOfOpcodesPredicate(GIMatchDagContext &Ctx, StringRef Name);
104
105  void addOpcode(const CodeGenInstruction *Instr) { Instrs.push_back(Instr); }
106
107  static bool classof(const GIMatchDagPredicate *P) {
108    return P->getKind() == GIMatchDagPredicateKind_OneOfOpcodes;
109  }
110
111  const SmallVectorImpl<const CodeGenInstruction *> &getInstrs() const {
112    return Instrs;
113  }
114
115  void printDescription(raw_ostream &OS) const override;
116
117#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
118  virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); }
119#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
120};
121
122class GIMatchDagSameMOPredicate : public GIMatchDagPredicate {
123public:
124  GIMatchDagSameMOPredicate(GIMatchDagContext &Ctx, StringRef Name);
125
126  static bool classof(const GIMatchDagPredicate *P) {
127    return P->getKind() == GIMatchDagPredicateKind_SameMO;
128  }
129
130  void printDescription(raw_ostream &OS) const override;
131
132#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
133  virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); }
134#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
135};
136
137raw_ostream &operator<<(raw_ostream &OS, const GIMatchDagPredicate &N);
138raw_ostream &operator<<(raw_ostream &OS, const GIMatchDagOpcodePredicate &N);
139
140} // end namespace llvm
141#endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H
142