1//===- CodeGenIntrinsic.h - Intrinsic Class Wrapper ------------*- C++ -*--===//
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// This file defines a wrapper class for the 'Intrinsic' TableGen class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H
14#define LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H
15
16#include "SDNodeProperties.h"
17#include "llvm/Support/MachineValueType.h"
18#include <string>
19#include <vector>
20
21namespace llvm {
22class Record;
23class RecordKeeper;
24class CodeGenTarget;
25
26struct CodeGenIntrinsic {
27  Record *TheDef;             // The actual record defining this intrinsic.
28  std::string Name;           // The name of the LLVM function "llvm.bswap.i32"
29  std::string EnumName;       // The name of the enum "bswap_i32"
30  std::string GCCBuiltinName; // Name of the corresponding GCC builtin, or "".
31  std::string MSBuiltinName;  // Name of the corresponding MS builtin, or "".
32  std::string TargetPrefix;   // Target prefix, e.g. "ppc" for t-s intrinsics.
33
34  /// This structure holds the return values and parameter values of an
35  /// intrinsic. If the number of return values is > 1, then the intrinsic
36  /// implicitly returns a first-class aggregate. The numbering of the types
37  /// starts at 0 with the first return value and continues from there through
38  /// the parameter list. This is useful for "matching" types.
39  struct IntrinsicSignature {
40    /// The MVT::SimpleValueType for each return type. Note that this list is
41    /// only populated when in the context of a target .td file. When building
42    /// Intrinsics.td, this isn't available, because we don't know the target
43    /// pointer size.
44    std::vector<MVT::SimpleValueType> RetVTs;
45
46    /// The records for each return type.
47    std::vector<Record *> RetTypeDefs;
48
49    /// The MVT::SimpleValueType for each parameter type. Note that this list is
50    /// only populated when in the context of a target .td file.  When building
51    /// Intrinsics.td, this isn't available, because we don't know the target
52    /// pointer size.
53    std::vector<MVT::SimpleValueType> ParamVTs;
54
55    /// The records for each parameter type.
56    std::vector<Record *> ParamTypeDefs;
57  };
58
59  IntrinsicSignature IS;
60
61  /// Bit flags describing the type (ref/mod) and location of memory
62  /// accesses that may be performed by the intrinsics. Analogous to
63  /// \c FunctionModRefBehaviour.
64  enum ModRefBits {
65    /// The intrinsic may access memory that is otherwise inaccessible via
66    /// LLVM IR.
67    MR_InaccessibleMem = 1,
68
69    /// The intrinsic may access memory through pointer arguments.
70    /// LLVM IR.
71    MR_ArgMem = 2,
72
73    /// The intrinsic may access memory anywhere, i.e. it is not restricted
74    /// to access through pointer arguments.
75    MR_Anywhere = 4 | MR_ArgMem | MR_InaccessibleMem,
76
77    /// The intrinsic may read memory.
78    MR_Ref = 8,
79
80    /// The intrinsic may write memory.
81    MR_Mod = 16,
82
83    /// The intrinsic may both read and write memory.
84    MR_ModRef = MR_Ref | MR_Mod,
85  };
86
87  /// Memory mod/ref behavior of this intrinsic, corresponding to intrinsic
88  /// properties (IntrReadMem, IntrArgMemOnly, etc.).
89  enum ModRefBehavior {
90    NoMem = 0,
91    ReadArgMem = MR_Ref | MR_ArgMem,
92    ReadInaccessibleMem = MR_Ref | MR_InaccessibleMem,
93    ReadInaccessibleMemOrArgMem = MR_Ref | MR_ArgMem | MR_InaccessibleMem,
94    ReadMem = MR_Ref | MR_Anywhere,
95    WriteArgMem = MR_Mod | MR_ArgMem,
96    WriteInaccessibleMem = MR_Mod | MR_InaccessibleMem,
97    WriteInaccessibleMemOrArgMem = MR_Mod | MR_ArgMem | MR_InaccessibleMem,
98    WriteMem = MR_Mod | MR_Anywhere,
99    ReadWriteArgMem = MR_ModRef | MR_ArgMem,
100    ReadWriteInaccessibleMem = MR_ModRef | MR_InaccessibleMem,
101    ReadWriteInaccessibleMemOrArgMem = MR_ModRef | MR_ArgMem |
102                                       MR_InaccessibleMem,
103    ReadWriteMem = MR_ModRef | MR_Anywhere,
104  };
105  ModRefBehavior ModRef;
106
107  /// SDPatternOperator Properties applied to the intrinsic.
108  unsigned Properties;
109
110  /// This is set to true if the intrinsic is overloaded by its argument
111  /// types.
112  bool isOverloaded;
113
114  /// True if the intrinsic is commutative.
115  bool isCommutative;
116
117  /// True if the intrinsic can throw.
118  bool canThrow;
119
120  /// True if the intrinsic is marked as noduplicate.
121  bool isNoDuplicate;
122
123  /// True if the intrinsic is no-return.
124  bool isNoReturn;
125
126  /// True if the intrinsic is no-sync.
127  bool isNoSync;
128
129  /// True if the intrinsic is no-free.
130  bool isNoFree;
131
132  /// True if the intrinsic is will-return.
133  bool isWillReturn;
134
135  /// True if the intrinsic is cold.
136  bool isCold;
137
138  /// True if the intrinsic is marked as convergent.
139  bool isConvergent;
140
141  /// True if the intrinsic has side effects that aren't captured by any
142  /// of the other flags.
143  bool hasSideEffects;
144
145  // True if the intrinsic is marked as speculatable.
146  bool isSpeculatable;
147
148  enum ArgAttrKind {
149    NoCapture,
150    NoAlias,
151    Returned,
152    ReadOnly,
153    WriteOnly,
154    ReadNone,
155    ImmArg,
156    Alignment
157  };
158
159  struct ArgAttribute {
160    unsigned Index;
161    ArgAttrKind Kind;
162    uint64_t Value;
163
164    ArgAttribute(unsigned Idx, ArgAttrKind K, uint64_t V)
165        : Index(Idx), Kind(K), Value(V) {}
166
167    bool operator<(const ArgAttribute &Other) const {
168      return std::tie(Index, Kind, Value) <
169             std::tie(Other.Index, Other.Kind, Other.Value);
170    }
171  };
172
173  std::vector<ArgAttribute> ArgumentAttributes;
174
175  bool hasProperty(enum SDNP Prop) const {
176    return Properties & (1 << Prop);
177  }
178
179  /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
180  /// false if the parameter is not a pointer, or \p ParamIdx is greater than
181  /// the size of \p IS.ParamVTs.
182  ///
183  /// Note that this requires that \p IS.ParamVTs is available.
184  bool isParamAPointer(unsigned ParamIdx) const;
185
186  bool isParamImmArg(unsigned ParamIdx) const;
187
188  CodeGenIntrinsic(Record *R);
189};
190
191class CodeGenIntrinsicTable {
192  std::vector<CodeGenIntrinsic> Intrinsics;
193
194public:
195  struct TargetSet {
196    std::string Name;
197    size_t Offset;
198    size_t Count;
199  };
200  std::vector<TargetSet> Targets;
201
202  explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
203  CodeGenIntrinsicTable() = default;
204
205  bool empty() const { return Intrinsics.empty(); }
206  size_t size() const { return Intrinsics.size(); }
207  CodeGenIntrinsic &operator[](size_t Pos) { return Intrinsics[Pos]; }
208  const CodeGenIntrinsic &operator[](size_t Pos) const {
209    return Intrinsics[Pos];
210  }
211};
212}
213
214#endif
215