xref: /openbsd-src/gnu/llvm/llvm/utils/TableGen/CodeGenTarget.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This class wraps target description classes used by the various code
1009467b48Spatrick // generation TableGen backends.  This makes it easier to access the data and
1109467b48Spatrick // provides a single place that needs to check it for validity.  All of these
1209467b48Spatrick // classes abort on error conditions.
1309467b48Spatrick //
1409467b48Spatrick //===----------------------------------------------------------------------===//
1509467b48Spatrick 
1609467b48Spatrick #include "CodeGenTarget.h"
17*d415bd75Srobert #include "CodeGenInstruction.h"
1809467b48Spatrick #include "CodeGenIntrinsics.h"
1909467b48Spatrick #include "CodeGenSchedule.h"
2009467b48Spatrick #include "llvm/ADT/STLExtras.h"
2109467b48Spatrick #include "llvm/Support/CommandLine.h"
2209467b48Spatrick #include "llvm/TableGen/Error.h"
2309467b48Spatrick #include "llvm/TableGen/Record.h"
2409467b48Spatrick #include <algorithm>
2509467b48Spatrick using namespace llvm;
2609467b48Spatrick 
2709467b48Spatrick cl::OptionCategory AsmParserCat("Options for -gen-asm-parser");
2809467b48Spatrick cl::OptionCategory AsmWriterCat("Options for -gen-asm-writer");
2909467b48Spatrick 
3009467b48Spatrick static cl::opt<unsigned>
3109467b48Spatrick     AsmParserNum("asmparsernum", cl::init(0),
3209467b48Spatrick                  cl::desc("Make -gen-asm-parser emit assembly parser #N"),
3309467b48Spatrick                  cl::cat(AsmParserCat));
3409467b48Spatrick 
3509467b48Spatrick static cl::opt<unsigned>
3609467b48Spatrick     AsmWriterNum("asmwriternum", cl::init(0),
3709467b48Spatrick                  cl::desc("Make -gen-asm-writer emit assembly writer #N"),
3809467b48Spatrick                  cl::cat(AsmWriterCat));
3909467b48Spatrick 
4009467b48Spatrick /// getValueType - Return the MVT::SimpleValueType that the specified TableGen
4109467b48Spatrick /// record corresponds to.
getValueType(Record * Rec)4209467b48Spatrick MVT::SimpleValueType llvm::getValueType(Record *Rec) {
4309467b48Spatrick   return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
4409467b48Spatrick }
4509467b48Spatrick 
getName(MVT::SimpleValueType T)4609467b48Spatrick StringRef llvm::getName(MVT::SimpleValueType T) {
4709467b48Spatrick   switch (T) {
4809467b48Spatrick   case MVT::Other:   return "UNKNOWN";
4909467b48Spatrick   case MVT::iPTR:    return "TLI.getPointerTy()";
5009467b48Spatrick   case MVT::iPTRAny: return "TLI.getPointerTy()";
5109467b48Spatrick   default: return getEnumName(T);
5209467b48Spatrick   }
5309467b48Spatrick }
5409467b48Spatrick 
getEnumName(MVT::SimpleValueType T)5509467b48Spatrick StringRef llvm::getEnumName(MVT::SimpleValueType T) {
56*d415bd75Srobert   // clang-format off
5709467b48Spatrick   switch (T) {
5809467b48Spatrick   case MVT::Other:    return "MVT::Other";
5909467b48Spatrick   case MVT::i1:       return "MVT::i1";
60*d415bd75Srobert   case MVT::i2:       return "MVT::i2";
61*d415bd75Srobert   case MVT::i4:       return "MVT::i4";
6209467b48Spatrick   case MVT::i8:       return "MVT::i8";
6309467b48Spatrick   case MVT::i16:      return "MVT::i16";
6409467b48Spatrick   case MVT::i32:      return "MVT::i32";
6509467b48Spatrick   case MVT::i64:      return "MVT::i64";
6609467b48Spatrick   case MVT::i128:     return "MVT::i128";
6709467b48Spatrick   case MVT::Any:      return "MVT::Any";
6809467b48Spatrick   case MVT::iAny:     return "MVT::iAny";
6909467b48Spatrick   case MVT::fAny:     return "MVT::fAny";
7009467b48Spatrick   case MVT::vAny:     return "MVT::vAny";
7109467b48Spatrick   case MVT::f16:      return "MVT::f16";
72097a140dSpatrick   case MVT::bf16:     return "MVT::bf16";
7309467b48Spatrick   case MVT::f32:      return "MVT::f32";
7409467b48Spatrick   case MVT::f64:      return "MVT::f64";
7509467b48Spatrick   case MVT::f80:      return "MVT::f80";
7609467b48Spatrick   case MVT::f128:     return "MVT::f128";
7709467b48Spatrick   case MVT::ppcf128:  return "MVT::ppcf128";
7809467b48Spatrick   case MVT::x86mmx:   return "MVT::x86mmx";
7973471bf0Spatrick   case MVT::x86amx:   return "MVT::x86amx";
8073471bf0Spatrick   case MVT::i64x8:    return "MVT::i64x8";
8109467b48Spatrick   case MVT::Glue:     return "MVT::Glue";
8209467b48Spatrick   case MVT::isVoid:   return "MVT::isVoid";
8309467b48Spatrick   case MVT::v1i1:     return "MVT::v1i1";
8409467b48Spatrick   case MVT::v2i1:     return "MVT::v2i1";
8509467b48Spatrick   case MVT::v4i1:     return "MVT::v4i1";
8609467b48Spatrick   case MVT::v8i1:     return "MVT::v8i1";
8709467b48Spatrick   case MVT::v16i1:    return "MVT::v16i1";
8809467b48Spatrick   case MVT::v32i1:    return "MVT::v32i1";
8909467b48Spatrick   case MVT::v64i1:    return "MVT::v64i1";
9009467b48Spatrick   case MVT::v128i1:   return "MVT::v128i1";
9173471bf0Spatrick   case MVT::v256i1:   return "MVT::v256i1";
9209467b48Spatrick   case MVT::v512i1:   return "MVT::v512i1";
9309467b48Spatrick   case MVT::v1024i1:  return "MVT::v1024i1";
94*d415bd75Srobert   case MVT::v2048i1:  return "MVT::v2048i1";
95*d415bd75Srobert   case MVT::v128i2:   return "MVT::v128i2";
96*d415bd75Srobert   case MVT::v256i2:   return "MVT::v256i2";
97*d415bd75Srobert   case MVT::v64i4:    return "MVT::v64i4";
98*d415bd75Srobert   case MVT::v128i4:   return "MVT::v128i4";
9909467b48Spatrick   case MVT::v1i8:     return "MVT::v1i8";
10009467b48Spatrick   case MVT::v2i8:     return "MVT::v2i8";
10109467b48Spatrick   case MVT::v4i8:     return "MVT::v4i8";
10209467b48Spatrick   case MVT::v8i8:     return "MVT::v8i8";
10309467b48Spatrick   case MVT::v16i8:    return "MVT::v16i8";
10409467b48Spatrick   case MVT::v32i8:    return "MVT::v32i8";
10509467b48Spatrick   case MVT::v64i8:    return "MVT::v64i8";
10609467b48Spatrick   case MVT::v128i8:   return "MVT::v128i8";
10709467b48Spatrick   case MVT::v256i8:   return "MVT::v256i8";
10873471bf0Spatrick   case MVT::v512i8:   return "MVT::v512i8";
10973471bf0Spatrick   case MVT::v1024i8:  return "MVT::v1024i8";
11009467b48Spatrick   case MVT::v1i16:    return "MVT::v1i16";
11109467b48Spatrick   case MVT::v2i16:    return "MVT::v2i16";
11209467b48Spatrick   case MVT::v3i16:    return "MVT::v3i16";
11309467b48Spatrick   case MVT::v4i16:    return "MVT::v4i16";
11409467b48Spatrick   case MVT::v8i16:    return "MVT::v8i16";
11509467b48Spatrick   case MVT::v16i16:   return "MVT::v16i16";
11609467b48Spatrick   case MVT::v32i16:   return "MVT::v32i16";
11709467b48Spatrick   case MVT::v64i16:   return "MVT::v64i16";
11809467b48Spatrick   case MVT::v128i16:  return "MVT::v128i16";
11973471bf0Spatrick   case MVT::v256i16:  return "MVT::v256i16";
12073471bf0Spatrick   case MVT::v512i16:  return "MVT::v512i16";
12109467b48Spatrick   case MVT::v1i32:    return "MVT::v1i32";
12209467b48Spatrick   case MVT::v2i32:    return "MVT::v2i32";
12309467b48Spatrick   case MVT::v3i32:    return "MVT::v3i32";
12409467b48Spatrick   case MVT::v4i32:    return "MVT::v4i32";
12509467b48Spatrick   case MVT::v5i32:    return "MVT::v5i32";
12673471bf0Spatrick   case MVT::v6i32:    return "MVT::v6i32";
12773471bf0Spatrick   case MVT::v7i32:    return "MVT::v7i32";
12809467b48Spatrick   case MVT::v8i32:    return "MVT::v8i32";
129*d415bd75Srobert   case MVT::v9i32:    return "MVT::v9i32";
130*d415bd75Srobert   case MVT::v10i32:   return "MVT::v10i32";
131*d415bd75Srobert   case MVT::v11i32:   return "MVT::v11i32";
132*d415bd75Srobert   case MVT::v12i32:   return "MVT::v12i32";
13309467b48Spatrick   case MVT::v16i32:   return "MVT::v16i32";
13409467b48Spatrick   case MVT::v32i32:   return "MVT::v32i32";
13509467b48Spatrick   case MVT::v64i32:   return "MVT::v64i32";
13609467b48Spatrick   case MVT::v128i32:  return "MVT::v128i32";
13709467b48Spatrick   case MVT::v256i32:  return "MVT::v256i32";
13809467b48Spatrick   case MVT::v512i32:  return "MVT::v512i32";
13909467b48Spatrick   case MVT::v1024i32: return "MVT::v1024i32";
14009467b48Spatrick   case MVT::v2048i32: return "MVT::v2048i32";
14109467b48Spatrick   case MVT::v1i64:    return "MVT::v1i64";
14209467b48Spatrick   case MVT::v2i64:    return "MVT::v2i64";
14373471bf0Spatrick   case MVT::v3i64:    return "MVT::v3i64";
14409467b48Spatrick   case MVT::v4i64:    return "MVT::v4i64";
14509467b48Spatrick   case MVT::v8i64:    return "MVT::v8i64";
14609467b48Spatrick   case MVT::v16i64:   return "MVT::v16i64";
14709467b48Spatrick   case MVT::v32i64:   return "MVT::v32i64";
14873471bf0Spatrick   case MVT::v64i64:   return "MVT::v64i64";
14973471bf0Spatrick   case MVT::v128i64:  return "MVT::v128i64";
15073471bf0Spatrick   case MVT::v256i64:  return "MVT::v256i64";
15109467b48Spatrick   case MVT::v1i128:   return "MVT::v1i128";
15273471bf0Spatrick   case MVT::v1f16:    return "MVT::v1f16";
15309467b48Spatrick   case MVT::v2f16:    return "MVT::v2f16";
15409467b48Spatrick   case MVT::v3f16:    return "MVT::v3f16";
15509467b48Spatrick   case MVT::v4f16:    return "MVT::v4f16";
15609467b48Spatrick   case MVT::v8f16:    return "MVT::v8f16";
15709467b48Spatrick   case MVT::v16f16:   return "MVT::v16f16";
15809467b48Spatrick   case MVT::v32f16:   return "MVT::v32f16";
159097a140dSpatrick   case MVT::v64f16:   return "MVT::v64f16";
160097a140dSpatrick   case MVT::v128f16:  return "MVT::v128f16";
16173471bf0Spatrick   case MVT::v256f16:  return "MVT::v256f16";
16273471bf0Spatrick   case MVT::v512f16:  return "MVT::v512f16";
163097a140dSpatrick   case MVT::v2bf16:   return "MVT::v2bf16";
164097a140dSpatrick   case MVT::v3bf16:   return "MVT::v3bf16";
165097a140dSpatrick   case MVT::v4bf16:   return "MVT::v4bf16";
166097a140dSpatrick   case MVT::v8bf16:   return "MVT::v8bf16";
167097a140dSpatrick   case MVT::v16bf16:  return "MVT::v16bf16";
168097a140dSpatrick   case MVT::v32bf16:  return "MVT::v32bf16";
169097a140dSpatrick   case MVT::v64bf16:  return "MVT::v64bf16";
170097a140dSpatrick   case MVT::v128bf16: return "MVT::v128bf16";
17109467b48Spatrick   case MVT::v1f32:    return "MVT::v1f32";
17209467b48Spatrick   case MVT::v2f32:    return "MVT::v2f32";
17309467b48Spatrick   case MVT::v3f32:    return "MVT::v3f32";
17409467b48Spatrick   case MVT::v4f32:    return "MVT::v4f32";
17509467b48Spatrick   case MVT::v5f32:    return "MVT::v5f32";
17673471bf0Spatrick   case MVT::v6f32:    return "MVT::v6f32";
17773471bf0Spatrick   case MVT::v7f32:    return "MVT::v7f32";
17809467b48Spatrick   case MVT::v8f32:    return "MVT::v8f32";
179*d415bd75Srobert   case MVT::v9f32:    return "MVT::v9f32";
180*d415bd75Srobert   case MVT::v10f32:   return "MVT::v10f32";
181*d415bd75Srobert   case MVT::v11f32:   return "MVT::v11f32";
182*d415bd75Srobert   case MVT::v12f32:   return "MVT::v12f32";
18309467b48Spatrick   case MVT::v16f32:   return "MVT::v16f32";
18409467b48Spatrick   case MVT::v32f32:   return "MVT::v32f32";
18509467b48Spatrick   case MVT::v64f32:   return "MVT::v64f32";
18609467b48Spatrick   case MVT::v128f32:  return "MVT::v128f32";
18709467b48Spatrick   case MVT::v256f32:  return "MVT::v256f32";
18809467b48Spatrick   case MVT::v512f32:  return "MVT::v512f32";
18909467b48Spatrick   case MVT::v1024f32: return "MVT::v1024f32";
19009467b48Spatrick   case MVT::v2048f32: return "MVT::v2048f32";
19109467b48Spatrick   case MVT::v1f64:    return "MVT::v1f64";
19209467b48Spatrick   case MVT::v2f64:    return "MVT::v2f64";
19373471bf0Spatrick   case MVT::v3f64:    return "MVT::v3f64";
19409467b48Spatrick   case MVT::v4f64:    return "MVT::v4f64";
19509467b48Spatrick   case MVT::v8f64:    return "MVT::v8f64";
196097a140dSpatrick   case MVT::v16f64:   return "MVT::v16f64";
197097a140dSpatrick   case MVT::v32f64:   return "MVT::v32f64";
19873471bf0Spatrick   case MVT::v64f64:   return "MVT::v64f64";
19973471bf0Spatrick   case MVT::v128f64:  return "MVT::v128f64";
20073471bf0Spatrick   case MVT::v256f64:  return "MVT::v256f64";
20109467b48Spatrick   case MVT::nxv1i1:   return "MVT::nxv1i1";
20209467b48Spatrick   case MVT::nxv2i1:   return "MVT::nxv2i1";
20309467b48Spatrick   case MVT::nxv4i1:   return "MVT::nxv4i1";
20409467b48Spatrick   case MVT::nxv8i1:   return "MVT::nxv8i1";
20509467b48Spatrick   case MVT::nxv16i1:  return "MVT::nxv16i1";
20609467b48Spatrick   case MVT::nxv32i1:  return "MVT::nxv32i1";
207097a140dSpatrick   case MVT::nxv64i1:  return "MVT::nxv64i1";
20809467b48Spatrick   case MVT::nxv1i8:   return "MVT::nxv1i8";
20909467b48Spatrick   case MVT::nxv2i8:   return "MVT::nxv2i8";
21009467b48Spatrick   case MVT::nxv4i8:   return "MVT::nxv4i8";
21109467b48Spatrick   case MVT::nxv8i8:   return "MVT::nxv8i8";
21209467b48Spatrick   case MVT::nxv16i8:  return "MVT::nxv16i8";
21309467b48Spatrick   case MVT::nxv32i8:  return "MVT::nxv32i8";
214097a140dSpatrick   case MVT::nxv64i8:  return "MVT::nxv64i8";
21509467b48Spatrick   case MVT::nxv1i16:  return "MVT::nxv1i16";
21609467b48Spatrick   case MVT::nxv2i16:  return "MVT::nxv2i16";
21709467b48Spatrick   case MVT::nxv4i16:  return "MVT::nxv4i16";
21809467b48Spatrick   case MVT::nxv8i16:  return "MVT::nxv8i16";
21909467b48Spatrick   case MVT::nxv16i16: return "MVT::nxv16i16";
22009467b48Spatrick   case MVT::nxv32i16: return "MVT::nxv32i16";
22109467b48Spatrick   case MVT::nxv1i32:  return "MVT::nxv1i32";
22209467b48Spatrick   case MVT::nxv2i32:  return "MVT::nxv2i32";
22309467b48Spatrick   case MVT::nxv4i32:  return "MVT::nxv4i32";
22409467b48Spatrick   case MVT::nxv8i32:  return "MVT::nxv8i32";
22509467b48Spatrick   case MVT::nxv16i32: return "MVT::nxv16i32";
226097a140dSpatrick   case MVT::nxv32i32: return "MVT::nxv32i32";
22709467b48Spatrick   case MVT::nxv1i64:  return "MVT::nxv1i64";
22809467b48Spatrick   case MVT::nxv2i64:  return "MVT::nxv2i64";
22909467b48Spatrick   case MVT::nxv4i64:  return "MVT::nxv4i64";
23009467b48Spatrick   case MVT::nxv8i64:  return "MVT::nxv8i64";
23109467b48Spatrick   case MVT::nxv16i64: return "MVT::nxv16i64";
232097a140dSpatrick   case MVT::nxv32i64: return "MVT::nxv32i64";
233097a140dSpatrick   case MVT::nxv1f16:  return "MVT::nxv1f16";
23409467b48Spatrick   case MVT::nxv2f16:  return "MVT::nxv2f16";
23509467b48Spatrick   case MVT::nxv4f16:  return "MVT::nxv4f16";
23609467b48Spatrick   case MVT::nxv8f16:  return "MVT::nxv8f16";
237097a140dSpatrick   case MVT::nxv16f16: return "MVT::nxv16f16";
238097a140dSpatrick   case MVT::nxv32f16: return "MVT::nxv32f16";
23973471bf0Spatrick   case MVT::nxv1bf16:  return "MVT::nxv1bf16";
240097a140dSpatrick   case MVT::nxv2bf16:  return "MVT::nxv2bf16";
241097a140dSpatrick   case MVT::nxv4bf16:  return "MVT::nxv4bf16";
242097a140dSpatrick   case MVT::nxv8bf16:  return "MVT::nxv8bf16";
243*d415bd75Srobert   case MVT::nxv16bf16: return "MVT::nxv16bf16";
244*d415bd75Srobert   case MVT::nxv32bf16: return "MVT::nxv32bf16";
24509467b48Spatrick   case MVT::nxv1f32:   return "MVT::nxv1f32";
24609467b48Spatrick   case MVT::nxv2f32:   return "MVT::nxv2f32";
24709467b48Spatrick   case MVT::nxv4f32:   return "MVT::nxv4f32";
24809467b48Spatrick   case MVT::nxv8f32:   return "MVT::nxv8f32";
24909467b48Spatrick   case MVT::nxv16f32:  return "MVT::nxv16f32";
25009467b48Spatrick   case MVT::nxv1f64:   return "MVT::nxv1f64";
25109467b48Spatrick   case MVT::nxv2f64:   return "MVT::nxv2f64";
25209467b48Spatrick   case MVT::nxv4f64:   return "MVT::nxv4f64";
25309467b48Spatrick   case MVT::nxv8f64:   return "MVT::nxv8f64";
25409467b48Spatrick   case MVT::token:     return "MVT::token";
25509467b48Spatrick   case MVT::Metadata:  return "MVT::Metadata";
25609467b48Spatrick   case MVT::iPTR:      return "MVT::iPTR";
25709467b48Spatrick   case MVT::iPTRAny:   return "MVT::iPTRAny";
25809467b48Spatrick   case MVT::Untyped:   return "MVT::Untyped";
25973471bf0Spatrick   case MVT::funcref:   return "MVT::funcref";
26073471bf0Spatrick   case MVT::externref: return "MVT::externref";
26109467b48Spatrick   default: llvm_unreachable("ILLEGAL VALUE TYPE!");
26209467b48Spatrick   }
263*d415bd75Srobert   // clang-format on
26409467b48Spatrick }
26509467b48Spatrick 
26609467b48Spatrick /// getQualifiedName - Return the name of the specified record, with a
26709467b48Spatrick /// namespace qualifier if the record contains one.
26809467b48Spatrick ///
getQualifiedName(const Record * R)26909467b48Spatrick std::string llvm::getQualifiedName(const Record *R) {
27009467b48Spatrick   std::string Namespace;
27109467b48Spatrick   if (R->getValue("Namespace"))
272097a140dSpatrick     Namespace = std::string(R->getValueAsString("Namespace"));
273097a140dSpatrick   if (Namespace.empty())
274097a140dSpatrick     return std::string(R->getName());
27509467b48Spatrick   return Namespace + "::" + R->getName().str();
27609467b48Spatrick }
27709467b48Spatrick 
27809467b48Spatrick 
27909467b48Spatrick /// getTarget - Return the current instance of the Target class.
28009467b48Spatrick ///
CodeGenTarget(RecordKeeper & records)28109467b48Spatrick CodeGenTarget::CodeGenTarget(RecordKeeper &records)
28209467b48Spatrick   : Records(records), CGH(records) {
28309467b48Spatrick   std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
28409467b48Spatrick   if (Targets.size() == 0)
28573471bf0Spatrick     PrintFatalError("No 'Target' subclasses defined!");
28609467b48Spatrick   if (Targets.size() != 1)
28773471bf0Spatrick     PrintFatalError("Multiple subclasses of Target defined!");
28809467b48Spatrick   TargetRec = Targets[0];
28909467b48Spatrick }
29009467b48Spatrick 
~CodeGenTarget()29109467b48Spatrick CodeGenTarget::~CodeGenTarget() {
29209467b48Spatrick }
29309467b48Spatrick 
getName() const29473471bf0Spatrick StringRef CodeGenTarget::getName() const { return TargetRec->getName(); }
29509467b48Spatrick 
29673471bf0Spatrick /// getInstNamespace - Find and return the target machine's instruction
29773471bf0Spatrick /// namespace. The namespace is cached because it is requested multiple times.
getInstNamespace() const29809467b48Spatrick StringRef CodeGenTarget::getInstNamespace() const {
29973471bf0Spatrick   if (InstNamespace.empty()) {
30009467b48Spatrick     for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) {
30173471bf0Spatrick       // We are not interested in the "TargetOpcode" namespace.
30273471bf0Spatrick       if (Inst->Namespace != "TargetOpcode") {
30373471bf0Spatrick         InstNamespace = Inst->Namespace;
30473471bf0Spatrick         break;
30573471bf0Spatrick       }
30673471bf0Spatrick     }
30709467b48Spatrick   }
30809467b48Spatrick 
30973471bf0Spatrick   return InstNamespace;
31073471bf0Spatrick }
31173471bf0Spatrick 
getRegNamespace() const31273471bf0Spatrick StringRef CodeGenTarget::getRegNamespace() const {
31373471bf0Spatrick   auto &RegClasses = RegBank->getRegClasses();
31473471bf0Spatrick   return RegClasses.size() > 0 ? RegClasses.front().Namespace : "";
31509467b48Spatrick }
31609467b48Spatrick 
getInstructionSet() const31709467b48Spatrick Record *CodeGenTarget::getInstructionSet() const {
31809467b48Spatrick   return TargetRec->getValueAsDef("InstructionSet");
31909467b48Spatrick }
32009467b48Spatrick 
getAllowRegisterRenaming() const32109467b48Spatrick bool CodeGenTarget::getAllowRegisterRenaming() const {
32209467b48Spatrick   return TargetRec->getValueAsInt("AllowRegisterRenaming");
32309467b48Spatrick }
32409467b48Spatrick 
32509467b48Spatrick /// getAsmParser - Return the AssemblyParser definition for this target.
32609467b48Spatrick ///
getAsmParser() const32709467b48Spatrick Record *CodeGenTarget::getAsmParser() const {
32809467b48Spatrick   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
32909467b48Spatrick   if (AsmParserNum >= LI.size())
33009467b48Spatrick     PrintFatalError("Target does not have an AsmParser #" +
33109467b48Spatrick                     Twine(AsmParserNum) + "!");
33209467b48Spatrick   return LI[AsmParserNum];
33309467b48Spatrick }
33409467b48Spatrick 
33509467b48Spatrick /// getAsmParserVariant - Return the AssemblyParserVariant definition for
33609467b48Spatrick /// this target.
33709467b48Spatrick ///
getAsmParserVariant(unsigned i) const33809467b48Spatrick Record *CodeGenTarget::getAsmParserVariant(unsigned i) const {
33909467b48Spatrick   std::vector<Record*> LI =
34009467b48Spatrick     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
34109467b48Spatrick   if (i >= LI.size())
34209467b48Spatrick     PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) +
34309467b48Spatrick                     "!");
34409467b48Spatrick   return LI[i];
34509467b48Spatrick }
34609467b48Spatrick 
34709467b48Spatrick /// getAsmParserVariantCount - Return the AssemblyParserVariant definition
34809467b48Spatrick /// available for this target.
34909467b48Spatrick ///
getAsmParserVariantCount() const35009467b48Spatrick unsigned CodeGenTarget::getAsmParserVariantCount() const {
35109467b48Spatrick   std::vector<Record*> LI =
35209467b48Spatrick     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
35309467b48Spatrick   return LI.size();
35409467b48Spatrick }
35509467b48Spatrick 
35609467b48Spatrick /// getAsmWriter - Return the AssemblyWriter definition for this target.
35709467b48Spatrick ///
getAsmWriter() const35809467b48Spatrick Record *CodeGenTarget::getAsmWriter() const {
35909467b48Spatrick   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
36009467b48Spatrick   if (AsmWriterNum >= LI.size())
36109467b48Spatrick     PrintFatalError("Target does not have an AsmWriter #" +
36209467b48Spatrick                     Twine(AsmWriterNum) + "!");
36309467b48Spatrick   return LI[AsmWriterNum];
36409467b48Spatrick }
36509467b48Spatrick 
getRegBank() const36609467b48Spatrick CodeGenRegBank &CodeGenTarget::getRegBank() const {
36709467b48Spatrick   if (!RegBank)
36809467b48Spatrick     RegBank = std::make_unique<CodeGenRegBank>(Records, getHwModes());
36909467b48Spatrick   return *RegBank;
37009467b48Spatrick }
37109467b48Spatrick 
getSuperRegForSubReg(const ValueTypeByHwMode & ValueTy,CodeGenRegBank & RegBank,const CodeGenSubRegIndex * SubIdx,bool MustBeAllocatable) const372*d415bd75Srobert std::optional<CodeGenRegisterClass *> CodeGenTarget::getSuperRegForSubReg(
373*d415bd75Srobert     const ValueTypeByHwMode &ValueTy, CodeGenRegBank &RegBank,
374*d415bd75Srobert     const CodeGenSubRegIndex *SubIdx, bool MustBeAllocatable) const {
37509467b48Spatrick   std::vector<CodeGenRegisterClass *> Candidates;
37609467b48Spatrick   auto &RegClasses = RegBank.getRegClasses();
37709467b48Spatrick 
37809467b48Spatrick   // Try to find a register class which supports ValueTy, and also contains
37909467b48Spatrick   // SubIdx.
38009467b48Spatrick   for (CodeGenRegisterClass &RC : RegClasses) {
38109467b48Spatrick     // Is there a subclass of this class which contains this subregister index?
38209467b48Spatrick     CodeGenRegisterClass *SubClassWithSubReg = RC.getSubClassWithSubReg(SubIdx);
38309467b48Spatrick     if (!SubClassWithSubReg)
38409467b48Spatrick       continue;
38509467b48Spatrick 
38609467b48Spatrick     // We have a class. Check if it supports this value type.
38773471bf0Spatrick     if (!llvm::is_contained(SubClassWithSubReg->VTs, ValueTy))
38873471bf0Spatrick       continue;
38973471bf0Spatrick 
39073471bf0Spatrick     // If necessary, check that it is allocatable.
39173471bf0Spatrick     if (MustBeAllocatable && !SubClassWithSubReg->Allocatable)
39209467b48Spatrick       continue;
39309467b48Spatrick 
39409467b48Spatrick     // We have a register class which supports both the value type and
39509467b48Spatrick     // subregister index. Remember it.
39609467b48Spatrick     Candidates.push_back(SubClassWithSubReg);
39709467b48Spatrick   }
39809467b48Spatrick 
39909467b48Spatrick   // If we didn't find anything, we're done.
40009467b48Spatrick   if (Candidates.empty())
401*d415bd75Srobert     return std::nullopt;
40209467b48Spatrick 
40309467b48Spatrick   // Find and return the largest of our candidate classes.
40409467b48Spatrick   llvm::stable_sort(Candidates, [&](const CodeGenRegisterClass *A,
40509467b48Spatrick                                     const CodeGenRegisterClass *B) {
40609467b48Spatrick     if (A->getMembers().size() > B->getMembers().size())
40709467b48Spatrick       return true;
40809467b48Spatrick 
40909467b48Spatrick     if (A->getMembers().size() < B->getMembers().size())
41009467b48Spatrick       return false;
41109467b48Spatrick 
41209467b48Spatrick     // Order by name as a tie-breaker.
41309467b48Spatrick     return StringRef(A->getName()) < B->getName();
41409467b48Spatrick   });
41509467b48Spatrick 
41609467b48Spatrick   return Candidates[0];
41709467b48Spatrick }
41809467b48Spatrick 
ReadRegAltNameIndices() const41909467b48Spatrick void CodeGenTarget::ReadRegAltNameIndices() const {
42009467b48Spatrick   RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
42109467b48Spatrick   llvm::sort(RegAltNameIndices, LessRecord());
42209467b48Spatrick }
42309467b48Spatrick 
42409467b48Spatrick /// getRegisterByName - If there is a register with the specific AsmName,
42509467b48Spatrick /// return it.
getRegisterByName(StringRef Name) const42609467b48Spatrick const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
42773471bf0Spatrick   return getRegBank().getRegistersByName().lookup(Name);
42809467b48Spatrick }
42909467b48Spatrick 
getRegisterVTs(Record * R) const43009467b48Spatrick std::vector<ValueTypeByHwMode> CodeGenTarget::getRegisterVTs(Record *R)
43109467b48Spatrick       const {
43209467b48Spatrick   const CodeGenRegister *Reg = getRegBank().getReg(R);
43309467b48Spatrick   std::vector<ValueTypeByHwMode> Result;
43409467b48Spatrick   for (const auto &RC : getRegBank().getRegClasses()) {
43509467b48Spatrick     if (RC.contains(Reg)) {
43609467b48Spatrick       ArrayRef<ValueTypeByHwMode> InVTs = RC.getValueTypes();
43773471bf0Spatrick       llvm::append_range(Result, InVTs);
43809467b48Spatrick     }
43909467b48Spatrick   }
44009467b48Spatrick 
44109467b48Spatrick   // Remove duplicates.
44209467b48Spatrick   llvm::sort(Result);
44309467b48Spatrick   Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
44409467b48Spatrick   return Result;
44509467b48Spatrick }
44609467b48Spatrick 
44709467b48Spatrick 
ReadLegalValueTypes() const44809467b48Spatrick void CodeGenTarget::ReadLegalValueTypes() const {
44909467b48Spatrick   for (const auto &RC : getRegBank().getRegClasses())
45073471bf0Spatrick     llvm::append_range(LegalValueTypes, RC.VTs);
45109467b48Spatrick 
45209467b48Spatrick   // Remove duplicates.
45309467b48Spatrick   llvm::sort(LegalValueTypes);
45409467b48Spatrick   LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
45509467b48Spatrick                                     LegalValueTypes.end()),
45609467b48Spatrick                         LegalValueTypes.end());
45709467b48Spatrick }
45809467b48Spatrick 
getSchedModels() const45909467b48Spatrick CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
46009467b48Spatrick   if (!SchedModels)
46109467b48Spatrick     SchedModels = std::make_unique<CodeGenSchedModels>(Records, *this);
46209467b48Spatrick   return *SchedModels;
46309467b48Spatrick }
46409467b48Spatrick 
ReadInstructions() const46509467b48Spatrick void CodeGenTarget::ReadInstructions() const {
46609467b48Spatrick   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
46709467b48Spatrick   if (Insts.size() <= 2)
46809467b48Spatrick     PrintFatalError("No 'Instruction' subclasses defined!");
46909467b48Spatrick 
47009467b48Spatrick   // Parse the instructions defined in the .td file.
47109467b48Spatrick   for (unsigned i = 0, e = Insts.size(); i != e; ++i)
47209467b48Spatrick     Instructions[Insts[i]] = std::make_unique<CodeGenInstruction>(Insts[i]);
47309467b48Spatrick }
47409467b48Spatrick 
47509467b48Spatrick static const CodeGenInstruction *
GetInstByName(const char * Name,const DenseMap<const Record *,std::unique_ptr<CodeGenInstruction>> & Insts,RecordKeeper & Records)47609467b48Spatrick GetInstByName(const char *Name,
47709467b48Spatrick               const DenseMap<const Record*,
47809467b48Spatrick                              std::unique_ptr<CodeGenInstruction>> &Insts,
47909467b48Spatrick               RecordKeeper &Records) {
48009467b48Spatrick   const Record *Rec = Records.getDef(Name);
48109467b48Spatrick 
48209467b48Spatrick   const auto I = Insts.find(Rec);
48309467b48Spatrick   if (!Rec || I == Insts.end())
48409467b48Spatrick     PrintFatalError(Twine("Could not find '") + Name + "' instruction!");
48509467b48Spatrick   return I->second.get();
48609467b48Spatrick }
48709467b48Spatrick 
488*d415bd75Srobert static const char *FixedInstrs[] = {
48909467b48Spatrick #define HANDLE_TARGET_OPCODE(OPC) #OPC,
49009467b48Spatrick #include "llvm/Support/TargetOpcodes.def"
49109467b48Spatrick     nullptr};
49209467b48Spatrick 
getNumFixedInstructions()49309467b48Spatrick unsigned CodeGenTarget::getNumFixedInstructions() {
494*d415bd75Srobert   return std::size(FixedInstrs) - 1;
49509467b48Spatrick }
49609467b48Spatrick 
49709467b48Spatrick /// Return all of the instructions defined by the target, ordered by
49809467b48Spatrick /// their enum value.
ComputeInstrsByEnum() const49909467b48Spatrick void CodeGenTarget::ComputeInstrsByEnum() const {
50009467b48Spatrick   const auto &Insts = getInstructions();
50109467b48Spatrick   for (const char *const *p = FixedInstrs; *p; ++p) {
50209467b48Spatrick     const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
50309467b48Spatrick     assert(Instr && "Missing target independent instruction");
50409467b48Spatrick     assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
50509467b48Spatrick     InstrsByEnum.push_back(Instr);
50609467b48Spatrick   }
50709467b48Spatrick   unsigned EndOfPredefines = InstrsByEnum.size();
50809467b48Spatrick   assert(EndOfPredefines == getNumFixedInstructions() &&
50909467b48Spatrick          "Missing generic opcode");
51009467b48Spatrick 
51109467b48Spatrick   for (const auto &I : Insts) {
51209467b48Spatrick     const CodeGenInstruction *CGI = I.second.get();
51309467b48Spatrick     if (CGI->Namespace != "TargetOpcode") {
51409467b48Spatrick       InstrsByEnum.push_back(CGI);
51509467b48Spatrick       if (CGI->TheDef->getValueAsBit("isPseudo"))
51609467b48Spatrick         ++NumPseudoInstructions;
51709467b48Spatrick     }
51809467b48Spatrick   }
51909467b48Spatrick 
52009467b48Spatrick   assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
52109467b48Spatrick 
52209467b48Spatrick   // All of the instructions are now in random order based on the map iteration.
52309467b48Spatrick   llvm::sort(
52409467b48Spatrick       InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
52509467b48Spatrick       [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
52609467b48Spatrick         const auto &D1 = *Rec1->TheDef;
52709467b48Spatrick         const auto &D2 = *Rec2->TheDef;
52809467b48Spatrick         return std::make_tuple(!D1.getValueAsBit("isPseudo"), D1.getName()) <
52909467b48Spatrick                std::make_tuple(!D2.getValueAsBit("isPseudo"), D2.getName());
53009467b48Spatrick       });
53109467b48Spatrick }
53209467b48Spatrick 
53309467b48Spatrick 
53409467b48Spatrick /// isLittleEndianEncoding - Return whether this target encodes its instruction
53509467b48Spatrick /// in little-endian format, i.e. bits laid out in the order [0..n]
53609467b48Spatrick ///
isLittleEndianEncoding() const53709467b48Spatrick bool CodeGenTarget::isLittleEndianEncoding() const {
53809467b48Spatrick   return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
53909467b48Spatrick }
54009467b48Spatrick 
54109467b48Spatrick /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
54209467b48Spatrick /// encodings, reverse the bit order of all instructions.
reverseBitsForLittleEndianEncoding()54309467b48Spatrick void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
54409467b48Spatrick   if (!isLittleEndianEncoding())
54509467b48Spatrick     return;
54609467b48Spatrick 
54709467b48Spatrick   std::vector<Record *> Insts =
54809467b48Spatrick       Records.getAllDerivedDefinitions("InstructionEncoding");
54909467b48Spatrick   for (Record *R : Insts) {
55009467b48Spatrick     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
55109467b48Spatrick         R->getValueAsBit("isPseudo"))
55209467b48Spatrick       continue;
55309467b48Spatrick 
55409467b48Spatrick     BitsInit *BI = R->getValueAsBitsInit("Inst");
55509467b48Spatrick 
55609467b48Spatrick     unsigned numBits = BI->getNumBits();
55709467b48Spatrick 
55809467b48Spatrick     SmallVector<Init *, 16> NewBits(numBits);
55909467b48Spatrick 
56009467b48Spatrick     for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
56109467b48Spatrick       unsigned bitSwapIdx = numBits - bit - 1;
56209467b48Spatrick       Init *OrigBit = BI->getBit(bit);
56309467b48Spatrick       Init *BitSwap = BI->getBit(bitSwapIdx);
56409467b48Spatrick       NewBits[bit]        = BitSwap;
56509467b48Spatrick       NewBits[bitSwapIdx] = OrigBit;
56609467b48Spatrick     }
56709467b48Spatrick     if (numBits % 2) {
56809467b48Spatrick       unsigned middle = (numBits + 1) / 2;
56909467b48Spatrick       NewBits[middle] = BI->getBit(middle);
57009467b48Spatrick     }
57109467b48Spatrick 
572*d415bd75Srobert     BitsInit *NewBI = BitsInit::get(Records, NewBits);
57309467b48Spatrick 
57409467b48Spatrick     // Update the bits in reversed order so that emitInstrOpBits will get the
57509467b48Spatrick     // correct endianness.
57609467b48Spatrick     R->getValue("Inst")->setValue(NewBI);
57709467b48Spatrick   }
57809467b48Spatrick }
57909467b48Spatrick 
58009467b48Spatrick /// guessInstructionProperties - Return true if it's OK to guess instruction
58109467b48Spatrick /// properties instead of raising an error.
58209467b48Spatrick ///
58309467b48Spatrick /// This is configurable as a temporary migration aid. It will eventually be
58409467b48Spatrick /// permanently false.
guessInstructionProperties() const58509467b48Spatrick bool CodeGenTarget::guessInstructionProperties() const {
58609467b48Spatrick   return getInstructionSet()->getValueAsBit("guessInstructionProperties");
58709467b48Spatrick }
58809467b48Spatrick 
58909467b48Spatrick //===----------------------------------------------------------------------===//
59009467b48Spatrick // ComplexPattern implementation
59109467b48Spatrick //
ComplexPattern(Record * R)59209467b48Spatrick ComplexPattern::ComplexPattern(Record *R) {
593*d415bd75Srobert   Ty          = R->getValueAsDef("Ty");
59409467b48Spatrick   NumOperands = R->getValueAsInt("NumOperands");
595097a140dSpatrick   SelectFunc = std::string(R->getValueAsString("SelectFunc"));
59609467b48Spatrick   RootNodes   = R->getValueAsListOfDefs("RootNodes");
59709467b48Spatrick 
59809467b48Spatrick   // FIXME: This is a hack to statically increase the priority of patterns which
59909467b48Spatrick   // maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. To get best
60009467b48Spatrick   // possible pattern match we'll need to dynamically calculate the complexity
60109467b48Spatrick   // of all patterns a dag can potentially map to.
60209467b48Spatrick   int64_t RawComplexity = R->getValueAsInt("Complexity");
60309467b48Spatrick   if (RawComplexity == -1)
60409467b48Spatrick     Complexity = NumOperands * 3;
60509467b48Spatrick   else
60609467b48Spatrick     Complexity = RawComplexity;
60709467b48Spatrick 
60809467b48Spatrick   // FIXME: Why is this different from parseSDPatternOperatorProperties?
60909467b48Spatrick   // Parse the properties.
61009467b48Spatrick   Properties = 0;
61109467b48Spatrick   std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
61209467b48Spatrick   for (unsigned i = 0, e = PropList.size(); i != e; ++i)
61309467b48Spatrick     if (PropList[i]->getName() == "SDNPHasChain") {
61409467b48Spatrick       Properties |= 1 << SDNPHasChain;
61509467b48Spatrick     } else if (PropList[i]->getName() == "SDNPOptInGlue") {
61609467b48Spatrick       Properties |= 1 << SDNPOptInGlue;
61709467b48Spatrick     } else if (PropList[i]->getName() == "SDNPMayStore") {
61809467b48Spatrick       Properties |= 1 << SDNPMayStore;
61909467b48Spatrick     } else if (PropList[i]->getName() == "SDNPMayLoad") {
62009467b48Spatrick       Properties |= 1 << SDNPMayLoad;
62109467b48Spatrick     } else if (PropList[i]->getName() == "SDNPSideEffect") {
62209467b48Spatrick       Properties |= 1 << SDNPSideEffect;
62309467b48Spatrick     } else if (PropList[i]->getName() == "SDNPMemOperand") {
62409467b48Spatrick       Properties |= 1 << SDNPMemOperand;
62509467b48Spatrick     } else if (PropList[i]->getName() == "SDNPVariadic") {
62609467b48Spatrick       Properties |= 1 << SDNPVariadic;
62709467b48Spatrick     } else if (PropList[i]->getName() == "SDNPWantRoot") {
62809467b48Spatrick       Properties |= 1 << SDNPWantRoot;
62909467b48Spatrick     } else if (PropList[i]->getName() == "SDNPWantParent") {
63009467b48Spatrick       Properties |= 1 << SDNPWantParent;
63109467b48Spatrick     } else {
63209467b48Spatrick       PrintFatalError(R->getLoc(), "Unsupported SD Node property '" +
63309467b48Spatrick                                        PropList[i]->getName() +
63409467b48Spatrick                                        "' on ComplexPattern '" + R->getName() +
63509467b48Spatrick                                        "'!");
63609467b48Spatrick     }
63709467b48Spatrick }
63809467b48Spatrick 
63909467b48Spatrick //===----------------------------------------------------------------------===//
64009467b48Spatrick // CodeGenIntrinsic Implementation
64109467b48Spatrick //===----------------------------------------------------------------------===//
64209467b48Spatrick 
CodeGenIntrinsicTable(const RecordKeeper & RC)64309467b48Spatrick CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
64473471bf0Spatrick   std::vector<Record *> IntrProperties =
64573471bf0Spatrick       RC.getAllDerivedDefinitions("IntrinsicProperty");
64609467b48Spatrick 
64773471bf0Spatrick   std::vector<Record *> DefaultProperties;
64873471bf0Spatrick   for (Record *Rec : IntrProperties)
64973471bf0Spatrick     if (Rec->getValueAsBit("IsDefault"))
65073471bf0Spatrick       DefaultProperties.push_back(Rec);
65173471bf0Spatrick 
65273471bf0Spatrick   std::vector<Record *> Defs = RC.getAllDerivedDefinitions("Intrinsic");
65309467b48Spatrick   Intrinsics.reserve(Defs.size());
65409467b48Spatrick 
65509467b48Spatrick   for (unsigned I = 0, e = Defs.size(); I != e; ++I)
65673471bf0Spatrick     Intrinsics.push_back(CodeGenIntrinsic(Defs[I], DefaultProperties));
65709467b48Spatrick 
65809467b48Spatrick   llvm::sort(Intrinsics,
65909467b48Spatrick              [](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
66009467b48Spatrick                return std::tie(LHS.TargetPrefix, LHS.Name) <
66109467b48Spatrick                       std::tie(RHS.TargetPrefix, RHS.Name);
66209467b48Spatrick              });
66309467b48Spatrick   Targets.push_back({"", 0, 0});
66409467b48Spatrick   for (size_t I = 0, E = Intrinsics.size(); I < E; ++I)
66509467b48Spatrick     if (Intrinsics[I].TargetPrefix != Targets.back().Name) {
66609467b48Spatrick       Targets.back().Count = I - Targets.back().Offset;
66709467b48Spatrick       Targets.push_back({Intrinsics[I].TargetPrefix, I, 0});
66809467b48Spatrick     }
66909467b48Spatrick   Targets.back().Count = Intrinsics.size() - Targets.back().Offset;
67009467b48Spatrick }
67109467b48Spatrick 
CodeGenIntrinsic(Record * R,std::vector<Record * > DefaultProperties)67273471bf0Spatrick CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
67373471bf0Spatrick                                    std::vector<Record *> DefaultProperties) {
67409467b48Spatrick   TheDef = R;
675097a140dSpatrick   std::string DefName = std::string(R->getName());
67609467b48Spatrick   ArrayRef<SMLoc> DefLoc = R->getLoc();
67709467b48Spatrick   Properties = 0;
67809467b48Spatrick   isOverloaded = false;
67909467b48Spatrick   isCommutative = false;
68009467b48Spatrick   canThrow = false;
68109467b48Spatrick   isNoReturn = false;
682*d415bd75Srobert   isNoCallback = false;
683097a140dSpatrick   isNoSync = false;
684097a140dSpatrick   isNoFree = false;
68509467b48Spatrick   isWillReturn = false;
68609467b48Spatrick   isCold = false;
68709467b48Spatrick   isNoDuplicate = false;
68873471bf0Spatrick   isNoMerge = false;
68909467b48Spatrick   isConvergent = false;
69009467b48Spatrick   isSpeculatable = false;
69109467b48Spatrick   hasSideEffects = false;
69209467b48Spatrick 
693*d415bd75Srobert   if (DefName.size() <= 4 || DefName.substr(0, 4) != "int_")
69409467b48Spatrick     PrintFatalError(DefLoc,
69509467b48Spatrick                     "Intrinsic '" + DefName + "' does not start with 'int_'!");
69609467b48Spatrick 
697*d415bd75Srobert   EnumName = DefName.substr(4);
69809467b48Spatrick 
699*d415bd75Srobert   if (R->getValue("ClangBuiltinName"))  // Ignore a missing ClangBuiltinName field.
700*d415bd75Srobert     ClangBuiltinName = std::string(R->getValueAsString("ClangBuiltinName"));
70109467b48Spatrick   if (R->getValue("MSBuiltinName"))   // Ignore a missing MSBuiltinName field.
702097a140dSpatrick     MSBuiltinName = std::string(R->getValueAsString("MSBuiltinName"));
70309467b48Spatrick 
704097a140dSpatrick   TargetPrefix = std::string(R->getValueAsString("TargetPrefix"));
705097a140dSpatrick   Name = std::string(R->getValueAsString("LLVMName"));
70609467b48Spatrick 
70709467b48Spatrick   if (Name == "") {
70809467b48Spatrick     // If an explicit name isn't specified, derive one from the DefName.
70909467b48Spatrick     Name = "llvm.";
71009467b48Spatrick 
71109467b48Spatrick     for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
71209467b48Spatrick       Name += (EnumName[i] == '_') ? '.' : EnumName[i];
71309467b48Spatrick   } else {
71409467b48Spatrick     // Verify it starts with "llvm.".
715*d415bd75Srobert     if (Name.size() <= 5 || Name.substr(0, 5) != "llvm.")
71609467b48Spatrick       PrintFatalError(DefLoc, "Intrinsic '" + DefName +
71709467b48Spatrick                                   "'s name does not start with 'llvm.'!");
71809467b48Spatrick   }
71909467b48Spatrick 
72009467b48Spatrick   // If TargetPrefix is specified, make sure that Name starts with
72109467b48Spatrick   // "llvm.<targetprefix>.".
72209467b48Spatrick   if (!TargetPrefix.empty()) {
72309467b48Spatrick     if (Name.size() < 6+TargetPrefix.size() ||
724*d415bd75Srobert         Name.substr(5, 1 + TargetPrefix.size()) != (TargetPrefix + "."))
72509467b48Spatrick       PrintFatalError(DefLoc, "Intrinsic '" + DefName +
72609467b48Spatrick                                   "' does not start with 'llvm." +
72709467b48Spatrick                                   TargetPrefix + ".'!");
72809467b48Spatrick   }
72909467b48Spatrick 
73009467b48Spatrick   ListInit *RetTypes = R->getValueAsListInit("RetTypes");
73109467b48Spatrick   ListInit *ParamTypes = R->getValueAsListInit("ParamTypes");
73209467b48Spatrick 
73309467b48Spatrick   // First collate a list of overloaded types.
73409467b48Spatrick   std::vector<MVT::SimpleValueType> OverloadedVTs;
73509467b48Spatrick   for (ListInit *TypeList : {RetTypes, ParamTypes}) {
73609467b48Spatrick     for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
73709467b48Spatrick       Record *TyEl = TypeList->getElementAsRecord(i);
73809467b48Spatrick       assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
73909467b48Spatrick 
74009467b48Spatrick       if (TyEl->isSubClassOf("LLVMMatchType"))
74109467b48Spatrick         continue;
74209467b48Spatrick 
74309467b48Spatrick       MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
74409467b48Spatrick       if (MVT(VT).isOverloaded()) {
74509467b48Spatrick         OverloadedVTs.push_back(VT);
74609467b48Spatrick         isOverloaded = true;
74709467b48Spatrick       }
74809467b48Spatrick     }
74909467b48Spatrick   }
75009467b48Spatrick 
75109467b48Spatrick   // Parse the list of return types.
75209467b48Spatrick   ListInit *TypeList = RetTypes;
75309467b48Spatrick   for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
75409467b48Spatrick     Record *TyEl = TypeList->getElementAsRecord(i);
75509467b48Spatrick     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
75609467b48Spatrick     MVT::SimpleValueType VT;
75709467b48Spatrick     if (TyEl->isSubClassOf("LLVMMatchType")) {
75809467b48Spatrick       unsigned MatchTy = TyEl->getValueAsInt("Number");
75909467b48Spatrick       assert(MatchTy < OverloadedVTs.size() &&
76009467b48Spatrick              "Invalid matching number!");
76109467b48Spatrick       VT = OverloadedVTs[MatchTy];
76209467b48Spatrick       // It only makes sense to use the extended and truncated vector element
76309467b48Spatrick       // variants with iAny types; otherwise, if the intrinsic is not
76409467b48Spatrick       // overloaded, all the types can be specified directly.
76509467b48Spatrick       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
76609467b48Spatrick                !TyEl->isSubClassOf("LLVMTruncatedType")) ||
76709467b48Spatrick               VT == MVT::iAny || VT == MVT::vAny) &&
76809467b48Spatrick              "Expected iAny or vAny type");
76909467b48Spatrick     } else {
77009467b48Spatrick       VT = getValueType(TyEl->getValueAsDef("VT"));
77109467b48Spatrick     }
77209467b48Spatrick 
77309467b48Spatrick     // Reject invalid types.
77409467b48Spatrick     if (VT == MVT::isVoid)
77509467b48Spatrick       PrintFatalError(DefLoc, "Intrinsic '" + DefName +
77609467b48Spatrick                                   " has void in result type list!");
77709467b48Spatrick 
77809467b48Spatrick     IS.RetVTs.push_back(VT);
77909467b48Spatrick     IS.RetTypeDefs.push_back(TyEl);
78009467b48Spatrick   }
78109467b48Spatrick 
78209467b48Spatrick   // Parse the list of parameter types.
78309467b48Spatrick   TypeList = ParamTypes;
78409467b48Spatrick   for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
78509467b48Spatrick     Record *TyEl = TypeList->getElementAsRecord(i);
78609467b48Spatrick     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
78709467b48Spatrick     MVT::SimpleValueType VT;
78809467b48Spatrick     if (TyEl->isSubClassOf("LLVMMatchType")) {
78909467b48Spatrick       unsigned MatchTy = TyEl->getValueAsInt("Number");
79009467b48Spatrick       if (MatchTy >= OverloadedVTs.size()) {
79109467b48Spatrick         PrintError(R->getLoc(),
79209467b48Spatrick                    "Parameter #" + Twine(i) + " has out of bounds matching "
79309467b48Spatrick                    "number " + Twine(MatchTy));
79409467b48Spatrick         PrintFatalError(DefLoc,
79509467b48Spatrick                         Twine("ParamTypes is ") + TypeList->getAsString());
79609467b48Spatrick       }
79709467b48Spatrick       VT = OverloadedVTs[MatchTy];
79809467b48Spatrick       // It only makes sense to use the extended and truncated vector element
79909467b48Spatrick       // variants with iAny types; otherwise, if the intrinsic is not
80009467b48Spatrick       // overloaded, all the types can be specified directly.
80109467b48Spatrick       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
802097a140dSpatrick                !TyEl->isSubClassOf("LLVMTruncatedType")) ||
80309467b48Spatrick               VT == MVT::iAny || VT == MVT::vAny) &&
80409467b48Spatrick              "Expected iAny or vAny type");
80509467b48Spatrick     } else
80609467b48Spatrick       VT = getValueType(TyEl->getValueAsDef("VT"));
80709467b48Spatrick 
80809467b48Spatrick     // Reject invalid types.
80909467b48Spatrick     if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
81009467b48Spatrick       PrintFatalError(DefLoc, "Intrinsic '" + DefName +
81109467b48Spatrick                                   " has void in result type list!");
81209467b48Spatrick 
81309467b48Spatrick     IS.ParamVTs.push_back(VT);
81409467b48Spatrick     IS.ParamTypeDefs.push_back(TyEl);
81509467b48Spatrick   }
81609467b48Spatrick 
81709467b48Spatrick   // Parse the intrinsic properties.
81809467b48Spatrick   ListInit *PropList = R->getValueAsListInit("IntrProperties");
81909467b48Spatrick   for (unsigned i = 0, e = PropList->size(); i != e; ++i) {
82009467b48Spatrick     Record *Property = PropList->getElementAsRecord(i);
82109467b48Spatrick     assert(Property->isSubClassOf("IntrinsicProperty") &&
82209467b48Spatrick            "Expected a property!");
82309467b48Spatrick 
82473471bf0Spatrick     setProperty(Property);
82509467b48Spatrick   }
82609467b48Spatrick 
82773471bf0Spatrick   // Set default properties to true.
82873471bf0Spatrick   setDefaultProperties(R, DefaultProperties);
82973471bf0Spatrick 
83009467b48Spatrick   // Also record the SDPatternOperator Properties.
83109467b48Spatrick   Properties = parseSDPatternOperatorProperties(R);
83209467b48Spatrick 
83309467b48Spatrick   // Sort the argument attributes for later benefit.
834*d415bd75Srobert   for (auto &Attrs : ArgumentAttributes)
835*d415bd75Srobert     llvm::sort(Attrs);
83609467b48Spatrick }
83709467b48Spatrick 
setDefaultProperties(Record * R,std::vector<Record * > DefaultProperties)83873471bf0Spatrick void CodeGenIntrinsic::setDefaultProperties(
83973471bf0Spatrick     Record *R, std::vector<Record *> DefaultProperties) {
84073471bf0Spatrick   // opt-out of using default attributes.
84173471bf0Spatrick   if (R->getValueAsBit("DisableDefaultAttributes"))
84273471bf0Spatrick     return;
84373471bf0Spatrick 
84473471bf0Spatrick   for (Record *Rec : DefaultProperties)
84573471bf0Spatrick     setProperty(Rec);
84673471bf0Spatrick }
84773471bf0Spatrick 
setProperty(Record * R)84873471bf0Spatrick void CodeGenIntrinsic::setProperty(Record *R) {
84973471bf0Spatrick   if (R->getName() == "IntrNoMem")
850*d415bd75Srobert     ME = MemoryEffects::none();
85173471bf0Spatrick   else if (R->getName() == "IntrReadMem") {
852*d415bd75Srobert     if (ME.onlyWritesMemory())
85373471bf0Spatrick       PrintFatalError(TheDef->getLoc(),
85473471bf0Spatrick                       Twine("IntrReadMem cannot be used after IntrNoMem or "
85573471bf0Spatrick                             "IntrWriteMem. Default is ReadWrite"));
856*d415bd75Srobert     ME &= MemoryEffects::readOnly();
85773471bf0Spatrick   } else if (R->getName() == "IntrWriteMem") {
858*d415bd75Srobert     if (ME.onlyReadsMemory())
85973471bf0Spatrick       PrintFatalError(TheDef->getLoc(),
86073471bf0Spatrick                       Twine("IntrWriteMem cannot be used after IntrNoMem or "
86173471bf0Spatrick                             "IntrReadMem. Default is ReadWrite"));
862*d415bd75Srobert     ME &= MemoryEffects::writeOnly();
86373471bf0Spatrick   } else if (R->getName() == "IntrArgMemOnly")
864*d415bd75Srobert     ME &= MemoryEffects::argMemOnly();
86573471bf0Spatrick   else if (R->getName() == "IntrInaccessibleMemOnly")
866*d415bd75Srobert     ME &= MemoryEffects::inaccessibleMemOnly();
86773471bf0Spatrick   else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
868*d415bd75Srobert     ME &= MemoryEffects::inaccessibleOrArgMemOnly();
86973471bf0Spatrick   else if (R->getName() == "Commutative")
87073471bf0Spatrick     isCommutative = true;
87173471bf0Spatrick   else if (R->getName() == "Throws")
87273471bf0Spatrick     canThrow = true;
87373471bf0Spatrick   else if (R->getName() == "IntrNoDuplicate")
87473471bf0Spatrick     isNoDuplicate = true;
87573471bf0Spatrick   else if (R->getName() == "IntrNoMerge")
87673471bf0Spatrick     isNoMerge = true;
87773471bf0Spatrick   else if (R->getName() == "IntrConvergent")
87873471bf0Spatrick     isConvergent = true;
87973471bf0Spatrick   else if (R->getName() == "IntrNoReturn")
88073471bf0Spatrick     isNoReturn = true;
881*d415bd75Srobert   else if (R->getName() == "IntrNoCallback")
882*d415bd75Srobert     isNoCallback = true;
88373471bf0Spatrick   else if (R->getName() == "IntrNoSync")
88473471bf0Spatrick     isNoSync = true;
88573471bf0Spatrick   else if (R->getName() == "IntrNoFree")
88673471bf0Spatrick     isNoFree = true;
88773471bf0Spatrick   else if (R->getName() == "IntrWillReturn")
88873471bf0Spatrick     isWillReturn = !isNoReturn;
88973471bf0Spatrick   else if (R->getName() == "IntrCold")
89073471bf0Spatrick     isCold = true;
89173471bf0Spatrick   else if (R->getName() == "IntrSpeculatable")
89273471bf0Spatrick     isSpeculatable = true;
89373471bf0Spatrick   else if (R->getName() == "IntrHasSideEffects")
89473471bf0Spatrick     hasSideEffects = true;
89573471bf0Spatrick   else if (R->isSubClassOf("NoCapture")) {
89673471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
897*d415bd75Srobert     addArgAttribute(ArgNo, NoCapture);
89873471bf0Spatrick   } else if (R->isSubClassOf("NoAlias")) {
89973471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
900*d415bd75Srobert     addArgAttribute(ArgNo, NoAlias);
90173471bf0Spatrick   } else if (R->isSubClassOf("NoUndef")) {
90273471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
903*d415bd75Srobert     addArgAttribute(ArgNo, NoUndef);
904*d415bd75Srobert   } else if (R->isSubClassOf("NonNull")) {
905*d415bd75Srobert     unsigned ArgNo = R->getValueAsInt("ArgNo");
906*d415bd75Srobert     addArgAttribute(ArgNo, NonNull);
90773471bf0Spatrick   } else if (R->isSubClassOf("Returned")) {
90873471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
909*d415bd75Srobert     addArgAttribute(ArgNo, Returned);
91073471bf0Spatrick   } else if (R->isSubClassOf("ReadOnly")) {
91173471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
912*d415bd75Srobert     addArgAttribute(ArgNo, ReadOnly);
91373471bf0Spatrick   } else if (R->isSubClassOf("WriteOnly")) {
91473471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
915*d415bd75Srobert     addArgAttribute(ArgNo, WriteOnly);
91673471bf0Spatrick   } else if (R->isSubClassOf("ReadNone")) {
91773471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
918*d415bd75Srobert     addArgAttribute(ArgNo, ReadNone);
91973471bf0Spatrick   } else if (R->isSubClassOf("ImmArg")) {
92073471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
921*d415bd75Srobert     addArgAttribute(ArgNo, ImmArg);
92273471bf0Spatrick   } else if (R->isSubClassOf("Align")) {
92373471bf0Spatrick     unsigned ArgNo = R->getValueAsInt("ArgNo");
92473471bf0Spatrick     uint64_t Align = R->getValueAsInt("Align");
925*d415bd75Srobert     addArgAttribute(ArgNo, Alignment, Align);
92673471bf0Spatrick   } else
92773471bf0Spatrick     llvm_unreachable("Unknown property!");
92873471bf0Spatrick }
92973471bf0Spatrick 
isParamAPointer(unsigned ParamIdx) const93009467b48Spatrick bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
93109467b48Spatrick   if (ParamIdx >= IS.ParamVTs.size())
93209467b48Spatrick     return false;
93309467b48Spatrick   MVT ParamType = MVT(IS.ParamVTs[ParamIdx]);
93409467b48Spatrick   return ParamType == MVT::iPTR || ParamType == MVT::iPTRAny;
93509467b48Spatrick }
93609467b48Spatrick 
isParamImmArg(unsigned ParamIdx) const93709467b48Spatrick bool CodeGenIntrinsic::isParamImmArg(unsigned ParamIdx) const {
938097a140dSpatrick   // Convert argument index to attribute index starting from `FirstArgIndex`.
939*d415bd75Srobert   ++ParamIdx;
940*d415bd75Srobert   if (ParamIdx >= ArgumentAttributes.size())
941*d415bd75Srobert     return false;
942*d415bd75Srobert   ArgAttribute Val{ImmArg, 0};
943*d415bd75Srobert   return std::binary_search(ArgumentAttributes[ParamIdx].begin(),
944*d415bd75Srobert                             ArgumentAttributes[ParamIdx].end(), Val);
945*d415bd75Srobert }
946*d415bd75Srobert 
addArgAttribute(unsigned Idx,ArgAttrKind AK,uint64_t V)947*d415bd75Srobert void CodeGenIntrinsic::addArgAttribute(unsigned Idx, ArgAttrKind AK,
948*d415bd75Srobert                                        uint64_t V) {
949*d415bd75Srobert   if (Idx >= ArgumentAttributes.size())
950*d415bd75Srobert     ArgumentAttributes.resize(Idx + 1);
951*d415bd75Srobert   ArgumentAttributes[Idx].emplace_back(AK, V);
95209467b48Spatrick }
953