Bug Summary

File:clang/utils/TableGen/MveEmitter.cpp
Warning:line 1400, column 23
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name MveEmitter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/build-llvm -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/utils/TableGen -I /build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/clang/utils/TableGen -I /build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-28-233020-220964-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/clang/utils/TableGen/MveEmitter.cpp

/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/clang/utils/TableGen/MveEmitter.cpp

1//===- MveEmitter.cpp - Generate arm_mve.h for use with clang -*- 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 set of linked tablegen backends is responsible for emitting the bits
10// and pieces that implement <arm_mve.h>, which is defined by the ACLE standard
11// and provides a set of types and functions for (more or less) direct access
12// to the MVE instruction set, including the scalar shifts as well as the
13// vector instructions.
14//
15// MVE's standard intrinsic functions are unusual in that they have a system of
16// polymorphism. For example, the function vaddq() can behave like vaddq_u16(),
17// vaddq_f32(), vaddq_s8(), etc., depending on the types of the vector
18// arguments you give it.
19//
20// This constrains the implementation strategies. The usual approach to making
21// the user-facing functions polymorphic would be to either use
22// __attribute__((overloadable)) to make a set of vaddq() functions that are
23// all inline wrappers on the underlying clang builtins, or to define a single
24// vaddq() macro which expands to an instance of _Generic.
25//
26// The inline-wrappers approach would work fine for most intrinsics, except for
27// the ones that take an argument required to be a compile-time constant,
28// because if you wrap an inline function around a call to a builtin, the
29// constant nature of the argument is not passed through.
30//
31// The _Generic approach can be made to work with enough effort, but it takes a
32// lot of machinery, because of the design feature of _Generic that even the
33// untaken branches are required to pass all front-end validity checks such as
34// type-correctness. You can work around that by nesting further _Generics all
35// over the place to coerce things to the right type in untaken branches, but
36// what you get out is complicated, hard to guarantee its correctness, and
37// worst of all, gives _completely unreadable_ error messages if the user gets
38// the types wrong for an intrinsic call.
39//
40// Therefore, my strategy is to introduce a new __attribute__ that allows a
41// function to be mapped to a clang builtin even though it doesn't have the
42// same name, and then declare all the user-facing MVE function names with that
43// attribute, mapping each one directly to the clang builtin. And the
44// polymorphic ones have __attribute__((overloadable)) as well. So once the
45// compiler has resolved the overload, it knows the internal builtin ID of the
46// selected function, and can check the immediate arguments against that; and
47// if the user gets the types wrong in a call to a polymorphic intrinsic, they
48// get a completely clear error message showing all the declarations of that
49// function in the header file and explaining why each one doesn't fit their
50// call.
51//
52// The downside of this is that if every clang builtin has to correspond
53// exactly to a user-facing ACLE intrinsic, then you can't save work in the
54// frontend by doing it in the header file: CGBuiltin.cpp has to do the entire
55// job of converting an ACLE intrinsic call into LLVM IR. So the Tablegen
56// description for an MVE intrinsic has to contain a full description of the
57// sequence of IRBuilder calls that clang will need to make.
58//
59//===----------------------------------------------------------------------===//
60
61#include "llvm/ADT/APInt.h"
62#include "llvm/ADT/StringRef.h"
63#include "llvm/ADT/StringSwitch.h"
64#include "llvm/Support/Casting.h"
65#include "llvm/Support/raw_ostream.h"
66#include "llvm/TableGen/Error.h"
67#include "llvm/TableGen/Record.h"
68#include "llvm/TableGen/StringToOffsetTable.h"
69#include <cassert>
70#include <cstddef>
71#include <cstdint>
72#include <list>
73#include <map>
74#include <memory>
75#include <set>
76#include <string>
77#include <vector>
78
79using namespace llvm;
80
81namespace {
82
83class EmitterBase;
84class Result;
85
86// -----------------------------------------------------------------------------
87// A system of classes to represent all the types we'll need to deal with in
88// the prototypes of intrinsics.
89//
90// Query methods include finding out the C name of a type; the "LLVM name" in
91// the sense of a C++ code snippet that can be used in the codegen function;
92// the suffix that represents the type in the ACLE intrinsic naming scheme
93// (e.g. 's32' represents int32_t in intrinsics such as vaddq_s32); whether the
94// type is floating-point related (hence should be under #ifdef in the MVE
95// header so that it isn't included in integer-only MVE mode); and the type's
96// size in bits. Not all subtypes support all these queries.
97
98class Type {
99public:
100 enum class TypeKind {
101 // Void appears as a return type (for store intrinsics, which are pure
102 // side-effect). It's also used as the parameter type in the Tablegen
103 // when an intrinsic doesn't need to come in various suffixed forms like
104 // vfooq_s8,vfooq_u16,vfooq_f32.
105 Void,
106
107 // Scalar is used for ordinary int and float types of all sizes.
108 Scalar,
109
110 // Vector is used for anything that occupies exactly one MVE vector
111 // register, i.e. {uint,int,float}NxM_t.
112 Vector,
113
114 // MultiVector is used for the {uint,int,float}NxMxK_t types used by the
115 // interleaving load/store intrinsics v{ld,st}{2,4}q.
116 MultiVector,
117
118 // Predicate is used by all the predicated intrinsics. Its C
119 // representation is mve_pred16_t (which is just an alias for uint16_t).
120 // But we give more detail here, by indicating that a given predicate
121 // instruction is logically regarded as a vector of i1 containing the
122 // same number of lanes as the input vector type. So our Predicate type
123 // comes with a lane count, which we use to decide which kind of <n x i1>
124 // we'll invoke the pred_i2v IR intrinsic to translate it into.
125 Predicate,
126
127 // Pointer is used for pointer types (obviously), and comes with a flag
128 // indicating whether it's a pointer to a const or mutable instance of
129 // the pointee type.
130 Pointer,
131 };
132
133private:
134 const TypeKind TKind;
135
136protected:
137 Type(TypeKind K) : TKind(K) {}
138
139public:
140 TypeKind typeKind() const { return TKind; }
141 virtual ~Type() = default;
142 virtual bool requiresFloat() const = 0;
143 virtual bool requiresMVE() const = 0;
144 virtual unsigned sizeInBits() const = 0;
145 virtual std::string cName() const = 0;
146 virtual std::string llvmName() const {
147 PrintFatalError("no LLVM type name available for type " + cName());
148 }
149 virtual std::string acleSuffix(std::string) const {
150 PrintFatalError("no ACLE suffix available for this type");
151 }
152};
153
154enum class ScalarTypeKind { SignedInt, UnsignedInt, Float };
155inline std::string toLetter(ScalarTypeKind kind) {
156 switch (kind) {
157 case ScalarTypeKind::SignedInt:
158 return "s";
159 case ScalarTypeKind::UnsignedInt:
160 return "u";
161 case ScalarTypeKind::Float:
162 return "f";
163 }
164 llvm_unreachable("Unhandled ScalarTypeKind enum")::llvm::llvm_unreachable_internal("Unhandled ScalarTypeKind enum"
, "clang/utils/TableGen/MveEmitter.cpp", 164)
;
165}
166inline std::string toCPrefix(ScalarTypeKind kind) {
167 switch (kind) {
168 case ScalarTypeKind::SignedInt:
169 return "int";
170 case ScalarTypeKind::UnsignedInt:
171 return "uint";
172 case ScalarTypeKind::Float:
173 return "float";
174 }
175 llvm_unreachable("Unhandled ScalarTypeKind enum")::llvm::llvm_unreachable_internal("Unhandled ScalarTypeKind enum"
, "clang/utils/TableGen/MveEmitter.cpp", 175)
;
176}
177
178class VoidType : public Type {
179public:
180 VoidType() : Type(TypeKind::Void) {}
181 unsigned sizeInBits() const override { return 0; }
37
Returning zero
182 bool requiresFloat() const override { return false; }
183 bool requiresMVE() const override { return false; }
184 std::string cName() const override { return "void"; }
185
186 static bool classof(const Type *T) { return T->typeKind() == TypeKind::Void; }
187 std::string acleSuffix(std::string) const override { return ""; }
188};
189
190class PointerType : public Type {
191 const Type *Pointee;
192 bool Const;
193
194public:
195 PointerType(const Type *Pointee, bool Const)
196 : Type(TypeKind::Pointer), Pointee(Pointee), Const(Const) {}
197 unsigned sizeInBits() const override { return 32; }
198 bool requiresFloat() const override { return Pointee->requiresFloat(); }
199 bool requiresMVE() const override { return Pointee->requiresMVE(); }
200 std::string cName() const override {
201 std::string Name = Pointee->cName();
202
203 // The syntax for a pointer in C is different when the pointee is
204 // itself a pointer. The MVE intrinsics don't contain any double
205 // pointers, so we don't need to worry about that wrinkle.
206 assert(!isa<PointerType>(Pointee) && "Pointer to pointer not supported")(static_cast <bool> (!isa<PointerType>(Pointee) &&
"Pointer to pointer not supported") ? void (0) : __assert_fail
("!isa<PointerType>(Pointee) && \"Pointer to pointer not supported\""
, "clang/utils/TableGen/MveEmitter.cpp", 206, __extension__ __PRETTY_FUNCTION__
))
;
207
208 if (Const)
209 Name = "const " + Name;
210 return Name + " *";
211 }
212 std::string llvmName() const override {
213 return "llvm::PointerType::getUnqual(" + Pointee->llvmName() + ")";
214 }
215
216 static bool classof(const Type *T) {
217 return T->typeKind() == TypeKind::Pointer;
218 }
219};
220
221// Base class for all the types that have a name of the form
222// [prefix][numbers]_t, like int32_t, uint16x8_t, float32x4x2_t.
223//
224// For this sub-hierarchy we invent a cNameBase() method which returns the
225// whole name except for the trailing "_t", so that Vector and MultiVector can
226// append an extra "x2" or whatever to their element type's cNameBase(). Then
227// the main cName() query method puts "_t" on the end for the final type name.
228
229class CRegularNamedType : public Type {
230 using Type::Type;
231 virtual std::string cNameBase() const = 0;
232
233public:
234 std::string cName() const override { return cNameBase() + "_t"; }
235};
236
237class ScalarType : public CRegularNamedType {
238 ScalarTypeKind Kind;
239 unsigned Bits;
240 std::string NameOverride;
241
242public:
243 ScalarType(const Record *Record) : CRegularNamedType(TypeKind::Scalar) {
244 Kind = StringSwitch<ScalarTypeKind>(Record->getValueAsString("kind"))
245 .Case("s", ScalarTypeKind::SignedInt)
246 .Case("u", ScalarTypeKind::UnsignedInt)
247 .Case("f", ScalarTypeKind::Float);
248 Bits = Record->getValueAsInt("size");
249 NameOverride = std::string(Record->getValueAsString("nameOverride"));
250 }
251 unsigned sizeInBits() const override { return Bits; }
252 ScalarTypeKind kind() const { return Kind; }
253 std::string suffix() const { return toLetter(Kind) + utostr(Bits); }
254 std::string cNameBase() const override {
255 return toCPrefix(Kind) + utostr(Bits);
256 }
257 std::string cName() const override {
258 if (NameOverride.empty())
259 return CRegularNamedType::cName();
260 return NameOverride;
261 }
262 std::string llvmName() const override {
263 if (Kind == ScalarTypeKind::Float) {
264 if (Bits == 16)
265 return "HalfTy";
266 if (Bits == 32)
267 return "FloatTy";
268 if (Bits == 64)
269 return "DoubleTy";
270 PrintFatalError("bad size for floating type");
271 }
272 return "Int" + utostr(Bits) + "Ty";
273 }
274 std::string acleSuffix(std::string overrideLetter) const override {
275 return "_" + (overrideLetter.size() ? overrideLetter : toLetter(Kind))
276 + utostr(Bits);
277 }
278 bool isInteger() const { return Kind != ScalarTypeKind::Float; }
279 bool requiresFloat() const override { return !isInteger(); }
280 bool requiresMVE() const override { return false; }
281 bool hasNonstandardName() const { return !NameOverride.empty(); }
282
283 static bool classof(const Type *T) {
284 return T->typeKind() == TypeKind::Scalar;
285 }
286};
287
288class VectorType : public CRegularNamedType {
289 const ScalarType *Element;
290 unsigned Lanes;
291
292public:
293 VectorType(const ScalarType *Element, unsigned Lanes)
294 : CRegularNamedType(TypeKind::Vector), Element(Element), Lanes(Lanes) {}
295 unsigned sizeInBits() const override { return Lanes * Element->sizeInBits(); }
296 unsigned lanes() const { return Lanes; }
297 bool requiresFloat() const override { return Element->requiresFloat(); }
298 bool requiresMVE() const override { return true; }
299 std::string cNameBase() const override {
300 return Element->cNameBase() + "x" + utostr(Lanes);
301 }
302 std::string llvmName() const override {
303 return "llvm::FixedVectorType::get(" + Element->llvmName() + ", " +
304 utostr(Lanes) + ")";
305 }
306
307 static bool classof(const Type *T) {
308 return T->typeKind() == TypeKind::Vector;
309 }
310};
311
312class MultiVectorType : public CRegularNamedType {
313 const VectorType *Element;
314 unsigned Registers;
315
316public:
317 MultiVectorType(unsigned Registers, const VectorType *Element)
318 : CRegularNamedType(TypeKind::MultiVector), Element(Element),
319 Registers(Registers) {}
320 unsigned sizeInBits() const override {
321 return Registers * Element->sizeInBits();
322 }
323 unsigned registers() const { return Registers; }
324 bool requiresFloat() const override { return Element->requiresFloat(); }
325 bool requiresMVE() const override { return true; }
326 std::string cNameBase() const override {
327 return Element->cNameBase() + "x" + utostr(Registers);
328 }
329
330 // MultiVectorType doesn't override llvmName, because we don't expect to do
331 // automatic code generation for the MVE intrinsics that use it: the {vld2,
332 // vld4, vst2, vst4} family are the only ones that use these types, so it was
333 // easier to hand-write the codegen for dealing with these structs than to
334 // build in lots of extra automatic machinery that would only be used once.
335
336 static bool classof(const Type *T) {
337 return T->typeKind() == TypeKind::MultiVector;
338 }
339};
340
341class PredicateType : public CRegularNamedType {
342 unsigned Lanes;
343
344public:
345 PredicateType(unsigned Lanes)
346 : CRegularNamedType(TypeKind::Predicate), Lanes(Lanes) {}
347 unsigned sizeInBits() const override { return 16; }
348 std::string cNameBase() const override { return "mve_pred16"; }
349 bool requiresFloat() const override { return false; };
350 bool requiresMVE() const override { return true; }
351 std::string llvmName() const override {
352 return "llvm::FixedVectorType::get(Builder.getInt1Ty(), " + utostr(Lanes) +
353 ")";
354 }
355
356 static bool classof(const Type *T) {
357 return T->typeKind() == TypeKind::Predicate;
358 }
359};
360
361// -----------------------------------------------------------------------------
362// Class to facilitate merging together the code generation for many intrinsics
363// by means of varying a few constant or type parameters.
364//
365// Most obviously, the intrinsics in a single parametrised family will have
366// code generation sequences that only differ in a type or two, e.g. vaddq_s8
367// and vaddq_u16 will look the same apart from putting a different vector type
368// in the call to CGM.getIntrinsic(). But also, completely different intrinsics
369// will often code-generate in the same way, with only a different choice of
370// _which_ IR intrinsic they lower to (e.g. vaddq_m_s8 and vmulq_m_s8), but
371// marshalling the arguments and return values of the IR intrinsic in exactly
372// the same way. And others might differ only in some other kind of constant,
373// such as a lane index.
374//
375// So, when we generate the IR-building code for all these intrinsics, we keep
376// track of every value that could possibly be pulled out of the code and
377// stored ahead of time in a local variable. Then we group together intrinsics
378// by textual equivalence of the code that would result if _all_ those
379// parameters were stored in local variables. That gives us maximal sets that
380// can be implemented by a single piece of IR-building code by changing
381// parameter values ahead of time.
382//
383// After we've done that, we do a second pass in which we only allocate _some_
384// of the parameters into local variables, by tracking which ones have the same
385// values as each other (so that a single variable can be reused) and which
386// ones are the same across the whole set (so that no variable is needed at
387// all).
388//
389// Hence the class below. Its allocParam method is invoked during code
390// generation by every method of a Result subclass (see below) that wants to
391// give it the opportunity to pull something out into a switchable parameter.
392// It returns a variable name for the parameter, or (if it's being used in the
393// second pass once we've decided that some parameters don't need to be stored
394// in variables after all) it might just return the input expression unchanged.
395
396struct CodeGenParamAllocator {
397 // Accumulated during code generation
398 std::vector<std::string> *ParamTypes = nullptr;
399 std::vector<std::string> *ParamValues = nullptr;
400
401 // Provided ahead of time in pass 2, to indicate which parameters are being
402 // assigned to what. This vector contains an entry for each call to
403 // allocParam expected during code gen (which we counted up in pass 1), and
404 // indicates the number of the parameter variable that should be returned, or
405 // -1 if this call shouldn't allocate a parameter variable at all.
406 //
407 // We rely on the recursive code generation working identically in passes 1
408 // and 2, so that the same list of calls to allocParam happen in the same
409 // order. That guarantees that the parameter numbers recorded in pass 1 will
410 // match the entries in this vector that store what EmitterBase::EmitBuiltinCG
411 // decided to do about each one in pass 2.
412 std::vector<int> *ParamNumberMap = nullptr;
413
414 // Internally track how many things we've allocated
415 unsigned nparams = 0;
416
417 std::string allocParam(StringRef Type, StringRef Value) {
418 unsigned ParamNumber;
419
420 if (!ParamNumberMap) {
421 // In pass 1, unconditionally assign a new parameter variable to every
422 // value we're asked to process.
423 ParamNumber = nparams++;
424 } else {
425 // In pass 2, consult the map provided by the caller to find out which
426 // variable we should be keeping things in.
427 int MapValue = (*ParamNumberMap)[nparams++];
428 if (MapValue < 0)
429 return std::string(Value);
430 ParamNumber = MapValue;
431 }
432
433 // If we've allocated a new parameter variable for the first time, store
434 // its type and value to be retrieved after codegen.
435 if (ParamTypes && ParamTypes->size() == ParamNumber)
436 ParamTypes->push_back(std::string(Type));
437 if (ParamValues && ParamValues->size() == ParamNumber)
438 ParamValues->push_back(std::string(Value));
439
440 // Unimaginative naming scheme for parameter variables.
441 return "Param" + utostr(ParamNumber);
442 }
443};
444
445// -----------------------------------------------------------------------------
446// System of classes that represent all the intermediate values used during
447// code-generation for an intrinsic.
448//
449// The base class 'Result' can represent a value of the LLVM type 'Value', or
450// sometimes 'Address' (for loads/stores, including an alignment requirement).
451//
452// In the case where the Tablegen provides a value in the codegen dag as a
453// plain integer literal, the Result object we construct here will be one that
454// returns true from hasIntegerConstantValue(). This allows the generated C++
455// code to use the constant directly in contexts which can take a literal
456// integer, such as Builder.CreateExtractValue(thing, 1), without going to the
457// effort of calling llvm::ConstantInt::get() and then pulling the constant
458// back out of the resulting llvm:Value later.
459
460class Result {
461public:
462 // Convenient shorthand for the pointer type we'll be using everywhere.
463 using Ptr = std::shared_ptr<Result>;
464
465private:
466 Ptr Predecessor;
467 std::string VarName;
468 bool VarNameUsed = false;
469 unsigned Visited = 0;
470
471public:
472 virtual ~Result() = default;
473 using Scope = std::map<std::string, Ptr>;
474 virtual void genCode(raw_ostream &OS, CodeGenParamAllocator &) const = 0;
475 virtual bool hasIntegerConstantValue() const { return false; }
476 virtual uint32_t integerConstantValue() const { return 0; }
477 virtual bool hasIntegerValue() const { return false; }
478 virtual std::string getIntegerValue(const std::string &) {
479 llvm_unreachable("non-working Result::getIntegerValue called")::llvm::llvm_unreachable_internal("non-working Result::getIntegerValue called"
, "clang/utils/TableGen/MveEmitter.cpp", 479)
;
480 }
481 virtual std::string typeName() const { return "Value *"; }
482
483 // Mostly, when a code-generation operation has a dependency on prior
484 // operations, it's because it uses the output values of those operations as
485 // inputs. But there's one exception, which is the use of 'seq' in Tablegen
486 // to indicate that operations have to be performed in sequence regardless of
487 // whether they use each others' output values.
488 //
489 // So, the actual generation of code is done by depth-first search, using the
490 // prerequisites() method to get a list of all the other Results that have to
491 // be computed before this one. That method divides into the 'predecessor',
492 // set by setPredecessor() while processing a 'seq' dag node, and the list
493 // returned by 'morePrerequisites', which each subclass implements to return
494 // a list of the Results it uses as input to whatever its own computation is
495 // doing.
496
497 virtual void morePrerequisites(std::vector<Ptr> &output) const {}
498 std::vector<Ptr> prerequisites() const {
499 std::vector<Ptr> ToRet;
500 if (Predecessor)
501 ToRet.push_back(Predecessor);
502 morePrerequisites(ToRet);
503 return ToRet;
504 }
505
506 void setPredecessor(Ptr p) {
507 // If the user has nested one 'seq' node inside another, and this
508 // method is called on the return value of the inner 'seq' (i.e.
509 // the final item inside it), then we can't link _this_ node to p,
510 // because it already has a predecessor. Instead, walk the chain
511 // until we find the first item in the inner seq, and link that to
512 // p, so that nesting seqs has the obvious effect of linking
513 // everything together into one long sequential chain.
514 Result *r = this;
515 while (r->Predecessor)
516 r = r->Predecessor.get();
517 r->Predecessor = p;
518 }
519
520 // Each Result will be assigned a variable name in the output code, but not
521 // all those variable names will actually be used (e.g. the return value of
522 // Builder.CreateStore has void type, so nobody will want to refer to it). To
523 // prevent annoying compiler warnings, we track whether each Result's
524 // variable name was ever actually mentioned in subsequent statements, so
525 // that it can be left out of the final generated code.
526 std::string varname() {
527 VarNameUsed = true;
528 return VarName;
529 }
530 void setVarname(const StringRef s) { VarName = std::string(s); }
531 bool varnameUsed() const { return VarNameUsed; }
532
533 // Emit code to generate this result as a Value *.
534 virtual std::string asValue() {
535 return varname();
536 }
537
538 // Code generation happens in multiple passes. This method tracks whether a
539 // Result has yet been visited in a given pass, without the need for a
540 // tedious loop in between passes that goes through and resets a 'visited'
541 // flag back to false: you just set Pass=1 the first time round, and Pass=2
542 // the second time.
543 bool needsVisiting(unsigned Pass) {
544 bool ToRet = Visited < Pass;
545 Visited = Pass;
546 return ToRet;
547 }
548};
549
550// Result subclass that retrieves one of the arguments to the clang builtin
551// function. In cases where the argument has pointer type, we call
552// EmitPointerWithAlignment and store the result in a variable of type Address,
553// so that load and store IR nodes can know the right alignment. Otherwise, we
554// call EmitScalarExpr.
555//
556// There are aggregate parameters in the MVE intrinsics API, but we don't deal
557// with them in this Tablegen back end: they only arise in the vld2q/vld4q and
558// vst2q/vst4q family, which is few enough that we just write the code by hand
559// for those in CGBuiltin.cpp.
560class BuiltinArgResult : public Result {
561public:
562 unsigned ArgNum;
563 bool AddressType;
564 bool Immediate;
565 BuiltinArgResult(unsigned ArgNum, bool AddressType, bool Immediate)
566 : ArgNum(ArgNum), AddressType(AddressType), Immediate(Immediate) {}
567 void genCode(raw_ostream &OS, CodeGenParamAllocator &) const override {
568 OS << (AddressType ? "EmitPointerWithAlignment" : "EmitScalarExpr")
569 << "(E->getArg(" << ArgNum << "))";
570 }
571 std::string typeName() const override {
572 return AddressType ? "Address" : Result::typeName();
573 }
574 // Emit code to generate this result as a Value *.
575 std::string asValue() override {
576 if (AddressType)
577 return "(" + varname() + ".getPointer())";
578 return Result::asValue();
579 }
580 bool hasIntegerValue() const override { return Immediate; }
581 std::string getIntegerValue(const std::string &IntType) override {
582 return "GetIntegerConstantValue<" + IntType + ">(E->getArg(" +
583 utostr(ArgNum) + "), getContext())";
584 }
585};
586
587// Result subclass for an integer literal appearing in Tablegen. This may need
588// to be turned into an llvm::Result by means of llvm::ConstantInt::get(), or
589// it may be used directly as an integer, depending on which IRBuilder method
590// it's being passed to.
591class IntLiteralResult : public Result {
592public:
593 const ScalarType *IntegerType;
594 uint32_t IntegerValue;
595 IntLiteralResult(const ScalarType *IntegerType, uint32_t IntegerValue)
596 : IntegerType(IntegerType), IntegerValue(IntegerValue) {}
597 void genCode(raw_ostream &OS,
598 CodeGenParamAllocator &ParamAlloc) const override {
599 OS << "llvm::ConstantInt::get("
600 << ParamAlloc.allocParam("llvm::Type *", IntegerType->llvmName())
601 << ", ";
602 OS << ParamAlloc.allocParam(IntegerType->cName(), utostr(IntegerValue))
603 << ")";
604 }
605 bool hasIntegerConstantValue() const override { return true; }
606 uint32_t integerConstantValue() const override { return IntegerValue; }
607};
608
609// Result subclass representing a cast between different integer types. We use
610// our own ScalarType abstraction as the representation of the target type,
611// which gives both size and signedness.
612class IntCastResult : public Result {
613public:
614 const ScalarType *IntegerType;
615 Ptr V;
616 IntCastResult(const ScalarType *IntegerType, Ptr V)
617 : IntegerType(IntegerType), V(V) {}
618 void genCode(raw_ostream &OS,
619 CodeGenParamAllocator &ParamAlloc) const override {
620 OS << "Builder.CreateIntCast(" << V->varname() << ", "
621 << ParamAlloc.allocParam("llvm::Type *", IntegerType->llvmName()) << ", "
622 << ParamAlloc.allocParam("bool",
623 IntegerType->kind() == ScalarTypeKind::SignedInt
624 ? "true"
625 : "false")
626 << ")";
627 }
628 void morePrerequisites(std::vector<Ptr> &output) const override {
629 output.push_back(V);
630 }
631};
632
633// Result subclass representing a cast between different pointer types.
634class PointerCastResult : public Result {
635public:
636 const PointerType *PtrType;
637 Ptr V;
638 PointerCastResult(const PointerType *PtrType, Ptr V)
639 : PtrType(PtrType), V(V) {}
640 void genCode(raw_ostream &OS,
641 CodeGenParamAllocator &ParamAlloc) const override {
642 OS << "Builder.CreatePointerCast(" << V->asValue() << ", "
643 << ParamAlloc.allocParam("llvm::Type *", PtrType->llvmName()) << ")";
644 }
645 void morePrerequisites(std::vector<Ptr> &output) const override {
646 output.push_back(V);
647 }
648};
649
650// Result subclass representing a call to an IRBuilder method. Each IRBuilder
651// method we want to use will have a Tablegen record giving the method name and
652// describing any important details of how to call it, such as whether a
653// particular argument should be an integer constant instead of an llvm::Value.
654class IRBuilderResult : public Result {
655public:
656 StringRef CallPrefix;
657 std::vector<Ptr> Args;
658 std::set<unsigned> AddressArgs;
659 std::map<unsigned, std::string> IntegerArgs;
660 IRBuilderResult(StringRef CallPrefix, std::vector<Ptr> Args,
661 std::set<unsigned> AddressArgs,
662 std::map<unsigned, std::string> IntegerArgs)
663 : CallPrefix(CallPrefix), Args(Args), AddressArgs(AddressArgs),
664 IntegerArgs(IntegerArgs) {}
665 void genCode(raw_ostream &OS,
666 CodeGenParamAllocator &ParamAlloc) const override {
667 OS << CallPrefix;
668 const char *Sep = "";
669 for (unsigned i = 0, e = Args.size(); i < e; ++i) {
670 Ptr Arg = Args[i];
671 auto it = IntegerArgs.find(i);
672
673 OS << Sep;
674 Sep = ", ";
675
676 if (it != IntegerArgs.end()) {
677 if (Arg->hasIntegerConstantValue())
678 OS << "static_cast<" << it->second << ">("
679 << ParamAlloc.allocParam(it->second,
680 utostr(Arg->integerConstantValue()))
681 << ")";
682 else if (Arg->hasIntegerValue())
683 OS << ParamAlloc.allocParam(it->second,
684 Arg->getIntegerValue(it->second));
685 } else {
686 OS << Arg->varname();
687 }
688 }
689 OS << ")";
690 }
691 void morePrerequisites(std::vector<Ptr> &output) const override {
692 for (unsigned i = 0, e = Args.size(); i < e; ++i) {
693 Ptr Arg = Args[i];
694 if (IntegerArgs.find(i) != IntegerArgs.end())
695 continue;
696 output.push_back(Arg);
697 }
698 }
699};
700
701// Result subclass representing making an Address out of a Value.
702class AddressResult : public Result {
703public:
704 Ptr Arg;
705 unsigned Align;
706 AddressResult(Ptr Arg, unsigned Align) : Arg(Arg), Align(Align) {}
707 void genCode(raw_ostream &OS,
708 CodeGenParamAllocator &ParamAlloc) const override {
709 OS << "Address(" << Arg->varname() << ", CharUnits::fromQuantity("
710 << Align << "))";
711 }
712 std::string typeName() const override {
713 return "Address";
714 }
715 void morePrerequisites(std::vector<Ptr> &output) const override {
716 output.push_back(Arg);
717 }
718};
719
720// Result subclass representing a call to an IR intrinsic, which we first have
721// to look up using an Intrinsic::ID constant and an array of types.
722class IRIntrinsicResult : public Result {
723public:
724 std::string IntrinsicID;
725 std::vector<const Type *> ParamTypes;
726 std::vector<Ptr> Args;
727 IRIntrinsicResult(StringRef IntrinsicID, std::vector<const Type *> ParamTypes,
728 std::vector<Ptr> Args)
729 : IntrinsicID(std::string(IntrinsicID)), ParamTypes(ParamTypes),
730 Args(Args) {}
731 void genCode(raw_ostream &OS,
732 CodeGenParamAllocator &ParamAlloc) const override {
733 std::string IntNo = ParamAlloc.allocParam(
734 "Intrinsic::ID", "Intrinsic::" + IntrinsicID);
735 OS << "Builder.CreateCall(CGM.getIntrinsic(" << IntNo;
736 if (!ParamTypes.empty()) {
737 OS << ", {";
738 const char *Sep = "";
739 for (auto T : ParamTypes) {
740 OS << Sep << ParamAlloc.allocParam("llvm::Type *", T->llvmName());
741 Sep = ", ";
742 }
743 OS << "}";
744 }
745 OS << "), {";
746 const char *Sep = "";
747 for (auto Arg : Args) {
748 OS << Sep << Arg->asValue();
749 Sep = ", ";
750 }
751 OS << "})";
752 }
753 void morePrerequisites(std::vector<Ptr> &output) const override {
754 output.insert(output.end(), Args.begin(), Args.end());
755 }
756};
757
758// Result subclass that specifies a type, for use in IRBuilder operations such
759// as CreateBitCast that take a type argument.
760class TypeResult : public Result {
761public:
762 const Type *T;
763 TypeResult(const Type *T) : T(T) {}
764 void genCode(raw_ostream &OS, CodeGenParamAllocator &) const override {
765 OS << T->llvmName();
766 }
767 std::string typeName() const override {
768 return "llvm::Type *";
769 }
770};
771
772// -----------------------------------------------------------------------------
773// Class that describes a single ACLE intrinsic.
774//
775// A Tablegen record will typically describe more than one ACLE intrinsic, by
776// means of setting the 'list<Type> Params' field to a list of multiple
777// parameter types, so as to define vaddq_{s8,u8,...,f16,f32} all in one go.
778// We'll end up with one instance of ACLEIntrinsic for *each* parameter type,
779// rather than a single one for all of them. Hence, the constructor takes both
780// a Tablegen record and the current value of the parameter type.
781
782class ACLEIntrinsic {
783 // Structure documenting that one of the intrinsic's arguments is required to
784 // be a compile-time constant integer, and what constraints there are on its
785 // value. Used when generating Sema checking code.
786 struct ImmediateArg {
787 enum class BoundsType { ExplicitRange, UInt };
788 BoundsType boundsType;
789 int64_t i1, i2;
790 StringRef ExtraCheckType, ExtraCheckArgs;
791 const Type *ArgType;
792 };
793
794 // For polymorphic intrinsics, FullName is the explicit name that uniquely
795 // identifies this variant of the intrinsic, and ShortName is the name it
796 // shares with at least one other intrinsic.
797 std::string ShortName, FullName;
798
799 // Name of the architecture extension, used in the Clang builtin name
800 StringRef BuiltinExtension;
801
802 // A very small number of intrinsics _only_ have a polymorphic
803 // variant (vuninitializedq taking an unevaluated argument).
804 bool PolymorphicOnly;
805
806 // Another rarely-used flag indicating that the builtin doesn't
807 // evaluate its argument(s) at all.
808 bool NonEvaluating;
809
810 // True if the intrinsic needs only the C header part (no codegen, semantic
811 // checks, etc). Used for redeclaring MVE intrinsics in the arm_cde.h header.
812 bool HeaderOnly;
813
814 const Type *ReturnType;
815 std::vector<const Type *> ArgTypes;
816 std::map<unsigned, ImmediateArg> ImmediateArgs;
817 Result::Ptr Code;
818
819 std::map<std::string, std::string> CustomCodeGenArgs;
820
821 // Recursive function that does the internals of code generation.
822 void genCodeDfs(Result::Ptr V, std::list<Result::Ptr> &Used,
823 unsigned Pass) const {
824 if (!V->needsVisiting(Pass))
825 return;
826
827 for (Result::Ptr W : V->prerequisites())
828 genCodeDfs(W, Used, Pass);
829
830 Used.push_back(V);
831 }
832
833public:
834 const std::string &shortName() const { return ShortName; }
835 const std::string &fullName() const { return FullName; }
836 StringRef builtinExtension() const { return BuiltinExtension; }
837 const Type *returnType() const { return ReturnType; }
838 const std::vector<const Type *> &argTypes() const { return ArgTypes; }
839 bool requiresFloat() const {
840 if (ReturnType->requiresFloat())
841 return true;
842 for (const Type *T : ArgTypes)
843 if (T->requiresFloat())
844 return true;
845 return false;
846 }
847 bool requiresMVE() const {
848 return ReturnType->requiresMVE() ||
849 any_of(ArgTypes, [](const Type *T) { return T->requiresMVE(); });
850 }
851 bool polymorphic() const { return ShortName != FullName; }
852 bool polymorphicOnly() const { return PolymorphicOnly; }
853 bool nonEvaluating() const { return NonEvaluating; }
854 bool headerOnly() const { return HeaderOnly; }
855
856 // External entry point for code generation, called from EmitterBase.
857 void genCode(raw_ostream &OS, CodeGenParamAllocator &ParamAlloc,
858 unsigned Pass) const {
859 assert(!headerOnly() && "Called genCode for header-only intrinsic")(static_cast <bool> (!headerOnly() && "Called genCode for header-only intrinsic"
) ? void (0) : __assert_fail ("!headerOnly() && \"Called genCode for header-only intrinsic\""
, "clang/utils/TableGen/MveEmitter.cpp", 859, __extension__ __PRETTY_FUNCTION__
))
;
860 if (!hasCode()) {
861 for (auto kv : CustomCodeGenArgs)
862 OS << " " << kv.first << " = " << kv.second << ";\n";
863 OS << " break; // custom code gen\n";
864 return;
865 }
866 std::list<Result::Ptr> Used;
867 genCodeDfs(Code, Used, Pass);
868
869 unsigned varindex = 0;
870 for (Result::Ptr V : Used)
871 if (V->varnameUsed())
872 V->setVarname("Val" + utostr(varindex++));
873
874 for (Result::Ptr V : Used) {
875 OS << " ";
876 if (V == Used.back()) {
877 assert(!V->varnameUsed())(static_cast <bool> (!V->varnameUsed()) ? void (0) :
__assert_fail ("!V->varnameUsed()", "clang/utils/TableGen/MveEmitter.cpp"
, 877, __extension__ __PRETTY_FUNCTION__))
;
878 OS << "return "; // FIXME: what if the top-level thing is void?
879 } else if (V->varnameUsed()) {
880 std::string Type = V->typeName();
881 OS << V->typeName();
882 if (!StringRef(Type).endswith("*"))
883 OS << " ";
884 OS << V->varname() << " = ";
885 }
886 V->genCode(OS, ParamAlloc);
887 OS << ";\n";
888 }
889 }
890 bool hasCode() const { return Code != nullptr; }
891
892 static std::string signedHexLiteral(const llvm::APInt &iOrig) {
893 llvm::APInt i = iOrig.trunc(64);
894 SmallString<40> s;
895 i.toString(s, 16, true, true);
896 return std::string(s.str());
897 }
898
899 std::string genSema() const {
900 assert(!headerOnly() && "Called genSema for header-only intrinsic")(static_cast <bool> (!headerOnly() && "Called genSema for header-only intrinsic"
) ? void (0) : __assert_fail ("!headerOnly() && \"Called genSema for header-only intrinsic\""
, "clang/utils/TableGen/MveEmitter.cpp", 900, __extension__ __PRETTY_FUNCTION__
))
;
901 std::vector<std::string> SemaChecks;
902
903 for (const auto &kv : ImmediateArgs) {
904 const ImmediateArg &IA = kv.second;
905
906 llvm::APInt lo(128, 0), hi(128, 0);
907 switch (IA.boundsType) {
908 case ImmediateArg::BoundsType::ExplicitRange:
909 lo = IA.i1;
910 hi = IA.i2;
911 break;
912 case ImmediateArg::BoundsType::UInt:
913 lo = 0;
914 hi = llvm::APInt::getMaxValue(IA.i1).zext(128);
915 break;
916 }
917
918 std::string Index = utostr(kv.first);
919
920 // Emit a range check if the legal range of values for the
921 // immediate is smaller than the _possible_ range of values for
922 // its type.
923 unsigned ArgTypeBits = IA.ArgType->sizeInBits();
924 llvm::APInt ArgTypeRange = llvm::APInt::getMaxValue(ArgTypeBits).zext(128);
925 llvm::APInt ActualRange = (hi-lo).trunc(64).sext(128);
926 if (ActualRange.ult(ArgTypeRange))
927 SemaChecks.push_back("SemaBuiltinConstantArgRange(TheCall, " + Index +
928 ", " + signedHexLiteral(lo) + ", " +
929 signedHexLiteral(hi) + ")");
930
931 if (!IA.ExtraCheckType.empty()) {
932 std::string Suffix;
933 if (!IA.ExtraCheckArgs.empty()) {
934 std::string tmp;
935 StringRef Arg = IA.ExtraCheckArgs;
936 if (Arg == "!lanesize") {
937 tmp = utostr(IA.ArgType->sizeInBits());
938 Arg = tmp;
939 }
940 Suffix = (Twine(", ") + Arg).str();
941 }
942 SemaChecks.push_back((Twine("SemaBuiltinConstantArg") +
943 IA.ExtraCheckType + "(TheCall, " + Index +
944 Suffix + ")")
945 .str());
946 }
947
948 assert(!SemaChecks.empty())(static_cast <bool> (!SemaChecks.empty()) ? void (0) : __assert_fail
("!SemaChecks.empty()", "clang/utils/TableGen/MveEmitter.cpp"
, 948, __extension__ __PRETTY_FUNCTION__))
;
949 }
950 if (SemaChecks.empty())
951 return "";
952 return join(std::begin(SemaChecks), std::end(SemaChecks),
953 " ||\n ") +
954 ";\n";
955 }
956
957 ACLEIntrinsic(EmitterBase &ME, Record *R, const Type *Param);
958};
959
960// -----------------------------------------------------------------------------
961// The top-level class that holds all the state from analyzing the entire
962// Tablegen input.
963
964class EmitterBase {
965protected:
966 // EmitterBase holds a collection of all the types we've instantiated.
967 VoidType Void;
968 std::map<std::string, std::unique_ptr<ScalarType>> ScalarTypes;
969 std::map<std::tuple<ScalarTypeKind, unsigned, unsigned>,
970 std::unique_ptr<VectorType>>
971 VectorTypes;
972 std::map<std::pair<std::string, unsigned>, std::unique_ptr<MultiVectorType>>
973 MultiVectorTypes;
974 std::map<unsigned, std::unique_ptr<PredicateType>> PredicateTypes;
975 std::map<std::string, std::unique_ptr<PointerType>> PointerTypes;
976
977 // And all the ACLEIntrinsic instances we've created.
978 std::map<std::string, std::unique_ptr<ACLEIntrinsic>> ACLEIntrinsics;
979
980public:
981 // Methods to create a Type object, or return the right existing one from the
982 // maps stored in this object.
983 const VoidType *getVoidType() { return &Void; }
984 const ScalarType *getScalarType(StringRef Name) {
985 return ScalarTypes[std::string(Name)].get();
986 }
987 const ScalarType *getScalarType(Record *R) {
988 return getScalarType(R->getName());
989 }
990 const VectorType *getVectorType(const ScalarType *ST, unsigned Lanes) {
991 std::tuple<ScalarTypeKind, unsigned, unsigned> key(ST->kind(),
992 ST->sizeInBits(), Lanes);
993 if (VectorTypes.find(key) == VectorTypes.end())
994 VectorTypes[key] = std::make_unique<VectorType>(ST, Lanes);
995 return VectorTypes[key].get();
996 }
997 const VectorType *getVectorType(const ScalarType *ST) {
998 return getVectorType(ST, 128 / ST->sizeInBits());
999 }
1000 const MultiVectorType *getMultiVectorType(unsigned Registers,
1001 const VectorType *VT) {
1002 std::pair<std::string, unsigned> key(VT->cNameBase(), Registers);
1003 if (MultiVectorTypes.find(key) == MultiVectorTypes.end())
1004 MultiVectorTypes[key] = std::make_unique<MultiVectorType>(Registers, VT);
1005 return MultiVectorTypes[key].get();
1006 }
1007 const PredicateType *getPredicateType(unsigned Lanes) {
1008 unsigned key = Lanes;
1009 if (PredicateTypes.find(key) == PredicateTypes.end())
1010 PredicateTypes[key] = std::make_unique<PredicateType>(Lanes);
1011 return PredicateTypes[key].get();
1012 }
1013 const PointerType *getPointerType(const Type *T, bool Const) {
1014 PointerType PT(T, Const);
1015 std::string key = PT.cName();
1016 if (PointerTypes.find(key) == PointerTypes.end())
1017 PointerTypes[key] = std::make_unique<PointerType>(PT);
1018 return PointerTypes[key].get();
1019 }
1020
1021 // Methods to construct a type from various pieces of Tablegen. These are
1022 // always called in the context of setting up a particular ACLEIntrinsic, so
1023 // there's always an ambient parameter type (because we're iterating through
1024 // the Params list in the Tablegen record for the intrinsic), which is used
1025 // to expand Tablegen classes like 'Vector' which mean something different in
1026 // each member of a parametric family.
1027 const Type *getType(Record *R, const Type *Param);
1028 const Type *getType(DagInit *D, const Type *Param);
1029 const Type *getType(Init *I, const Type *Param);
1030
1031 // Functions that translate the Tablegen representation of an intrinsic's
1032 // code generation into a collection of Value objects (which will then be
1033 // reprocessed to read out the actual C++ code included by CGBuiltin.cpp).
1034 Result::Ptr getCodeForDag(DagInit *D, const Result::Scope &Scope,
1035 const Type *Param);
1036 Result::Ptr getCodeForDagArg(DagInit *D, unsigned ArgNum,
1037 const Result::Scope &Scope, const Type *Param);
1038 Result::Ptr getCodeForArg(unsigned ArgNum, const Type *ArgType, bool Promote,
1039 bool Immediate);
1040
1041 void GroupSemaChecks(std::map<std::string, std::set<std::string>> &Checks);
1042
1043 // Constructor and top-level functions.
1044
1045 EmitterBase(RecordKeeper &Records);
1046 virtual ~EmitterBase() = default;
1047
1048 virtual void EmitHeader(raw_ostream &OS) = 0;
1049 virtual void EmitBuiltinDef(raw_ostream &OS) = 0;
1050 virtual void EmitBuiltinSema(raw_ostream &OS) = 0;
1051 void EmitBuiltinCG(raw_ostream &OS);
1052 void EmitBuiltinAliases(raw_ostream &OS);
1053};
1054
1055const Type *EmitterBase::getType(Init *I, const Type *Param) {
1056 if (auto Dag = dyn_cast<DagInit>(I))
1057 return getType(Dag, Param);
1058 if (auto Def = dyn_cast<DefInit>(I))
1059 return getType(Def->getDef(), Param);
1060
1061 PrintFatalError("Could not convert this value into a type");
1062}
1063
1064const Type *EmitterBase::getType(Record *R, const Type *Param) {
1065 // Pass to a subfield of any wrapper records. We don't expect more than one
1066 // of these: immediate operands are used as plain numbers rather than as
1067 // llvm::Value, so it's meaningless to promote their type anyway.
1068 if (R->isSubClassOf("Immediate"))
1069 R = R->getValueAsDef("type");
1070 else if (R->isSubClassOf("unpromoted"))
1071 R = R->getValueAsDef("underlying_type");
1072
1073 if (R->getName() == "Void")
1074 return getVoidType();
1075 if (R->isSubClassOf("PrimitiveType"))
1076 return getScalarType(R);
1077 if (R->isSubClassOf("ComplexType"))
1078 return getType(R->getValueAsDag("spec"), Param);
1079
1080 PrintFatalError(R->getLoc(), "Could not convert this record into a type");
1081}
1082
1083const Type *EmitterBase::getType(DagInit *D, const Type *Param) {
1084 // The meat of the getType system: types in the Tablegen are represented by a
1085 // dag whose operators select sub-cases of this function.
1086
1087 Record *Op = cast<DefInit>(D->getOperator())->getDef();
1088 if (!Op->isSubClassOf("ComplexTypeOp"))
1089 PrintFatalError(
1090 "Expected ComplexTypeOp as dag operator in type expression");
1091
1092 if (Op->getName() == "CTO_Parameter") {
1093 if (isa<VoidType>(Param))
1094 PrintFatalError("Parametric type in unparametrised context");
1095 return Param;
1096 }
1097
1098 if (Op->getName() == "CTO_Vec") {
1099 const Type *Element = getType(D->getArg(0), Param);
1100 if (D->getNumArgs() == 1) {
1101 return getVectorType(cast<ScalarType>(Element));
1102 } else {
1103 const Type *ExistingVector = getType(D->getArg(1), Param);
1104 return getVectorType(cast<ScalarType>(Element),
1105 cast<VectorType>(ExistingVector)->lanes());
1106 }
1107 }
1108
1109 if (Op->getName() == "CTO_Pred") {
1110 const Type *Element = getType(D->getArg(0), Param);
1111 return getPredicateType(128 / Element->sizeInBits());
1112 }
1113
1114 if (Op->isSubClassOf("CTO_Tuple")) {
1115 unsigned Registers = Op->getValueAsInt("n");
1116 const Type *Element = getType(D->getArg(0), Param);
1117 return getMultiVectorType(Registers, cast<VectorType>(Element));
1118 }
1119
1120 if (Op->isSubClassOf("CTO_Pointer")) {
1121 const Type *Pointee = getType(D->getArg(0), Param);
1122 return getPointerType(Pointee, Op->getValueAsBit("const"));
1123 }
1124
1125 if (Op->getName() == "CTO_CopyKind") {
1126 const ScalarType *STSize = cast<ScalarType>(getType(D->getArg(0), Param));
1127 const ScalarType *STKind = cast<ScalarType>(getType(D->getArg(1), Param));
1128 for (const auto &kv : ScalarTypes) {
1129 const ScalarType *RT = kv.second.get();
1130 if (RT->kind() == STKind->kind() && RT->sizeInBits() == STSize->sizeInBits())
1131 return RT;
1132 }
1133 PrintFatalError("Cannot find a type to satisfy CopyKind");
1134 }
1135
1136 if (Op->isSubClassOf("CTO_ScaleSize")) {
1137 const ScalarType *STKind = cast<ScalarType>(getType(D->getArg(0), Param));
1138 int Num = Op->getValueAsInt("num"), Denom = Op->getValueAsInt("denom");
1139 unsigned DesiredSize = STKind->sizeInBits() * Num / Denom;
1140 for (const auto &kv : ScalarTypes) {
1141 const ScalarType *RT = kv.second.get();
1142 if (RT->kind() == STKind->kind() && RT->sizeInBits() == DesiredSize)
1143 return RT;
1144 }
1145 PrintFatalError("Cannot find a type to satisfy ScaleSize");
1146 }
1147
1148 PrintFatalError("Bad operator in type dag expression");
1149}
1150
1151Result::Ptr EmitterBase::getCodeForDag(DagInit *D, const Result::Scope &Scope,
1152 const Type *Param) {
1153 Record *Op = cast<DefInit>(D->getOperator())->getDef();
1154
1155 if (Op->getName() == "seq") {
1156 Result::Scope SubScope = Scope;
1157 Result::Ptr PrevV = nullptr;
1158 for (unsigned i = 0, e = D->getNumArgs(); i < e; ++i) {
1159 // We don't use getCodeForDagArg here, because the argument name
1160 // has different semantics in a seq
1161 Result::Ptr V =
1162 getCodeForDag(cast<DagInit>(D->getArg(i)), SubScope, Param);
1163 StringRef ArgName = D->getArgNameStr(i);
1164 if (!ArgName.empty())
1165 SubScope[std::string(ArgName)] = V;
1166 if (PrevV)
1167 V->setPredecessor(PrevV);
1168 PrevV = V;
1169 }
1170 return PrevV;
1171 } else if (Op->isSubClassOf("Type")) {
1172 if (D->getNumArgs() != 1)
1173 PrintFatalError("Type casts should have exactly one argument");
1174 const Type *CastType = getType(Op, Param);
1175 Result::Ptr Arg = getCodeForDagArg(D, 0, Scope, Param);
1176 if (const auto *ST = dyn_cast<ScalarType>(CastType)) {
1177 if (!ST->requiresFloat()) {
1178 if (Arg->hasIntegerConstantValue())
1179 return std::make_shared<IntLiteralResult>(
1180 ST, Arg->integerConstantValue());
1181 else
1182 return std::make_shared<IntCastResult>(ST, Arg);
1183 }
1184 } else if (const auto *PT = dyn_cast<PointerType>(CastType)) {
1185 return std::make_shared<PointerCastResult>(PT, Arg);
1186 }
1187 PrintFatalError("Unsupported type cast");
1188 } else if (Op->getName() == "address") {
1189 if (D->getNumArgs() != 2)
1190 PrintFatalError("'address' should have two arguments");
1191 Result::Ptr Arg = getCodeForDagArg(D, 0, Scope, Param);
1192 unsigned Alignment;
1193 if (auto *II = dyn_cast<IntInit>(D->getArg(1))) {
1194 Alignment = II->getValue();
1195 } else {
1196 PrintFatalError("'address' alignment argument should be an integer");
1197 }
1198 return std::make_shared<AddressResult>(Arg, Alignment);
1199 } else if (Op->getName() == "unsignedflag") {
1200 if (D->getNumArgs() != 1)
1201 PrintFatalError("unsignedflag should have exactly one argument");
1202 Record *TypeRec = cast<DefInit>(D->getArg(0))->getDef();
1203 if (!TypeRec->isSubClassOf("Type"))
1204 PrintFatalError("unsignedflag's argument should be a type");
1205 if (const auto *ST = dyn_cast<ScalarType>(getType(TypeRec, Param))) {
1206 return std::make_shared<IntLiteralResult>(
1207 getScalarType("u32"), ST->kind() == ScalarTypeKind::UnsignedInt);
1208 } else {
1209 PrintFatalError("unsignedflag's argument should be a scalar type");
1210 }
1211 } else if (Op->getName() == "bitsize") {
1212 if (D->getNumArgs() != 1)
1213 PrintFatalError("bitsize should have exactly one argument");
1214 Record *TypeRec = cast<DefInit>(D->getArg(0))->getDef();
1215 if (!TypeRec->isSubClassOf("Type"))
1216 PrintFatalError("bitsize's argument should be a type");
1217 if (const auto *ST = dyn_cast<ScalarType>(getType(TypeRec, Param))) {
1218 return std::make_shared<IntLiteralResult>(getScalarType("u32"),
1219 ST->sizeInBits());
1220 } else {
1221 PrintFatalError("bitsize's argument should be a scalar type");
1222 }
1223 } else {
1224 std::vector<Result::Ptr> Args;
1225 for (unsigned i = 0, e = D->getNumArgs(); i < e; ++i)
1226 Args.push_back(getCodeForDagArg(D, i, Scope, Param));
1227 if (Op->isSubClassOf("IRBuilderBase")) {
1228 std::set<unsigned> AddressArgs;
1229 std::map<unsigned, std::string> IntegerArgs;
1230 for (Record *sp : Op->getValueAsListOfDefs("special_params")) {
1231 unsigned Index = sp->getValueAsInt("index");
1232 if (sp->isSubClassOf("IRBuilderAddrParam")) {
1233 AddressArgs.insert(Index);
1234 } else if (sp->isSubClassOf("IRBuilderIntParam")) {
1235 IntegerArgs[Index] = std::string(sp->getValueAsString("type"));
1236 }
1237 }
1238 return std::make_shared<IRBuilderResult>(Op->getValueAsString("prefix"),
1239 Args, AddressArgs, IntegerArgs);
1240 } else if (Op->isSubClassOf("IRIntBase")) {
1241 std::vector<const Type *> ParamTypes;
1242 for (Record *RParam : Op->getValueAsListOfDefs("params"))
1243 ParamTypes.push_back(getType(RParam, Param));
1244 std::string IntName = std::string(Op->getValueAsString("intname"));
1245 if (Op->getValueAsBit("appendKind"))
1246 IntName += "_" + toLetter(cast<ScalarType>(Param)->kind());
1247 return std::make_shared<IRIntrinsicResult>(IntName, ParamTypes, Args);
1248 } else {
1249 PrintFatalError("Unsupported dag node " + Op->getName());
1250 }
1251 }
1252}
1253
1254Result::Ptr EmitterBase::getCodeForDagArg(DagInit *D, unsigned ArgNum,
1255 const Result::Scope &Scope,
1256 const Type *Param) {
1257 Init *Arg = D->getArg(ArgNum);
1258 StringRef Name = D->getArgNameStr(ArgNum);
1259
1260 if (!Name.empty()) {
1261 if (!isa<UnsetInit>(Arg))
1262 PrintFatalError(
1263 "dag operator argument should not have both a value and a name");
1264 auto it = Scope.find(std::string(Name));
1265 if (it == Scope.end())
1266 PrintFatalError("unrecognized variable name '" + Name + "'");
1267 return it->second;
1268 }
1269
1270 // Sometimes the Arg is a bit. Prior to multiclass template argument
1271 // checking, integers would sneak through the bit declaration,
1272 // but now they really are bits.
1273 if (auto *BI = dyn_cast<BitInit>(Arg))
1274 return std::make_shared<IntLiteralResult>(getScalarType("u32"),
1275 BI->getValue());
1276
1277 if (auto *II = dyn_cast<IntInit>(Arg))
1278 return std::make_shared<IntLiteralResult>(getScalarType("u32"),
1279 II->getValue());
1280
1281 if (auto *DI = dyn_cast<DagInit>(Arg))
1282 return getCodeForDag(DI, Scope, Param);
1283
1284 if (auto *DI = dyn_cast<DefInit>(Arg)) {
1285 Record *Rec = DI->getDef();
1286 if (Rec->isSubClassOf("Type")) {
1287 const Type *T = getType(Rec, Param);
1288 return std::make_shared<TypeResult>(T);
1289 }
1290 }
1291
1292 PrintError("bad DAG argument type for code generation");
1293 PrintNote("DAG: " + D->getAsString());
1294 if (TypedInit *Typed = dyn_cast<TypedInit>(Arg))
1295 PrintNote("argument type: " + Typed->getType()->getAsString());
1296 PrintFatalNote("argument number " + Twine(ArgNum) + ": " + Arg->getAsString());
1297}
1298
1299Result::Ptr EmitterBase::getCodeForArg(unsigned ArgNum, const Type *ArgType,
1300 bool Promote, bool Immediate) {
1301 Result::Ptr V = std::make_shared<BuiltinArgResult>(
1302 ArgNum, isa<PointerType>(ArgType), Immediate);
1303
1304 if (Promote) {
1305 if (const auto *ST = dyn_cast<ScalarType>(ArgType)) {
1306 if (ST->isInteger() && ST->sizeInBits() < 32)
1307 V = std::make_shared<IntCastResult>(getScalarType("u32"), V);
1308 } else if (const auto *PT = dyn_cast<PredicateType>(ArgType)) {
1309 V = std::make_shared<IntCastResult>(getScalarType("u32"), V);
1310 V = std::make_shared<IRIntrinsicResult>("arm_mve_pred_i2v",
1311 std::vector<const Type *>{PT},
1312 std::vector<Result::Ptr>{V});
1313 }
1314 }
1315
1316 return V;
1317}
1318
1319ACLEIntrinsic::ACLEIntrinsic(EmitterBase &ME, Record *R, const Type *Param)
1320 : ReturnType(ME.getType(R->getValueAsDef("ret"), Param)) {
1321 // Derive the intrinsic's full name, by taking the name of the
1322 // Tablegen record (or override) and appending the suffix from its
1323 // parameter type. (If the intrinsic is unparametrised, its
1324 // parameter type will be given as Void, which returns the empty
1325 // string for acleSuffix.)
1326 StringRef BaseName =
1327 (R->isSubClassOf("NameOverride") ? R->getValueAsString("basename")
5
'?' condition is false
1328 : R->getName());
1329 StringRef overrideLetter = R->getValueAsString("overrideKindLetter");
1330 FullName =
1331 (Twine(BaseName) + Param->acleSuffix(std::string(overrideLetter))).str();
1332
1333 // Derive the intrinsic's polymorphic name, by removing components from the
1334 // full name as specified by its 'pnt' member ('polymorphic name type'),
1335 // which indicates how many type suffixes to remove, and any other piece of
1336 // the name that should be removed.
1337 Record *PolymorphicNameType = R->getValueAsDef("pnt");
1338 SmallVector<StringRef, 8> NameParts;
1339 StringRef(FullName).split(NameParts, '_');
1340 for (unsigned i = 0, e = PolymorphicNameType->getValueAsInt(
7
Loop condition is false. Execution continues on line 1344
1341 "NumTypeSuffixesToDiscard");
1342 i < e; ++i)
6
Assuming 'i' is >= 'e'
1343 NameParts.pop_back();
1344 if (!PolymorphicNameType->isValueUnset("ExtraSuffixToDiscard")) {
8
Taking true branch
1345 StringRef ExtraSuffix =
1346 PolymorphicNameType->getValueAsString("ExtraSuffixToDiscard");
1347 auto it = NameParts.end();
1348 while (it != NameParts.begin()) {
9
Assuming the condition is false
10
Loop condition is false. Execution continues on line 1356
1349 --it;
1350 if (*it == ExtraSuffix) {
1351 NameParts.erase(it);
1352 break;
1353 }
1354 }
1355 }
1356 ShortName = join(std::begin(NameParts), std::end(NameParts), "_");
1357
1358 BuiltinExtension = R->getValueAsString("builtinExtension");
1359
1360 PolymorphicOnly = R->getValueAsBit("polymorphicOnly");
1361 NonEvaluating = R->getValueAsBit("nonEvaluating");
1362 HeaderOnly = R->getValueAsBit("headerOnly");
1363
1364 // Process the intrinsic's argument list.
1365 DagInit *ArgsDag = R->getValueAsDag("args");
1366 Result::Scope Scope;
1367 for (unsigned i = 0, e = ArgsDag->getNumArgs(); i < e; ++i) {
11
Assuming 'i' is < 'e'
12
Loop condition is true. Entering loop body
1368 Init *TypeInit = ArgsDag->getArg(i);
1369
1370 bool Promote = true;
1371 if (auto TypeDI
13.1
'TypeDI' is non-null
13.1
'TypeDI' is non-null
13.1
'TypeDI' is non-null
= dyn_cast<DefInit>(TypeInit))
13
Assuming 'TypeInit' is a 'DefInit'
14
Taking true branch
1372 if (TypeDI->getDef()->isSubClassOf("unpromoted"))
15
Taking false branch
1373 Promote = false;
1374
1375 // Work out the type of the argument, for use in the function prototype in
1376 // the header file.
1377 const Type *ArgType = ME.getType(TypeInit, Param);
1378 ArgTypes.push_back(ArgType);
1379
1380 // If the argument is a subclass of Immediate, record the details about
1381 // what values it can take, for Sema checking.
1382 bool Immediate = false;
1383 if (auto TypeDI
16.1
'TypeDI' is non-null
16.1
'TypeDI' is non-null
16.1
'TypeDI' is non-null
= dyn_cast<DefInit>(TypeInit)) {
16
'TypeInit' is a 'DefInit'
17
Taking true branch
1384 Record *TypeRec = TypeDI->getDef();
1385 if (TypeRec->isSubClassOf("Immediate")) {
18
Calling 'Record::isSubClassOf'
25
Returning from 'Record::isSubClassOf'
26
Taking true branch
1386 Immediate = true;
1387
1388 Record *Bounds = TypeRec->getValueAsDef("bounds");
1389 ImmediateArg &IA = ImmediateArgs[i];
1390 if (Bounds->isSubClassOf("IB_ConstRange")) {
27
Calling 'Record::isSubClassOf'
30
Returning from 'Record::isSubClassOf'
31
Taking false branch
1391 IA.boundsType = ImmediateArg::BoundsType::ExplicitRange;
1392 IA.i1 = Bounds->getValueAsInt("lo");
1393 IA.i2 = Bounds->getValueAsInt("hi");
1394 } else if (Bounds->getName() == "IB_UEltValue") {
32
Assuming the condition is false
33
Taking false branch
1395 IA.boundsType = ImmediateArg::BoundsType::UInt;
1396 IA.i1 = Param->sizeInBits();
1397 } else if (Bounds->getName() == "IB_LaneIndex") {
34
Assuming the condition is true
35
Taking true branch
1398 IA.boundsType = ImmediateArg::BoundsType::ExplicitRange;
1399 IA.i1 = 0;
1400 IA.i2 = 128 / Param->sizeInBits() - 1;
36
Calling 'VoidType::sizeInBits'
38
Returning from 'VoidType::sizeInBits'
39
Division by zero
1401 } else if (Bounds->isSubClassOf("IB_EltBit")) {
1402 IA.boundsType = ImmediateArg::BoundsType::ExplicitRange;
1403 IA.i1 = Bounds->getValueAsInt("base");
1404 const Type *T = ME.getType(Bounds->getValueAsDef("type"), Param);
1405 IA.i2 = IA.i1 + T->sizeInBits() - 1;
1406 } else {
1407 PrintFatalError("unrecognised ImmediateBounds subclass");
1408 }
1409
1410 IA.ArgType = ArgType;
1411
1412 if (!TypeRec->isValueUnset("extra")) {
1413 IA.ExtraCheckType = TypeRec->getValueAsString("extra");
1414 if (!TypeRec->isValueUnset("extraarg"))
1415 IA.ExtraCheckArgs = TypeRec->getValueAsString("extraarg");
1416 }
1417 }
1418 }
1419
1420 // The argument will usually have a name in the arguments dag, which goes
1421 // into the variable-name scope that the code gen will refer to.
1422 StringRef ArgName = ArgsDag->getArgNameStr(i);
1423 if (!ArgName.empty())
1424 Scope[std::string(ArgName)] =
1425 ME.getCodeForArg(i, ArgType, Promote, Immediate);
1426 }
1427
1428 // Finally, go through the codegen dag and translate it into a Result object
1429 // (with an arbitrary DAG of depended-on Results hanging off it).
1430 DagInit *CodeDag = R->getValueAsDag("codegen");
1431 Record *MainOp = cast<DefInit>(CodeDag->getOperator())->getDef();
1432 if (MainOp->isSubClassOf("CustomCodegen")) {
1433 // Or, if it's the special case of CustomCodegen, just accumulate
1434 // a list of parameters we're going to assign to variables before
1435 // breaking from the loop.
1436 CustomCodeGenArgs["CustomCodeGenType"] =
1437 (Twine("CustomCodeGen::") + MainOp->getValueAsString("type")).str();
1438 for (unsigned i = 0, e = CodeDag->getNumArgs(); i < e; ++i) {
1439 StringRef Name = CodeDag->getArgNameStr(i);
1440 if (Name.empty()) {
1441 PrintFatalError("Operands to CustomCodegen should have names");
1442 } else if (auto *II = dyn_cast<IntInit>(CodeDag->getArg(i))) {
1443 CustomCodeGenArgs[std::string(Name)] = itostr(II->getValue());
1444 } else if (auto *SI = dyn_cast<StringInit>(CodeDag->getArg(i))) {
1445 CustomCodeGenArgs[std::string(Name)] = std::string(SI->getValue());
1446 } else {
1447 PrintFatalError("Operands to CustomCodegen should be integers");
1448 }
1449 }
1450 } else {
1451 Code = ME.getCodeForDag(CodeDag, Scope, Param);
1452 }
1453}
1454
1455EmitterBase::EmitterBase(RecordKeeper &Records) {
1456 // Construct the whole EmitterBase.
1457
1458 // First, look up all the instances of PrimitiveType. This gives us the list
1459 // of vector typedefs we have to put in arm_mve.h, and also allows us to
1460 // collect all the useful ScalarType instances into a big list so that we can
1461 // use it for operations such as 'find the unsigned version of this signed
1462 // integer type'.
1463 for (Record *R : Records.getAllDerivedDefinitions("PrimitiveType"))
1464 ScalarTypes[std::string(R->getName())] = std::make_unique<ScalarType>(R);
1465
1466 // Now go through the instances of Intrinsic, and for each one, iterate
1467 // through its list of type parameters making an ACLEIntrinsic for each one.
1468 for (Record *R : Records.getAllDerivedDefinitions("Intrinsic")) {
1469 for (Record *RParam : R->getValueAsListOfDefs("params")) {
1470 const Type *Param = getType(RParam, getVoidType());
1471 auto Intrinsic = std::make_unique<ACLEIntrinsic>(*this, R, Param);
3
Calling 'make_unique<(anonymous namespace)::ACLEIntrinsic, (anonymous namespace)::EmitterBase &, llvm::Record *&, const (anonymous namespace)::Type *&>'
1472 ACLEIntrinsics[Intrinsic->fullName()] = std::move(Intrinsic);
1473 }
1474 }
1475}
1476
1477/// A wrapper on raw_string_ostream that contains its own buffer rather than
1478/// having to point it at one elsewhere. (In other words, it works just like
1479/// std::ostringstream; also, this makes it convenient to declare a whole array
1480/// of them at once.)
1481///
1482/// We have to set this up using multiple inheritance, to ensure that the
1483/// string member has been constructed before raw_string_ostream's constructor
1484/// is given a pointer to it.
1485class string_holder {
1486protected:
1487 std::string S;
1488};
1489class raw_self_contained_string_ostream : private string_holder,
1490 public raw_string_ostream {
1491public:
1492 raw_self_contained_string_ostream() : raw_string_ostream(S) {}
1493};
1494
1495const char LLVMLicenseHeader[] =
1496 " *\n"
1497 " *\n"
1498 " * Part of the LLVM Project, under the Apache License v2.0 with LLVM"
1499 " Exceptions.\n"
1500 " * See https://llvm.org/LICENSE.txt for license information.\n"
1501 " * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
1502 " *\n"
1503 " *===-----------------------------------------------------------------"
1504 "------===\n"
1505 " */\n"
1506 "\n";
1507
1508// Machinery for the grouping of intrinsics by similar codegen.
1509//
1510// The general setup is that 'MergeableGroup' stores the things that a set of
1511// similarly shaped intrinsics have in common: the text of their code
1512// generation, and the number and type of their parameter variables.
1513// MergeableGroup is the key in a std::map whose value is a set of
1514// OutputIntrinsic, which stores the ways in which a particular intrinsic
1515// specializes the MergeableGroup's generic description: the function name and
1516// the _values_ of the parameter variables.
1517
1518struct ComparableStringVector : std::vector<std::string> {
1519 // Infrastructure: a derived class of vector<string> which comes with an
1520 // ordering, so that it can be used as a key in maps and an element in sets.
1521 // There's no requirement on the ordering beyond being deterministic.
1522 bool operator<(const ComparableStringVector &rhs) const {
1523 if (size() != rhs.size())
1524 return size() < rhs.size();
1525 for (size_t i = 0, e = size(); i < e; ++i)
1526 if ((*this)[i] != rhs[i])
1527 return (*this)[i] < rhs[i];
1528 return false;
1529 }
1530};
1531
1532struct OutputIntrinsic {
1533 const ACLEIntrinsic *Int;
1534 std::string Name;
1535 ComparableStringVector ParamValues;
1536 bool operator<(const OutputIntrinsic &rhs) const {
1537 if (Name != rhs.Name)
1538 return Name < rhs.Name;
1539 return ParamValues < rhs.ParamValues;
1540 }
1541};
1542struct MergeableGroup {
1543 std::string Code;
1544 ComparableStringVector ParamTypes;
1545 bool operator<(const MergeableGroup &rhs) const {
1546 if (Code != rhs.Code)
1547 return Code < rhs.Code;
1548 return ParamTypes < rhs.ParamTypes;
1549 }
1550};
1551
1552void EmitterBase::EmitBuiltinCG(raw_ostream &OS) {
1553 // Pass 1: generate code for all the intrinsics as if every type or constant
1554 // that can possibly be abstracted out into a parameter variable will be.
1555 // This identifies the sets of intrinsics we'll group together into a single
1556 // piece of code generation.
1557
1558 std::map<MergeableGroup, std::set<OutputIntrinsic>> MergeableGroupsPrelim;
1559
1560 for (const auto &kv : ACLEIntrinsics) {
1561 const ACLEIntrinsic &Int = *kv.second;
1562 if (Int.headerOnly())
1563 continue;
1564
1565 MergeableGroup MG;
1566 OutputIntrinsic OI;
1567
1568 OI.Int = &Int;
1569 OI.Name = Int.fullName();
1570 CodeGenParamAllocator ParamAllocPrelim{&MG.ParamTypes, &OI.ParamValues};
1571 raw_string_ostream OS(MG.Code);
1572 Int.genCode(OS, ParamAllocPrelim, 1);
1573 OS.flush();
1574
1575 MergeableGroupsPrelim[MG].insert(OI);
1576 }
1577
1578 // Pass 2: for each of those groups, optimize the parameter variable set by
1579 // eliminating 'parameters' that are the same for all intrinsics in the
1580 // group, and merging together pairs of parameter variables that take the
1581 // same values as each other for all intrinsics in the group.
1582
1583 std::map<MergeableGroup, std::set<OutputIntrinsic>> MergeableGroups;
1584
1585 for (const auto &kv : MergeableGroupsPrelim) {
1586 const MergeableGroup &MG = kv.first;
1587 std::vector<int> ParamNumbers;
1588 std::map<ComparableStringVector, int> ParamNumberMap;
1589
1590 // Loop over the parameters for this group.
1591 for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i) {
1592 // Is this parameter the same for all intrinsics in the group?
1593 const OutputIntrinsic &OI_first = *kv.second.begin();
1594 bool Constant = all_of(kv.second, [&](const OutputIntrinsic &OI) {
1595 return OI.ParamValues[i] == OI_first.ParamValues[i];
1596 });
1597
1598 // If so, record it as -1, meaning 'no parameter variable needed'. Then
1599 // the corresponding call to allocParam in pass 2 will not generate a
1600 // variable at all, and just use the value inline.
1601 if (Constant) {
1602 ParamNumbers.push_back(-1);
1603 continue;
1604 }
1605
1606 // Otherwise, make a list of the values this parameter takes for each
1607 // intrinsic, and see if that value vector matches anything we already
1608 // have. We also record the parameter type, so that we don't accidentally
1609 // match up two parameter variables with different types. (Not that
1610 // there's much chance of them having textually equivalent values, but in
1611 // _principle_ it could happen.)
1612 ComparableStringVector key;
1613 key.push_back(MG.ParamTypes[i]);
1614 for (const auto &OI : kv.second)
1615 key.push_back(OI.ParamValues[i]);
1616
1617 auto Found = ParamNumberMap.find(key);
1618 if (Found != ParamNumberMap.end()) {
1619 // Yes, an existing parameter variable can be reused for this.
1620 ParamNumbers.push_back(Found->second);
1621 continue;
1622 }
1623
1624 // No, we need a new parameter variable.
1625 int ExistingIndex = ParamNumberMap.size();
1626 ParamNumberMap[key] = ExistingIndex;
1627 ParamNumbers.push_back(ExistingIndex);
1628 }
1629
1630 // Now we're ready to do the pass 2 code generation, which will emit the
1631 // reduced set of parameter variables we've just worked out.
1632
1633 for (const auto &OI_prelim : kv.second) {
1634 const ACLEIntrinsic *Int = OI_prelim.Int;
1635
1636 MergeableGroup MG;
1637 OutputIntrinsic OI;
1638
1639 OI.Int = OI_prelim.Int;
1640 OI.Name = OI_prelim.Name;
1641 CodeGenParamAllocator ParamAlloc{&MG.ParamTypes, &OI.ParamValues,
1642 &ParamNumbers};
1643 raw_string_ostream OS(MG.Code);
1644 Int->genCode(OS, ParamAlloc, 2);
1645 OS.flush();
1646
1647 MergeableGroups[MG].insert(OI);
1648 }
1649 }
1650
1651 // Output the actual C++ code.
1652
1653 for (const auto &kv : MergeableGroups) {
1654 const MergeableGroup &MG = kv.first;
1655
1656 // List of case statements in the main switch on BuiltinID, and an open
1657 // brace.
1658 const char *prefix = "";
1659 for (const auto &OI : kv.second) {
1660 OS << prefix << "case ARM::BI__builtin_arm_" << OI.Int->builtinExtension()
1661 << "_" << OI.Name << ":";
1662
1663 prefix = "\n";
1664 }
1665 OS << " {\n";
1666
1667 if (!MG.ParamTypes.empty()) {
1668 // If we've got some parameter variables, then emit their declarations...
1669 for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i) {
1670 StringRef Type = MG.ParamTypes[i];
1671 OS << " " << Type;
1672 if (!Type.endswith("*"))
1673 OS << " ";
1674 OS << " Param" << utostr(i) << ";\n";
1675 }
1676
1677 // ... and an inner switch on BuiltinID that will fill them in with each
1678 // individual intrinsic's values.
1679 OS << " switch (BuiltinID) {\n";
1680 for (const auto &OI : kv.second) {
1681 OS << " case ARM::BI__builtin_arm_" << OI.Int->builtinExtension()
1682 << "_" << OI.Name << ":\n";
1683 for (size_t i = 0, e = MG.ParamTypes.size(); i < e; ++i)
1684 OS << " Param" << utostr(i) << " = " << OI.ParamValues[i] << ";\n";
1685 OS << " break;\n";
1686 }
1687 OS << " }\n";
1688 }
1689
1690 // And finally, output the code, and close the outer pair of braces. (The
1691 // code will always end with a 'return' statement, so we need not insert a
1692 // 'break' here.)
1693 OS << MG.Code << "}\n";
1694 }
1695}
1696
1697void EmitterBase::EmitBuiltinAliases(raw_ostream &OS) {
1698 // Build a sorted table of:
1699 // - intrinsic id number
1700 // - full name
1701 // - polymorphic name or -1
1702 StringToOffsetTable StringTable;
1703 OS << "static const IntrinToName MapData[] = {\n";
1704 for (const auto &kv : ACLEIntrinsics) {
1705 const ACLEIntrinsic &Int = *kv.second;
1706 if (Int.headerOnly())
1707 continue;
1708 int32_t ShortNameOffset =
1709 Int.polymorphic() ? StringTable.GetOrAddStringOffset(Int.shortName())
1710 : -1;
1711 OS << " { ARM::BI__builtin_arm_" << Int.builtinExtension() << "_"
1712 << Int.fullName() << ", "
1713 << StringTable.GetOrAddStringOffset(Int.fullName()) << ", "
1714 << ShortNameOffset << "},\n";
1715 }
1716 OS << "};\n\n";
1717
1718 OS << "ArrayRef<IntrinToName> Map(MapData);\n\n";
1719
1720 OS << "static const char IntrinNames[] = {\n";
1721 StringTable.EmitString(OS);
1722 OS << "};\n\n";
1723}
1724
1725void EmitterBase::GroupSemaChecks(
1726 std::map<std::string, std::set<std::string>> &Checks) {
1727 for (const auto &kv : ACLEIntrinsics) {
1728 const ACLEIntrinsic &Int = *kv.second;
1729 if (Int.headerOnly())
1730 continue;
1731 std::string Check = Int.genSema();
1732 if (!Check.empty())
1733 Checks[Check].insert(Int.fullName());
1734 }
1735}
1736
1737// -----------------------------------------------------------------------------
1738// The class used for generating arm_mve.h and related Clang bits
1739//
1740
1741class MveEmitter : public EmitterBase {
1742public:
1743 MveEmitter(RecordKeeper &Records) : EmitterBase(Records){};
1744 void EmitHeader(raw_ostream &OS) override;
1745 void EmitBuiltinDef(raw_ostream &OS) override;
1746 void EmitBuiltinSema(raw_ostream &OS) override;
1747};
1748
1749void MveEmitter::EmitHeader(raw_ostream &OS) {
1750 // Accumulate pieces of the header file that will be enabled under various
1751 // different combinations of #ifdef. The index into parts[] is made up of
1752 // the following bit flags.
1753 constexpr unsigned Float = 1;
1754 constexpr unsigned UseUserNamespace = 2;
1755
1756 constexpr unsigned NumParts = 4;
1757 raw_self_contained_string_ostream parts[NumParts];
1758
1759 // Write typedefs for all the required vector types, and a few scalar
1760 // types that don't already have the name we want them to have.
1761
1762 parts[0] << "typedef uint16_t mve_pred16_t;\n";
1763 parts[Float] << "typedef __fp16 float16_t;\n"
1764 "typedef float float32_t;\n";
1765 for (const auto &kv : ScalarTypes) {
1766 const ScalarType *ST = kv.second.get();
1767 if (ST->hasNonstandardName())
1768 continue;
1769 raw_ostream &OS = parts[ST->requiresFloat() ? Float : 0];
1770 const VectorType *VT = getVectorType(ST);
1771
1772 OS << "typedef __attribute__((__neon_vector_type__(" << VT->lanes()
1773 << "), __clang_arm_mve_strict_polymorphism)) " << ST->cName() << " "
1774 << VT->cName() << ";\n";
1775
1776 // Every vector type also comes with a pair of multi-vector types for
1777 // the VLD2 and VLD4 instructions.
1778 for (unsigned n = 2; n <= 4; n += 2) {
1779 const MultiVectorType *MT = getMultiVectorType(n, VT);
1780 OS << "typedef struct { " << VT->cName() << " val[" << n << "]; } "
1781 << MT->cName() << ";\n";
1782 }
1783 }
1784 parts[0] << "\n";
1785 parts[Float] << "\n";
1786
1787 // Write declarations for all the intrinsics.
1788
1789 for (const auto &kv : ACLEIntrinsics) {
1790 const ACLEIntrinsic &Int = *kv.second;
1791
1792 // We generate each intrinsic twice, under its full unambiguous
1793 // name and its shorter polymorphic name (if the latter exists).
1794 for (bool Polymorphic : {false, true}) {
1795 if (Polymorphic && !Int.polymorphic())
1796 continue;
1797 if (!Polymorphic && Int.polymorphicOnly())
1798 continue;
1799
1800 // We also generate each intrinsic under a name like __arm_vfooq
1801 // (which is in C language implementation namespace, so it's
1802 // safe to define in any conforming user program) and a shorter
1803 // one like vfooq (which is in user namespace, so a user might
1804 // reasonably have used it for something already). If so, they
1805 // can #define __ARM_MVE_PRESERVE_USER_NAMESPACE before
1806 // including the header, which will suppress the shorter names
1807 // and leave only the implementation-namespace ones. Then they
1808 // have to write __arm_vfooq everywhere, of course.
1809
1810 for (bool UserNamespace : {false, true}) {
1811 raw_ostream &OS = parts[(Int.requiresFloat() ? Float : 0) |
1812 (UserNamespace ? UseUserNamespace : 0)];
1813
1814 // Make the name of the function in this declaration.
1815
1816 std::string FunctionName =
1817 Polymorphic ? Int.shortName() : Int.fullName();
1818 if (!UserNamespace)
1819 FunctionName = "__arm_" + FunctionName;
1820
1821 // Make strings for the types involved in the function's
1822 // prototype.
1823
1824 std::string RetTypeName = Int.returnType()->cName();
1825 if (!StringRef(RetTypeName).endswith("*"))
1826 RetTypeName += " ";
1827
1828 std::vector<std::string> ArgTypeNames;
1829 for (const Type *ArgTypePtr : Int.argTypes())
1830 ArgTypeNames.push_back(ArgTypePtr->cName());
1831 std::string ArgTypesString =
1832 join(std::begin(ArgTypeNames), std::end(ArgTypeNames), ", ");
1833
1834 // Emit the actual declaration. All these functions are
1835 // declared 'static inline' without a body, which is fine
1836 // provided clang recognizes them as builtins, and has the
1837 // effect that this type signature is used in place of the one
1838 // that Builtins.def didn't provide. That's how we can get
1839 // structure types that weren't defined until this header was
1840 // included to be part of the type signature of a builtin that
1841 // was known to clang already.
1842 //
1843 // The declarations use __attribute__(__clang_arm_builtin_alias),
1844 // so that each function declared will be recognized as the
1845 // appropriate MVE builtin in spite of its user-facing name.
1846 //
1847 // (That's better than making them all wrapper functions,
1848 // partly because it avoids any compiler error message citing
1849 // the wrapper function definition instead of the user's code,
1850 // and mostly because some MVE intrinsics have arguments
1851 // required to be compile-time constants, and that property
1852 // can't be propagated through a wrapper function. It can be
1853 // propagated through a macro, but macros can't be overloaded
1854 // on argument types very easily - you have to use _Generic,
1855 // which makes error messages very confusing when the user
1856 // gets it wrong.)
1857 //
1858 // Finally, the polymorphic versions of the intrinsics are
1859 // also defined with __attribute__(overloadable), so that when
1860 // the same name is defined with several type signatures, the
1861 // right thing happens. Each one of the overloaded
1862 // declarations is given a different builtin id, which
1863 // has exactly the effect we want: first clang resolves the
1864 // overload to the right function, then it knows which builtin
1865 // it's referring to, and then the Sema checking for that
1866 // builtin can check further things like the constant
1867 // arguments.
1868 //
1869 // One more subtlety is the newline just before the return
1870 // type name. That's a cosmetic tweak to make the error
1871 // messages legible if the user gets the types wrong in a call
1872 // to a polymorphic function: this way, clang will print just
1873 // the _final_ line of each declaration in the header, to show
1874 // the type signatures that would have been legal. So all the
1875 // confusing machinery with __attribute__ is left out of the
1876 // error message, and the user sees something that's more or
1877 // less self-documenting: "here's a list of actually readable
1878 // type signatures for vfooq(), and here's why each one didn't
1879 // match your call".
1880
1881 OS << "static __inline__ __attribute__(("
1882 << (Polymorphic ? "__overloadable__, " : "")
1883 << "__clang_arm_builtin_alias(__builtin_arm_mve_" << Int.fullName()
1884 << ")))\n"
1885 << RetTypeName << FunctionName << "(" << ArgTypesString << ");\n";
1886 }
1887 }
1888 }
1889 for (auto &part : parts)
1890 part << "\n";
1891
1892 // Now we've finished accumulating bits and pieces into the parts[] array.
1893 // Put it all together to write the final output file.
1894
1895 OS << "/*===---- arm_mve.h - ARM MVE intrinsics "
1896 "-----------------------------------===\n"
1897 << LLVMLicenseHeader
1898 << "#ifndef __ARM_MVE_H\n"
1899 "#define __ARM_MVE_H\n"
1900 "\n"
1901 "#if !__ARM_FEATURE_MVE\n"
1902 "#error \"MVE support not enabled\"\n"
1903 "#endif\n"
1904 "\n"
1905 "#include <stdint.h>\n"
1906 "\n"
1907 "#ifdef __cplusplus\n"
1908 "extern \"C\" {\n"
1909 "#endif\n"
1910 "\n";
1911
1912 for (size_t i = 0; i < NumParts; ++i) {
1913 std::vector<std::string> conditions;
1914 if (i & Float)
1915 conditions.push_back("(__ARM_FEATURE_MVE & 2)");
1916 if (i & UseUserNamespace)
1917 conditions.push_back("(!defined __ARM_MVE_PRESERVE_USER_NAMESPACE)");
1918
1919 std::string condition =
1920 join(std::begin(conditions), std::end(conditions), " && ");
1921 if (!condition.empty())
1922 OS << "#if " << condition << "\n\n";
1923 OS << parts[i].str();
1924 if (!condition.empty())
1925 OS << "#endif /* " << condition << " */\n\n";
1926 }
1927
1928 OS << "#ifdef __cplusplus\n"
1929 "} /* extern \"C\" */\n"
1930 "#endif\n"
1931 "\n"
1932 "#endif /* __ARM_MVE_H */\n";
1933}
1934
1935void MveEmitter::EmitBuiltinDef(raw_ostream &OS) {
1936 for (const auto &kv : ACLEIntrinsics) {
1937 const ACLEIntrinsic &Int = *kv.second;
1938 OS << "BUILTIN(__builtin_arm_mve_" << Int.fullName()
1939 << ", \"\", \"n\")\n";
1940 }
1941
1942 std::set<std::string> ShortNamesSeen;
1943
1944 for (const auto &kv : ACLEIntrinsics) {
1945 const ACLEIntrinsic &Int = *kv.second;
1946 if (Int.polymorphic()) {
1947 StringRef Name = Int.shortName();
1948 if (ShortNamesSeen.find(std::string(Name)) == ShortNamesSeen.end()) {
1949 OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt";
1950 if (Int.nonEvaluating())
1951 OS << "u"; // indicate that this builtin doesn't evaluate its args
1952 OS << "\")\n";
1953 ShortNamesSeen.insert(std::string(Name));
1954 }
1955 }
1956 }
1957}
1958
1959void MveEmitter::EmitBuiltinSema(raw_ostream &OS) {
1960 std::map<std::string, std::set<std::string>> Checks;
1961 GroupSemaChecks(Checks);
1962
1963 for (const auto &kv : Checks) {
1964 for (StringRef Name : kv.second)
1965 OS << "case ARM::BI__builtin_arm_mve_" << Name << ":\n";
1966 OS << " return " << kv.first;
1967 }
1968}
1969
1970// -----------------------------------------------------------------------------
1971// Class that describes an ACLE intrinsic implemented as a macro.
1972//
1973// This class is used when the intrinsic is polymorphic in 2 or 3 types, but we
1974// want to avoid a combinatorial explosion by reinterpreting the arguments to
1975// fixed types.
1976
1977class FunctionMacro {
1978 std::vector<StringRef> Params;
1979 StringRef Definition;
1980
1981public:
1982 FunctionMacro(const Record &R);
1983
1984 const std::vector<StringRef> &getParams() const { return Params; }
1985 StringRef getDefinition() const { return Definition; }
1986};
1987
1988FunctionMacro::FunctionMacro(const Record &R) {
1989 Params = R.getValueAsListOfStrings("params");
1990 Definition = R.getValueAsString("definition");
1991}
1992
1993// -----------------------------------------------------------------------------
1994// The class used for generating arm_cde.h and related Clang bits
1995//
1996
1997class CdeEmitter : public EmitterBase {
1998 std::map<StringRef, FunctionMacro> FunctionMacros;
1999
2000public:
2001 CdeEmitter(RecordKeeper &Records);
2002 void EmitHeader(raw_ostream &OS) override;
2003 void EmitBuiltinDef(raw_ostream &OS) override;
2004 void EmitBuiltinSema(raw_ostream &OS) override;
2005};
2006
2007CdeEmitter::CdeEmitter(RecordKeeper &Records) : EmitterBase(Records) {
2
Calling constructor for 'EmitterBase'
2008 for (Record *R : Records.getAllDerivedDefinitions("FunctionMacro"))
2009 FunctionMacros.emplace(R->getName(), FunctionMacro(*R));
2010}
2011
2012void CdeEmitter::EmitHeader(raw_ostream &OS) {
2013 // Accumulate pieces of the header file that will be enabled under various
2014 // different combinations of #ifdef. The index into parts[] is one of the
2015 // following:
2016 constexpr unsigned None = 0;
2017 constexpr unsigned MVE = 1;
2018 constexpr unsigned MVEFloat = 2;
2019
2020 constexpr unsigned NumParts = 3;
2021 raw_self_contained_string_ostream parts[NumParts];
2022
2023 // Write typedefs for all the required vector types, and a few scalar
2024 // types that don't already have the name we want them to have.
2025
2026 parts[MVE] << "typedef uint16_t mve_pred16_t;\n";
2027 parts[MVEFloat] << "typedef __fp16 float16_t;\n"
2028 "typedef float float32_t;\n";
2029 for (const auto &kv : ScalarTypes) {
2030 const ScalarType *ST = kv.second.get();
2031 if (ST->hasNonstandardName())
2032 continue;
2033 // We don't have float64x2_t
2034 if (ST->kind() == ScalarTypeKind::Float && ST->sizeInBits() == 64)
2035 continue;
2036 raw_ostream &OS = parts[ST->requiresFloat() ? MVEFloat : MVE];
2037 const VectorType *VT = getVectorType(ST);
2038
2039 OS << "typedef __attribute__((__neon_vector_type__(" << VT->lanes()
2040 << "), __clang_arm_mve_strict_polymorphism)) " << ST->cName() << " "
2041 << VT->cName() << ";\n";
2042 }
2043 parts[MVE] << "\n";
2044 parts[MVEFloat] << "\n";
2045
2046 // Write declarations for all the intrinsics.
2047
2048 for (const auto &kv : ACLEIntrinsics) {
2049 const ACLEIntrinsic &Int = *kv.second;
2050
2051 // We generate each intrinsic twice, under its full unambiguous
2052 // name and its shorter polymorphic name (if the latter exists).
2053 for (bool Polymorphic : {false, true}) {
2054 if (Polymorphic && !Int.polymorphic())
2055 continue;
2056 if (!Polymorphic && Int.polymorphicOnly())
2057 continue;
2058
2059 raw_ostream &OS =
2060 parts[Int.requiresFloat() ? MVEFloat
2061 : Int.requiresMVE() ? MVE : None];
2062
2063 // Make the name of the function in this declaration.
2064 std::string FunctionName =
2065 "__arm_" + (Polymorphic ? Int.shortName() : Int.fullName());
2066
2067 // Make strings for the types involved in the function's
2068 // prototype.
2069 std::string RetTypeName = Int.returnType()->cName();
2070 if (!StringRef(RetTypeName).endswith("*"))
2071 RetTypeName += " ";
2072
2073 std::vector<std::string> ArgTypeNames;
2074 for (const Type *ArgTypePtr : Int.argTypes())
2075 ArgTypeNames.push_back(ArgTypePtr->cName());
2076 std::string ArgTypesString =
2077 join(std::begin(ArgTypeNames), std::end(ArgTypeNames), ", ");
2078
2079 // Emit the actual declaration. See MveEmitter::EmitHeader for detailed
2080 // comments
2081 OS << "static __inline__ __attribute__(("
2082 << (Polymorphic ? "__overloadable__, " : "")
2083 << "__clang_arm_builtin_alias(__builtin_arm_" << Int.builtinExtension()
2084 << "_" << Int.fullName() << ")))\n"
2085 << RetTypeName << FunctionName << "(" << ArgTypesString << ");\n";
2086 }
2087 }
2088
2089 for (const auto &kv : FunctionMacros) {
2090 StringRef Name = kv.first;
2091 const FunctionMacro &FM = kv.second;
2092
2093 raw_ostream &OS = parts[MVE];
2094 OS << "#define "
2095 << "__arm_" << Name << "(" << join(FM.getParams(), ", ") << ") "
2096 << FM.getDefinition() << "\n";
2097 }
2098
2099 for (auto &part : parts)
2100 part << "\n";
2101
2102 // Now we've finished accumulating bits and pieces into the parts[] array.
2103 // Put it all together to write the final output file.
2104
2105 OS << "/*===---- arm_cde.h - ARM CDE intrinsics "
2106 "-----------------------------------===\n"
2107 << LLVMLicenseHeader
2108 << "#ifndef __ARM_CDE_H\n"
2109 "#define __ARM_CDE_H\n"
2110 "\n"
2111 "#if !__ARM_FEATURE_CDE\n"
2112 "#error \"CDE support not enabled\"\n"
2113 "#endif\n"
2114 "\n"
2115 "#include <stdint.h>\n"
2116 "\n"
2117 "#ifdef __cplusplus\n"
2118 "extern \"C\" {\n"
2119 "#endif\n"
2120 "\n";
2121
2122 for (size_t i = 0; i < NumParts; ++i) {
2123 std::string condition;
2124 if (i == MVEFloat)
2125 condition = "__ARM_FEATURE_MVE & 2";
2126 else if (i == MVE)
2127 condition = "__ARM_FEATURE_MVE";
2128
2129 if (!condition.empty())
2130 OS << "#if " << condition << "\n\n";
2131 OS << parts[i].str();
2132 if (!condition.empty())
2133 OS << "#endif /* " << condition << " */\n\n";
2134 }
2135
2136 OS << "#ifdef __cplusplus\n"
2137 "} /* extern \"C\" */\n"
2138 "#endif\n"
2139 "\n"
2140 "#endif /* __ARM_CDE_H */\n";
2141}
2142
2143void CdeEmitter::EmitBuiltinDef(raw_ostream &OS) {
2144 for (const auto &kv : ACLEIntrinsics) {
2145 if (kv.second->headerOnly())
2146 continue;
2147 const ACLEIntrinsic &Int = *kv.second;
2148 OS << "BUILTIN(__builtin_arm_cde_" << Int.fullName()
2149 << ", \"\", \"ncU\")\n";
2150 }
2151}
2152
2153void CdeEmitter::EmitBuiltinSema(raw_ostream &OS) {
2154 std::map<std::string, std::set<std::string>> Checks;
2155 GroupSemaChecks(Checks);
2156
2157 for (const auto &kv : Checks) {
2158 for (StringRef Name : kv.second)
2159 OS << "case ARM::BI__builtin_arm_cde_" << Name << ":\n";
2160 OS << " Err = " << kv.first << " break;\n";
2161 }
2162}
2163
2164} // namespace
2165
2166namespace clang {
2167
2168// MVE
2169
2170void EmitMveHeader(RecordKeeper &Records, raw_ostream &OS) {
2171 MveEmitter(Records).EmitHeader(OS);
2172}
2173
2174void EmitMveBuiltinDef(RecordKeeper &Records, raw_ostream &OS) {
2175 MveEmitter(Records).EmitBuiltinDef(OS);
2176}
2177
2178void EmitMveBuiltinSema(RecordKeeper &Records, raw_ostream &OS) {
2179 MveEmitter(Records).EmitBuiltinSema(OS);
2180}
2181
2182void EmitMveBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
2183 MveEmitter(Records).EmitBuiltinCG(OS);
2184}
2185
2186void EmitMveBuiltinAliases(RecordKeeper &Records, raw_ostream &OS) {
2187 MveEmitter(Records).EmitBuiltinAliases(OS);
2188}
2189
2190// CDE
2191
2192void EmitCdeHeader(RecordKeeper &Records, raw_ostream &OS) {
2193 CdeEmitter(Records).EmitHeader(OS);
2194}
2195
2196void EmitCdeBuiltinDef(RecordKeeper &Records, raw_ostream &OS) {
2197 CdeEmitter(Records).EmitBuiltinDef(OS);
2198}
2199
2200void EmitCdeBuiltinSema(RecordKeeper &Records, raw_ostream &OS) {
2201 CdeEmitter(Records).EmitBuiltinSema(OS);
2202}
2203
2204void EmitCdeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
2205 CdeEmitter(Records).EmitBuiltinCG(OS);
2206}
2207
2208void EmitCdeBuiltinAliases(RecordKeeper &Records, raw_ostream &OS) {
2209 CdeEmitter(Records).EmitBuiltinAliases(OS);
1
Calling constructor for 'CdeEmitter'
2210}
2211
2212} // end namespace clang

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/unique_ptr.h

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40#if __cplusplus201402L > 201703L
41# include <compare>
42# include <ostream>
43#endif
44
45namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48
49 /**
50 * @addtogroup pointer_abstractions
51 * @{
52 */
53
54#if _GLIBCXX_USE_DEPRECATED1
55#pragma GCC diagnostic push
56#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
57 template<typename> class auto_ptr;
58#pragma GCC diagnostic pop
59#endif
60
61 /// Primary template of default_delete, used by unique_ptr for single objects
62 template<typename _Tp>
63 struct default_delete
64 {
65 /// Default constructor
66 constexpr default_delete() noexcept = default;
67
68 /** @brief Converting constructor.
69 *
70 * Allows conversion from a deleter for objects of another type, `_Up`,
71 * only if `_Up*` is convertible to `_Tp*`.
72 */
73 template<typename _Up,
74 typename = _Require<is_convertible<_Up*, _Tp*>>>
75 default_delete(const default_delete<_Up>&) noexcept { }
76
77 /// Calls `delete __ptr`
78 void
79 operator()(_Tp* __ptr) const
80 {
81 static_assert(!is_void<_Tp>::value,
82 "can't delete pointer to incomplete type");
83 static_assert(sizeof(_Tp)>0,
84 "can't delete pointer to incomplete type");
85 delete __ptr;
86 }
87 };
88
89 // _GLIBCXX_RESOLVE_LIB_DEFECTS
90 // DR 740 - omit specialization for array objects with a compile time length
91
92 /// Specialization of default_delete for arrays, used by `unique_ptr<T[]>`
93 template<typename _Tp>
94 struct default_delete<_Tp[]>
95 {
96 public:
97 /// Default constructor
98 constexpr default_delete() noexcept = default;
99
100 /** @brief Converting constructor.
101 *
102 * Allows conversion from a deleter for arrays of another type, such as
103 * a const-qualified version of `_Tp`.
104 *
105 * Conversions from types derived from `_Tp` are not allowed because
106 * it is undefined to `delete[]` an array of derived types through a
107 * pointer to the base type.
108 */
109 template<typename _Up,
110 typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>>
111 default_delete(const default_delete<_Up[]>&) noexcept { }
112
113 /// Calls `delete[] __ptr`
114 template<typename _Up>
115 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
116 operator()(_Up* __ptr) const
117 {
118 static_assert(sizeof(_Tp)>0,
119 "can't delete pointer to incomplete type");
120 delete [] __ptr;
121 }
122 };
123
124 /// @cond undocumented
125
126 // Manages the pointer and deleter of a unique_ptr
127 template <typename _Tp, typename _Dp>
128 class __uniq_ptr_impl
129 {
130 template <typename _Up, typename _Ep, typename = void>
131 struct _Ptr
132 {
133 using type = _Up*;
134 };
135
136 template <typename _Up, typename _Ep>
137 struct
138 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
139 {
140 using type = typename remove_reference<_Ep>::type::pointer;
141 };
142
143 public:
144 using _DeleterConstraint = enable_if<
145 __and_<__not_<is_pointer<_Dp>>,
146 is_default_constructible<_Dp>>::value>;
147
148 using pointer = typename _Ptr<_Tp, _Dp>::type;
149
150 static_assert( !is_rvalue_reference<_Dp>::value,
151 "unique_ptr's deleter type must be a function object type"
152 " or an lvalue reference type" );
153
154 __uniq_ptr_impl() = default;
155 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
156
157 template<typename _Del>
158 __uniq_ptr_impl(pointer __p, _Del&& __d)
159 : _M_t(__p, std::forward<_Del>(__d)) { }
160
161 __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
162 : _M_t(std::move(__u._M_t))
163 { __u._M_ptr() = nullptr; }
164
165 __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
166 {
167 reset(__u.release());
168 _M_deleter() = std::forward<_Dp>(__u._M_deleter());
169 return *this;
170 }
171
172 pointer& _M_ptr() { return std::get<0>(_M_t); }
173 pointer _M_ptr() const { return std::get<0>(_M_t); }
174 _Dp& _M_deleter() { return std::get<1>(_M_t); }
175 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
176
177 void reset(pointer __p) noexcept
178 {
179 const pointer __old_p = _M_ptr();
180 _M_ptr() = __p;
181 if (__old_p)
182 _M_deleter()(__old_p);
183 }
184
185 pointer release() noexcept
186 {
187 pointer __p = _M_ptr();
188 _M_ptr() = nullptr;
189 return __p;
190 }
191
192 void
193 swap(__uniq_ptr_impl& __rhs) noexcept
194 {
195 using std::swap;
196 swap(this->_M_ptr(), __rhs._M_ptr());
197 swap(this->_M_deleter(), __rhs._M_deleter());
198 }
199
200 private:
201 tuple<pointer, _Dp> _M_t;
202 };
203
204 // Defines move construction + assignment as either defaulted or deleted.
205 template <typename _Tp, typename _Dp,
206 bool = is_move_constructible<_Dp>::value,
207 bool = is_move_assignable<_Dp>::value>
208 struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp>
209 {
210 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
211 __uniq_ptr_data(__uniq_ptr_data&&) = default;
212 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
213 };
214
215 template <typename _Tp, typename _Dp>
216 struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp>
217 {
218 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
219 __uniq_ptr_data(__uniq_ptr_data&&) = default;
220 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
221 };
222
223 template <typename _Tp, typename _Dp>
224 struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp>
225 {
226 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
227 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
228 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default;
229 };
230
231 template <typename _Tp, typename _Dp>
232 struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp>
233 {
234 using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl;
235 __uniq_ptr_data(__uniq_ptr_data&&) = delete;
236 __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete;
237 };
238 /// @endcond
239
240 /// 20.7.1.2 unique_ptr for single objects.
241 template <typename _Tp, typename _Dp = default_delete<_Tp>>
242 class unique_ptr
243 {
244 template <typename _Up>
245 using _DeleterConstraint =
246 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
247
248 __uniq_ptr_data<_Tp, _Dp> _M_t;
249
250 public:
251 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
252 using element_type = _Tp;
253 using deleter_type = _Dp;
254
255 private:
256 // helper template for detecting a safe conversion from another
257 // unique_ptr
258 template<typename _Up, typename _Ep>
259 using __safe_conversion_up = __and_<
260 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
261 __not_<is_array<_Up>>
262 >;
263
264 public:
265 // Constructors.
266
267 /// Default constructor, creates a unique_ptr that owns nothing.
268 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
269 constexpr unique_ptr() noexcept
270 : _M_t()
271 { }
272
273 /** Takes ownership of a pointer.
274 *
275 * @param __p A pointer to an object of @c element_type
276 *
277 * The deleter will be value-initialized.
278 */
279 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
280 explicit
281 unique_ptr(pointer __p) noexcept
282 : _M_t(__p)
283 { }
284
285 /** Takes ownership of a pointer.
286 *
287 * @param __p A pointer to an object of @c element_type
288 * @param __d A reference to a deleter.
289 *
290 * The deleter will be initialized with @p __d
291 */
292 template<typename _Del = deleter_type,
293 typename = _Require<is_copy_constructible<_Del>>>
294 unique_ptr(pointer __p, const deleter_type& __d) noexcept
295 : _M_t(__p, __d) { }
296
297 /** Takes ownership of a pointer.
298 *
299 * @param __p A pointer to an object of @c element_type
300 * @param __d An rvalue reference to a (non-reference) deleter.
301 *
302 * The deleter will be initialized with @p std::move(__d)
303 */
304 template<typename _Del = deleter_type,
305 typename = _Require<is_move_constructible<_Del>>>
306 unique_ptr(pointer __p,
307 __enable_if_t<!is_lvalue_reference<_Del>::value,
308 _Del&&> __d) noexcept
309 : _M_t(__p, std::move(__d))
310 { }
311
312 template<typename _Del = deleter_type,
313 typename _DelUnref = typename remove_reference<_Del>::type>
314 unique_ptr(pointer,
315 __enable_if_t<is_lvalue_reference<_Del>::value,
316 _DelUnref&&>) = delete;
317
318 /// Creates a unique_ptr that owns nothing.
319 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
320 constexpr unique_ptr(nullptr_t) noexcept
321 : _M_t()
322 { }
323
324 // Move constructors.
325
326 /// Move constructor.
327 unique_ptr(unique_ptr&&) = default;
328
329 /** @brief Converting constructor from another type
330 *
331 * Requires that the pointer owned by @p __u is convertible to the
332 * type of pointer owned by this object, @p __u does not own an array,
333 * and @p __u has a compatible deleter type.
334 */
335 template<typename _Up, typename _Ep, typename = _Require<
336 __safe_conversion_up<_Up, _Ep>,
337 typename conditional<is_reference<_Dp>::value,
338 is_same<_Ep, _Dp>,
339 is_convertible<_Ep, _Dp>>::type>>
340 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
341 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
342 { }
343
344#if _GLIBCXX_USE_DEPRECATED1
345#pragma GCC diagnostic push
346#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
347 /// Converting constructor from @c auto_ptr
348 template<typename _Up, typename = _Require<
349 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
350 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
351#pragma GCC diagnostic pop
352#endif
353
354 /// Destructor, invokes the deleter if the stored pointer is not null.
355 ~unique_ptr() noexcept
356 {
357 static_assert(__is_invocable<deleter_type&, pointer>::value,
358 "unique_ptr's deleter must be invocable with a pointer");
359 auto& __ptr = _M_t._M_ptr();
360 if (__ptr != nullptr)
361 get_deleter()(std::move(__ptr));
362 __ptr = pointer();
363 }
364
365 // Assignment.
366
367 /** @brief Move assignment operator.
368 *
369 * Invokes the deleter if this object owns a pointer.
370 */
371 unique_ptr& operator=(unique_ptr&&) = default;
372
373 /** @brief Assignment from another type.
374 *
375 * @param __u The object to transfer ownership from, which owns a
376 * convertible pointer to a non-array object.
377 *
378 * Invokes the deleter if this object owns a pointer.
379 */
380 template<typename _Up, typename _Ep>
381 typename enable_if< __and_<
382 __safe_conversion_up<_Up, _Ep>,
383 is_assignable<deleter_type&, _Ep&&>
384 >::value,
385 unique_ptr&>::type
386 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
387 {
388 reset(__u.release());
389 get_deleter() = std::forward<_Ep>(__u.get_deleter());
390 return *this;
391 }
392
393 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
394 unique_ptr&
395 operator=(nullptr_t) noexcept
396 {
397 reset();
398 return *this;
399 }
400
401 // Observers.
402
403 /// Dereference the stored pointer.
404 typename add_lvalue_reference<element_type>::type
405 operator*() const
406 {
407 __glibcxx_assert(get() != pointer());
408 return *get();
409 }
410
411 /// Return the stored pointer.
412 pointer
413 operator->() const noexcept
414 {
415 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
416 return get();
417 }
418
419 /// Return the stored pointer.
420 pointer
421 get() const noexcept
422 { return _M_t._M_ptr(); }
423
424 /// Return a reference to the stored deleter.
425 deleter_type&
426 get_deleter() noexcept
427 { return _M_t._M_deleter(); }
428
429 /// Return a reference to the stored deleter.
430 const deleter_type&
431 get_deleter() const noexcept
432 { return _M_t._M_deleter(); }
433
434 /// Return @c true if the stored pointer is not null.
435 explicit operator bool() const noexcept
436 { return get() == pointer() ? false : true; }
437
438 // Modifiers.
439
440 /// Release ownership of any stored pointer.
441 pointer
442 release() noexcept
443 { return _M_t.release(); }
444
445 /** @brief Replace the stored pointer.
446 *
447 * @param __p The new pointer to store.
448 *
449 * The deleter will be invoked if a pointer is already owned.
450 */
451 void
452 reset(pointer __p = pointer()) noexcept
453 {
454 static_assert(__is_invocable<deleter_type&, pointer>::value,
455 "unique_ptr's deleter must be invocable with a pointer");
456 _M_t.reset(std::move(__p));
457 }
458
459 /// Exchange the pointer and deleter with another object.
460 void
461 swap(unique_ptr& __u) noexcept
462 {
463 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
464 _M_t.swap(__u._M_t);
465 }
466
467 // Disable copy from lvalue.
468 unique_ptr(const unique_ptr&) = delete;
469 unique_ptr& operator=(const unique_ptr&) = delete;
470 };
471
472 /// 20.7.1.3 unique_ptr for array objects with a runtime length
473 // [unique.ptr.runtime]
474 // _GLIBCXX_RESOLVE_LIB_DEFECTS
475 // DR 740 - omit specialization for array objects with a compile time length
476 template<typename _Tp, typename _Dp>
477 class unique_ptr<_Tp[], _Dp>
478 {
479 template <typename _Up>
480 using _DeleterConstraint =
481 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
482
483 __uniq_ptr_data<_Tp, _Dp> _M_t;
484
485 template<typename _Up>
486 using __remove_cv = typename remove_cv<_Up>::type;
487
488 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
489 template<typename _Up>
490 using __is_derived_Tp
491 = __and_< is_base_of<_Tp, _Up>,
492 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
493
494 public:
495 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
496 using element_type = _Tp;
497 using deleter_type = _Dp;
498
499 // helper template for detecting a safe conversion from another
500 // unique_ptr
501 template<typename _Up, typename _Ep,
502 typename _UPtr = unique_ptr<_Up, _Ep>,
503 typename _UP_pointer = typename _UPtr::pointer,
504 typename _UP_element_type = typename _UPtr::element_type>
505 using __safe_conversion_up = __and_<
506 is_array<_Up>,
507 is_same<pointer, element_type*>,
508 is_same<_UP_pointer, _UP_element_type*>,
509 is_convertible<_UP_element_type(*)[], element_type(*)[]>
510 >;
511
512 // helper template for detecting a safe conversion from a raw pointer
513 template<typename _Up>
514 using __safe_conversion_raw = __and_<
515 __or_<__or_<is_same<_Up, pointer>,
516 is_same<_Up, nullptr_t>>,
517 __and_<is_pointer<_Up>,
518 is_same<pointer, element_type*>,
519 is_convertible<
520 typename remove_pointer<_Up>::type(*)[],
521 element_type(*)[]>
522 >
523 >
524 >;
525
526 // Constructors.
527
528 /// Default constructor, creates a unique_ptr that owns nothing.
529 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
530 constexpr unique_ptr() noexcept
531 : _M_t()
532 { }
533
534 /** Takes ownership of a pointer.
535 *
536 * @param __p A pointer to an array of a type safely convertible
537 * to an array of @c element_type
538 *
539 * The deleter will be value-initialized.
540 */
541 template<typename _Up,
542 typename _Vp = _Dp,
543 typename = _DeleterConstraint<_Vp>,
544 typename = typename enable_if<
545 __safe_conversion_raw<_Up>::value, bool>::type>
546 explicit
547 unique_ptr(_Up __p) noexcept
548 : _M_t(__p)
549 { }
550
551 /** Takes ownership of a pointer.
552 *
553 * @param __p A pointer to an array of a type safely convertible
554 * to an array of @c element_type
555 * @param __d A reference to a deleter.
556 *
557 * The deleter will be initialized with @p __d
558 */
559 template<typename _Up, typename _Del = deleter_type,
560 typename = _Require<__safe_conversion_raw<_Up>,
561 is_copy_constructible<_Del>>>
562 unique_ptr(_Up __p, const deleter_type& __d) noexcept
563 : _M_t(__p, __d) { }
564
565 /** Takes ownership of a pointer.
566 *
567 * @param __p A pointer to an array of a type safely convertible
568 * to an array of @c element_type
569 * @param __d A reference to a deleter.
570 *
571 * The deleter will be initialized with @p std::move(__d)
572 */
573 template<typename _Up, typename _Del = deleter_type,
574 typename = _Require<__safe_conversion_raw<_Up>,
575 is_move_constructible<_Del>>>
576 unique_ptr(_Up __p,
577 __enable_if_t<!is_lvalue_reference<_Del>::value,
578 _Del&&> __d) noexcept
579 : _M_t(std::move(__p), std::move(__d))
580 { }
581
582 template<typename _Up, typename _Del = deleter_type,
583 typename _DelUnref = typename remove_reference<_Del>::type,
584 typename = _Require<__safe_conversion_raw<_Up>>>
585 unique_ptr(_Up,
586 __enable_if_t<is_lvalue_reference<_Del>::value,
587 _DelUnref&&>) = delete;
588
589 /// Move constructor.
590 unique_ptr(unique_ptr&&) = default;
591
592 /// Creates a unique_ptr that owns nothing.
593 template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>>
594 constexpr unique_ptr(nullptr_t) noexcept
595 : _M_t()
596 { }
597
598 template<typename _Up, typename _Ep, typename = _Require<
599 __safe_conversion_up<_Up, _Ep>,
600 typename conditional<is_reference<_Dp>::value,
601 is_same<_Ep, _Dp>,
602 is_convertible<_Ep, _Dp>>::type>>
603 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
604 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
605 { }
606
607 /// Destructor, invokes the deleter if the stored pointer is not null.
608 ~unique_ptr()
609 {
610 auto& __ptr = _M_t._M_ptr();
611 if (__ptr != nullptr)
612 get_deleter()(__ptr);
613 __ptr = pointer();
614 }
615
616 // Assignment.
617
618 /** @brief Move assignment operator.
619 *
620 * Invokes the deleter if this object owns a pointer.
621 */
622 unique_ptr&
623 operator=(unique_ptr&&) = default;
624
625 /** @brief Assignment from another type.
626 *
627 * @param __u The object to transfer ownership from, which owns a
628 * convertible pointer to an array object.
629 *
630 * Invokes the deleter if this object owns a pointer.
631 */
632 template<typename _Up, typename _Ep>
633 typename
634 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
635 is_assignable<deleter_type&, _Ep&&>
636 >::value,
637 unique_ptr&>::type
638 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
639 {
640 reset(__u.release());
641 get_deleter() = std::forward<_Ep>(__u.get_deleter());
642 return *this;
643 }
644
645 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
646 unique_ptr&
647 operator=(nullptr_t) noexcept
648 {
649 reset();
650 return *this;
651 }
652
653 // Observers.
654
655 /// Access an element of owned array.
656 typename std::add_lvalue_reference<element_type>::type
657 operator[](size_t __i) const
658 {
659 __glibcxx_assert(get() != pointer());
660 return get()[__i];
661 }
662
663 /// Return the stored pointer.
664 pointer
665 get() const noexcept
666 { return _M_t._M_ptr(); }
667
668 /// Return a reference to the stored deleter.
669 deleter_type&
670 get_deleter() noexcept
671 { return _M_t._M_deleter(); }
672
673 /// Return a reference to the stored deleter.
674 const deleter_type&
675 get_deleter() const noexcept
676 { return _M_t._M_deleter(); }
677
678 /// Return @c true if the stored pointer is not null.
679 explicit operator bool() const noexcept
680 { return get() == pointer() ? false : true; }
681
682 // Modifiers.
683
684 /// Release ownership of any stored pointer.
685 pointer
686 release() noexcept
687 { return _M_t.release(); }
688
689 /** @brief Replace the stored pointer.
690 *
691 * @param __p The new pointer to store.
692 *
693 * The deleter will be invoked if a pointer is already owned.
694 */
695 template <typename _Up,
696 typename = _Require<
697 __or_<is_same<_Up, pointer>,
698 __and_<is_same<pointer, element_type*>,
699 is_pointer<_Up>,
700 is_convertible<
701 typename remove_pointer<_Up>::type(*)[],
702 element_type(*)[]
703 >
704 >
705 >
706 >>
707 void
708 reset(_Up __p) noexcept
709 { _M_t.reset(std::move(__p)); }
710
711 void reset(nullptr_t = nullptr) noexcept
712 { reset(pointer()); }
713
714 /// Exchange the pointer and deleter with another object.
715 void
716 swap(unique_ptr& __u) noexcept
717 {
718 static_assert(__is_swappable<_Dp>::value, "deleter must be swappable");
719 _M_t.swap(__u._M_t);
720 }
721
722 // Disable copy from lvalue.
723 unique_ptr(const unique_ptr&) = delete;
724 unique_ptr& operator=(const unique_ptr&) = delete;
725 };
726
727 /// @relates unique_ptr @{
728
729 /// Swap overload for unique_ptr
730 template<typename _Tp, typename _Dp>
731 inline
732#if __cplusplus201402L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
733 // Constrained free swap overload, see p0185r1
734 typename enable_if<__is_swappable<_Dp>::value>::type
735#else
736 void
737#endif
738 swap(unique_ptr<_Tp, _Dp>& __x,
739 unique_ptr<_Tp, _Dp>& __y) noexcept
740 { __x.swap(__y); }
741
742#if __cplusplus201402L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
743 template<typename _Tp, typename _Dp>
744 typename enable_if<!__is_swappable<_Dp>::value>::type
745 swap(unique_ptr<_Tp, _Dp>&,
746 unique_ptr<_Tp, _Dp>&) = delete;
747#endif
748
749 /// Equality operator for unique_ptr objects, compares the owned pointers
750 template<typename _Tp, typename _Dp,
751 typename _Up, typename _Ep>
752 _GLIBCXX_NODISCARD inline bool
753 operator==(const unique_ptr<_Tp, _Dp>& __x,
754 const unique_ptr<_Up, _Ep>& __y)
755 { return __x.get() == __y.get(); }
756
757 /// unique_ptr comparison with nullptr
758 template<typename _Tp, typename _Dp>
759 _GLIBCXX_NODISCARD inline bool
760 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
761 { return !__x; }
762
763#ifndef __cpp_lib_three_way_comparison
764 /// unique_ptr comparison with nullptr
765 template<typename _Tp, typename _Dp>
766 _GLIBCXX_NODISCARD inline bool
767 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
768 { return !__x; }
769
770 /// Inequality operator for unique_ptr objects, compares the owned pointers
771 template<typename _Tp, typename _Dp,
772 typename _Up, typename _Ep>
773 _GLIBCXX_NODISCARD inline bool
774 operator!=(const unique_ptr<_Tp, _Dp>& __x,
775 const unique_ptr<_Up, _Ep>& __y)
776 { return __x.get() != __y.get(); }
777
778 /// unique_ptr comparison with nullptr
779 template<typename _Tp, typename _Dp>
780 _GLIBCXX_NODISCARD inline bool
781 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
782 { return (bool)__x; }
783
784 /// unique_ptr comparison with nullptr
785 template<typename _Tp, typename _Dp>
786 _GLIBCXX_NODISCARD inline bool
787 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
788 { return (bool)__x; }
789#endif // three way comparison
790
791 /// Relational operator for unique_ptr objects, compares the owned pointers
792 template<typename _Tp, typename _Dp,
793 typename _Up, typename _Ep>
794 _GLIBCXX_NODISCARD inline bool
795 operator<(const unique_ptr<_Tp, _Dp>& __x,
796 const unique_ptr<_Up, _Ep>& __y)
797 {
798 typedef typename
799 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
800 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
801 return std::less<_CT>()(__x.get(), __y.get());
802 }
803
804 /// unique_ptr comparison with nullptr
805 template<typename _Tp, typename _Dp>
806 _GLIBCXX_NODISCARD inline bool
807 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
808 {
809 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
810 nullptr);
811 }
812
813 /// unique_ptr comparison with nullptr
814 template<typename _Tp, typename _Dp>
815 _GLIBCXX_NODISCARD inline bool
816 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
817 {
818 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
819 __x.get());
820 }
821
822 /// Relational operator for unique_ptr objects, compares the owned pointers
823 template<typename _Tp, typename _Dp,
824 typename _Up, typename _Ep>
825 _GLIBCXX_NODISCARD inline bool
826 operator<=(const unique_ptr<_Tp, _Dp>& __x,
827 const unique_ptr<_Up, _Ep>& __y)
828 { return !(__y < __x); }
829
830 /// unique_ptr comparison with nullptr
831 template<typename _Tp, typename _Dp>
832 _GLIBCXX_NODISCARD inline bool
833 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
834 { return !(nullptr < __x); }
835
836 /// unique_ptr comparison with nullptr
837 template<typename _Tp, typename _Dp>
838 _GLIBCXX_NODISCARD inline bool
839 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
840 { return !(__x < nullptr); }
841
842 /// Relational operator for unique_ptr objects, compares the owned pointers
843 template<typename _Tp, typename _Dp,
844 typename _Up, typename _Ep>
845 _GLIBCXX_NODISCARD inline bool
846 operator>(const unique_ptr<_Tp, _Dp>& __x,
847 const unique_ptr<_Up, _Ep>& __y)
848 { return (__y < __x); }
849
850 /// unique_ptr comparison with nullptr
851 template<typename _Tp, typename _Dp>
852 _GLIBCXX_NODISCARD inline bool
853 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
854 {
855 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
856 __x.get());
857 }
858
859 /// unique_ptr comparison with nullptr
860 template<typename _Tp, typename _Dp>
861 _GLIBCXX_NODISCARD inline bool
862 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
863 {
864 return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
865 nullptr);
866 }
867
868 /// Relational operator for unique_ptr objects, compares the owned pointers
869 template<typename _Tp, typename _Dp,
870 typename _Up, typename _Ep>
871 _GLIBCXX_NODISCARD inline bool
872 operator>=(const unique_ptr<_Tp, _Dp>& __x,
873 const unique_ptr<_Up, _Ep>& __y)
874 { return !(__x < __y); }
875
876 /// unique_ptr comparison with nullptr
877 template<typename _Tp, typename _Dp>
878 _GLIBCXX_NODISCARD inline bool
879 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
880 { return !(__x < nullptr); }
881
882 /// unique_ptr comparison with nullptr
883 template<typename _Tp, typename _Dp>
884 _GLIBCXX_NODISCARD inline bool
885 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
886 { return !(nullptr < __x); }
887
888#ifdef __cpp_lib_three_way_comparison
889 template<typename _Tp, typename _Dp, typename _Up, typename _Ep>
890 requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer,
891 typename unique_ptr<_Up, _Ep>::pointer>
892 inline
893 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer,
894 typename unique_ptr<_Up, _Ep>::pointer>
895 operator<=>(const unique_ptr<_Tp, _Dp>& __x,
896 const unique_ptr<_Up, _Ep>& __y)
897 { return compare_three_way()(__x.get(), __y.get()); }
898
899 template<typename _Tp, typename _Dp>
900 requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer>
901 inline
902 compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer>
903 operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
904 {
905 using pointer = typename unique_ptr<_Tp, _Dp>::pointer;
906 return compare_three_way()(__x.get(), static_cast<pointer>(nullptr));
907 }
908#endif
909 // @} relates unique_ptr
910
911 /// @cond undocumented
912 template<typename _Up, typename _Ptr = typename _Up::pointer,
913 bool = __poison_hash<_Ptr>::__enable_hash_call>
914 struct __uniq_ptr_hash
915#if ! _GLIBCXX_INLINE_VERSION0
916 : private __poison_hash<_Ptr>
917#endif
918 {
919 size_t
920 operator()(const _Up& __u) const
921 noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>())))
922 { return hash<_Ptr>()(__u.get()); }
923 };
924
925 template<typename _Up, typename _Ptr>
926 struct __uniq_ptr_hash<_Up, _Ptr, false>
927 : private __poison_hash<_Ptr>
928 { };
929 /// @endcond
930
931 /// std::hash specialization for unique_ptr.
932 template<typename _Tp, typename _Dp>
933 struct hash<unique_ptr<_Tp, _Dp>>
934 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
935 public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>>
936 { };
937
938#if __cplusplus201402L >= 201402L
939 /// @relates unique_ptr @{
940#define __cpp_lib_make_unique201304 201304
941
942 /// @cond undocumented
943
944 template<typename _Tp>
945 struct _MakeUniq
946 { typedef unique_ptr<_Tp> __single_object; };
947
948 template<typename _Tp>
949 struct _MakeUniq<_Tp[]>
950 { typedef unique_ptr<_Tp[]> __array; };
951
952 template<typename _Tp, size_t _Bound>
953 struct _MakeUniq<_Tp[_Bound]>
954 { struct __invalid_type { }; };
955
956 /// @endcond
957
958 /// std::make_unique for single objects
959 template<typename _Tp, typename... _Args>
960 inline typename _MakeUniq<_Tp>::__single_object
961 make_unique(_Args&&... __args)
962 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
4
Calling constructor for 'ACLEIntrinsic'
963
964 /// std::make_unique for arrays of unknown bound
965 template<typename _Tp>
966 inline typename _MakeUniq<_Tp>::__array
967 make_unique(size_t __num)
968 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
969
970 /// Disable std::make_unique for arrays of known bound
971 template<typename _Tp, typename... _Args>
972 inline typename _MakeUniq<_Tp>::__invalid_type
973 make_unique(_Args&&...) = delete;
974 // @} relates unique_ptr
975#endif // C++14
976
977#if __cplusplus201402L > 201703L && __cpp_concepts
978 // _GLIBCXX_RESOLVE_LIB_DEFECTS
979 // 2948. unique_ptr does not define operator<< for stream output
980 /// Stream output operator for unique_ptr
981 template<typename _CharT, typename _Traits, typename _Tp, typename _Dp>
982 inline basic_ostream<_CharT, _Traits>&
983 operator<<(basic_ostream<_CharT, _Traits>& __os,
984 const unique_ptr<_Tp, _Dp>& __p)
985 requires requires { __os << __p.get(); }
986 {
987 __os << __p.get();
988 return __os;
989 }
990#endif // C++20
991
992 // @} group pointer_abstractions
993
994#if __cplusplus201402L >= 201703L
995 namespace __detail::__variant
996 {
997 template<typename> struct _Never_valueless_alt; // see <variant>
998
999 // Provide the strong exception-safety guarantee when emplacing a
1000 // unique_ptr into a variant.
1001 template<typename _Tp, typename _Del>
1002 struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>>
1003 : std::true_type
1004 { };
1005 } // namespace __detail::__variant
1006#endif // C++17
1007
1008_GLIBCXX_END_NAMESPACE_VERSION
1009} // namespace
1010
1011#endif /* _UNIQUE_PTR_H */

/build/llvm-toolchain-snapshot-14~++20220128100846+e1a12767ee62/llvm/include/llvm/TableGen/Record.h

1//===- llvm/TableGen/Record.h - Classes for Table Records -------*- 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 the main TableGen data structures, including the TableGen
10// types, values, and high-level data structures.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TABLEGEN_RECORD_H
15#define LLVM_TABLEGEN_RECORD_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/DenseSet.h"
20#include "llvm/ADT/FoldingSet.h"
21#include "llvm/ADT/PointerIntPair.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/SMLoc.h"
28#include "llvm/Support/Timer.h"
29#include "llvm/Support/TrailingObjects.h"
30#include "llvm/Support/raw_ostream.h"
31#include <algorithm>
32#include <cassert>
33#include <cstddef>
34#include <cstdint>
35#include <map>
36#include <memory>
37#include <string>
38#include <utility>
39#include <vector>
40
41namespace llvm {
42namespace detail {
43struct RecordContext;
44} // namespace detail
45
46class ListRecTy;
47class Record;
48class RecordKeeper;
49class RecordVal;
50class Resolver;
51class StringInit;
52class TypedInit;
53
54//===----------------------------------------------------------------------===//
55// Type Classes
56//===----------------------------------------------------------------------===//
57
58class RecTy {
59public:
60 /// Subclass discriminator (for dyn_cast<> et al.)
61 enum RecTyKind {
62 BitRecTyKind,
63 BitsRecTyKind,
64 IntRecTyKind,
65 StringRecTyKind,
66 ListRecTyKind,
67 DagRecTyKind,
68 RecordRecTyKind
69 };
70
71private:
72 RecTyKind Kind;
73 /// ListRecTy of the list that has elements of this type.
74 ListRecTy *ListTy = nullptr;
75
76public:
77 RecTy(RecTyKind K) : Kind(K) {}
78 virtual ~RecTy() = default;
79
80 RecTyKind getRecTyKind() const { return Kind; }
81
82 virtual std::string getAsString() const = 0;
83 void print(raw_ostream &OS) const { OS << getAsString(); }
84 void dump() const;
85
86 /// Return true if all values of 'this' type can be converted to the specified
87 /// type.
88 virtual bool typeIsConvertibleTo(const RecTy *RHS) const;
89
90 /// Return true if 'this' type is equal to or a subtype of RHS. For example,
91 /// a bit set is not an int, but they are convertible.
92 virtual bool typeIsA(const RecTy *RHS) const;
93
94 /// Returns the type representing list<thistype>.
95 ListRecTy *getListTy();
96};
97
98inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
99 Ty.print(OS);
100 return OS;
101}
102
103/// 'bit' - Represent a single bit
104class BitRecTy : public RecTy {
105 friend detail::RecordContext;
106
107 BitRecTy() : RecTy(BitRecTyKind) {}
108
109public:
110 static bool classof(const RecTy *RT) {
111 return RT->getRecTyKind() == BitRecTyKind;
112 }
113
114 static BitRecTy *get();
115
116 std::string getAsString() const override { return "bit"; }
117
118 bool typeIsConvertibleTo(const RecTy *RHS) const override;
119};
120
121/// 'bits<n>' - Represent a fixed number of bits
122class BitsRecTy : public RecTy {
123 unsigned Size;
124
125 explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {}
126
127public:
128 static bool classof(const RecTy *RT) {
129 return RT->getRecTyKind() == BitsRecTyKind;
130 }
131
132 static BitsRecTy *get(unsigned Sz);
133
134 unsigned getNumBits() const { return Size; }
135
136 std::string getAsString() const override;
137
138 bool typeIsConvertibleTo(const RecTy *RHS) const override;
139
140 bool typeIsA(const RecTy *RHS) const override;
141};
142
143/// 'int' - Represent an integer value of no particular size
144class IntRecTy : public RecTy {
145 friend detail::RecordContext;
146
147 IntRecTy() : RecTy(IntRecTyKind) {}
148
149public:
150 static bool classof(const RecTy *RT) {
151 return RT->getRecTyKind() == IntRecTyKind;
152 }
153
154 static IntRecTy *get();
155
156 std::string getAsString() const override { return "int"; }
157
158 bool typeIsConvertibleTo(const RecTy *RHS) const override;
159};
160
161/// 'string' - Represent an string value
162class StringRecTy : public RecTy {
163 friend detail::RecordContext;
164
165 StringRecTy() : RecTy(StringRecTyKind) {}
166
167public:
168 static bool classof(const RecTy *RT) {
169 return RT->getRecTyKind() == StringRecTyKind;
170 }
171
172 static StringRecTy *get();
173
174 std::string getAsString() const override;
175
176 bool typeIsConvertibleTo(const RecTy *RHS) const override;
177};
178
179/// 'list<Ty>' - Represent a list of element values, all of which must be of
180/// the specified type. The type is stored in ElementTy.
181class ListRecTy : public RecTy {
182 friend ListRecTy *RecTy::getListTy();
183
184 RecTy *ElementTy;
185
186 explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), ElementTy(T) {}
187
188public:
189 static bool classof(const RecTy *RT) {
190 return RT->getRecTyKind() == ListRecTyKind;
191 }
192
193 static ListRecTy *get(RecTy *T) { return T->getListTy(); }
194 RecTy *getElementType() const { return ElementTy; }
195
196 std::string getAsString() const override;
197
198 bool typeIsConvertibleTo(const RecTy *RHS) const override;
199
200 bool typeIsA(const RecTy *RHS) const override;
201};
202
203/// 'dag' - Represent a dag fragment
204class DagRecTy : public RecTy {
205 friend detail::RecordContext;
206
207 DagRecTy() : RecTy(DagRecTyKind) {}
208
209public:
210 static bool classof(const RecTy *RT) {
211 return RT->getRecTyKind() == DagRecTyKind;
212 }
213
214 static DagRecTy *get();
215
216 std::string getAsString() const override;
217};
218
219/// '[classname]' - Type of record values that have zero or more superclasses.
220///
221/// The list of superclasses is non-redundant, i.e. only contains classes that
222/// are not the superclass of some other listed class.
223class RecordRecTy final : public RecTy, public FoldingSetNode,
224 public TrailingObjects<RecordRecTy, Record *> {
225 friend class Record;
226 friend detail::RecordContext;
227
228 unsigned NumClasses;
229
230 explicit RecordRecTy(unsigned Num)
231 : RecTy(RecordRecTyKind), NumClasses(Num) {}
232
233public:
234 RecordRecTy(const RecordRecTy &) = delete;
235 RecordRecTy &operator=(const RecordRecTy &) = delete;
236
237 // Do not use sized deallocation due to trailing objects.
238 void operator delete(void *p) { ::operator delete(p); }
239
240 static bool classof(const RecTy *RT) {
241 return RT->getRecTyKind() == RecordRecTyKind;
242 }
243
244 /// Get the record type with the given non-redundant list of superclasses.
245 static RecordRecTy *get(ArrayRef<Record *> Classes);
246
247 void Profile(FoldingSetNodeID &ID) const;
248
249 ArrayRef<Record *> getClasses() const {
250 return makeArrayRef(getTrailingObjects<Record *>(), NumClasses);
251 }
252
253 using const_record_iterator = Record * const *;
254
255 const_record_iterator classes_begin() const { return getClasses().begin(); }
256 const_record_iterator classes_end() const { return getClasses().end(); }
257
258 std::string getAsString() const override;
259
260 bool isSubClassOf(Record *Class) const;
261 bool typeIsConvertibleTo(const RecTy *RHS) const override;
262
263 bool typeIsA(const RecTy *RHS) const override;
264};
265
266/// Find a common type that T1 and T2 convert to.
267/// Return 0 if no such type exists.
268RecTy *resolveTypes(RecTy *T1, RecTy *T2);
269
270//===----------------------------------------------------------------------===//
271// Initializer Classes
272//===----------------------------------------------------------------------===//
273
274class Init {
275protected:
276 /// Discriminator enum (for isa<>, dyn_cast<>, et al.)
277 ///
278 /// This enum is laid out by a preorder traversal of the inheritance
279 /// hierarchy, and does not contain an entry for abstract classes, as per
280 /// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst.
281 ///
282 /// We also explicitly include "first" and "last" values for each
283 /// interior node of the inheritance tree, to make it easier to read the
284 /// corresponding classof().
285 ///
286 /// We could pack these a bit tighter by not having the IK_FirstXXXInit
287 /// and IK_LastXXXInit be their own values, but that would degrade
288 /// readability for really no benefit.
289 enum InitKind : uint8_t {
290 IK_First, // unused; silence a spurious warning
291 IK_FirstTypedInit,
292 IK_BitInit,
293 IK_BitsInit,
294 IK_DagInit,
295 IK_DefInit,
296 IK_FieldInit,
297 IK_IntInit,
298 IK_ListInit,
299 IK_FirstOpInit,
300 IK_BinOpInit,
301 IK_TernOpInit,
302 IK_UnOpInit,
303 IK_LastOpInit,
304 IK_CondOpInit,
305 IK_FoldOpInit,
306 IK_IsAOpInit,
307 IK_AnonymousNameInit,
308 IK_StringInit,
309 IK_VarInit,
310 IK_VarListElementInit,
311 IK_VarBitInit,
312 IK_VarDefInit,
313 IK_LastTypedInit,
314 IK_UnsetInit
315 };
316
317private:
318 const InitKind Kind;
319
320protected:
321 uint8_t Opc; // Used by UnOpInit, BinOpInit, and TernOpInit
322
323private:
324 virtual void anchor();
325
326public:
327 /// Get the kind (type) of the value.
328 InitKind getKind() const { return Kind; }
329
330protected:
331 explicit Init(InitKind K, uint8_t Opc = 0) : Kind(K), Opc(Opc) {}
332
333public:
334 Init(const Init &) = delete;
335 Init &operator=(const Init &) = delete;
336 virtual ~Init() = default;
337
338 /// Is this a complete value with no unset (uninitialized) subvalues?
339 virtual bool isComplete() const { return true; }
340
341 /// Is this a concrete and fully resolved value without any references or
342 /// stuck operations? Unset values are concrete.
343 virtual bool isConcrete() const { return false; }
344
345 /// Print this value.
346 void print(raw_ostream &OS) const { OS << getAsString(); }
347
348 /// Convert this value to a literal form.
349 virtual std::string getAsString() const = 0;
350
351 /// Convert this value to a literal form,
352 /// without adding quotes around a string.
353 virtual std::string getAsUnquotedString() const { return getAsString(); }
354
355 /// Debugging method that may be called through a debugger; just
356 /// invokes print on stderr.
357 void dump() const;
358
359 /// If this value is convertible to type \p Ty, return a value whose
360 /// type is \p Ty, generating a !cast operation if required.
361 /// Otherwise, return null.
362 virtual Init *getCastTo(RecTy *Ty) const = 0;
363
364 /// Convert to a value whose type is \p Ty, or return null if this
365 /// is not possible. This can happen if the value's type is convertible
366 /// to \p Ty, but there are unresolved references.
367 virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
368
369 /// This function is used to implement the bit range
370 /// selection operator. Given a value, it selects the specified bits,
371 /// returning them as a new \p Init of type \p bits. If it is not legal
372 /// to use the bit selection operator on this value, null is returned.
373 virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
374 return nullptr;
375 }
376
377 /// This function is used to implement the list slice
378 /// selection operator. Given a value, it selects the specified list
379 /// elements, returning them as a new \p Init of type \p list. If it
380 /// is not legal to use the slice operator, null is returned.
381 virtual Init *convertInitListSlice(ArrayRef<unsigned> Elements) const {
382 return nullptr;
383 }
384
385 /// This function is used to implement the FieldInit class.
386 /// Implementors of this method should return the type of the named
387 /// field if they are of type record.
388 virtual RecTy *getFieldType(StringInit *FieldName) const {
389 return nullptr;
390 }
391
392 /// This function is used by classes that refer to other
393 /// variables which may not be defined at the time the expression is formed.
394 /// If a value is set for the variable later, this method will be called on
395 /// users of the value to allow the value to propagate out.
396 virtual Init *resolveReferences(Resolver &R) const {
397 return const_cast<Init *>(this);
398 }
399
400 /// Get the \p Init value of the specified bit.
401 virtual Init *getBit(unsigned Bit) const = 0;
402};
403
404inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
405 I.print(OS); return OS;
406}
407
408/// This is the common superclass of types that have a specific,
409/// explicit type, stored in ValueTy.
410class TypedInit : public Init {
411 RecTy *ValueTy;
412
413protected:
414 explicit TypedInit(InitKind K, RecTy *T, uint8_t Opc = 0)
415 : Init(K, Opc), ValueTy(T) {}
416
417public:
418 TypedInit(const TypedInit &) = delete;
419 TypedInit &operator=(const TypedInit &) = delete;
420
421 static bool classof(const Init *I) {
422 return I->getKind() >= IK_FirstTypedInit &&
423 I->getKind() <= IK_LastTypedInit;
424 }
425
426 /// Get the type of the Init as a RecTy.
427 RecTy *getType() const { return ValueTy; }
428
429 Init *getCastTo(RecTy *Ty) const override;
430 Init *convertInitializerTo(RecTy *Ty) const override;
431
432 Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
433 Init *convertInitListSlice(ArrayRef<unsigned> Elements) const override;
434
435 /// This method is used to implement the FieldInit class.
436 /// Implementors of this method should return the type of the named field if
437 /// they are of type record.
438 RecTy *getFieldType(StringInit *FieldName) const override;
439};
440
441/// '?' - Represents an uninitialized value.
442class UnsetInit : public Init {
443 friend detail::RecordContext;
444
445 UnsetInit() : Init(IK_UnsetInit) {}
446
447public:
448 UnsetInit(const UnsetInit &) = delete;
449 UnsetInit &operator=(const UnsetInit &) = delete;
450
451 static bool classof(const Init *I) {
452 return I->getKind() == IK_UnsetInit;
453 }
454
455 /// Get the singleton unset Init.
456 static UnsetInit *get();
457
458 Init *getCastTo(RecTy *Ty) const override;
459 Init *convertInitializerTo(RecTy *Ty) const override;
460
461 Init *getBit(unsigned Bit) const override {
462 return const_cast<UnsetInit*>(this);
463 }
464
465 /// Is this a complete value with no unset (uninitialized) subvalues?
466 bool isComplete() const override { return false; }
467
468 bool isConcrete() const override { return true; }
469
470 /// Get the string representation of the Init.
471 std::string getAsString() const override { return "?"; }
472};
473
474/// 'true'/'false' - Represent a concrete initializer for a bit.
475class BitInit final : public TypedInit {
476 friend detail::RecordContext;
477
478 bool Value;
479
480 explicit BitInit(bool V, RecTy *T) : TypedInit(IK_BitInit, T), Value(V) {}
481
482public:
483 BitInit(const BitInit &) = delete;
484 BitInit &operator=(BitInit &) = delete;
485
486 static bool classof(const Init *I) {
487 return I->getKind() == IK_BitInit;
488 }
489
490 static BitInit *get(bool V);
491
492 bool getValue() const { return Value; }
493
494 Init *convertInitializerTo(RecTy *Ty) const override;
495
496 Init *getBit(unsigned Bit) const override {
497 assert(Bit < 1 && "Bit index out of range!")(static_cast <bool> (Bit < 1 && "Bit index out of range!"
) ? void (0) : __assert_fail ("Bit < 1 && \"Bit index out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 497, __extension__ __PRETTY_FUNCTION__
))
;
498 return const_cast<BitInit*>(this);
499 }
500
501 bool isConcrete() const override { return true; }
502 std::string getAsString() const override { return Value ? "1" : "0"; }
503};
504
505/// '{ a, b, c }' - Represents an initializer for a BitsRecTy value.
506/// It contains a vector of bits, whose size is determined by the type.
507class BitsInit final : public TypedInit, public FoldingSetNode,
508 public TrailingObjects<BitsInit, Init *> {
509 unsigned NumBits;
510
511 BitsInit(unsigned N)
512 : TypedInit(IK_BitsInit, BitsRecTy::get(N)), NumBits(N) {}
513
514public:
515 BitsInit(const BitsInit &) = delete;
516 BitsInit &operator=(const BitsInit &) = delete;
517
518 // Do not use sized deallocation due to trailing objects.
519 void operator delete(void *p) { ::operator delete(p); }
520
521 static bool classof(const Init *I) {
522 return I->getKind() == IK_BitsInit;
523 }
524
525 static BitsInit *get(ArrayRef<Init *> Range);
526
527 void Profile(FoldingSetNodeID &ID) const;
528
529 unsigned getNumBits() const { return NumBits; }
530
531 Init *convertInitializerTo(RecTy *Ty) const override;
532 Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
533
534 bool isComplete() const override {
535 for (unsigned i = 0; i != getNumBits(); ++i)
536 if (!getBit(i)->isComplete()) return false;
537 return true;
538 }
539
540 bool allInComplete() const {
541 for (unsigned i = 0; i != getNumBits(); ++i)
542 if (getBit(i)->isComplete()) return false;
543 return true;
544 }
545
546 bool isConcrete() const override;
547 std::string getAsString() const override;
548
549 Init *resolveReferences(Resolver &R) const override;
550
551 Init *getBit(unsigned Bit) const override {
552 assert(Bit < NumBits && "Bit index out of range!")(static_cast <bool> (Bit < NumBits && "Bit index out of range!"
) ? void (0) : __assert_fail ("Bit < NumBits && \"Bit index out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 552, __extension__ __PRETTY_FUNCTION__
))
;
553 return getTrailingObjects<Init *>()[Bit];
554 }
555};
556
557/// '7' - Represent an initialization by a literal integer value.
558class IntInit : public TypedInit {
559 int64_t Value;
560
561 explicit IntInit(int64_t V)
562 : TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {}
563
564public:
565 IntInit(const IntInit &) = delete;
566 IntInit &operator=(const IntInit &) = delete;
567
568 static bool classof(const Init *I) {
569 return I->getKind() == IK_IntInit;
570 }
571
572 static IntInit *get(int64_t V);
573
574 int64_t getValue() const { return Value; }
575
576 Init *convertInitializerTo(RecTy *Ty) const override;
577 Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
578
579 bool isConcrete() const override { return true; }
580 std::string getAsString() const override;
581
582 Init *getBit(unsigned Bit) const override {
583 return BitInit::get((Value & (1ULL << Bit)) != 0);
584 }
585};
586
587/// "anonymous_n" - Represent an anonymous record name
588class AnonymousNameInit : public TypedInit {
589 unsigned Value;
590
591 explicit AnonymousNameInit(unsigned V)
592 : TypedInit(IK_AnonymousNameInit, StringRecTy::get()), Value(V) {}
593
594public:
595 AnonymousNameInit(const AnonymousNameInit &) = delete;
596 AnonymousNameInit &operator=(const AnonymousNameInit &) = delete;
597
598 static bool classof(const Init *I) {
599 return I->getKind() == IK_AnonymousNameInit;
600 }
601
602 static AnonymousNameInit *get(unsigned);
603
604 unsigned getValue() const { return Value; }
605
606 StringInit *getNameInit() const;
607
608 std::string getAsString() const override;
609
610 Init *resolveReferences(Resolver &R) const override;
611
612 Init *getBit(unsigned Bit) const override {
613 llvm_unreachable("Illegal bit reference off string")::llvm::llvm_unreachable_internal("Illegal bit reference off string"
, "llvm/include/llvm/TableGen/Record.h", 613)
;
614 }
615};
616
617/// "foo" - Represent an initialization by a string value.
618class StringInit : public TypedInit {
619public:
620 enum StringFormat {
621 SF_String, // Format as "text"
622 SF_Code, // Format as [{text}]
623 };
624
625private:
626 StringRef Value;
627 StringFormat Format;
628
629 explicit StringInit(StringRef V, StringFormat Fmt)
630 : TypedInit(IK_StringInit, StringRecTy::get()), Value(V), Format(Fmt) {}
631
632public:
633 StringInit(const StringInit &) = delete;
634 StringInit &operator=(const StringInit &) = delete;
635
636 static bool classof(const Init *I) {
637 return I->getKind() == IK_StringInit;
638 }
639
640 static StringInit *get(StringRef, StringFormat Fmt = SF_String);
641
642 static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2) {
643 return (Fmt1 == SF_Code || Fmt2 == SF_Code) ? SF_Code : SF_String;
644 }
645
646 StringRef getValue() const { return Value; }
647 StringFormat getFormat() const { return Format; }
648 bool hasCodeFormat() const { return Format == SF_Code; }
649
650 Init *convertInitializerTo(RecTy *Ty) const override;
651
652 bool isConcrete() const override { return true; }
653
654 std::string getAsString() const override {
655 if (Format == SF_String)
656 return "\"" + Value.str() + "\"";
657 else
658 return "[{" + Value.str() + "}]";
659 }
660
661 std::string getAsUnquotedString() const override {
662 return std::string(Value);
663 }
664
665 Init *getBit(unsigned Bit) const override {
666 llvm_unreachable("Illegal bit reference off string")::llvm::llvm_unreachable_internal("Illegal bit reference off string"
, "llvm/include/llvm/TableGen/Record.h", 666)
;
667 }
668};
669
670/// [AL, AH, CL] - Represent a list of defs
671///
672class ListInit final : public TypedInit, public FoldingSetNode,
673 public TrailingObjects<ListInit, Init *> {
674 unsigned NumValues;
675
676public:
677 using const_iterator = Init *const *;
678
679private:
680 explicit ListInit(unsigned N, RecTy *EltTy)
681 : TypedInit(IK_ListInit, ListRecTy::get(EltTy)), NumValues(N) {}
682
683public:
684 ListInit(const ListInit &) = delete;
685 ListInit &operator=(const ListInit &) = delete;
686
687 // Do not use sized deallocation due to trailing objects.
688 void operator delete(void *p) { ::operator delete(p); }
689
690 static bool classof(const Init *I) {
691 return I->getKind() == IK_ListInit;
692 }
693 static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
694
695 void Profile(FoldingSetNodeID &ID) const;
696
697 Init *getElement(unsigned i) const {
698 assert(i < NumValues && "List element index out of range!")(static_cast <bool> (i < NumValues && "List element index out of range!"
) ? void (0) : __assert_fail ("i < NumValues && \"List element index out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 698, __extension__ __PRETTY_FUNCTION__
))
;
699 return getTrailingObjects<Init *>()[i];
700 }
701 RecTy *getElementType() const {
702 return cast<ListRecTy>(getType())->getElementType();
703 }
704
705 Record *getElementAsRecord(unsigned i) const;
706
707 Init *convertInitListSlice(ArrayRef<unsigned> Elements) const override;
708
709 Init *convertInitializerTo(RecTy *Ty) const override;
710
711 /// This method is used by classes that refer to other
712 /// variables which may not be defined at the time they expression is formed.
713 /// If a value is set for the variable later, this method will be called on
714 /// users of the value to allow the value to propagate out.
715 ///
716 Init *resolveReferences(Resolver &R) const override;
717
718 bool isComplete() const override;
719 bool isConcrete() const override;
720 std::string getAsString() const override;
721
722 ArrayRef<Init*> getValues() const {
723 return makeArrayRef(getTrailingObjects<Init *>(), NumValues);
724 }
725
726 const_iterator begin() const { return getTrailingObjects<Init *>(); }
727 const_iterator end () const { return begin() + NumValues; }
728
729 size_t size () const { return NumValues; }
730 bool empty() const { return NumValues == 0; }
731
732 Init *getBit(unsigned Bit) const override {
733 llvm_unreachable("Illegal bit reference off list")::llvm::llvm_unreachable_internal("Illegal bit reference off list"
, "llvm/include/llvm/TableGen/Record.h", 733)
;
734 }
735};
736
737/// Base class for operators
738///
739class OpInit : public TypedInit {
740protected:
741 explicit OpInit(InitKind K, RecTy *Type, uint8_t Opc)
742 : TypedInit(K, Type, Opc) {}
743
744public:
745 OpInit(const OpInit &) = delete;
746 OpInit &operator=(OpInit &) = delete;
747
748 static bool classof(const Init *I) {
749 return I->getKind() >= IK_FirstOpInit &&
750 I->getKind() <= IK_LastOpInit;
751 }
752
753 // Clone - Clone this operator, replacing arguments with the new list
754 virtual OpInit *clone(ArrayRef<Init *> Operands) const = 0;
755
756 virtual unsigned getNumOperands() const = 0;
757 virtual Init *getOperand(unsigned i) const = 0;
758
759 Init *getBit(unsigned Bit) const override;
760};
761
762/// !op (X) - Transform an init.
763///
764class UnOpInit : public OpInit, public FoldingSetNode {
765public:
766 enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP };
767
768private:
769 Init *LHS;
770
771 UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
772 : OpInit(IK_UnOpInit, Type, opc), LHS(lhs) {}
773
774public:
775 UnOpInit(const UnOpInit &) = delete;
776 UnOpInit &operator=(const UnOpInit &) = delete;
777
778 static bool classof(const Init *I) {
779 return I->getKind() == IK_UnOpInit;
780 }
781
782 static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
783
784 void Profile(FoldingSetNodeID &ID) const;
785
786 // Clone - Clone this operator, replacing arguments with the new list
787 OpInit *clone(ArrayRef<Init *> Operands) const override {
788 assert(Operands.size() == 1 &&(static_cast <bool> (Operands.size() == 1 && "Wrong number of operands for unary operation"
) ? void (0) : __assert_fail ("Operands.size() == 1 && \"Wrong number of operands for unary operation\""
, "llvm/include/llvm/TableGen/Record.h", 789, __extension__ __PRETTY_FUNCTION__
))
789 "Wrong number of operands for unary operation")(static_cast <bool> (Operands.size() == 1 && "Wrong number of operands for unary operation"
) ? void (0) : __assert_fail ("Operands.size() == 1 && \"Wrong number of operands for unary operation\""
, "llvm/include/llvm/TableGen/Record.h", 789, __extension__ __PRETTY_FUNCTION__
))
;
790 return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
791 }
792
793 unsigned getNumOperands() const override { return 1; }
794
795 Init *getOperand(unsigned i) const override {
796 assert(i == 0 && "Invalid operand id for unary operator")(static_cast <bool> (i == 0 && "Invalid operand id for unary operator"
) ? void (0) : __assert_fail ("i == 0 && \"Invalid operand id for unary operator\""
, "llvm/include/llvm/TableGen/Record.h", 796, __extension__ __PRETTY_FUNCTION__
))
;
797 return getOperand();
798 }
799
800 UnaryOp getOpcode() const { return (UnaryOp)Opc; }
801 Init *getOperand() const { return LHS; }
802
803 // Fold - If possible, fold this to a simpler init. Return this if not
804 // possible to fold.
805 Init *Fold(Record *CurRec, bool IsFinal = false) const;
806
807 Init *resolveReferences(Resolver &R) const override;
808
809 std::string getAsString() const override;
810};
811
812/// !op (X, Y) - Combine two inits.
813class BinOpInit : public OpInit, public FoldingSetNode {
814public:
815 enum BinaryOp : uint8_t { ADD, SUB, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
816 LISTSPLAT, STRCONCAT, INTERLEAVE, CONCAT, EQ,
817 NE, LE, LT, GE, GT, SETDAGOP };
818
819private:
820 Init *LHS, *RHS;
821
822 BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
823 OpInit(IK_BinOpInit, Type, opc), LHS(lhs), RHS(rhs) {}
824
825public:
826 BinOpInit(const BinOpInit &) = delete;
827 BinOpInit &operator=(const BinOpInit &) = delete;
828
829 static bool classof(const Init *I) {
830 return I->getKind() == IK_BinOpInit;
831 }
832
833 static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
834 RecTy *Type);
835 static Init *getStrConcat(Init *lhs, Init *rhs);
836 static Init *getListConcat(TypedInit *lhs, Init *rhs);
837
838 void Profile(FoldingSetNodeID &ID) const;
839
840 // Clone - Clone this operator, replacing arguments with the new list
841 OpInit *clone(ArrayRef<Init *> Operands) const override {
842 assert(Operands.size() == 2 &&(static_cast <bool> (Operands.size() == 2 && "Wrong number of operands for binary operation"
) ? void (0) : __assert_fail ("Operands.size() == 2 && \"Wrong number of operands for binary operation\""
, "llvm/include/llvm/TableGen/Record.h", 843, __extension__ __PRETTY_FUNCTION__
))
843 "Wrong number of operands for binary operation")(static_cast <bool> (Operands.size() == 2 && "Wrong number of operands for binary operation"
) ? void (0) : __assert_fail ("Operands.size() == 2 && \"Wrong number of operands for binary operation\""
, "llvm/include/llvm/TableGen/Record.h", 843, __extension__ __PRETTY_FUNCTION__
))
;
844 return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
845 }
846
847 unsigned getNumOperands() const override { return 2; }
848 Init *getOperand(unsigned i) const override {
849 switch (i) {
850 default: llvm_unreachable("Invalid operand id for binary operator")::llvm::llvm_unreachable_internal("Invalid operand id for binary operator"
, "llvm/include/llvm/TableGen/Record.h", 850)
;
851 case 0: return getLHS();
852 case 1: return getRHS();
853 }
854 }
855
856 BinaryOp getOpcode() const { return (BinaryOp)Opc; }
857 Init *getLHS() const { return LHS; }
858 Init *getRHS() const { return RHS; }
859
860 // Fold - If possible, fold this to a simpler init. Return this if not
861 // possible to fold.
862 Init *Fold(Record *CurRec) const;
863
864 Init *resolveReferences(Resolver &R) const override;
865
866 std::string getAsString() const override;
867};
868
869/// !op (X, Y, Z) - Combine two inits.
870class TernOpInit : public OpInit, public FoldingSetNode {
871public:
872 enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG, SUBSTR, FIND };
873
874private:
875 Init *LHS, *MHS, *RHS;
876
877 TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
878 RecTy *Type) :
879 OpInit(IK_TernOpInit, Type, opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
880
881public:
882 TernOpInit(const TernOpInit &) = delete;
883 TernOpInit &operator=(const TernOpInit &) = delete;
884
885 static bool classof(const Init *I) {
886 return I->getKind() == IK_TernOpInit;
887 }
888
889 static TernOpInit *get(TernaryOp opc, Init *lhs,
890 Init *mhs, Init *rhs,
891 RecTy *Type);
892
893 void Profile(FoldingSetNodeID &ID) const;
894
895 // Clone - Clone this operator, replacing arguments with the new list
896 OpInit *clone(ArrayRef<Init *> Operands) const override {
897 assert(Operands.size() == 3 &&(static_cast <bool> (Operands.size() == 3 && "Wrong number of operands for ternary operation"
) ? void (0) : __assert_fail ("Operands.size() == 3 && \"Wrong number of operands for ternary operation\""
, "llvm/include/llvm/TableGen/Record.h", 898, __extension__ __PRETTY_FUNCTION__
))
898 "Wrong number of operands for ternary operation")(static_cast <bool> (Operands.size() == 3 && "Wrong number of operands for ternary operation"
) ? void (0) : __assert_fail ("Operands.size() == 3 && \"Wrong number of operands for ternary operation\""
, "llvm/include/llvm/TableGen/Record.h", 898, __extension__ __PRETTY_FUNCTION__
))
;
899 return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
900 getType());
901 }
902
903 unsigned getNumOperands() const override { return 3; }
904 Init *getOperand(unsigned i) const override {
905 switch (i) {
906 default: llvm_unreachable("Invalid operand id for ternary operator")::llvm::llvm_unreachable_internal("Invalid operand id for ternary operator"
, "llvm/include/llvm/TableGen/Record.h", 906)
;
907 case 0: return getLHS();
908 case 1: return getMHS();
909 case 2: return getRHS();
910 }
911 }
912
913 TernaryOp getOpcode() const { return (TernaryOp)Opc; }
914 Init *getLHS() const { return LHS; }
915 Init *getMHS() const { return MHS; }
916 Init *getRHS() const { return RHS; }
917
918 // Fold - If possible, fold this to a simpler init. Return this if not
919 // possible to fold.
920 Init *Fold(Record *CurRec) const;
921
922 bool isComplete() const override {
923 return LHS->isComplete() && MHS->isComplete() && RHS->isComplete();
924 }
925
926 Init *resolveReferences(Resolver &R) const override;
927
928 std::string getAsString() const override;
929};
930
931/// !cond(condition_1: value1, ... , condition_n: value)
932/// Selects the first value for which condition is true.
933/// Otherwise reports an error.
934class CondOpInit final : public TypedInit, public FoldingSetNode,
935 public TrailingObjects<CondOpInit, Init *> {
936 unsigned NumConds;
937 RecTy *ValType;
938
939 CondOpInit(unsigned NC, RecTy *Type)
940 : TypedInit(IK_CondOpInit, Type),
941 NumConds(NC), ValType(Type) {}
942
943 size_t numTrailingObjects(OverloadToken<Init *>) const {
944 return 2*NumConds;
945 }
946
947public:
948 CondOpInit(const CondOpInit &) = delete;
949 CondOpInit &operator=(const CondOpInit &) = delete;
950
951 static bool classof(const Init *I) {
952 return I->getKind() == IK_CondOpInit;
953 }
954
955 static CondOpInit *get(ArrayRef<Init*> C, ArrayRef<Init*> V,
956 RecTy *Type);
957
958 void Profile(FoldingSetNodeID &ID) const;
959
960 RecTy *getValType() const { return ValType; }
961
962 unsigned getNumConds() const { return NumConds; }
963
964 Init *getCond(unsigned Num) const {
965 assert(Num < NumConds && "Condition number out of range!")(static_cast <bool> (Num < NumConds && "Condition number out of range!"
) ? void (0) : __assert_fail ("Num < NumConds && \"Condition number out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 965, __extension__ __PRETTY_FUNCTION__
))
;
966 return getTrailingObjects<Init *>()[Num];
967 }
968
969 Init *getVal(unsigned Num) const {
970 assert(Num < NumConds && "Val number out of range!")(static_cast <bool> (Num < NumConds && "Val number out of range!"
) ? void (0) : __assert_fail ("Num < NumConds && \"Val number out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 970, __extension__ __PRETTY_FUNCTION__
))
;
971 return getTrailingObjects<Init *>()[Num+NumConds];
972 }
973
974 ArrayRef<Init *> getConds() const {
975 return makeArrayRef(getTrailingObjects<Init *>(), NumConds);
976 }
977
978 ArrayRef<Init *> getVals() const {
979 return makeArrayRef(getTrailingObjects<Init *>()+NumConds, NumConds);
980 }
981
982 Init *Fold(Record *CurRec) const;
983
984 Init *resolveReferences(Resolver &R) const override;
985
986 bool isConcrete() const override;
987 bool isComplete() const override;
988 std::string getAsString() const override;
989
990 using const_case_iterator = SmallVectorImpl<Init*>::const_iterator;
991 using const_val_iterator = SmallVectorImpl<Init*>::const_iterator;
992
993 inline const_case_iterator arg_begin() const { return getConds().begin(); }
994 inline const_case_iterator arg_end () const { return getConds().end(); }
995
996 inline size_t case_size () const { return NumConds; }
997 inline bool case_empty() const { return NumConds == 0; }
998
999 inline const_val_iterator name_begin() const { return getVals().begin();}
1000 inline const_val_iterator name_end () const { return getVals().end(); }
1001
1002 inline size_t val_size () const { return NumConds; }
1003 inline bool val_empty() const { return NumConds == 0; }
1004
1005 Init *getBit(unsigned Bit) const override;
1006};
1007
1008/// !foldl (a, b, expr, start, lst) - Fold over a list.
1009class FoldOpInit : public TypedInit, public FoldingSetNode {
1010private:
1011 Init *Start;
1012 Init *List;
1013 Init *A;
1014 Init *B;
1015 Init *Expr;
1016
1017 FoldOpInit(Init *Start, Init *List, Init *A, Init *B, Init *Expr, RecTy *Type)
1018 : TypedInit(IK_FoldOpInit, Type), Start(Start), List(List), A(A), B(B),
1019 Expr(Expr) {}
1020
1021public:
1022 FoldOpInit(const FoldOpInit &) = delete;
1023 FoldOpInit &operator=(const FoldOpInit &) = delete;
1024
1025 static bool classof(const Init *I) { return I->getKind() == IK_FoldOpInit; }
1026
1027 static FoldOpInit *get(Init *Start, Init *List, Init *A, Init *B, Init *Expr,
1028 RecTy *Type);
1029
1030 void Profile(FoldingSetNodeID &ID) const;
1031
1032 // Fold - If possible, fold this to a simpler init. Return this if not
1033 // possible to fold.
1034 Init *Fold(Record *CurRec) const;
1035
1036 bool isComplete() const override { return false; }
1037
1038 Init *resolveReferences(Resolver &R) const override;
1039
1040 Init *getBit(unsigned Bit) const override;
1041
1042 std::string getAsString() const override;
1043};
1044
1045/// !isa<type>(expr) - Dynamically determine the type of an expression.
1046class IsAOpInit : public TypedInit, public FoldingSetNode {
1047private:
1048 RecTy *CheckType;
1049 Init *Expr;
1050
1051 IsAOpInit(RecTy *CheckType, Init *Expr)
1052 : TypedInit(IK_IsAOpInit, IntRecTy::get()), CheckType(CheckType),
1053 Expr(Expr) {}
1054
1055public:
1056 IsAOpInit(const IsAOpInit &) = delete;
1057 IsAOpInit &operator=(const IsAOpInit &) = delete;
1058
1059 static bool classof(const Init *I) { return I->getKind() == IK_IsAOpInit; }
1060
1061 static IsAOpInit *get(RecTy *CheckType, Init *Expr);
1062
1063 void Profile(FoldingSetNodeID &ID) const;
1064
1065 // Fold - If possible, fold this to a simpler init. Return this if not
1066 // possible to fold.
1067 Init *Fold() const;
1068
1069 bool isComplete() const override { return false; }
1070
1071 Init *resolveReferences(Resolver &R) const override;
1072
1073 Init *getBit(unsigned Bit) const override;
1074
1075 std::string getAsString() const override;
1076};
1077
1078/// 'Opcode' - Represent a reference to an entire variable object.
1079class VarInit : public TypedInit {
1080 Init *VarName;
1081
1082 explicit VarInit(Init *VN, RecTy *T)
1083 : TypedInit(IK_VarInit, T), VarName(VN) {}
1084
1085public:
1086 VarInit(const VarInit &) = delete;
1087 VarInit &operator=(const VarInit &) = delete;
1088
1089 static bool classof(const Init *I) {
1090 return I->getKind() == IK_VarInit;
1091 }
1092
1093 static VarInit *get(StringRef VN, RecTy *T);
1094 static VarInit *get(Init *VN, RecTy *T);
1095
1096 StringRef getName() const;
1097 Init *getNameInit() const { return VarName; }
1098
1099 std::string getNameInitAsString() const {
1100 return getNameInit()->getAsUnquotedString();
1101 }
1102
1103 /// This method is used by classes that refer to other
1104 /// variables which may not be defined at the time they expression is formed.
1105 /// If a value is set for the variable later, this method will be called on
1106 /// users of the value to allow the value to propagate out.
1107 ///
1108 Init *resolveReferences(Resolver &R) const override;
1109
1110 Init *getBit(unsigned Bit) const override;
1111
1112 std::string getAsString() const override { return std::string(getName()); }
1113};
1114
1115/// Opcode{0} - Represent access to one bit of a variable or field.
1116class VarBitInit final : public TypedInit {
1117 TypedInit *TI;
1118 unsigned Bit;
1119
1120 VarBitInit(TypedInit *T, unsigned B)
1121 : TypedInit(IK_VarBitInit, BitRecTy::get()), TI(T), Bit(B) {
1122 assert(T->getType() &&(static_cast <bool> (T->getType() && (isa<
IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->
getType()) && cast<BitsRecTy>(T->getType())->
getNumBits() > B)) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && (isa<IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->getType()) && cast<BitsRecTy>(T->getType())->getNumBits() > B)) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1126, __extension__ __PRETTY_FUNCTION__
))
1123 (isa<IntRecTy>(T->getType()) ||(static_cast <bool> (T->getType() && (isa<
IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->
getType()) && cast<BitsRecTy>(T->getType())->
getNumBits() > B)) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && (isa<IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->getType()) && cast<BitsRecTy>(T->getType())->getNumBits() > B)) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1126, __extension__ __PRETTY_FUNCTION__
))
1124 (isa<BitsRecTy>(T->getType()) &&(static_cast <bool> (T->getType() && (isa<
IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->
getType()) && cast<BitsRecTy>(T->getType())->
getNumBits() > B)) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && (isa<IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->getType()) && cast<BitsRecTy>(T->getType())->getNumBits() > B)) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1126, __extension__ __PRETTY_FUNCTION__
))
1125 cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&(static_cast <bool> (T->getType() && (isa<
IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->
getType()) && cast<BitsRecTy>(T->getType())->
getNumBits() > B)) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && (isa<IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->getType()) && cast<BitsRecTy>(T->getType())->getNumBits() > B)) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1126, __extension__ __PRETTY_FUNCTION__
))
1126 "Illegal VarBitInit expression!")(static_cast <bool> (T->getType() && (isa<
IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->
getType()) && cast<BitsRecTy>(T->getType())->
getNumBits() > B)) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && (isa<IntRecTy>(T->getType()) || (isa<BitsRecTy>(T->getType()) && cast<BitsRecTy>(T->getType())->getNumBits() > B)) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1126, __extension__ __PRETTY_FUNCTION__
))
;
1127 }
1128
1129public:
1130 VarBitInit(const VarBitInit &) = delete;
1131 VarBitInit &operator=(const VarBitInit &) = delete;
1132
1133 static bool classof(const Init *I) {
1134 return I->getKind() == IK_VarBitInit;
1135 }
1136
1137 static VarBitInit *get(TypedInit *T, unsigned B);
1138
1139 Init *getBitVar() const { return TI; }
1140 unsigned getBitNum() const { return Bit; }
1141
1142 std::string getAsString() const override;
1143 Init *resolveReferences(Resolver &R) const override;
1144
1145 Init *getBit(unsigned B) const override {
1146 assert(B < 1 && "Bit index out of range!")(static_cast <bool> (B < 1 && "Bit index out of range!"
) ? void (0) : __assert_fail ("B < 1 && \"Bit index out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 1146, __extension__ __PRETTY_FUNCTION__
))
;
1147 return const_cast<VarBitInit*>(this);
1148 }
1149};
1150
1151/// List[4] - Represent access to one element of a var or
1152/// field.
1153class VarListElementInit : public TypedInit {
1154 TypedInit *TI;
1155 unsigned Element;
1156
1157 VarListElementInit(TypedInit *T, unsigned E)
1158 : TypedInit(IK_VarListElementInit,
1159 cast<ListRecTy>(T->getType())->getElementType()),
1160 TI(T), Element(E) {
1161 assert(T->getType() && isa<ListRecTy>(T->getType()) &&(static_cast <bool> (T->getType() && isa<
ListRecTy>(T->getType()) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && isa<ListRecTy>(T->getType()) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1162, __extension__ __PRETTY_FUNCTION__
))
1162 "Illegal VarBitInit expression!")(static_cast <bool> (T->getType() && isa<
ListRecTy>(T->getType()) && "Illegal VarBitInit expression!"
) ? void (0) : __assert_fail ("T->getType() && isa<ListRecTy>(T->getType()) && \"Illegal VarBitInit expression!\""
, "llvm/include/llvm/TableGen/Record.h", 1162, __extension__ __PRETTY_FUNCTION__
))
;
1163 }
1164
1165public:
1166 VarListElementInit(const VarListElementInit &) = delete;
1167 VarListElementInit &operator=(const VarListElementInit &) = delete;
1168
1169 static bool classof(const Init *I) {
1170 return I->getKind() == IK_VarListElementInit;
1171 }
1172
1173 static VarListElementInit *get(TypedInit *T, unsigned E);
1174
1175 TypedInit *getVariable() const { return TI; }
1176 unsigned getElementNum() const { return Element; }
1177
1178 std::string getAsString() const override;
1179 Init *resolveReferences(Resolver &R) const override;
1180
1181 Init *getBit(unsigned Bit) const override;
1182};
1183
1184/// AL - Represent a reference to a 'def' in the description
1185class DefInit : public TypedInit {
1186 friend class Record;
1187
1188 Record *Def;
1189
1190 explicit DefInit(Record *D);
1191
1192public:
1193 DefInit(const DefInit &) = delete;
1194 DefInit &operator=(const DefInit &) = delete;
1195
1196 static bool classof(const Init *I) {
1197 return I->getKind() == IK_DefInit;
1198 }
1199
1200 static DefInit *get(Record*);
1201
1202 Init *convertInitializerTo(RecTy *Ty) const override;
1203
1204 Record *getDef() const { return Def; }
1205
1206 //virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits);
1207
1208 RecTy *getFieldType(StringInit *FieldName) const override;
1209
1210 bool isConcrete() const override { return true; }
1211 std::string getAsString() const override;
1212
1213 Init *getBit(unsigned Bit) const override {
1214 llvm_unreachable("Illegal bit reference off def")::llvm::llvm_unreachable_internal("Illegal bit reference off def"
, "llvm/include/llvm/TableGen/Record.h", 1214)
;
1215 }
1216};
1217
1218/// classname<targs...> - Represent an uninstantiated anonymous class
1219/// instantiation.
1220class VarDefInit final : public TypedInit, public FoldingSetNode,
1221 public TrailingObjects<VarDefInit, Init *> {
1222 Record *Class;
1223 DefInit *Def = nullptr; // after instantiation
1224 unsigned NumArgs;
1225
1226 explicit VarDefInit(Record *Class, unsigned N)
1227 : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Class(Class), NumArgs(N) {}
1228
1229 DefInit *instantiate();
1230
1231public:
1232 VarDefInit(const VarDefInit &) = delete;
1233 VarDefInit &operator=(const VarDefInit &) = delete;
1234
1235 // Do not use sized deallocation due to trailing objects.
1236 void operator delete(void *p) { ::operator delete(p); }
1237
1238 static bool classof(const Init *I) {
1239 return I->getKind() == IK_VarDefInit;
1240 }
1241 static VarDefInit *get(Record *Class, ArrayRef<Init *> Args);
1242
1243 void Profile(FoldingSetNodeID &ID) const;
1244
1245 Init *resolveReferences(Resolver &R) const override;
1246 Init *Fold() const;
1247
1248 std::string getAsString() const override;
1249
1250 Init *getArg(unsigned i) const {
1251 assert(i < NumArgs && "Argument index out of range!")(static_cast <bool> (i < NumArgs && "Argument index out of range!"
) ? void (0) : __assert_fail ("i < NumArgs && \"Argument index out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 1251, __extension__ __PRETTY_FUNCTION__
))
;
1252 return getTrailingObjects<Init *>()[i];
1253 }
1254
1255 using const_iterator = Init *const *;
1256
1257 const_iterator args_begin() const { return getTrailingObjects<Init *>(); }
1258 const_iterator args_end () const { return args_begin() + NumArgs; }
1259
1260 size_t args_size () const { return NumArgs; }
1261 bool args_empty() const { return NumArgs == 0; }
1262
1263 ArrayRef<Init *> args() const { return makeArrayRef(args_begin(), NumArgs); }
1264
1265 Init *getBit(unsigned Bit) const override {
1266 llvm_unreachable("Illegal bit reference off anonymous def")::llvm::llvm_unreachable_internal("Illegal bit reference off anonymous def"
, "llvm/include/llvm/TableGen/Record.h", 1266)
;
1267 }
1268};
1269
1270/// X.Y - Represent a reference to a subfield of a variable
1271class FieldInit : public TypedInit {
1272 Init *Rec; // Record we are referring to
1273 StringInit *FieldName; // Field we are accessing
1274
1275 FieldInit(Init *R, StringInit *FN)
1276 : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
1277#ifndef NDEBUG
1278 if (!getType()) {
1279 llvm::errs() << "In Record = " << Rec->getAsString()
1280 << ", got FieldName = " << *FieldName
1281 << " with non-record type!\n";
1282 llvm_unreachable("FieldInit with non-record type!")::llvm::llvm_unreachable_internal("FieldInit with non-record type!"
, "llvm/include/llvm/TableGen/Record.h", 1282)
;
1283 }
1284#endif
1285 }
1286
1287public:
1288 FieldInit(const FieldInit &) = delete;
1289 FieldInit &operator=(const FieldInit &) = delete;
1290
1291 static bool classof(const Init *I) {
1292 return I->getKind() == IK_FieldInit;
1293 }
1294
1295 static FieldInit *get(Init *R, StringInit *FN);
1296
1297 Init *getRecord() const { return Rec; }
1298 StringInit *getFieldName() const { return FieldName; }
1299
1300 Init *getBit(unsigned Bit) const override;
1301
1302 Init *resolveReferences(Resolver &R) const override;
1303 Init *Fold(Record *CurRec) const;
1304
1305 bool isConcrete() const override;
1306 std::string getAsString() const override {
1307 return Rec->getAsString() + "." + FieldName->getValue().str();
1308 }
1309};
1310
1311/// (v a, b) - Represent a DAG tree value. DAG inits are required
1312/// to have at least one value then a (possibly empty) list of arguments. Each
1313/// argument can have a name associated with it.
1314class DagInit final : public TypedInit, public FoldingSetNode,
1315 public TrailingObjects<DagInit, Init *, StringInit *> {
1316 friend TrailingObjects;
1317
1318 Init *Val;
1319 StringInit *ValName;
1320 unsigned NumArgs;
1321 unsigned NumArgNames;
1322
1323 DagInit(Init *V, StringInit *VN, unsigned NumArgs, unsigned NumArgNames)
1324 : TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
1325 NumArgs(NumArgs), NumArgNames(NumArgNames) {}
1326
1327 size_t numTrailingObjects(OverloadToken<Init *>) const { return NumArgs; }
1328
1329public:
1330 DagInit(const DagInit &) = delete;
1331 DagInit &operator=(const DagInit &) = delete;
1332
1333 static bool classof(const Init *I) {
1334 return I->getKind() == IK_DagInit;
1335 }
1336
1337 static DagInit *get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
1338 ArrayRef<StringInit*> NameRange);
1339 static DagInit *get(Init *V, StringInit *VN,
1340 ArrayRef<std::pair<Init*, StringInit*>> Args);
1341
1342 void Profile(FoldingSetNodeID &ID) const;
1343
1344 Init *getOperator() const { return Val; }
1345 Record *getOperatorAsDef(ArrayRef<SMLoc> Loc) const;
1346
1347 StringInit *getName() const { return ValName; }
1348
1349 StringRef getNameStr() const {
1350 return ValName ? ValName->getValue() : StringRef();
1351 }
1352
1353 unsigned getNumArgs() const { return NumArgs; }
1354
1355 Init *getArg(unsigned Num) const {
1356 assert(Num < NumArgs && "Arg number out of range!")(static_cast <bool> (Num < NumArgs && "Arg number out of range!"
) ? void (0) : __assert_fail ("Num < NumArgs && \"Arg number out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 1356, __extension__ __PRETTY_FUNCTION__
))
;
1357 return getTrailingObjects<Init *>()[Num];
1358 }
1359
1360 StringInit *getArgName(unsigned Num) const {
1361 assert(Num < NumArgNames && "Arg number out of range!")(static_cast <bool> (Num < NumArgNames && "Arg number out of range!"
) ? void (0) : __assert_fail ("Num < NumArgNames && \"Arg number out of range!\""
, "llvm/include/llvm/TableGen/Record.h", 1361, __extension__ __PRETTY_FUNCTION__
))
;
1362 return getTrailingObjects<StringInit *>()[Num];
1363 }
1364
1365 StringRef getArgNameStr(unsigned Num) const {
1366 StringInit *Init = getArgName(Num);
1367 return Init ? Init->getValue() : StringRef();
1368 }
1369
1370 ArrayRef<Init *> getArgs() const {
1371 return makeArrayRef(getTrailingObjects<Init *>(), NumArgs);
1372 }
1373
1374 ArrayRef<StringInit *> getArgNames() const {
1375 return makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames);
1376 }
1377
1378 Init *resolveReferences(Resolver &R) const override;
1379
1380 bool isConcrete() const override;
1381 std::string getAsString() const override;
1382
1383 using const_arg_iterator = SmallVectorImpl<Init*>::const_iterator;
1384 using const_name_iterator = SmallVectorImpl<StringInit*>::const_iterator;
1385
1386 inline const_arg_iterator arg_begin() const { return getArgs().begin(); }
1387 inline const_arg_iterator arg_end () const { return getArgs().end(); }
1388
1389 inline size_t arg_size () const { return NumArgs; }
1390 inline bool arg_empty() const { return NumArgs == 0; }
1391
1392 inline const_name_iterator name_begin() const { return getArgNames().begin();}
1393 inline const_name_iterator name_end () const { return getArgNames().end(); }
1394
1395 inline size_t name_size () const { return NumArgNames; }
1396 inline bool name_empty() const { return NumArgNames == 0; }
1397
1398 Init *getBit(unsigned Bit) const override {
1399 llvm_unreachable("Illegal bit reference off dag")::llvm::llvm_unreachable_internal("Illegal bit reference off dag"
, "llvm/include/llvm/TableGen/Record.h", 1399)
;
1400 }
1401};
1402
1403//===----------------------------------------------------------------------===//
1404// High-Level Classes
1405//===----------------------------------------------------------------------===//
1406
1407/// This class represents a field in a record, including its name, type,
1408/// value, and source location.
1409class RecordVal {
1410 friend class Record;
1411
1412public:
1413 enum FieldKind {
1414 FK_Normal, // A normal record field.
1415 FK_NonconcreteOK, // A field that can be nonconcrete ('field' keyword).
1416 FK_TemplateArg, // A template argument.
1417 };
1418
1419private:
1420 Init *Name;
1421 SMLoc Loc; // Source location of definition of name.
1422 PointerIntPair<RecTy *, 2, FieldKind> TyAndKind;
1423 Init *Value;
1424 bool IsUsed = false;
1425
1426public:
1427 RecordVal(Init *N, RecTy *T, FieldKind K);
1428 RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K);
1429
1430 /// Get the name of the field as a StringRef.
1431 StringRef getName() const;
1432
1433 /// Get the name of the field as an Init.
1434 Init *getNameInit() const { return Name; }
1435
1436 /// Get the name of the field as a std::string.
1437 std::string getNameInitAsString() const {
1438 return getNameInit()->getAsUnquotedString();
1439 }
1440
1441 /// Get the source location of the point where the field was defined.
1442 const SMLoc &getLoc() const { return Loc; }
1443
1444 /// Is this a field where nonconcrete values are okay?
1445 bool isNonconcreteOK() const {
1446 return TyAndKind.getInt() == FK_NonconcreteOK;
1447 }
1448
1449 /// Is this a template argument?
1450 bool isTemplateArg() const {
1451 return TyAndKind.getInt() == FK_TemplateArg;
1452 }
1453
1454 /// Get the type of the field value as a RecTy.
1455 RecTy *getType() const { return TyAndKind.getPointer(); }
1456
1457 /// Get the type of the field for printing purposes.
1458 std::string getPrintType() const;
1459
1460 /// Get the value of the field as an Init.
1461 Init *getValue() const { return Value; }
1462
1463 /// Set the value of the field from an Init.
1464 bool setValue(Init *V);
1465
1466 /// Set the value and source location of the field.
1467 bool setValue(Init *V, SMLoc NewLoc);
1468
1469 /// Whether this value is used. Useful for reporting warnings, for example
1470 /// when a template argument is unused.
1471 void setUsed(bool Used) { IsUsed = Used; }
1472 bool isUsed() const { return IsUsed; }
1473
1474 void dump() const;
1475
1476 /// Print the value to an output stream, possibly with a semicolon.
1477 void print(raw_ostream &OS, bool PrintSem = true) const;
1478};
1479
1480inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
1481 RV.print(OS << " ");
1482 return OS;
1483}
1484
1485class Record {
1486public:
1487 struct AssertionInfo {
1488 SMLoc Loc;
1489 Init *Condition;
1490 Init *Message;
1491
1492 // User-defined constructor to support std::make_unique(). It can be
1493 // removed in C++20 when braced initialization is supported.
1494 AssertionInfo(SMLoc Loc, Init *Condition, Init *Message)
1495 : Loc(Loc), Condition(Condition), Message(Message) {}
1496 };
1497
1498private:
1499 Init *Name;
1500 // Location where record was instantiated, followed by the location of
1501 // multiclass prototypes used.
1502 SmallVector<SMLoc, 4> Locs;
1503 SmallVector<Init *, 0> TemplateArgs;
1504 SmallVector<RecordVal, 0> Values;
1505 SmallVector<AssertionInfo, 0> Assertions;
1506
1507 // All superclasses in the inheritance forest in post-order (yes, it
1508 // must be a forest; diamond-shaped inheritance is not allowed).
1509 SmallVector<std::pair<Record *, SMRange>, 0> SuperClasses;
1510
1511 // Tracks Record instances. Not owned by Record.
1512 RecordKeeper &TrackedRecords;
1513
1514 // The DefInit corresponding to this record.
1515 DefInit *CorrespondingDefInit = nullptr;
1516
1517 // Unique record ID.
1518 unsigned ID;
1519
1520 bool IsAnonymous;
1521 bool IsClass;
1522
1523 void checkName();
1524
1525public:
1526 // Constructs a record.
1527 explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
1528 bool Anonymous = false, bool Class = false)
1529 : Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records),
1530 ID(getNewUID()), IsAnonymous(Anonymous), IsClass(Class) {
1531 checkName();
1532 }
1533
1534 explicit Record(StringRef N, ArrayRef<SMLoc> locs, RecordKeeper &records,
1535 bool Class = false)
1536 : Record(StringInit::get(N), locs, records, false, Class) {}
1537
1538 // When copy-constructing a Record, we must still guarantee a globally unique
1539 // ID number. Don't copy CorrespondingDefInit either, since it's owned by the
1540 // original record. All other fields can be copied normally.
1541 Record(const Record &O)
1542 : Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
1543 Values(O.Values), Assertions(O.Assertions),
1544 SuperClasses(O.SuperClasses), TrackedRecords(O.TrackedRecords),
1545 ID(getNewUID()), IsAnonymous(O.IsAnonymous), IsClass(O.IsClass) {}
1546
1547 static unsigned getNewUID();
1548
1549 unsigned getID() const { return ID; }
1550
1551 StringRef getName() const { return cast<StringInit>(Name)->getValue(); }
1552
1553 Init *getNameInit() const {
1554 return Name;
1555 }
1556
1557 const std::string getNameInitAsString() const {
1558 return getNameInit()->getAsUnquotedString();
1559 }
1560
1561 void setName(Init *Name); // Also updates RecordKeeper.
1562
1563 ArrayRef<SMLoc> getLoc() const { return Locs; }
1564 void appendLoc(SMLoc Loc) { Locs.push_back(Loc); }
1565
1566 // Make the type that this record should have based on its superclasses.
1567 RecordRecTy *getType();
1568
1569 /// get the corresponding DefInit.
1570 DefInit *getDefInit();
1571
1572 bool isClass() const { return IsClass; }
1573
1574 ArrayRef<Init *> getTemplateArgs() const {
1575 return TemplateArgs;
1576 }
1577
1578 ArrayRef<RecordVal> getValues() const { return Values; }
1579
1580 ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
1581
1582 ArrayRef<std::pair<Record *, SMRange>> getSuperClasses() const {
1583 return SuperClasses;
1584 }
1585
1586 /// Determine whether this record has the specified direct superclass.
1587 bool hasDirectSuperClass(const Record *SuperClass) const;
1588
1589 /// Append the direct superclasses of this record to Classes.
1590 void getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const;
1591
1592 bool isTemplateArg(Init *Name) const {
1593 return llvm::is_contained(TemplateArgs, Name);
1594 }
1595
1596 const RecordVal *getValue(const Init *Name) const {
1597 for (const RecordVal &Val : Values)
1598 if (Val.Name == Name) return &Val;
1599 return nullptr;
1600 }
1601
1602 const RecordVal *getValue(StringRef Name) const {
1603 return getValue(StringInit::get(Name));
1604 }
1605
1606 RecordVal *getValue(const Init *Name) {
1607 return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name));
1608 }
1609
1610 RecordVal *getValue(StringRef Name) {
1611 return const_cast<RecordVal *>(static_cast<const Record *>(this)->getValue(Name));
1612 }
1613
1614 void addTemplateArg(Init *Name) {
1615 assert(!isTemplateArg(Name) && "Template arg already defined!")(static_cast <bool> (!isTemplateArg(Name) && "Template arg already defined!"
) ? void (0) : __assert_fail ("!isTemplateArg(Name) && \"Template arg already defined!\""
, "llvm/include/llvm/TableGen/Record.h", 1615, __extension__ __PRETTY_FUNCTION__
))
;
1616 TemplateArgs.push_back(Name);
1617 }
1618
1619 void addValue(const RecordVal &RV) {
1620 assert(getValue(RV.getNameInit()) == nullptr && "Value already added!")(static_cast <bool> (getValue(RV.getNameInit()) == nullptr
&& "Value already added!") ? void (0) : __assert_fail
("getValue(RV.getNameInit()) == nullptr && \"Value already added!\""
, "llvm/include/llvm/TableGen/Record.h", 1620, __extension__ __PRETTY_FUNCTION__
))
;
1621 Values.push_back(RV);
1622 }
1623
1624 void removeValue(Init *Name) {
1625 for (unsigned i = 0, e = Values.size(); i != e; ++i)
1626 if (Values[i].getNameInit() == Name) {
1627 Values.erase(Values.begin()+i);
1628 return;
1629 }
1630 llvm_unreachable("Cannot remove an entry that does not exist!")::llvm::llvm_unreachable_internal("Cannot remove an entry that does not exist!"
, "llvm/include/llvm/TableGen/Record.h", 1630)
;
1631 }
1632
1633 void removeValue(StringRef Name) {
1634 removeValue(StringInit::get(Name));
1635 }
1636
1637 void addAssertion(SMLoc Loc, Init *Condition, Init *Message) {
1638 Assertions.push_back(AssertionInfo(Loc, Condition, Message));
1639 }
1640
1641 void appendAssertions(const Record *Rec) {
1642 Assertions.append(Rec->Assertions);
1643 }
1644
1645 void checkRecordAssertions();
1646 void checkUnusedTemplateArgs();
1647
1648 bool isSubClassOf(const Record *R) const {
1649 for (const auto &SCPair : SuperClasses)
1650 if (SCPair.first == R)
1651 return true;
1652 return false;
1653 }
1654
1655 bool isSubClassOf(StringRef Name) const {
1656 for (const auto &SCPair : SuperClasses) {
19
Assuming '__begin2' is not equal to '__end2'
28
Assuming '__begin2' is equal to '__end2'
1657 if (const auto *SI
20.1
'SI' is null
20.1
'SI' is null
20.1
'SI' is null
= dyn_cast<StringInit>(SCPair.first->getNameInit())) {
20
Assuming the object is not a 'StringInit'
21
Taking false branch
1658 if (SI->getValue() == Name)
1659 return true;
1660 } else if (SCPair.first->getNameInitAsString() == Name) {
22
Assuming the condition is true
23
Taking true branch
1661 return true;
24
Returning the value 1, which participates in a condition later
1662 }
1663 }
1664 return false;
29
Returning zero, which participates in a condition later
1665 }
1666
1667 void addSuperClass(Record *R, SMRange Range) {
1668 assert(!CorrespondingDefInit &&(static_cast <bool> (!CorrespondingDefInit && "changing type of record after it has been referenced"
) ? void (0) : __assert_fail ("!CorrespondingDefInit && \"changing type of record after it has been referenced\""
, "llvm/include/llvm/TableGen/Record.h", 1669, __extension__ __PRETTY_FUNCTION__
))
1669 "changing type of record after it has been referenced")(static_cast <bool> (!CorrespondingDefInit && "changing type of record after it has been referenced"
) ? void (0) : __assert_fail ("!CorrespondingDefInit && \"changing type of record after it has been referenced\""
, "llvm/include/llvm/TableGen/Record.h", 1669, __extension__ __PRETTY_FUNCTION__
))
;
1670 assert(!isSubClassOf(R) && "Already subclassing record!")(static_cast <bool> (!isSubClassOf(R) && "Already subclassing record!"
) ? void (0) : __assert_fail ("!isSubClassOf(R) && \"Already subclassing record!\""
, "llvm/include/llvm/TableGen/Record.h", 1670, __extension__ __PRETTY_FUNCTION__
))
;
1671 SuperClasses.push_back(std::make_pair(R, Range));
1672 }
1673
1674 /// If there are any field references that refer to fields
1675 /// that have been filled in, we can propagate the values now.
1676 ///
1677 /// This is a final resolve: any error messages, e.g. due to undefined
1678 /// !cast references, are generated now.
1679 void resolveReferences(Init *NewName = nullptr);
1680
1681 /// Apply the resolver to the name of the record as well as to the
1682 /// initializers of all fields of the record except SkipVal.
1683 ///
1684 /// The resolver should not resolve any of the fields itself, to avoid
1685 /// recursion / infinite loops.
1686 void resolveReferences(Resolver &R, const RecordVal *SkipVal = nullptr);
1687
1688 RecordKeeper &getRecords() const {
1689 return TrackedRecords;
1690 }
1691
1692 bool isAnonymous() const {
1693 return IsAnonymous;
1694 }
1695
1696 void dump() const;
1697
1698 //===--------------------------------------------------------------------===//
1699 // High-level methods useful to tablegen back-ends
1700 //
1701
1702 ///Return the source location for the named field.
1703 SMLoc getFieldLoc(StringRef FieldName) const;
1704
1705 /// Return the initializer for a value with the specified name,
1706 /// or throw an exception if the field does not exist.
1707 Init *getValueInit(StringRef FieldName) const;
1708
1709 /// Return true if the named field is unset.
1710 bool isValueUnset(StringRef FieldName) const {
1711 return isa<UnsetInit>(getValueInit(FieldName));
1712 }
1713
1714 /// This method looks up the specified field and returns
1715 /// its value as a string, throwing an exception if the field does not exist
1716 /// or if the value is not a string.
1717 StringRef getValueAsString(StringRef FieldName) const;
1718
1719 /// This method looks up the specified field and returns
1720 /// its value as a string, throwing an exception if the field if the value is
1721 /// not a string and llvm::Optional() if the field does not exist.
1722 llvm::Optional<StringRef> getValueAsOptionalString(StringRef FieldName) const;
1723
1724 /// This method looks up the specified field and returns
1725 /// its value as a BitsInit, throwing an exception if the field does not exist
1726 /// or if the value is not the right type.
1727 BitsInit *getValueAsBitsInit(StringRef FieldName) const;
1728
1729 /// This method looks up the specified field and returns
1730 /// its value as a ListInit, throwing an exception if the field does not exist
1731 /// or if the value is not the right type.
1732 ListInit *getValueAsListInit(StringRef FieldName) const;
1733
1734 /// This method looks up the specified field and
1735 /// returns its value as a vector of records, throwing an exception if the
1736 /// field does not exist or if the value is not the right type.
1737 std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
1738
1739 /// This method looks up the specified field and
1740 /// returns its value as a vector of integers, throwing an exception if the
1741 /// field does not exist or if the value is not the right type.
1742 std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
1743
1744 /// This method looks up the specified field and
1745 /// returns its value as a vector of strings, throwing an exception if the
1746 /// field does not exist or if the value is not the right type.
1747 std::vector<StringRef> getValueAsListOfStrings(StringRef FieldName) const;
1748
1749 /// This method looks up the specified field and returns its
1750 /// value as a Record, throwing an exception if the field does not exist or if
1751 /// the value is not the right type.
1752 Record *getValueAsDef(StringRef FieldName) const;
1753
1754 /// This method looks up the specified field and returns its value as a
1755 /// Record, returning null if the field exists but is "uninitialized"
1756 /// (i.e. set to `?`), and throwing an exception if the field does not
1757 /// exist or if its value is not the right type.
1758 Record *getValueAsOptionalDef(StringRef FieldName) const;
1759
1760 /// This method looks up the specified field and returns its
1761 /// value as a bit, throwing an exception if the field does not exist or if
1762 /// the value is not the right type.
1763 bool getValueAsBit(StringRef FieldName) const;
1764
1765 /// This method looks up the specified field and
1766 /// returns its value as a bit. If the field is unset, sets Unset to true and
1767 /// returns false.
1768 bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const;
1769
1770 /// This method looks up the specified field and returns its
1771 /// value as an int64_t, throwing an exception if the field does not exist or
1772 /// if the value is not the right type.
1773 int64_t getValueAsInt(StringRef FieldName) const;
1774
1775 /// This method looks up the specified field and returns its
1776 /// value as an Dag, throwing an exception if the field does not exist or if
1777 /// the value is not the right type.
1778 DagInit *getValueAsDag(StringRef FieldName) const;
1779};
1780
1781raw_ostream &operator<<(raw_ostream &OS, const Record &R);
1782
1783class RecordKeeper {
1784 friend class RecordRecTy;
1785
1786 using RecordMap = std::map<std::string, std::unique_ptr<Record>, std::less<>>;
1787 using GlobalMap = std::map<std::string, Init *, std::less<>>;
1788
1789 std::string InputFilename;
1790 RecordMap Classes, Defs;
1791 mutable StringMap<std::vector<Record *>> ClassRecordsMap;
1792 FoldingSet<RecordRecTy> RecordTypePool;
1793 std::map<std::string, Init *, std::less<>> ExtraGlobals;
1794 unsigned AnonCounter = 0;
1795
1796 // These members are for the phase timing feature. We need a timer group,
1797 // the last timer started, and a flag to say whether the last timer
1798 // is the special "backend overall timer."
1799 TimerGroup *TimingGroup = nullptr;
1800 Timer *LastTimer = nullptr;
1801 bool BackendTimer = false;
1802
1803public:
1804 /// Get the main TableGen input file's name.
1805 const std::string getInputFilename() const { return InputFilename; }
1806
1807 /// Get the map of classes.
1808 const RecordMap &getClasses() const { return Classes; }
1809
1810 /// Get the map of records (defs).
1811 const RecordMap &getDefs() const { return Defs; }
1812
1813 /// Get the map of global variables.
1814 const GlobalMap &getGlobals() const { return ExtraGlobals; }
1815
1816 /// Get the class with the specified name.
1817 Record *getClass(StringRef Name) const {
1818 auto I = Classes.find(Name);
1819 return I == Classes.end() ? nullptr : I->second.get();
1820 }
1821
1822 /// Get the concrete record with the specified name.
1823 Record *getDef(StringRef Name) const {
1824 auto I = Defs.find(Name);
1825 return I == Defs.end() ? nullptr : I->second.get();
1826 }
1827
1828 /// Get the \p Init value of the specified global variable.
1829 Init *getGlobal(StringRef Name) const {
1830 if (Record *R = getDef(Name))
1831 return R->getDefInit();
1832 auto It = ExtraGlobals.find(Name);
1833 return It == ExtraGlobals.end() ? nullptr : It->second;
1834 }
1835
1836 void saveInputFilename(std::string Filename) {
1837 InputFilename = Filename;
1838 }
1839
1840 void addClass(std::unique_ptr<Record> R) {
1841 bool Ins = Classes.insert(std::make_pair(std::string(R->getName()),
1842 std::move(R))).second;
1843 (void)Ins;
1844 assert(Ins && "Class already exists")(static_cast <bool> (Ins && "Class already exists"
) ? void (0) : __assert_fail ("Ins && \"Class already exists\""
, "llvm/include/llvm/TableGen/Record.h", 1844, __extension__ __PRETTY_FUNCTION__
))
;
1845 }
1846
1847 void addDef(std::unique_ptr<Record> R) {
1848 bool Ins = Defs.insert(std::make_pair(std::string(R->getName()),
1849 std::move(R))).second;
1850 (void)Ins;
1851 assert(Ins && "Record already exists")(static_cast <bool> (Ins && "Record already exists"
) ? void (0) : __assert_fail ("Ins && \"Record already exists\""
, "llvm/include/llvm/TableGen/Record.h", 1851, __extension__ __PRETTY_FUNCTION__
))
;
1852 }
1853
1854 void addExtraGlobal(StringRef Name, Init *I) {
1855 bool Ins = ExtraGlobals.insert(std::make_pair(std::string(Name), I)).second;
1856 (void)Ins;
1857 assert(!getDef(Name))(static_cast <bool> (!getDef(Name)) ? void (0) : __assert_fail
("!getDef(Name)", "llvm/include/llvm/TableGen/Record.h", 1857
, __extension__ __PRETTY_FUNCTION__))
;
1858 assert(Ins && "Global already exists")(static_cast <bool> (Ins && "Global already exists"
) ? void (0) : __assert_fail ("Ins && \"Global already exists\""
, "llvm/include/llvm/TableGen/Record.h", 1858, __extension__ __PRETTY_FUNCTION__
))
;
1859 }
1860
1861 Init *getNewAnonymousName();
1862
1863 /// Start phase timing; called if the --time-phases option is specified.
1864 void startPhaseTiming() {
1865 TimingGroup = new TimerGroup("TableGen", "TableGen Phase Timing");
1866 }
1867
1868 /// Start timing a phase. Automatically stops any previous phase timer.
1869 void startTimer(StringRef Name);
1870
1871 /// Stop timing a phase.
1872 void stopTimer();
1873
1874 /// Start timing the overall backend. If the backend itself starts a timer,
1875 /// then this timer is cleared.
1876 void startBackendTimer(StringRef Name);
1877
1878 /// Stop timing the overall backend.
1879 void stopBackendTimer();
1880
1881 /// Stop phase timing and print the report.
1882 void stopPhaseTiming() {
1883 if (TimingGroup)
1884 delete TimingGroup;
1885 }
1886
1887 //===--------------------------------------------------------------------===//
1888 // High-level helper methods, useful for tablegen backends.
1889
1890 /// Get all the concrete records that inherit from the one specified
1891 /// class. The class must be defined.
1892 std::vector<Record *> getAllDerivedDefinitions(StringRef ClassName) const;
1893
1894 /// Get all the concrete records that inherit from all the specified
1895 /// classes. The classes must be defined.
1896 std::vector<Record *> getAllDerivedDefinitions(
1897 ArrayRef<StringRef> ClassNames) const;
1898
1899 void dump() const;
1900};
1901
1902/// Sorting predicate to sort record pointers by name.
1903struct LessRecord {
1904 bool operator()(const Record *Rec1, const Record *Rec2) const {
1905 return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
1906 }
1907};
1908
1909/// Sorting predicate to sort record pointers by their
1910/// unique ID. If you just need a deterministic order, use this, since it
1911/// just compares two `unsigned`; the other sorting predicates require
1912/// string manipulation.
1913struct LessRecordByID {
1914 bool operator()(const Record *LHS, const Record *RHS) const {
1915 return LHS->getID() < RHS->getID();
1916 }
1917};
1918
1919/// Sorting predicate to sort record pointers by their
1920/// name field.
1921struct LessRecordFieldName {
1922 bool operator()(const Record *Rec1, const Record *Rec2) const {
1923 return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
1924 }
1925};
1926
1927struct LessRecordRegister {
1928 struct RecordParts {
1929 SmallVector<std::pair< bool, StringRef>, 4> Parts;
1930
1931 RecordParts(StringRef Rec) {
1932 if (Rec.empty())
1933 return;
1934
1935 size_t Len = 0;
1936 const char *Start = Rec.data();
1937 const char *Curr = Start;
1938 bool IsDigitPart = isDigit(Curr[0]);
1939 for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
1940 bool IsDigit = isDigit(Curr[I]);
1941 if (IsDigit != IsDigitPart) {
1942 Parts.push_back(std::make_pair(IsDigitPart, StringRef(Start, Len)));
1943 Len = 0;
1944 Start = &Curr[I];
1945 IsDigitPart = isDigit(Curr[I]);
1946 }
1947 }
1948 // Push the last part.
1949 Parts.push_back(std::make_pair(IsDigitPart, StringRef(Start, Len)));
1950 }
1951
1952 size_t size() { return Parts.size(); }
1953
1954 std::pair<bool, StringRef> getPart(size_t i) {
1955 assert (i < Parts.size() && "Invalid idx!")(static_cast <bool> (i < Parts.size() && "Invalid idx!"
) ? void (0) : __assert_fail ("i < Parts.size() && \"Invalid idx!\""
, "llvm/include/llvm/TableGen/Record.h", 1955, __extension__ __PRETTY_FUNCTION__
))
;
1956 return Parts[i];
1957 }
1958 };
1959
1960 bool operator()(const Record *Rec1, const Record *Rec2) const {
1961 RecordParts LHSParts(StringRef(Rec1->getName()));
1962 RecordParts RHSParts(StringRef(Rec2->getName()));
1963
1964 size_t LHSNumParts = LHSParts.size();
1965 size_t RHSNumParts = RHSParts.size();
1966 assert (LHSNumParts && RHSNumParts && "Expected at least one part!")(static_cast <bool> (LHSNumParts && RHSNumParts
&& "Expected at least one part!") ? void (0) : __assert_fail
("LHSNumParts && RHSNumParts && \"Expected at least one part!\""
, "llvm/include/llvm/TableGen/Record.h", 1966, __extension__ __PRETTY_FUNCTION__
))
;
1967
1968 if (LHSNumParts != RHSNumParts)
1969 return LHSNumParts < RHSNumParts;
1970
1971 // We expect the registers to be of the form [_a-zA-Z]+([0-9]*[_a-zA-Z]*)*.
1972 for (size_t I = 0, E = LHSNumParts; I < E; I+=2) {
1973 std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
1974 std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
1975 // Expect even part to always be alpha.
1976 assert (LHSPart.first == false && RHSPart.first == false &&(static_cast <bool> (LHSPart.first == false && RHSPart
.first == false && "Expected both parts to be alpha."
) ? void (0) : __assert_fail ("LHSPart.first == false && RHSPart.first == false && \"Expected both parts to be alpha.\""
, "llvm/include/llvm/TableGen/Record.h", 1977, __extension__ __PRETTY_FUNCTION__
))
1977 "Expected both parts to be alpha.")(static_cast <bool> (LHSPart.first == false && RHSPart
.first == false && "Expected both parts to be alpha."
) ? void (0) : __assert_fail ("LHSPart.first == false && RHSPart.first == false && \"Expected both parts to be alpha.\""
, "llvm/include/llvm/TableGen/Record.h", 1977, __extension__ __PRETTY_FUNCTION__
))
;
1978 if (int Res = LHSPart.second.compare(RHSPart.second))
1979 return Res < 0;
1980 }
1981 for (size_t I = 1, E = LHSNumParts; I < E; I+=2) {
1982 std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
1983 std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
1984 // Expect odd part to always be numeric.
1985 assert (LHSPart.first == true && RHSPart.first == true &&(static_cast <bool> (LHSPart.first == true && RHSPart
.first == true && "Expected both parts to be numeric."
) ? void (0) : __assert_fail ("LHSPart.first == true && RHSPart.first == true && \"Expected both parts to be numeric.\""
, "llvm/include/llvm/TableGen/Record.h", 1986, __extension__ __PRETTY_FUNCTION__
))
1986 "Expected both parts to be numeric.")(static_cast <bool> (LHSPart.first == true && RHSPart
.first == true && "Expected both parts to be numeric."
) ? void (0) : __assert_fail ("LHSPart.first == true && RHSPart.first == true && \"Expected both parts to be numeric.\""
, "llvm/include/llvm/TableGen/Record.h", 1986, __extension__ __PRETTY_FUNCTION__
))
;
1987 if (LHSPart.second.size() != RHSPart.second.size())
1988 return LHSPart.second.size() < RHSPart.second.size();
1989
1990 unsigned LHSVal, RHSVal;
1991
1992 bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed;
1993 assert(!LHSFailed && "Unable to convert LHS to integer.")(static_cast <bool> (!LHSFailed && "Unable to convert LHS to integer."
) ? void (0) : __assert_fail ("!LHSFailed && \"Unable to convert LHS to integer.\""
, "llvm/include/llvm/TableGen/Record.h", 1993, __extension__ __PRETTY_FUNCTION__
))
;
1994 bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed;
1995 assert(!RHSFailed && "Unable to convert RHS to integer.")(static_cast <bool> (!RHSFailed && "Unable to convert RHS to integer."
) ? void (0) : __assert_fail ("!RHSFailed && \"Unable to convert RHS to integer.\""
, "llvm/include/llvm/TableGen/Record.h", 1995, __extension__ __PRETTY_FUNCTION__
))
;
1996
1997 if (LHSVal != RHSVal)
1998 return LHSVal < RHSVal;
1999 }
2000 return LHSNumParts < RHSNumParts;
2001 }
2002};
2003
2004raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
2005
2006//===----------------------------------------------------------------------===//
2007// Resolvers
2008//===----------------------------------------------------------------------===//
2009
2010/// Interface for looking up the initializer for a variable name, used by
2011/// Init::resolveReferences.
2012class Resolver {
2013 Record *CurRec;
2014 bool IsFinal = false;
2015
2016public:
2017 explicit Resolver(Record *CurRec) : CurRec(CurRec) {}
2018 virtual ~Resolver() {}
2019
2020 Record *getCurrentRecord() const { return CurRec; }
2021
2022 /// Return the initializer for the given variable name (should normally be a
2023 /// StringInit), or nullptr if the name could not be resolved.
2024 virtual Init *resolve(Init *VarName) = 0;
2025
2026 // Whether bits in a BitsInit should stay unresolved if resolving them would
2027 // result in a ? (UnsetInit). This behavior is used to represent instruction
2028 // encodings by keeping references to unset variables within a record.
2029 virtual bool keepUnsetBits() const { return false; }
2030
2031 // Whether this is the final resolve step before adding a record to the
2032 // RecordKeeper. Error reporting during resolve and related constant folding
2033 // should only happen when this is true.
2034 bool isFinal() const { return IsFinal; }
2035
2036 void setFinal(bool Final) { IsFinal = Final; }
2037};
2038
2039/// Resolve arbitrary mappings.
2040class MapResolver final : public Resolver {
2041 struct MappedValue {
2042 Init *V;
2043 bool Resolved;
2044
2045 MappedValue() : V(nullptr), Resolved(false) {}
2046 MappedValue(Init *V, bool Resolved) : V(V), Resolved(Resolved) {}
2047 };
2048
2049 DenseMap<Init *, MappedValue> Map;
2050
2051public:
2052 explicit MapResolver(Record *CurRec = nullptr) : Resolver(CurRec) {}
2053
2054 void set(Init *Key, Init *Value) { Map[Key] = {Value, false}; }
2055
2056 bool isComplete(Init *VarName) const {
2057 auto It = Map.find(VarName);
2058 assert(It != Map.end() && "key must be present in map")(static_cast <bool> (It != Map.end() && "key must be present in map"
) ? void (0) : __assert_fail ("It != Map.end() && \"key must be present in map\""
, "llvm/include/llvm/TableGen/Record.h", 2058, __extension__ __PRETTY_FUNCTION__
))
;
2059 return It->second.V->isComplete();
2060 }
2061
2062 Init *resolve(Init *VarName) override;
2063};
2064
2065/// Resolve all variables from a record except for unset variables.
2066class RecordResolver final : public Resolver {
2067 DenseMap<Init *, Init *> Cache;
2068 SmallVector<Init *, 4> Stack;
2069 Init *Name = nullptr;
2070
2071public:
2072 explicit RecordResolver(Record &R) : Resolver(&R) {}
2073
2074 void setName(Init *NewName) { Name = NewName; }
2075
2076 Init *resolve(Init *VarName) override;
2077
2078 bool keepUnsetBits() const override { return true; }
2079};
2080
2081/// Delegate resolving to a sub-resolver, but shadow some variable names.
2082class ShadowResolver final : public Resolver {
2083 Resolver &R;
2084 DenseSet<Init *> Shadowed;
2085
2086public:
2087 explicit ShadowResolver(Resolver &R)
2088 : Resolver(R.getCurrentRecord()), R(R) {
2089 setFinal(R.isFinal());
2090 }
2091
2092 void addShadow(Init *Key) { Shadowed.insert(Key); }
2093
2094 Init *resolve(Init *VarName) override {
2095 if (Shadowed.count(VarName))
2096 return nullptr;
2097 return R.resolve(VarName);
2098 }
2099};
2100
2101/// (Optionally) delegate resolving to a sub-resolver, and keep track whether
2102/// there were unresolved references.
2103class TrackUnresolvedResolver final : public Resolver {
2104 Resolver *R;
2105 bool FoundUnresolved = false;
2106
2107public:
2108 explicit TrackUnresolvedResolver(Resolver *R = nullptr)
2109 : Resolver(R ? R->getCurrentRecord() : nullptr), R(R) {}
2110
2111 bool foundUnresolved() const { return FoundUnresolved; }
2112
2113 Init *resolve(Init *VarName) override;
2114};
2115
2116/// Do not resolve anything, but keep track of whether a given variable was
2117/// referenced.
2118class HasReferenceResolver final : public Resolver {
2119 Init *VarNameToTrack;
2120 bool Found = false;
2121
2122public:
2123 explicit HasReferenceResolver(Init *VarNameToTrack)
2124 : Resolver(nullptr), VarNameToTrack(VarNameToTrack) {}
2125
2126 bool found() const { return Found; }
2127
2128 Init *resolve(Init *VarName) override;
2129};
2130
2131void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS);
2132void EmitJSON(RecordKeeper &RK, raw_ostream &OS);
2133
2134} // end namespace llvm
2135
2136#endif // LLVM_TABLEGEN_RECORD_H