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 will-return.
127  bool isWillReturn;
128
129  /// True if the intrinsic is cold.
130  bool isCold;
131
132  /// True if the intrinsic is marked as convergent.
133  bool isConvergent;
134
135  /// True if the intrinsic has side effects that aren't captured by any
136  /// of the other flags.
137  bool hasSideEffects;
138
139  // True if the intrinsic is marked as speculatable.
140  bool isSpeculatable;
141
142  enum ArgAttribute {
143    NoCapture,
144    NoAlias,
145    Returned,
146    ReadOnly,
147    WriteOnly,
148    ReadNone,
149    ImmArg
150  };
151
152  std::vector<std::pair<unsigned, ArgAttribute>> ArgumentAttributes;
153
154  bool hasProperty(enum SDNP Prop) const {
155    return Properties & (1 << Prop);
156  }
157
158  /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
159  /// false if the parameter is not a pointer, or \p ParamIdx is greater than
160  /// the size of \p IS.ParamVTs.
161  ///
162  /// Note that this requires that \p IS.ParamVTs is available.
163  bool isParamAPointer(unsigned ParamIdx) const;
164
165  bool isParamImmArg(unsigned ParamIdx) const;
166
167  CodeGenIntrinsic(Record *R);
168};
169
170class CodeGenIntrinsicTable {
171  std::vector<CodeGenIntrinsic> Intrinsics;
172
173public:
174  struct TargetSet {
175    std::string Name;
176    size_t Offset;
177    size_t Count;
178  };
179  std::vector<TargetSet> Targets;
180
181  explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
182  CodeGenIntrinsicTable() = default;
183
184  bool empty() const { return Intrinsics.empty(); }
185  size_t size() const { return Intrinsics.size(); }
186  CodeGenIntrinsic &operator[](size_t Pos) { return Intrinsics[Pos]; }
187  const CodeGenIntrinsic &operator[](size_t Pos) const {
188    return Intrinsics[Pos];
189  }
190};
191}
192
193#endif
194