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