1f4a2713aSLionel Sambuc //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This class wraps target description classes used by the various code
11f4a2713aSLionel Sambuc // generation TableGen backends.  This makes it easier to access the data and
12f4a2713aSLionel Sambuc // provides a single place that needs to check it for validity.  All of these
13f4a2713aSLionel Sambuc // classes abort on error conditions.
14f4a2713aSLionel Sambuc //
15f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc #include "CodeGenTarget.h"
18f4a2713aSLionel Sambuc #include "CodeGenIntrinsics.h"
19f4a2713aSLionel Sambuc #include "CodeGenSchedule.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
23f4a2713aSLionel Sambuc #include "llvm/TableGen/Error.h"
24f4a2713aSLionel Sambuc #include "llvm/TableGen/Record.h"
25f4a2713aSLionel Sambuc #include <algorithm>
26f4a2713aSLionel Sambuc using namespace llvm;
27f4a2713aSLionel Sambuc 
28f4a2713aSLionel Sambuc static cl::opt<unsigned>
29f4a2713aSLionel Sambuc AsmParserNum("asmparsernum", cl::init(0),
30f4a2713aSLionel Sambuc              cl::desc("Make -gen-asm-parser emit assembly parser #N"));
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc static cl::opt<unsigned>
33f4a2713aSLionel Sambuc AsmWriterNum("asmwriternum", cl::init(0),
34f4a2713aSLionel Sambuc              cl::desc("Make -gen-asm-writer emit assembly writer #N"));
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc /// getValueType - Return the MVT::SimpleValueType that the specified TableGen
37f4a2713aSLionel Sambuc /// record corresponds to.
getValueType(Record * Rec)38f4a2713aSLionel Sambuc MVT::SimpleValueType llvm::getValueType(Record *Rec) {
39f4a2713aSLionel Sambuc   return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
40f4a2713aSLionel Sambuc }
41f4a2713aSLionel Sambuc 
getName(MVT::SimpleValueType T)42f4a2713aSLionel Sambuc std::string llvm::getName(MVT::SimpleValueType T) {
43f4a2713aSLionel Sambuc   switch (T) {
44f4a2713aSLionel Sambuc   case MVT::Other:   return "UNKNOWN";
45f4a2713aSLionel Sambuc   case MVT::iPTR:    return "TLI.getPointerTy()";
46f4a2713aSLionel Sambuc   case MVT::iPTRAny: return "TLI.getPointerTy()";
47f4a2713aSLionel Sambuc   default: return getEnumName(T);
48f4a2713aSLionel Sambuc   }
49f4a2713aSLionel Sambuc }
50f4a2713aSLionel Sambuc 
getEnumName(MVT::SimpleValueType T)51f4a2713aSLionel Sambuc std::string llvm::getEnumName(MVT::SimpleValueType T) {
52f4a2713aSLionel Sambuc   switch (T) {
53f4a2713aSLionel Sambuc   case MVT::Other:    return "MVT::Other";
54f4a2713aSLionel Sambuc   case MVT::i1:       return "MVT::i1";
55f4a2713aSLionel Sambuc   case MVT::i8:       return "MVT::i8";
56f4a2713aSLionel Sambuc   case MVT::i16:      return "MVT::i16";
57f4a2713aSLionel Sambuc   case MVT::i32:      return "MVT::i32";
58f4a2713aSLionel Sambuc   case MVT::i64:      return "MVT::i64";
59f4a2713aSLionel Sambuc   case MVT::i128:     return "MVT::i128";
60f4a2713aSLionel Sambuc   case MVT::iAny:     return "MVT::iAny";
61f4a2713aSLionel Sambuc   case MVT::fAny:     return "MVT::fAny";
62f4a2713aSLionel Sambuc   case MVT::vAny:     return "MVT::vAny";
63f4a2713aSLionel Sambuc   case MVT::f16:      return "MVT::f16";
64f4a2713aSLionel Sambuc   case MVT::f32:      return "MVT::f32";
65f4a2713aSLionel Sambuc   case MVT::f64:      return "MVT::f64";
66f4a2713aSLionel Sambuc   case MVT::f80:      return "MVT::f80";
67f4a2713aSLionel Sambuc   case MVT::f128:     return "MVT::f128";
68f4a2713aSLionel Sambuc   case MVT::ppcf128:  return "MVT::ppcf128";
69f4a2713aSLionel Sambuc   case MVT::x86mmx:   return "MVT::x86mmx";
70f4a2713aSLionel Sambuc   case MVT::Glue:     return "MVT::Glue";
71f4a2713aSLionel Sambuc   case MVT::isVoid:   return "MVT::isVoid";
72f4a2713aSLionel Sambuc   case MVT::v2i1:     return "MVT::v2i1";
73f4a2713aSLionel Sambuc   case MVT::v4i1:     return "MVT::v4i1";
74f4a2713aSLionel Sambuc   case MVT::v8i1:     return "MVT::v8i1";
75f4a2713aSLionel Sambuc   case MVT::v16i1:    return "MVT::v16i1";
76f4a2713aSLionel Sambuc   case MVT::v32i1:    return "MVT::v32i1";
77f4a2713aSLionel Sambuc   case MVT::v64i1:    return "MVT::v64i1";
78f4a2713aSLionel Sambuc   case MVT::v1i8:     return "MVT::v1i8";
79f4a2713aSLionel Sambuc   case MVT::v2i8:     return "MVT::v2i8";
80f4a2713aSLionel Sambuc   case MVT::v4i8:     return "MVT::v4i8";
81f4a2713aSLionel Sambuc   case MVT::v8i8:     return "MVT::v8i8";
82f4a2713aSLionel Sambuc   case MVT::v16i8:    return "MVT::v16i8";
83f4a2713aSLionel Sambuc   case MVT::v32i8:    return "MVT::v32i8";
84f4a2713aSLionel Sambuc   case MVT::v64i8:    return "MVT::v64i8";
85f4a2713aSLionel Sambuc   case MVT::v1i16:    return "MVT::v1i16";
86f4a2713aSLionel Sambuc   case MVT::v2i16:    return "MVT::v2i16";
87f4a2713aSLionel Sambuc   case MVT::v4i16:    return "MVT::v4i16";
88f4a2713aSLionel Sambuc   case MVT::v8i16:    return "MVT::v8i16";
89f4a2713aSLionel Sambuc   case MVT::v16i16:   return "MVT::v16i16";
90f4a2713aSLionel Sambuc   case MVT::v32i16:   return "MVT::v32i16";
91f4a2713aSLionel Sambuc   case MVT::v1i32:    return "MVT::v1i32";
92f4a2713aSLionel Sambuc   case MVT::v2i32:    return "MVT::v2i32";
93f4a2713aSLionel Sambuc   case MVT::v4i32:    return "MVT::v4i32";
94f4a2713aSLionel Sambuc   case MVT::v8i32:    return "MVT::v8i32";
95f4a2713aSLionel Sambuc   case MVT::v16i32:   return "MVT::v16i32";
96f4a2713aSLionel Sambuc   case MVT::v1i64:    return "MVT::v1i64";
97f4a2713aSLionel Sambuc   case MVT::v2i64:    return "MVT::v2i64";
98f4a2713aSLionel Sambuc   case MVT::v4i64:    return "MVT::v4i64";
99f4a2713aSLionel Sambuc   case MVT::v8i64:    return "MVT::v8i64";
100f4a2713aSLionel Sambuc   case MVT::v16i64:   return "MVT::v16i64";
101f4a2713aSLionel Sambuc   case MVT::v2f16:    return "MVT::v2f16";
102f4a2713aSLionel Sambuc   case MVT::v4f16:    return "MVT::v4f16";
103f4a2713aSLionel Sambuc   case MVT::v8f16:    return "MVT::v8f16";
104f4a2713aSLionel Sambuc   case MVT::v1f32:    return "MVT::v1f32";
105f4a2713aSLionel Sambuc   case MVT::v2f32:    return "MVT::v2f32";
106f4a2713aSLionel Sambuc   case MVT::v4f32:    return "MVT::v4f32";
107f4a2713aSLionel Sambuc   case MVT::v8f32:    return "MVT::v8f32";
108f4a2713aSLionel Sambuc   case MVT::v16f32:   return "MVT::v16f32";
109f4a2713aSLionel Sambuc   case MVT::v1f64:    return "MVT::v1f64";
110f4a2713aSLionel Sambuc   case MVT::v2f64:    return "MVT::v2f64";
111f4a2713aSLionel Sambuc   case MVT::v4f64:    return "MVT::v4f64";
112f4a2713aSLionel Sambuc   case MVT::v8f64:    return "MVT::v8f64";
113f4a2713aSLionel Sambuc   case MVT::Metadata: return "MVT::Metadata";
114f4a2713aSLionel Sambuc   case MVT::iPTR:     return "MVT::iPTR";
115f4a2713aSLionel Sambuc   case MVT::iPTRAny:  return "MVT::iPTRAny";
116f4a2713aSLionel Sambuc   case MVT::Untyped:  return "MVT::Untyped";
117f4a2713aSLionel Sambuc   default: llvm_unreachable("ILLEGAL VALUE TYPE!");
118f4a2713aSLionel Sambuc   }
119f4a2713aSLionel Sambuc }
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc /// getQualifiedName - Return the name of the specified record, with a
122f4a2713aSLionel Sambuc /// namespace qualifier if the record contains one.
123f4a2713aSLionel Sambuc ///
getQualifiedName(const Record * R)124f4a2713aSLionel Sambuc std::string llvm::getQualifiedName(const Record *R) {
125f4a2713aSLionel Sambuc   std::string Namespace;
126f4a2713aSLionel Sambuc   if (R->getValue("Namespace"))
127f4a2713aSLionel Sambuc      Namespace = R->getValueAsString("Namespace");
128f4a2713aSLionel Sambuc   if (Namespace.empty()) return R->getName();
129f4a2713aSLionel Sambuc   return Namespace + "::" + R->getName();
130f4a2713aSLionel Sambuc }
131f4a2713aSLionel Sambuc 
132f4a2713aSLionel Sambuc 
133f4a2713aSLionel Sambuc /// getTarget - Return the current instance of the Target class.
134f4a2713aSLionel Sambuc ///
CodeGenTarget(RecordKeeper & records)135f4a2713aSLionel Sambuc CodeGenTarget::CodeGenTarget(RecordKeeper &records)
136*0a6a1f1dSLionel Sambuc   : Records(records) {
137f4a2713aSLionel Sambuc   std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
138f4a2713aSLionel Sambuc   if (Targets.size() == 0)
139f4a2713aSLionel Sambuc     PrintFatalError("ERROR: No 'Target' subclasses defined!");
140f4a2713aSLionel Sambuc   if (Targets.size() != 1)
141f4a2713aSLionel Sambuc     PrintFatalError("ERROR: Multiple subclasses of Target defined!");
142f4a2713aSLionel Sambuc   TargetRec = Targets[0];
143f4a2713aSLionel Sambuc }
144f4a2713aSLionel Sambuc 
~CodeGenTarget()145f4a2713aSLionel Sambuc CodeGenTarget::~CodeGenTarget() {
146f4a2713aSLionel Sambuc }
147f4a2713aSLionel Sambuc 
getName() const148f4a2713aSLionel Sambuc const std::string &CodeGenTarget::getName() const {
149f4a2713aSLionel Sambuc   return TargetRec->getName();
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc 
getInstNamespace() const152f4a2713aSLionel Sambuc std::string CodeGenTarget::getInstNamespace() const {
153*0a6a1f1dSLionel Sambuc   for (const CodeGenInstruction *Inst : instructions()) {
154f4a2713aSLionel Sambuc     // Make sure not to pick up "TargetOpcode" by accidentally getting
155f4a2713aSLionel Sambuc     // the namespace off the PHI instruction or something.
156*0a6a1f1dSLionel Sambuc     if (Inst->Namespace != "TargetOpcode")
157*0a6a1f1dSLionel Sambuc       return Inst->Namespace;
158f4a2713aSLionel Sambuc   }
159f4a2713aSLionel Sambuc 
160f4a2713aSLionel Sambuc   return "";
161f4a2713aSLionel Sambuc }
162f4a2713aSLionel Sambuc 
getInstructionSet() const163f4a2713aSLionel Sambuc Record *CodeGenTarget::getInstructionSet() const {
164f4a2713aSLionel Sambuc   return TargetRec->getValueAsDef("InstructionSet");
165f4a2713aSLionel Sambuc }
166f4a2713aSLionel Sambuc 
167f4a2713aSLionel Sambuc 
168f4a2713aSLionel Sambuc /// getAsmParser - Return the AssemblyParser definition for this target.
169f4a2713aSLionel Sambuc ///
getAsmParser() const170f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmParser() const {
171f4a2713aSLionel Sambuc   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
172f4a2713aSLionel Sambuc   if (AsmParserNum >= LI.size())
173*0a6a1f1dSLionel Sambuc     PrintFatalError("Target does not have an AsmParser #" +
174*0a6a1f1dSLionel Sambuc                     Twine(AsmParserNum) + "!");
175f4a2713aSLionel Sambuc   return LI[AsmParserNum];
176f4a2713aSLionel Sambuc }
177f4a2713aSLionel Sambuc 
178f4a2713aSLionel Sambuc /// getAsmParserVariant - Return the AssmblyParserVariant definition for
179f4a2713aSLionel Sambuc /// this target.
180f4a2713aSLionel Sambuc ///
getAsmParserVariant(unsigned i) const181f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmParserVariant(unsigned i) const {
182f4a2713aSLionel Sambuc   std::vector<Record*> LI =
183f4a2713aSLionel Sambuc     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
184f4a2713aSLionel Sambuc   if (i >= LI.size())
185*0a6a1f1dSLionel Sambuc     PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) +
186*0a6a1f1dSLionel Sambuc                     "!");
187f4a2713aSLionel Sambuc   return LI[i];
188f4a2713aSLionel Sambuc }
189f4a2713aSLionel Sambuc 
190f4a2713aSLionel Sambuc /// getAsmParserVariantCount - Return the AssmblyParserVariant definition
191f4a2713aSLionel Sambuc /// available for this target.
192f4a2713aSLionel Sambuc ///
getAsmParserVariantCount() const193f4a2713aSLionel Sambuc unsigned CodeGenTarget::getAsmParserVariantCount() const {
194f4a2713aSLionel Sambuc   std::vector<Record*> LI =
195f4a2713aSLionel Sambuc     TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
196f4a2713aSLionel Sambuc   return LI.size();
197f4a2713aSLionel Sambuc }
198f4a2713aSLionel Sambuc 
199f4a2713aSLionel Sambuc /// getAsmWriter - Return the AssemblyWriter definition for this target.
200f4a2713aSLionel Sambuc ///
getAsmWriter() const201f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmWriter() const {
202f4a2713aSLionel Sambuc   std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
203f4a2713aSLionel Sambuc   if (AsmWriterNum >= LI.size())
204*0a6a1f1dSLionel Sambuc     PrintFatalError("Target does not have an AsmWriter #" +
205*0a6a1f1dSLionel Sambuc                     Twine(AsmWriterNum) + "!");
206f4a2713aSLionel Sambuc   return LI[AsmWriterNum];
207f4a2713aSLionel Sambuc }
208f4a2713aSLionel Sambuc 
getRegBank() const209f4a2713aSLionel Sambuc CodeGenRegBank &CodeGenTarget::getRegBank() const {
210f4a2713aSLionel Sambuc   if (!RegBank)
211*0a6a1f1dSLionel Sambuc     RegBank = llvm::make_unique<CodeGenRegBank>(Records);
212f4a2713aSLionel Sambuc   return *RegBank;
213f4a2713aSLionel Sambuc }
214f4a2713aSLionel Sambuc 
ReadRegAltNameIndices() const215f4a2713aSLionel Sambuc void CodeGenTarget::ReadRegAltNameIndices() const {
216f4a2713aSLionel Sambuc   RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
217f4a2713aSLionel Sambuc   std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord());
218f4a2713aSLionel Sambuc }
219f4a2713aSLionel Sambuc 
220f4a2713aSLionel Sambuc /// getRegisterByName - If there is a register with the specific AsmName,
221f4a2713aSLionel Sambuc /// return it.
getRegisterByName(StringRef Name) const222f4a2713aSLionel Sambuc const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
223f4a2713aSLionel Sambuc   const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName();
224f4a2713aSLionel Sambuc   StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name);
225f4a2713aSLionel Sambuc   if (I == Regs.end())
226*0a6a1f1dSLionel Sambuc     return nullptr;
227f4a2713aSLionel Sambuc   return I->second;
228f4a2713aSLionel Sambuc }
229f4a2713aSLionel Sambuc 
230f4a2713aSLionel Sambuc std::vector<MVT::SimpleValueType> CodeGenTarget::
getRegisterVTs(Record * R) const231f4a2713aSLionel Sambuc getRegisterVTs(Record *R) const {
232f4a2713aSLionel Sambuc   const CodeGenRegister *Reg = getRegBank().getReg(R);
233f4a2713aSLionel Sambuc   std::vector<MVT::SimpleValueType> Result;
234*0a6a1f1dSLionel Sambuc   for (const auto &RC : getRegBank().getRegClasses()) {
235f4a2713aSLionel Sambuc     if (RC.contains(Reg)) {
236f4a2713aSLionel Sambuc       ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
237f4a2713aSLionel Sambuc       Result.insert(Result.end(), InVTs.begin(), InVTs.end());
238f4a2713aSLionel Sambuc     }
239f4a2713aSLionel Sambuc   }
240f4a2713aSLionel Sambuc 
241f4a2713aSLionel Sambuc   // Remove duplicates.
242f4a2713aSLionel Sambuc   array_pod_sort(Result.begin(), Result.end());
243f4a2713aSLionel Sambuc   Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
244f4a2713aSLionel Sambuc   return Result;
245f4a2713aSLionel Sambuc }
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc 
ReadLegalValueTypes() const248f4a2713aSLionel Sambuc void CodeGenTarget::ReadLegalValueTypes() const {
249*0a6a1f1dSLionel Sambuc   for (const auto &RC : getRegBank().getRegClasses())
250*0a6a1f1dSLionel Sambuc     LegalValueTypes.insert(LegalValueTypes.end(), RC.VTs.begin(), RC.VTs.end());
251f4a2713aSLionel Sambuc 
252f4a2713aSLionel Sambuc   // Remove duplicates.
253f4a2713aSLionel Sambuc   std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
254f4a2713aSLionel Sambuc   LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
255f4a2713aSLionel Sambuc                                     LegalValueTypes.end()),
256f4a2713aSLionel Sambuc                         LegalValueTypes.end());
257f4a2713aSLionel Sambuc }
258f4a2713aSLionel Sambuc 
getSchedModels() const259f4a2713aSLionel Sambuc CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
260f4a2713aSLionel Sambuc   if (!SchedModels)
261*0a6a1f1dSLionel Sambuc     SchedModels = llvm::make_unique<CodeGenSchedModels>(Records, *this);
262f4a2713aSLionel Sambuc   return *SchedModels;
263f4a2713aSLionel Sambuc }
264f4a2713aSLionel Sambuc 
ReadInstructions() const265f4a2713aSLionel Sambuc void CodeGenTarget::ReadInstructions() const {
266f4a2713aSLionel Sambuc   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
267f4a2713aSLionel Sambuc   if (Insts.size() <= 2)
268f4a2713aSLionel Sambuc     PrintFatalError("No 'Instruction' subclasses defined!");
269f4a2713aSLionel Sambuc 
270f4a2713aSLionel Sambuc   // Parse the instructions defined in the .td file.
271f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Insts.size(); i != e; ++i)
272*0a6a1f1dSLionel Sambuc     Instructions[Insts[i]] = llvm::make_unique<CodeGenInstruction>(Insts[i]);
273f4a2713aSLionel Sambuc }
274f4a2713aSLionel Sambuc 
275f4a2713aSLionel Sambuc static const CodeGenInstruction *
GetInstByName(const char * Name,const DenseMap<const Record *,std::unique_ptr<CodeGenInstruction>> & Insts,RecordKeeper & Records)276f4a2713aSLionel Sambuc GetInstByName(const char *Name,
277*0a6a1f1dSLionel Sambuc               const DenseMap<const Record*,
278*0a6a1f1dSLionel Sambuc                              std::unique_ptr<CodeGenInstruction>> &Insts,
279f4a2713aSLionel Sambuc               RecordKeeper &Records) {
280f4a2713aSLionel Sambuc   const Record *Rec = Records.getDef(Name);
281f4a2713aSLionel Sambuc 
282*0a6a1f1dSLionel Sambuc   const auto I = Insts.find(Rec);
283*0a6a1f1dSLionel Sambuc   if (!Rec || I == Insts.end())
284*0a6a1f1dSLionel Sambuc     PrintFatalError(Twine("Could not find '") + Name + "' instruction!");
285*0a6a1f1dSLionel Sambuc   return I->second.get();
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc 
288*0a6a1f1dSLionel Sambuc /// \brief Return all of the instructions defined by the target, ordered by
289*0a6a1f1dSLionel Sambuc /// their enum value.
ComputeInstrsByEnum() const290f4a2713aSLionel Sambuc void CodeGenTarget::ComputeInstrsByEnum() const {
291f4a2713aSLionel Sambuc   // The ordering here must match the ordering in TargetOpcodes.h.
292f4a2713aSLionel Sambuc   static const char *const FixedInstrs[] = {
293*0a6a1f1dSLionel Sambuc       "PHI",          "INLINEASM",     "CFI_INSTRUCTION",  "EH_LABEL",
294*0a6a1f1dSLionel Sambuc       "GC_LABEL",     "KILL",          "EXTRACT_SUBREG",   "INSERT_SUBREG",
295*0a6a1f1dSLionel Sambuc       "IMPLICIT_DEF", "SUBREG_TO_REG", "COPY_TO_REGCLASS", "DBG_VALUE",
296*0a6a1f1dSLionel Sambuc       "REG_SEQUENCE", "COPY",          "BUNDLE",           "LIFETIME_START",
297*0a6a1f1dSLionel Sambuc       "LIFETIME_END", "STACKMAP",      "PATCHPOINT",       "LOAD_STACK_GUARD",
298*0a6a1f1dSLionel Sambuc       "STATEPOINT",   "FRAME_ALLOC",
299*0a6a1f1dSLionel Sambuc       nullptr};
300*0a6a1f1dSLionel Sambuc   const auto &Insts = getInstructions();
301f4a2713aSLionel Sambuc   for (const char *const *p = FixedInstrs; *p; ++p) {
302f4a2713aSLionel Sambuc     const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
303f4a2713aSLionel Sambuc     assert(Instr && "Missing target independent instruction");
304f4a2713aSLionel Sambuc     assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
305f4a2713aSLionel Sambuc     InstrsByEnum.push_back(Instr);
306f4a2713aSLionel Sambuc   }
307f4a2713aSLionel Sambuc   unsigned EndOfPredefines = InstrsByEnum.size();
308f4a2713aSLionel Sambuc 
309*0a6a1f1dSLionel Sambuc   for (const auto &I : Insts) {
310*0a6a1f1dSLionel Sambuc     const CodeGenInstruction *CGI = I.second.get();
311f4a2713aSLionel Sambuc     if (CGI->Namespace != "TargetOpcode")
312f4a2713aSLionel Sambuc       InstrsByEnum.push_back(CGI);
313f4a2713aSLionel Sambuc   }
314f4a2713aSLionel Sambuc 
315f4a2713aSLionel Sambuc   assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
316f4a2713aSLionel Sambuc 
317f4a2713aSLionel Sambuc   // All of the instructions are now in random order based on the map iteration.
318f4a2713aSLionel Sambuc   // Sort them by name.
319f4a2713aSLionel Sambuc   std::sort(InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
320*0a6a1f1dSLionel Sambuc             [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
321*0a6a1f1dSLionel Sambuc     return Rec1->TheDef->getName() < Rec2->TheDef->getName();
322*0a6a1f1dSLionel Sambuc   });
323f4a2713aSLionel Sambuc }
324f4a2713aSLionel Sambuc 
325f4a2713aSLionel Sambuc 
326f4a2713aSLionel Sambuc /// isLittleEndianEncoding - Return whether this target encodes its instruction
327f4a2713aSLionel Sambuc /// in little-endian format, i.e. bits laid out in the order [0..n]
328f4a2713aSLionel Sambuc ///
isLittleEndianEncoding() const329f4a2713aSLionel Sambuc bool CodeGenTarget::isLittleEndianEncoding() const {
330f4a2713aSLionel Sambuc   return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
331f4a2713aSLionel Sambuc }
332f4a2713aSLionel Sambuc 
333*0a6a1f1dSLionel Sambuc /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
334*0a6a1f1dSLionel Sambuc /// encodings, reverse the bit order of all instructions.
reverseBitsForLittleEndianEncoding()335*0a6a1f1dSLionel Sambuc void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
336*0a6a1f1dSLionel Sambuc   if (!isLittleEndianEncoding())
337*0a6a1f1dSLionel Sambuc     return;
338*0a6a1f1dSLionel Sambuc 
339*0a6a1f1dSLionel Sambuc   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
340*0a6a1f1dSLionel Sambuc   for (Record *R : Insts) {
341*0a6a1f1dSLionel Sambuc     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
342*0a6a1f1dSLionel Sambuc         R->getValueAsBit("isPseudo"))
343*0a6a1f1dSLionel Sambuc       continue;
344*0a6a1f1dSLionel Sambuc 
345*0a6a1f1dSLionel Sambuc     BitsInit *BI = R->getValueAsBitsInit("Inst");
346*0a6a1f1dSLionel Sambuc 
347*0a6a1f1dSLionel Sambuc     unsigned numBits = BI->getNumBits();
348*0a6a1f1dSLionel Sambuc 
349*0a6a1f1dSLionel Sambuc     SmallVector<Init *, 16> NewBits(numBits);
350*0a6a1f1dSLionel Sambuc 
351*0a6a1f1dSLionel Sambuc     for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
352*0a6a1f1dSLionel Sambuc       unsigned bitSwapIdx = numBits - bit - 1;
353*0a6a1f1dSLionel Sambuc       Init *OrigBit = BI->getBit(bit);
354*0a6a1f1dSLionel Sambuc       Init *BitSwap = BI->getBit(bitSwapIdx);
355*0a6a1f1dSLionel Sambuc       NewBits[bit]        = BitSwap;
356*0a6a1f1dSLionel Sambuc       NewBits[bitSwapIdx] = OrigBit;
357*0a6a1f1dSLionel Sambuc     }
358*0a6a1f1dSLionel Sambuc     if (numBits % 2) {
359*0a6a1f1dSLionel Sambuc       unsigned middle = (numBits + 1) / 2;
360*0a6a1f1dSLionel Sambuc       NewBits[middle] = BI->getBit(middle);
361*0a6a1f1dSLionel Sambuc     }
362*0a6a1f1dSLionel Sambuc 
363*0a6a1f1dSLionel Sambuc     BitsInit *NewBI = BitsInit::get(NewBits);
364*0a6a1f1dSLionel Sambuc 
365*0a6a1f1dSLionel Sambuc     // Update the bits in reversed order so that emitInstrOpBits will get the
366*0a6a1f1dSLionel Sambuc     // correct endianness.
367*0a6a1f1dSLionel Sambuc     R->getValue("Inst")->setValue(NewBI);
368*0a6a1f1dSLionel Sambuc   }
369*0a6a1f1dSLionel Sambuc }
370*0a6a1f1dSLionel Sambuc 
371f4a2713aSLionel Sambuc /// guessInstructionProperties - Return true if it's OK to guess instruction
372f4a2713aSLionel Sambuc /// properties instead of raising an error.
373f4a2713aSLionel Sambuc ///
374f4a2713aSLionel Sambuc /// This is configurable as a temporary migration aid. It will eventually be
375f4a2713aSLionel Sambuc /// permanently false.
guessInstructionProperties() const376f4a2713aSLionel Sambuc bool CodeGenTarget::guessInstructionProperties() const {
377f4a2713aSLionel Sambuc   return getInstructionSet()->getValueAsBit("guessInstructionProperties");
378f4a2713aSLionel Sambuc }
379f4a2713aSLionel Sambuc 
380f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
381f4a2713aSLionel Sambuc // ComplexPattern implementation
382f4a2713aSLionel Sambuc //
ComplexPattern(Record * R)383f4a2713aSLionel Sambuc ComplexPattern::ComplexPattern(Record *R) {
384f4a2713aSLionel Sambuc   Ty          = ::getValueType(R->getValueAsDef("Ty"));
385f4a2713aSLionel Sambuc   NumOperands = R->getValueAsInt("NumOperands");
386f4a2713aSLionel Sambuc   SelectFunc  = R->getValueAsString("SelectFunc");
387f4a2713aSLionel Sambuc   RootNodes   = R->getValueAsListOfDefs("RootNodes");
388f4a2713aSLionel Sambuc 
389f4a2713aSLionel Sambuc   // Parse the properties.
390f4a2713aSLionel Sambuc   Properties = 0;
391f4a2713aSLionel Sambuc   std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
392f4a2713aSLionel Sambuc   for (unsigned i = 0, e = PropList.size(); i != e; ++i)
393f4a2713aSLionel Sambuc     if (PropList[i]->getName() == "SDNPHasChain") {
394f4a2713aSLionel Sambuc       Properties |= 1 << SDNPHasChain;
395f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPOptInGlue") {
396f4a2713aSLionel Sambuc       Properties |= 1 << SDNPOptInGlue;
397f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPMayStore") {
398f4a2713aSLionel Sambuc       Properties |= 1 << SDNPMayStore;
399f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPMayLoad") {
400f4a2713aSLionel Sambuc       Properties |= 1 << SDNPMayLoad;
401f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPSideEffect") {
402f4a2713aSLionel Sambuc       Properties |= 1 << SDNPSideEffect;
403f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPMemOperand") {
404f4a2713aSLionel Sambuc       Properties |= 1 << SDNPMemOperand;
405f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPVariadic") {
406f4a2713aSLionel Sambuc       Properties |= 1 << SDNPVariadic;
407f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPWantRoot") {
408f4a2713aSLionel Sambuc       Properties |= 1 << SDNPWantRoot;
409f4a2713aSLionel Sambuc     } else if (PropList[i]->getName() == "SDNPWantParent") {
410f4a2713aSLionel Sambuc       Properties |= 1 << SDNPWantParent;
411f4a2713aSLionel Sambuc     } else {
412f4a2713aSLionel Sambuc       errs() << "Unsupported SD Node property '" << PropList[i]->getName()
413f4a2713aSLionel Sambuc              << "' on ComplexPattern '" << R->getName() << "'!\n";
414f4a2713aSLionel Sambuc       exit(1);
415f4a2713aSLionel Sambuc     }
416f4a2713aSLionel Sambuc }
417f4a2713aSLionel Sambuc 
418f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
419f4a2713aSLionel Sambuc // CodeGenIntrinsic Implementation
420f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
421f4a2713aSLionel Sambuc 
LoadIntrinsics(const RecordKeeper & RC,bool TargetOnly)422f4a2713aSLionel Sambuc std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
423f4a2713aSLionel Sambuc                                                    bool TargetOnly) {
424f4a2713aSLionel Sambuc   std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
425f4a2713aSLionel Sambuc 
426f4a2713aSLionel Sambuc   std::vector<CodeGenIntrinsic> Result;
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc   for (unsigned i = 0, e = I.size(); i != e; ++i) {
429f4a2713aSLionel Sambuc     bool isTarget = I[i]->getValueAsBit("isTarget");
430f4a2713aSLionel Sambuc     if (isTarget == TargetOnly)
431f4a2713aSLionel Sambuc       Result.push_back(CodeGenIntrinsic(I[i]));
432f4a2713aSLionel Sambuc   }
433f4a2713aSLionel Sambuc   return Result;
434f4a2713aSLionel Sambuc }
435f4a2713aSLionel Sambuc 
CodeGenIntrinsic(Record * R)436f4a2713aSLionel Sambuc CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
437f4a2713aSLionel Sambuc   TheDef = R;
438f4a2713aSLionel Sambuc   std::string DefName = R->getName();
439f4a2713aSLionel Sambuc   ModRef = ReadWriteMem;
440f4a2713aSLionel Sambuc   isOverloaded = false;
441f4a2713aSLionel Sambuc   isCommutative = false;
442f4a2713aSLionel Sambuc   canThrow = false;
443f4a2713aSLionel Sambuc   isNoReturn = false;
444*0a6a1f1dSLionel Sambuc   isNoDuplicate = false;
445f4a2713aSLionel Sambuc 
446f4a2713aSLionel Sambuc   if (DefName.size() <= 4 ||
447f4a2713aSLionel Sambuc       std::string(DefName.begin(), DefName.begin() + 4) != "int_")
448f4a2713aSLionel Sambuc     PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");
449f4a2713aSLionel Sambuc 
450f4a2713aSLionel Sambuc   EnumName = std::string(DefName.begin()+4, DefName.end());
451f4a2713aSLionel Sambuc 
452f4a2713aSLionel Sambuc   if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
453f4a2713aSLionel Sambuc     GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
454*0a6a1f1dSLionel Sambuc   if (R->getValue("MSBuiltinName"))   // Ignore a missing MSBuiltinName field.
455*0a6a1f1dSLionel Sambuc     MSBuiltinName = R->getValueAsString("MSBuiltinName");
456f4a2713aSLionel Sambuc 
457f4a2713aSLionel Sambuc   TargetPrefix = R->getValueAsString("TargetPrefix");
458f4a2713aSLionel Sambuc   Name = R->getValueAsString("LLVMName");
459f4a2713aSLionel Sambuc 
460f4a2713aSLionel Sambuc   if (Name == "") {
461f4a2713aSLionel Sambuc     // If an explicit name isn't specified, derive one from the DefName.
462f4a2713aSLionel Sambuc     Name = "llvm.";
463f4a2713aSLionel Sambuc 
464f4a2713aSLionel Sambuc     for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
465f4a2713aSLionel Sambuc       Name += (EnumName[i] == '_') ? '.' : EnumName[i];
466f4a2713aSLionel Sambuc   } else {
467f4a2713aSLionel Sambuc     // Verify it starts with "llvm.".
468f4a2713aSLionel Sambuc     if (Name.size() <= 5 ||
469f4a2713aSLionel Sambuc         std::string(Name.begin(), Name.begin() + 5) != "llvm.")
470f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
471f4a2713aSLionel Sambuc   }
472f4a2713aSLionel Sambuc 
473f4a2713aSLionel Sambuc   // If TargetPrefix is specified, make sure that Name starts with
474f4a2713aSLionel Sambuc   // "llvm.<targetprefix>.".
475f4a2713aSLionel Sambuc   if (!TargetPrefix.empty()) {
476f4a2713aSLionel Sambuc     if (Name.size() < 6+TargetPrefix.size() ||
477f4a2713aSLionel Sambuc         std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
478f4a2713aSLionel Sambuc         != (TargetPrefix + "."))
479f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
480f4a2713aSLionel Sambuc         TargetPrefix + ".'!");
481f4a2713aSLionel Sambuc   }
482f4a2713aSLionel Sambuc 
483f4a2713aSLionel Sambuc   // Parse the list of return types.
484f4a2713aSLionel Sambuc   std::vector<MVT::SimpleValueType> OverloadedVTs;
485f4a2713aSLionel Sambuc   ListInit *TypeList = R->getValueAsListInit("RetTypes");
486f4a2713aSLionel Sambuc   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
487f4a2713aSLionel Sambuc     Record *TyEl = TypeList->getElementAsRecord(i);
488f4a2713aSLionel Sambuc     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
489f4a2713aSLionel Sambuc     MVT::SimpleValueType VT;
490f4a2713aSLionel Sambuc     if (TyEl->isSubClassOf("LLVMMatchType")) {
491f4a2713aSLionel Sambuc       unsigned MatchTy = TyEl->getValueAsInt("Number");
492f4a2713aSLionel Sambuc       assert(MatchTy < OverloadedVTs.size() &&
493f4a2713aSLionel Sambuc              "Invalid matching number!");
494f4a2713aSLionel Sambuc       VT = OverloadedVTs[MatchTy];
495f4a2713aSLionel Sambuc       // It only makes sense to use the extended and truncated vector element
496f4a2713aSLionel Sambuc       // variants with iAny types; otherwise, if the intrinsic is not
497f4a2713aSLionel Sambuc       // overloaded, all the types can be specified directly.
498*0a6a1f1dSLionel Sambuc       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
499*0a6a1f1dSLionel Sambuc                !TyEl->isSubClassOf("LLVMTruncatedType")) ||
500f4a2713aSLionel Sambuc               VT == MVT::iAny || VT == MVT::vAny) &&
501f4a2713aSLionel Sambuc              "Expected iAny or vAny type");
502f4a2713aSLionel Sambuc     } else {
503f4a2713aSLionel Sambuc       VT = getValueType(TyEl->getValueAsDef("VT"));
504f4a2713aSLionel Sambuc     }
505*0a6a1f1dSLionel Sambuc     if (MVT(VT).isOverloaded()) {
506f4a2713aSLionel Sambuc       OverloadedVTs.push_back(VT);
507f4a2713aSLionel Sambuc       isOverloaded = true;
508f4a2713aSLionel Sambuc     }
509f4a2713aSLionel Sambuc 
510f4a2713aSLionel Sambuc     // Reject invalid types.
511f4a2713aSLionel Sambuc     if (VT == MVT::isVoid)
512f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
513f4a2713aSLionel Sambuc 
514f4a2713aSLionel Sambuc     IS.RetVTs.push_back(VT);
515f4a2713aSLionel Sambuc     IS.RetTypeDefs.push_back(TyEl);
516f4a2713aSLionel Sambuc   }
517f4a2713aSLionel Sambuc 
518f4a2713aSLionel Sambuc   // Parse the list of parameter types.
519f4a2713aSLionel Sambuc   TypeList = R->getValueAsListInit("ParamTypes");
520f4a2713aSLionel Sambuc   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
521f4a2713aSLionel Sambuc     Record *TyEl = TypeList->getElementAsRecord(i);
522f4a2713aSLionel Sambuc     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
523f4a2713aSLionel Sambuc     MVT::SimpleValueType VT;
524f4a2713aSLionel Sambuc     if (TyEl->isSubClassOf("LLVMMatchType")) {
525f4a2713aSLionel Sambuc       unsigned MatchTy = TyEl->getValueAsInt("Number");
526f4a2713aSLionel Sambuc       assert(MatchTy < OverloadedVTs.size() &&
527f4a2713aSLionel Sambuc              "Invalid matching number!");
528f4a2713aSLionel Sambuc       VT = OverloadedVTs[MatchTy];
529f4a2713aSLionel Sambuc       // It only makes sense to use the extended and truncated vector element
530f4a2713aSLionel Sambuc       // variants with iAny types; otherwise, if the intrinsic is not
531f4a2713aSLionel Sambuc       // overloaded, all the types can be specified directly.
532*0a6a1f1dSLionel Sambuc       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
533*0a6a1f1dSLionel Sambuc                !TyEl->isSubClassOf("LLVMTruncatedType") &&
534*0a6a1f1dSLionel Sambuc                !TyEl->isSubClassOf("LLVMVectorSameWidth") &&
535*0a6a1f1dSLionel Sambuc                !TyEl->isSubClassOf("LLVMPointerToElt")) ||
536f4a2713aSLionel Sambuc               VT == MVT::iAny || VT == MVT::vAny) &&
537f4a2713aSLionel Sambuc              "Expected iAny or vAny type");
538f4a2713aSLionel Sambuc     } else
539f4a2713aSLionel Sambuc       VT = getValueType(TyEl->getValueAsDef("VT"));
540f4a2713aSLionel Sambuc 
541*0a6a1f1dSLionel Sambuc     if (MVT(VT).isOverloaded()) {
542f4a2713aSLionel Sambuc       OverloadedVTs.push_back(VT);
543f4a2713aSLionel Sambuc       isOverloaded = true;
544f4a2713aSLionel Sambuc     }
545f4a2713aSLionel Sambuc 
546f4a2713aSLionel Sambuc     // Reject invalid types.
547f4a2713aSLionel Sambuc     if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
548f4a2713aSLionel Sambuc       PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
549f4a2713aSLionel Sambuc 
550f4a2713aSLionel Sambuc     IS.ParamVTs.push_back(VT);
551f4a2713aSLionel Sambuc     IS.ParamTypeDefs.push_back(TyEl);
552f4a2713aSLionel Sambuc   }
553f4a2713aSLionel Sambuc 
554f4a2713aSLionel Sambuc   // Parse the intrinsic properties.
555f4a2713aSLionel Sambuc   ListInit *PropList = R->getValueAsListInit("Properties");
556f4a2713aSLionel Sambuc   for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
557f4a2713aSLionel Sambuc     Record *Property = PropList->getElementAsRecord(i);
558f4a2713aSLionel Sambuc     assert(Property->isSubClassOf("IntrinsicProperty") &&
559f4a2713aSLionel Sambuc            "Expected a property!");
560f4a2713aSLionel Sambuc 
561f4a2713aSLionel Sambuc     if (Property->getName() == "IntrNoMem")
562f4a2713aSLionel Sambuc       ModRef = NoMem;
563f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrReadArgMem")
564f4a2713aSLionel Sambuc       ModRef = ReadArgMem;
565f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrReadMem")
566f4a2713aSLionel Sambuc       ModRef = ReadMem;
567f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrReadWriteArgMem")
568f4a2713aSLionel Sambuc       ModRef = ReadWriteArgMem;
569f4a2713aSLionel Sambuc     else if (Property->getName() == "Commutative")
570f4a2713aSLionel Sambuc       isCommutative = true;
571f4a2713aSLionel Sambuc     else if (Property->getName() == "Throws")
572f4a2713aSLionel Sambuc       canThrow = true;
573*0a6a1f1dSLionel Sambuc     else if (Property->getName() == "IntrNoDuplicate")
574*0a6a1f1dSLionel Sambuc       isNoDuplicate = true;
575f4a2713aSLionel Sambuc     else if (Property->getName() == "IntrNoReturn")
576f4a2713aSLionel Sambuc       isNoReturn = true;
577f4a2713aSLionel Sambuc     else if (Property->isSubClassOf("NoCapture")) {
578f4a2713aSLionel Sambuc       unsigned ArgNo = Property->getValueAsInt("ArgNo");
579f4a2713aSLionel Sambuc       ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
580f4a2713aSLionel Sambuc     } else if (Property->isSubClassOf("ReadOnly")) {
581f4a2713aSLionel Sambuc       unsigned ArgNo = Property->getValueAsInt("ArgNo");
582f4a2713aSLionel Sambuc       ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
583f4a2713aSLionel Sambuc     } else if (Property->isSubClassOf("ReadNone")) {
584f4a2713aSLionel Sambuc       unsigned ArgNo = Property->getValueAsInt("ArgNo");
585f4a2713aSLionel Sambuc       ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
586f4a2713aSLionel Sambuc     } else
587f4a2713aSLionel Sambuc       llvm_unreachable("Unknown property!");
588f4a2713aSLionel Sambuc   }
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc   // Sort the argument attributes for later benefit.
591f4a2713aSLionel Sambuc   std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end());
592f4a2713aSLionel Sambuc }
593