1356843Sdim//===- GIMatchDagPredicate - Represent a predicate to check ---------------===//
2356843Sdim//
3356843Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4356843Sdim// See https://llvm.org/LICENSE.txt for license information.
5356843Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6356843Sdim//
7356843Sdim//===----------------------------------------------------------------------===//
8356843Sdim
9356843Sdim#ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H
10356843Sdim#define LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H
11356843Sdim
12356843Sdim#include "llvm/ADT/StringRef.h"
13356843Sdim#include "GIMatchDag.h"
14356843Sdim
15356843Sdimnamespace llvm {
16356843Sdimclass CodeExpansions;
17356843Sdimclass CodeGenInstruction;
18356843Sdimclass GIMatchDagOperandList;
19356843Sdimclass GIMatchDagContext;
20356843Sdimclass raw_ostream;
21356843Sdim
22356843Sdim/// Represents a predicate on the match DAG. This records the details of the
23356843Sdim/// predicate. The dependencies are stored in the GIMatchDag as edges.
24356843Sdim///
25356843Sdim/// Instances of this class objects are owned by the GIMatchDag and are not
26356843Sdim/// shareable between instances of GIMatchDag.
27356843Sdimclass GIMatchDagPredicate {
28356843Sdimpublic:
29356843Sdim  enum GIMatchDagPredicateKind {
30356843Sdim    GIMatchDagPredicateKind_Opcode,
31356843Sdim    GIMatchDagPredicateKind_OneOfOpcodes,
32356843Sdim    GIMatchDagPredicateKind_SameMO,
33356843Sdim  };
34356843Sdim
35356843Sdimprotected:
36356843Sdim  const GIMatchDagPredicateKind Kind;
37356843Sdim
38356843Sdim  /// The name of the predicate. For example:
39356843Sdim  ///     (FOO $a:s32, $b, $c)
40356843Sdim  /// will cause 's32' to be assigned to this member for the $a predicate.
41356843Sdim  /// Similarly, the opcode predicate will cause 'FOO' to be assigned to this
42356843Sdim  /// member. Anonymous instructions will have a name assigned for debugging
43356843Sdim  /// purposes.
44356843Sdim  StringRef Name;
45356843Sdim
46356843Sdim  /// The operand list for this predicate. This object may be shared with
47356843Sdim  /// other predicates of a similar 'shape'.
48356843Sdim  const GIMatchDagOperandList &OperandInfo;
49356843Sdim
50356843Sdimpublic:
51356843Sdim  GIMatchDagPredicate(GIMatchDagPredicateKind Kind, StringRef Name,
52356843Sdim                      const GIMatchDagOperandList &OperandInfo)
53356843Sdim      : Kind(Kind), Name(Name), OperandInfo(OperandInfo) {}
54356843Sdim  virtual ~GIMatchDagPredicate() {}
55356843Sdim
56356843Sdim  GIMatchDagPredicateKind getKind() const { return Kind; }
57356843Sdim
58356843Sdim  StringRef getName() const { return Name; }
59356843Sdim  const GIMatchDagOperandList &getOperandInfo() const { return OperandInfo; }
60356843Sdim
61356843Sdim  // Generate C++ code to check this predicate. If a partitioner has already
62356843Sdim  // tested this predicate then this function won't be called. If this function
63356843Sdim  // is called, it must emit code and return true to indicate that it did so. If
64356843Sdim  // it ever returns false, then the caller will abort due to an untested
65356843Sdim  // predicate.
66356843Sdim  virtual bool generateCheckCode(raw_ostream &OS, StringRef Indent,
67356843Sdim                                 const CodeExpansions &Expansions) const {
68356843Sdim    return false;
69356843Sdim  }
70356843Sdim
71356843Sdim  virtual void print(raw_ostream &OS) const;
72356843Sdim  virtual void printDescription(raw_ostream &OS) const;
73356843Sdim
74356843Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
75356843Sdim  virtual LLVM_DUMP_METHOD void dump() const { print(errs()); }
76356843Sdim#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
77356843Sdim};
78356843Sdim
79356843Sdimclass GIMatchDagOpcodePredicate : public GIMatchDagPredicate {
80356843Sdim  const CodeGenInstruction &Instr;
81356843Sdim
82356843Sdimpublic:
83356843Sdim  GIMatchDagOpcodePredicate(GIMatchDagContext &Ctx, StringRef Name,
84356843Sdim                            const CodeGenInstruction &Instr);
85356843Sdim
86356843Sdim  static bool classof(const GIMatchDagPredicate *P) {
87356843Sdim    return P->getKind() == GIMatchDagPredicateKind_Opcode;
88356843Sdim  }
89356843Sdim
90356843Sdim  const CodeGenInstruction *getInstr() const { return &Instr; }
91356843Sdim
92356843Sdim  void printDescription(raw_ostream &OS) const override;
93356843Sdim
94356843Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
95356843Sdim  virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); }
96356843Sdim#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
97356843Sdim};
98356843Sdim
99356843Sdimclass GIMatchDagOneOfOpcodesPredicate : public GIMatchDagPredicate {
100356843Sdim  SmallVector<const CodeGenInstruction *, 4> Instrs;
101356843Sdim
102356843Sdimpublic:
103356843Sdim  GIMatchDagOneOfOpcodesPredicate(GIMatchDagContext &Ctx, StringRef Name);
104356843Sdim
105356843Sdim  void addOpcode(const CodeGenInstruction *Instr) { Instrs.push_back(Instr); }
106356843Sdim
107356843Sdim  static bool classof(const GIMatchDagPredicate *P) {
108356843Sdim    return P->getKind() == GIMatchDagPredicateKind_OneOfOpcodes;
109356843Sdim  }
110356843Sdim
111356843Sdim  const SmallVectorImpl<const CodeGenInstruction *> &getInstrs() const {
112356843Sdim    return Instrs;
113356843Sdim  }
114356843Sdim
115356843Sdim  void printDescription(raw_ostream &OS) const override;
116356843Sdim
117356843Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
118356843Sdim  virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); }
119356843Sdim#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
120356843Sdim};
121356843Sdim
122356843Sdimclass GIMatchDagSameMOPredicate : public GIMatchDagPredicate {
123356843Sdimpublic:
124356843Sdim  GIMatchDagSameMOPredicate(GIMatchDagContext &Ctx, StringRef Name);
125356843Sdim
126356843Sdim  static bool classof(const GIMatchDagPredicate *P) {
127356843Sdim    return P->getKind() == GIMatchDagPredicateKind_SameMO;
128356843Sdim  }
129356843Sdim
130356843Sdim  void printDescription(raw_ostream &OS) const override;
131356843Sdim
132356843Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
133356843Sdim  virtual LLVM_DUMP_METHOD void dump() const override { print(errs()); }
134356843Sdim#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
135356843Sdim};
136356843Sdim
137356843Sdimraw_ostream &operator<<(raw_ostream &OS, const GIMatchDagPredicate &N);
138356843Sdimraw_ostream &operator<<(raw_ostream &OS, const GIMatchDagOpcodePredicate &N);
139356843Sdim
140356843Sdim} // end namespace llvm
141356843Sdim#endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGPREDICATE_H
142