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 79 using namespace llvm; 80 81 namespace { 82 83 class EmitterBase; 84 class 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 98 class Type { 99 public: 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 133 private: 134 const TypeKind TKind; 135 136 protected: 137 Type(TypeKind K) : TKind(K) {} 138 139 public: 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 154 enum class ScalarTypeKind { SignedInt, UnsignedInt, Float }; 155 inline 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"); 165 } 166 inline 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"); 176 } 177 178 class VoidType : public Type { 179 public: 180 VoidType() : Type(TypeKind::Void) {} 181 unsigned sizeInBits() const override { return 0; } 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 190 class PointerType : public Type { 191 const Type *Pointee; 192 bool Const; 193 194 public: 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"); 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 229 class CRegularNamedType : public Type { 230 using Type::Type; 231 virtual std::string cNameBase() const = 0; 232 233 public: 234 std::string cName() const override { return cNameBase() + "_t"; } 235 }; 236 237 class ScalarType : public CRegularNamedType { 238 ScalarTypeKind Kind; 239 unsigned Bits; 240 std::string NameOverride; 241 242 public: 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 288 class VectorType : public CRegularNamedType { 289 const ScalarType *Element; 290 unsigned Lanes; 291 292 public: 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 312 class MultiVectorType : public CRegularNamedType { 313 const VectorType *Element; 314 unsigned Registers; 315 316 public: 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 341 class PredicateType : public CRegularNamedType { 342 unsigned Lanes; 343 344 public: 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 396 struct 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 460 class Result { 461 public: 462 // Convenient shorthand for the pointer type we'll be using everywhere. 463 using Ptr = std::shared_ptr<Result>; 464 465 private: 466 Ptr Predecessor; 467 std::string VarName; 468 bool VarNameUsed = false; 469 unsigned Visited = 0; 470 471 public: 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"); 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. 560 class BuiltinArgResult : public Result { 561 public: 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. 591 class IntLiteralResult : public Result { 592 public: 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. 612 class IntCastResult : public Result { 613 public: 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. 634 class PointerCastResult : public Result { 635 public: 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. 654 class IRBuilderResult : public Result { 655 public: 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. 702 class AddressResult : public Result { 703 public: 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. 722 class IRIntrinsicResult : public Result { 723 public: 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. 760 class TypeResult : public Result { 761 public: 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 782 class 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 833 public: 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"); 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()); 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"); 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()); 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 964 class EmitterBase { 965 protected: 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 980 public: 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 1055 const 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 1064 const 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 1083 const 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 1151 Result::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 1254 Result::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 1299 Result::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 1319 ACLEIntrinsic::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") 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( 1341 "NumTypeSuffixesToDiscard"); 1342 i < e; ++i) 1343 NameParts.pop_back(); 1344 if (!PolymorphicNameType->isValueUnset("ExtraSuffixToDiscard")) { 1345 StringRef ExtraSuffix = 1346 PolymorphicNameType->getValueAsString("ExtraSuffixToDiscard"); 1347 auto it = NameParts.end(); 1348 while (it != NameParts.begin()) { 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) { 1368 Init *TypeInit = ArgsDag->getArg(i); 1369 1370 bool Promote = true; 1371 if (auto TypeDI = dyn_cast<DefInit>(TypeInit)) 1372 if (TypeDI->getDef()->isSubClassOf("unpromoted")) 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 = dyn_cast<DefInit>(TypeInit)) { 1384 Record *TypeRec = TypeDI->getDef(); 1385 if (TypeRec->isSubClassOf("Immediate")) { 1386 Immediate = true; 1387 1388 Record *Bounds = TypeRec->getValueAsDef("bounds"); 1389 ImmediateArg &IA = ImmediateArgs[i]; 1390 if (Bounds->isSubClassOf("IB_ConstRange")) { 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") { 1395 IA.boundsType = ImmediateArg::BoundsType::UInt; 1396 IA.i1 = Param->sizeInBits(); 1397 } else if (Bounds->getName() == "IB_LaneIndex") { 1398 IA.boundsType = ImmediateArg::BoundsType::ExplicitRange; 1399 IA.i1 = 0; 1400 IA.i2 = 128 / Param->sizeInBits() - 1; 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 1455 EmitterBase::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); 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. 1485 class string_holder { 1486 protected: 1487 std::string S; 1488 }; 1489 class raw_self_contained_string_ostream : private string_holder, 1490 public raw_string_ostream { 1491 public: 1492 raw_self_contained_string_ostream() : raw_string_ostream(S) {} 1493 }; 1494 1495 const 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 1518 struct 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 1532 struct 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 }; 1542 struct 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 1552 void 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 = ∬ 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 1697 void 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 1725 void 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 1741 class MveEmitter : public EmitterBase { 1742 public: 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 1749 void 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 1935 void 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 1959 void 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 1977 class FunctionMacro { 1978 std::vector<StringRef> Params; 1979 StringRef Definition; 1980 1981 public: 1982 FunctionMacro(const Record &R); 1983 1984 const std::vector<StringRef> &getParams() const { return Params; } 1985 StringRef getDefinition() const { return Definition; } 1986 }; 1987 1988 FunctionMacro::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 1997 class CdeEmitter : public EmitterBase { 1998 std::map<StringRef, FunctionMacro> FunctionMacros; 1999 2000 public: 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 2007 CdeEmitter::CdeEmitter(RecordKeeper &Records) : EmitterBase(Records) { 2008 for (Record *R : Records.getAllDerivedDefinitions("FunctionMacro")) 2009 FunctionMacros.emplace(R->getName(), FunctionMacro(*R)); 2010 } 2011 2012 void 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 2143 void 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 2153 void 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 2166 namespace clang { 2167 2168 // MVE 2169 2170 void EmitMveHeader(RecordKeeper &Records, raw_ostream &OS) { 2171 MveEmitter(Records).EmitHeader(OS); 2172 } 2173 2174 void EmitMveBuiltinDef(RecordKeeper &Records, raw_ostream &OS) { 2175 MveEmitter(Records).EmitBuiltinDef(OS); 2176 } 2177 2178 void EmitMveBuiltinSema(RecordKeeper &Records, raw_ostream &OS) { 2179 MveEmitter(Records).EmitBuiltinSema(OS); 2180 } 2181 2182 void EmitMveBuiltinCG(RecordKeeper &Records, raw_ostream &OS) { 2183 MveEmitter(Records).EmitBuiltinCG(OS); 2184 } 2185 2186 void EmitMveBuiltinAliases(RecordKeeper &Records, raw_ostream &OS) { 2187 MveEmitter(Records).EmitBuiltinAliases(OS); 2188 } 2189 2190 // CDE 2191 2192 void EmitCdeHeader(RecordKeeper &Records, raw_ostream &OS) { 2193 CdeEmitter(Records).EmitHeader(OS); 2194 } 2195 2196 void EmitCdeBuiltinDef(RecordKeeper &Records, raw_ostream &OS) { 2197 CdeEmitter(Records).EmitBuiltinDef(OS); 2198 } 2199 2200 void EmitCdeBuiltinSema(RecordKeeper &Records, raw_ostream &OS) { 2201 CdeEmitter(Records).EmitBuiltinSema(OS); 2202 } 2203 2204 void EmitCdeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) { 2205 CdeEmitter(Records).EmitBuiltinCG(OS); 2206 } 2207 2208 void EmitCdeBuiltinAliases(RecordKeeper &Records, raw_ostream &OS) { 2209 CdeEmitter(Records).EmitBuiltinAliases(OS); 2210 } 2211 2212 } // end namespace clang 2213