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/ADT/SmallVector.h"
18 #include "llvm/Support/MachineValueType.h"
19 #include "llvm/Support/ModRef.h"
20 #include <string>
21 #include <vector>
22 
23 namespace llvm {
24 class Record;
25 class RecordKeeper;
26 
27 struct CodeGenIntrinsic {
28   Record *TheDef;             // The actual record defining this intrinsic.
29   std::string Name;           // The name of the LLVM function "llvm.bswap.i32"
30   std::string EnumName;       // The name of the enum "bswap_i32"
31   std::string ClangBuiltinName; // Name of the corresponding GCC builtin, or "".
32   std::string MSBuiltinName;  // Name of the corresponding MS builtin, or "".
33   std::string TargetPrefix;   // Target prefix, e.g. "ppc" for t-s intrinsics.
34 
35   /// This structure holds the return values and parameter values of an
36   /// intrinsic. If the number of return values is > 1, then the intrinsic
37   /// implicitly returns a first-class aggregate. The numbering of the types
38   /// starts at 0 with the first return value and continues from there through
39   /// the parameter list. This is useful for "matching" types.
40   struct IntrinsicSignature {
41     /// The MVT::SimpleValueType for each return type. Note that this list is
42     /// only populated when in the context of a target .td file. When building
43     /// Intrinsics.td, this isn't available, because we don't know the target
44     /// pointer size.
45     std::vector<MVT::SimpleValueType> RetVTs;
46 
47     /// The records for each return type.
48     std::vector<Record *> RetTypeDefs;
49 
50     /// The MVT::SimpleValueType for each parameter type. Note that this list is
51     /// only populated when in the context of a target .td file.  When building
52     /// Intrinsics.td, this isn't available, because we don't know the target
53     /// pointer size.
54     std::vector<MVT::SimpleValueType> ParamVTs;
55 
56     /// The records for each parameter type.
57     std::vector<Record *> ParamTypeDefs;
58   };
59 
60   IntrinsicSignature IS;
61 
62   /// Memory effects of the intrinsic.
63   MemoryEffects ME = MemoryEffects::unknown();
64 
65   /// SDPatternOperator Properties applied to the intrinsic.
66   unsigned Properties;
67 
68   /// This is set to true if the intrinsic is overloaded by its argument
69   /// types.
70   bool isOverloaded;
71 
72   /// True if the intrinsic is commutative.
73   bool isCommutative;
74 
75   /// True if the intrinsic can throw.
76   bool canThrow;
77 
78   /// True if the intrinsic is marked as noduplicate.
79   bool isNoDuplicate;
80 
81   /// True if the intrinsic is marked as nomerge.
82   bool isNoMerge;
83 
84   /// True if the intrinsic is no-return.
85   bool isNoReturn;
86 
87   /// True if the intrinsic is no-callback.
88   bool isNoCallback;
89 
90   /// True if the intrinsic is no-sync.
91   bool isNoSync;
92 
93   /// True if the intrinsic is no-free.
94   bool isNoFree;
95 
96   /// True if the intrinsic is will-return.
97   bool isWillReturn;
98 
99   /// True if the intrinsic is cold.
100   bool isCold;
101 
102   /// True if the intrinsic is marked as convergent.
103   bool isConvergent;
104 
105   /// True if the intrinsic has side effects that aren't captured by any
106   /// of the other flags.
107   bool hasSideEffects;
108 
109   // True if the intrinsic is marked as speculatable.
110   bool isSpeculatable;
111 
112   enum ArgAttrKind {
113     NoCapture,
114     NoAlias,
115     NoUndef,
116     NonNull,
117     Returned,
118     ReadOnly,
119     WriteOnly,
120     ReadNone,
121     ImmArg,
122     Alignment
123   };
124 
125   struct ArgAttribute {
126     ArgAttrKind Kind;
127     uint64_t Value;
128 
129     ArgAttribute(ArgAttrKind K, uint64_t V) : Kind(K), Value(V) {}
130 
131     bool operator<(const ArgAttribute &Other) const {
132       return std::tie(Kind, Value) < std::tie(Other.Kind, Other.Value);
133     }
134   };
135 
136   /// Vector of attributes for each argument.
137   SmallVector<SmallVector<ArgAttribute, 0>> ArgumentAttributes;
138 
139   void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0);
140 
141   bool hasProperty(enum SDNP Prop) const {
142     return Properties & (1 << Prop);
143   }
144 
145   /// Goes through all IntrProperties that have IsDefault
146   /// value set and sets the property.
147   void setDefaultProperties(Record *R, std::vector<Record *> DefaultProperties);
148 
149   /// Helper function to set property \p Name to true;
150   void setProperty(Record *R);
151 
152   /// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
153   /// false if the parameter is not a pointer, or \p ParamIdx is greater than
154   /// the size of \p IS.ParamVTs.
155   ///
156   /// Note that this requires that \p IS.ParamVTs is available.
157   bool isParamAPointer(unsigned ParamIdx) const;
158 
159   bool isParamImmArg(unsigned ParamIdx) const;
160 
161   CodeGenIntrinsic(Record *R, std::vector<Record *> DefaultProperties);
162 };
163 
164 class CodeGenIntrinsicTable {
165   std::vector<CodeGenIntrinsic> Intrinsics;
166 
167 public:
168   struct TargetSet {
169     std::string Name;
170     size_t Offset;
171     size_t Count;
172   };
173   std::vector<TargetSet> Targets;
174 
175   explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
176   CodeGenIntrinsicTable() = default;
177 
178   bool empty() const { return Intrinsics.empty(); }
179   size_t size() const { return Intrinsics.size(); }
180   auto begin() const { return Intrinsics.begin(); }
181   auto end() const { return Intrinsics.end(); }
182   CodeGenIntrinsic &operator[](size_t Pos) { return Intrinsics[Pos]; }
183   const CodeGenIntrinsic &operator[](size_t Pos) const {
184     return Intrinsics[Pos];
185   }
186 };
187 }
188 
189 #endif
190