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
23namespace llvm {
24class Record;
25class RecordKeeper;
26
27struct 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
162class CodeGenIntrinsicTable {
163  std::vector<CodeGenIntrinsic> Intrinsics;
164
165public:
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