1//===- GIMatchDagOperands.h - Represent a shared operand list for nodes ---===//
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//
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGOPERANDS_H
13#define LLVM_UTILS_TABLEGEN_GIMATCHDAGOPERANDS_H
14
15#include "llvm/ADT/FoldingSet.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/Support/raw_ostream.h"
19
20#include <vector>
21
22namespace llvm {
23class CodeGenInstruction;
24/// Describes an operand of a MachineInstr w.r.t the DAG Matching. This
25/// information is derived from CodeGenInstruction::Operands but is more
26/// readily available for context-less access as we don't need to know which
27/// instruction it's used with or know how many defs that instruction had.
28///
29/// There may be multiple GIMatchDagOperand's with the same contents. However,
30/// they are uniqued within the set of instructions that have the same overall
31/// operand list. For example, given:
32///     Inst1 operands ($dst:<def>, $src1, $src2)
33///     Inst2 operands ($dst:<def>, $src1, $src2)
34///     Inst3 operands ($dst:<def>, $src)
35/// $src1 will have a single instance of GIMatchDagOperand shared by Inst1 and
36/// Inst2, as will $src2. $dst however, will have two instances one shared
37/// between Inst1 and Inst2 and one unique to Inst3. We could potentially
38/// fully de-dupe the GIMatchDagOperand instances but the saving is not expected
39/// to be worth the overhead.
40///
41/// The result of this is that the address of the object can be relied upon to
42/// trivially identify commonality between two instructions which will be useful
43/// when generating the matcher. When the pointers differ, the contents can be
44/// inspected instead.
45class GIMatchDagOperand {
46  unsigned Idx;
47  StringRef Name;
48  bool IsDef;
49
50public:
51  GIMatchDagOperand(unsigned Idx, StringRef Name, bool IsDef)
52      : Idx(Idx), Name(Name), IsDef(IsDef) {}
53
54  unsigned getIdx() const { return Idx; }
55  StringRef getName() const { return Name; }
56  bool isDef() const { return IsDef; }
57
58  /// This object isn't a FoldingSetNode but it's part of one. See FoldingSet
59  /// for details on the Profile function.
60  void Profile(FoldingSetNodeID &ID) const;
61
62  /// A helper that behaves like Profile() but is also usable without the object.
63  /// We use size_t here to match enumerate<...>::index(). If we don't match
64  /// that the hashes won't be equal.
65  static void Profile(FoldingSetNodeID &ID, size_t Idx, StringRef Name,
66                      bool IsDef);
67};
68
69/// A list of GIMatchDagOperands for an instruction without any association with
70/// a particular instruction.
71///
72/// An important detail to be aware of with this class is that they are shared
73/// with other instructions of a similar 'shape'. For example, all the binary
74/// instructions are likely to share a single GIMatchDagOperandList. This is
75/// primarily a memory optimization as it's fairly common to have a large number
76/// of instructions but only a few 'shapes'.
77///
78/// See GIMatchDagOperandList::Profile() for the details on how they are folded.
79class GIMatchDagOperandList : public FoldingSetNode {
80public:
81  using value_type = GIMatchDagOperand;
82
83protected:
84  using vector_type = SmallVector<GIMatchDagOperand, 3>;
85
86public:
87  using iterator = vector_type::iterator;
88  using const_iterator = vector_type::const_iterator;
89
90protected:
91  vector_type Operands;
92  StringMap<unsigned> OperandsByName;
93
94public:
95  void add(StringRef Name, unsigned Idx, bool IsDef);
96
97  /// See FoldingSet for details.
98  void Profile(FoldingSetNodeID &ID) const;
99
100  iterator begin() { return Operands.begin(); }
101  const_iterator begin() const { return Operands.begin(); }
102  iterator end() { return Operands.end(); }
103  const_iterator end() const { return Operands.end(); }
104
105  const value_type &operator[](unsigned I) const { return Operands[I]; }
106  const value_type &operator[](StringRef K) const;
107
108  void print(raw_ostream &OS) const;
109#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
110  LLVM_DUMP_METHOD void dump() const { print(errs()); }
111#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
112};
113
114/// This is the portion of GIMatchDagContext that directly relates to
115/// GIMatchDagOperandList and GIMatchDagOperandList.
116class GIMatchDagOperandListContext {
117  FoldingSet<GIMatchDagOperandList> OperandLists;
118  std::vector<std::unique_ptr<GIMatchDagOperandList>> OperandListsOwner;
119
120public:
121  const GIMatchDagOperandList &makeEmptyOperandList();
122  const GIMatchDagOperandList &makeOperandList(const CodeGenInstruction &I);
123  const GIMatchDagOperandList &makeMIPredicateOperandList();
124  const GIMatchDagOperandList &makeTwoMOPredicateOperandList();
125
126  void print(raw_ostream &OS) const;
127#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
128  LLVM_DUMP_METHOD void dump() const { print(errs()); }
129#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
130};
131
132} // end namespace llvm
133#endif // ifndef LLVM_UTILS_TABLEGEN_GIMATCHDAGOPERANDS_H
134