IntrinsicEmitter.cpp revision 245431
1193323Sed//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This tablegen backend emits information about intrinsic functions.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14245431Sdim#include "CodeGenIntrinsics.h"
15193323Sed#include "CodeGenTarget.h"
16245431Sdim#include "SequenceToOffsetTable.h"
17245431Sdim#include "llvm/ADT/StringExtras.h"
18245431Sdim#include "llvm/TableGen/Error.h"
19226890Sdim#include "llvm/TableGen/Record.h"
20245431Sdim#include "llvm/TableGen/StringMatcher.h"
21245431Sdim#include "llvm/TableGen/TableGenBackend.h"
22193323Sed#include <algorithm>
23193323Sedusing namespace llvm;
24193323Sed
25245431Sdimnamespace {
26245431Sdimclass IntrinsicEmitter {
27245431Sdim  RecordKeeper &Records;
28245431Sdim  bool TargetOnly;
29245431Sdim  std::string TargetPrefix;
30245431Sdim
31245431Sdimpublic:
32245431Sdim  IntrinsicEmitter(RecordKeeper &R, bool T)
33245431Sdim    : Records(R), TargetOnly(T) {}
34245431Sdim
35245431Sdim  void run(raw_ostream &OS);
36245431Sdim
37245431Sdim  void EmitPrefix(raw_ostream &OS);
38245431Sdim
39245431Sdim  void EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
40245431Sdim                    raw_ostream &OS);
41245431Sdim
42245431Sdim  void EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
43245431Sdim                            raw_ostream &OS);
44245431Sdim  void EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints,
45245431Sdim                                raw_ostream &OS);
46245431Sdim  void EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints,
47245431Sdim                                    raw_ostream &OS);
48245431Sdim  void EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
49245431Sdim                    raw_ostream &OS);
50245431Sdim  void EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
51245431Sdim                     raw_ostream &OS);
52245431Sdim  void EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints,
53245431Sdim                      raw_ostream &OS);
54245431Sdim  void EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints,
55245431Sdim                          raw_ostream &OS);
56245431Sdim  void EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
57245431Sdim                                    raw_ostream &OS);
58245431Sdim  void EmitSuffix(raw_ostream &OS);
59245431Sdim};
60245431Sdim} // End anonymous namespace
61245431Sdim
62193323Sed//===----------------------------------------------------------------------===//
63193323Sed// IntrinsicEmitter Implementation
64193323Sed//===----------------------------------------------------------------------===//
65193323Sed
66195340Sedvoid IntrinsicEmitter::run(raw_ostream &OS) {
67245431Sdim  emitSourceFileHeader("Intrinsic Function Source Fragment", OS);
68245431Sdim
69193323Sed  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly);
70245431Sdim
71193323Sed  if (TargetOnly && !Ints.empty())
72193323Sed    TargetPrefix = Ints[0].TargetPrefix;
73193323Sed
74208599Srdivacky  EmitPrefix(OS);
75208599Srdivacky
76193323Sed  // Emit the enum information.
77193323Sed  EmitEnumInfo(Ints, OS);
78193323Sed
79193323Sed  // Emit the intrinsic ID -> name table.
80193323Sed  EmitIntrinsicToNameTable(Ints, OS);
81193323Sed
82193323Sed  // Emit the intrinsic ID -> overload table.
83193323Sed  EmitIntrinsicToOverloadTable(Ints, OS);
84193323Sed
85193323Sed  // Emit the function name recognizer.
86193323Sed  EmitFnNameRecognizer(Ints, OS);
87193323Sed
88193323Sed  // Emit the intrinsic declaration generator.
89193323Sed  EmitGenerator(Ints, OS);
90193323Sed
91193323Sed  // Emit the intrinsic parameter attributes.
92193323Sed  EmitAttributes(Ints, OS);
93193323Sed
94193323Sed  // Emit intrinsic alias analysis mod/ref behavior.
95193323Sed  EmitModRefBehavior(Ints, OS);
96193323Sed
97193323Sed  // Emit code to translate GCC builtins into LLVM intrinsics.
98193323Sed  EmitIntrinsicToGCCBuiltinMap(Ints, OS);
99208599Srdivacky
100208599Srdivacky  EmitSuffix(OS);
101193323Sed}
102193323Sed
103208599Srdivackyvoid IntrinsicEmitter::EmitPrefix(raw_ostream &OS) {
104208599Srdivacky  OS << "// VisualStudio defines setjmp as _setjmp\n"
105218893Sdim        "#if defined(_MSC_VER) && defined(setjmp) && \\\n"
106218893Sdim        "                         !defined(setjmp_undefined_for_msvc)\n"
107218893Sdim        "#  pragma push_macro(\"setjmp\")\n"
108218893Sdim        "#  undef setjmp\n"
109218893Sdim        "#  define setjmp_undefined_for_msvc\n"
110208599Srdivacky        "#endif\n\n";
111208599Srdivacky}
112208599Srdivacky
113208599Srdivackyvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) {
114218893Sdim  OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n"
115208599Srdivacky        "// let's return it to _setjmp state\n"
116218893Sdim        "#  pragma pop_macro(\"setjmp\")\n"
117218893Sdim        "#  undef setjmp_undefined_for_msvc\n"
118208599Srdivacky        "#endif\n\n";
119208599Srdivacky}
120208599Srdivacky
121193323Sedvoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
122195340Sed                                    raw_ostream &OS) {
123193323Sed  OS << "// Enum values for Intrinsics.h\n";
124193323Sed  OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
125193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
126193323Sed    OS << "    " << Ints[i].EnumName;
127193323Sed    OS << ((i != e-1) ? ", " : "  ");
128193323Sed    OS << std::string(40-Ints[i].EnumName.size(), ' ')
129193323Sed      << "// " << Ints[i].Name << "\n";
130193323Sed  }
131193323Sed  OS << "#endif\n\n";
132193323Sed}
133193323Sed
134193323Sedvoid IntrinsicEmitter::
135193323SedEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
136195340Sed                     raw_ostream &OS) {
137218893Sdim  // Build a 'first character of function name' -> intrinsic # mapping.
138218893Sdim  std::map<char, std::vector<unsigned> > IntMapping;
139193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
140218893Sdim    IntMapping[Ints[i].Name[5]].push_back(i);
141218893Sdim
142193323Sed  OS << "// Function name -> enum value recognizer code.\n";
143193323Sed  OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
144218893Sdim  OS << "  StringRef NameR(Name+6, Len-6);   // Skip over 'llvm.'\n";
145218893Sdim  OS << "  switch (Name[5]) {                  // Dispatch on first letter.\n";
146218893Sdim  OS << "  default: break;\n";
147218893Sdim  // Emit the intrinsic matching stuff by first letter.
148218893Sdim  for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(),
149193323Sed       E = IntMapping.end(); I != E; ++I) {
150218893Sdim    OS << "  case '" << I->first << "':\n";
151218893Sdim    std::vector<unsigned> &IntList = I->second;
152218893Sdim
153218893Sdim    // Emit all the overloaded intrinsics first, build a table of the
154218893Sdim    // non-overloaded ones.
155218893Sdim    std::vector<StringMatcher::StringPair> MatchTable;
156218893Sdim
157218893Sdim    for (unsigned i = 0, e = IntList.size(); i != e; ++i) {
158218893Sdim      unsigned IntNo = IntList[i];
159218893Sdim      std::string Result = "return " + TargetPrefix + "Intrinsic::" +
160218893Sdim        Ints[IntNo].EnumName + ";";
161218893Sdim
162218893Sdim      if (!Ints[IntNo].isOverloaded) {
163218893Sdim        MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result));
164218893Sdim        continue;
165218893Sdim      }
166218893Sdim
167218893Sdim      // For overloaded intrinsics, only the prefix needs to match
168218893Sdim      std::string TheStr = Ints[IntNo].Name.substr(6);
169218893Sdim      TheStr += '.';  // Require "bswap." instead of bswap.
170218893Sdim      OS << "    if (NameR.startswith(\"" << TheStr << "\")) "
171218893Sdim         << Result << '\n';
172193323Sed    }
173193323Sed
174218893Sdim    // Emit the matcher logic for the fixed length strings.
175218893Sdim    StringMatcher("NameR", MatchTable, OS).Emit(1);
176218893Sdim    OS << "    break;  // end of '" << I->first << "' case.\n";
177193323Sed  }
178218893Sdim
179193323Sed  OS << "  }\n";
180193323Sed  OS << "#endif\n\n";
181193323Sed}
182193323Sed
183193323Sedvoid IntrinsicEmitter::
184193323SedEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints,
185195340Sed                         raw_ostream &OS) {
186193323Sed  OS << "// Intrinsic ID to name table\n";
187193323Sed  OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n";
188193323Sed  OS << "  // Note that entry #0 is the invalid intrinsic!\n";
189193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
190193323Sed    OS << "  \"" << Ints[i].Name << "\",\n";
191193323Sed  OS << "#endif\n\n";
192193323Sed}
193193323Sed
194193323Sedvoid IntrinsicEmitter::
195193323SedEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints,
196195340Sed                         raw_ostream &OS) {
197235633Sdim  OS << "// Intrinsic ID to overload bitset\n";
198193323Sed  OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n";
199235633Sdim  OS << "static const uint8_t OTable[] = {\n";
200235633Sdim  OS << "  0";
201193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
202235633Sdim    // Add one to the index so we emit a null bit for the invalid #0 intrinsic.
203235633Sdim    if ((i+1)%8 == 0)
204235633Sdim      OS << ",\n  0";
205193323Sed    if (Ints[i].isOverloaded)
206235633Sdim      OS << " | (1<<" << (i+1)%8 << ')';
207193323Sed  }
208235633Sdim  OS << "\n};\n\n";
209235633Sdim  // OTable contains a true bit at the position if the intrinsic is overloaded.
210235633Sdim  OS << "return (OTable[id/8] & (1 << (id%8))) != 0;\n";
211193323Sed  OS << "#endif\n\n";
212193323Sed}
213193323Sed
214245431Sdim
215245431Sdim// NOTE: This must be kept in synch with the copy in lib/VMCore/Function.cpp!
216245431Sdimenum IIT_Info {
217245431Sdim  // Common values should be encoded with 0-15.
218245431Sdim  IIT_Done = 0,
219245431Sdim  IIT_I1   = 1,
220245431Sdim  IIT_I8   = 2,
221245431Sdim  IIT_I16  = 3,
222245431Sdim  IIT_I32  = 4,
223245431Sdim  IIT_I64  = 5,
224245431Sdim  IIT_F32  = 6,
225245431Sdim  IIT_F64  = 7,
226245431Sdim  IIT_V2   = 8,
227245431Sdim  IIT_V4   = 9,
228245431Sdim  IIT_V8   = 10,
229245431Sdim  IIT_V16  = 11,
230245431Sdim  IIT_V32  = 12,
231245431Sdim  IIT_MMX  = 13,
232245431Sdim  IIT_PTR  = 14,
233245431Sdim  IIT_ARG  = 15,
234245431Sdim
235245431Sdim  // Values from 16+ are only encodable with the inefficient encoding.
236245431Sdim  IIT_METADATA = 16,
237245431Sdim  IIT_EMPTYSTRUCT = 17,
238245431Sdim  IIT_STRUCT2 = 18,
239245431Sdim  IIT_STRUCT3 = 19,
240245431Sdim  IIT_STRUCT4 = 20,
241245431Sdim  IIT_STRUCT5 = 21,
242245431Sdim  IIT_EXTEND_VEC_ARG = 22,
243245431Sdim  IIT_TRUNC_VEC_ARG = 23,
244245431Sdim  IIT_ANYPTR = 24
245245431Sdim};
246245431Sdim
247245431Sdim
248245431Sdimstatic void EncodeFixedValueType(MVT::SimpleValueType VT,
249245431Sdim                                 std::vector<unsigned char> &Sig) {
250198090Srdivacky  if (EVT(VT).isInteger()) {
251198090Srdivacky    unsigned BitWidth = EVT(VT).getSizeInBits();
252245431Sdim    switch (BitWidth) {
253245431Sdim    default: PrintFatalError("unhandled integer type width in intrinsic!");
254245431Sdim    case 1: return Sig.push_back(IIT_I1);
255245431Sdim    case 8: return Sig.push_back(IIT_I8);
256245431Sdim    case 16: return Sig.push_back(IIT_I16);
257245431Sdim    case 32: return Sig.push_back(IIT_I32);
258245431Sdim    case 64: return Sig.push_back(IIT_I64);
259245431Sdim    }
260193323Sed  }
261245431Sdim
262245431Sdim  switch (VT) {
263245431Sdim  default: PrintFatalError("unhandled MVT in intrinsic!");
264245431Sdim  case MVT::f32: return Sig.push_back(IIT_F32);
265245431Sdim  case MVT::f64: return Sig.push_back(IIT_F64);
266245431Sdim  case MVT::Metadata: return Sig.push_back(IIT_METADATA);
267245431Sdim  case MVT::x86mmx: return Sig.push_back(IIT_MMX);
268245431Sdim  // MVT::OtherVT is used to mean the empty struct type here.
269245431Sdim  case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT);
270245431Sdim  }
271193323Sed}
272193323Sed
273245431Sdim#ifdef _MSC_VER
274245431Sdim#pragma optimize("",off) // MSVC 2010 optimizer can't deal with this function.
275245431Sdim#endif
276193323Sed
277245431Sdimstatic void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
278245431Sdim                            std::vector<unsigned char> &Sig) {
279206083Srdivacky
280245431Sdim  if (R->isSubClassOf("LLVMMatchType")) {
281245431Sdim    unsigned Number = R->getValueAsInt("Number");
282245431Sdim    assert(Number < ArgCodes.size() && "Invalid matching number!");
283245431Sdim    if (R->isSubClassOf("LLVMExtendedElementVectorType"))
284245431Sdim      Sig.push_back(IIT_EXTEND_VEC_ARG);
285245431Sdim    else if (R->isSubClassOf("LLVMTruncatedElementVectorType"))
286245431Sdim      Sig.push_back(IIT_TRUNC_VEC_ARG);
287245431Sdim    else
288245431Sdim      Sig.push_back(IIT_ARG);
289245431Sdim    return Sig.push_back((Number << 2) | ArgCodes[Number]);
290245431Sdim  }
291245431Sdim
292245431Sdim  MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT"));
293193323Sed
294245431Sdim  unsigned Tmp = 0;
295245431Sdim  switch (VT) {
296245431Sdim  default: break;
297245431Sdim  case MVT::iPTRAny: ++Tmp; // FALL THROUGH.
298245431Sdim  case MVT::vAny: ++Tmp; // FALL THROUGH.
299245431Sdim  case MVT::fAny: ++Tmp; // FALL THROUGH.
300245431Sdim  case MVT::iAny: {
301245431Sdim    // If this is an "any" valuetype, then the type is the type of the next
302245431Sdim    // type in the list specified to getIntrinsic().
303245431Sdim    Sig.push_back(IIT_ARG);
304245431Sdim
305245431Sdim    // Figure out what arg # this is consuming, and remember what kind it was.
306245431Sdim    unsigned ArgNo = ArgCodes.size();
307245431Sdim    ArgCodes.push_back(Tmp);
308245431Sdim
309245431Sdim    // Encode what sort of argument it must be in the low 2 bits of the ArgNo.
310245431Sdim    return Sig.push_back((ArgNo << 2) | Tmp);
311193323Sed  }
312245431Sdim
313245431Sdim  case MVT::iPTR: {
314245431Sdim    unsigned AddrSpace = 0;
315245431Sdim    if (R->isSubClassOf("LLVMQualPointerType")) {
316245431Sdim      AddrSpace = R->getValueAsInt("AddrSpace");
317245431Sdim      assert(AddrSpace < 256 && "Address space exceeds 255");
318245431Sdim    }
319245431Sdim    if (AddrSpace) {
320245431Sdim      Sig.push_back(IIT_ANYPTR);
321245431Sdim      Sig.push_back(AddrSpace);
322245431Sdim    } else {
323245431Sdim      Sig.push_back(IIT_PTR);
324245431Sdim    }
325245431Sdim    return EncodeFixedType(R->getValueAsDef("ElTy"), ArgCodes, Sig);
326245431Sdim  }
327245431Sdim  }
328245431Sdim
329245431Sdim  if (EVT(VT).isVector()) {
330245431Sdim    EVT VVT = VT;
331245431Sdim    switch (VVT.getVectorNumElements()) {
332245431Sdim    default: PrintFatalError("unhandled vector type width in intrinsic!");
333245431Sdim    case 2: Sig.push_back(IIT_V2); break;
334245431Sdim    case 4: Sig.push_back(IIT_V4); break;
335245431Sdim    case 8: Sig.push_back(IIT_V8); break;
336245431Sdim    case 16: Sig.push_back(IIT_V16); break;
337245431Sdim    case 32: Sig.push_back(IIT_V32); break;
338245431Sdim    }
339245431Sdim
340245431Sdim    return EncodeFixedValueType(VVT.getVectorElementType().
341245431Sdim                                getSimpleVT().SimpleTy, Sig);
342245431Sdim  }
343193323Sed
344245431Sdim  EncodeFixedValueType(VT, Sig);
345193323Sed}
346193323Sed
347245431Sdim#ifdef _MSC_VER
348245431Sdim#pragma optimize("",on)
349245431Sdim#endif
350193323Sed
351245431Sdim/// ComputeFixedEncoding - If we can encode the type signature for this
352245431Sdim/// intrinsic into 32 bits, return it.  If not, return ~0U.
353245431Sdimstatic void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
354245431Sdim                                 std::vector<unsigned char> &TypeSig) {
355245431Sdim  std::vector<unsigned char> ArgCodes;
356245431Sdim
357245431Sdim  if (Int.IS.RetVTs.empty())
358245431Sdim    TypeSig.push_back(IIT_Done);
359245431Sdim  else if (Int.IS.RetVTs.size() == 1 &&
360245431Sdim           Int.IS.RetVTs[0] == MVT::isVoid)
361245431Sdim    TypeSig.push_back(IIT_Done);
362245431Sdim  else {
363245431Sdim    switch (Int.IS.RetVTs.size()) {
364245431Sdim      case 1: break;
365245431Sdim      case 2: TypeSig.push_back(IIT_STRUCT2); break;
366245431Sdim      case 3: TypeSig.push_back(IIT_STRUCT3); break;
367245431Sdim      case 4: TypeSig.push_back(IIT_STRUCT4); break;
368245431Sdim      case 5: TypeSig.push_back(IIT_STRUCT5); break;
369245431Sdim      default: assert(0 && "Unhandled case in struct");
370245431Sdim    }
371245431Sdim
372245431Sdim    for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
373245431Sdim      EncodeFixedType(Int.IS.RetTypeDefs[i], ArgCodes, TypeSig);
374193323Sed  }
375245431Sdim
376245431Sdim  for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i)
377245431Sdim    EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig);
378193323Sed}
379193323Sed
380245431Sdimstatic void printIITEntry(raw_ostream &OS, unsigned char X) {
381245431Sdim  OS << (unsigned)X;
382193323Sed}
383193323Sed
384245431Sdimvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
385245431Sdim                                     raw_ostream &OS) {
386245431Sdim  // If we can compute a 32-bit fixed encoding for this intrinsic, do so and
387245431Sdim  // capture it in this vector, otherwise store a ~0U.
388245431Sdim  std::vector<unsigned> FixedEncodings;
389193323Sed
390245431Sdim  SequenceToOffsetTable<std::vector<unsigned char> > LongEncodingTable;
391193323Sed
392245431Sdim  std::vector<unsigned char> TypeSig;
393245431Sdim
394193323Sed  // Compute the unique argument type info.
395245431Sdim  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
396245431Sdim    // Get the signature for the intrinsic.
397245431Sdim    TypeSig.clear();
398245431Sdim    ComputeFixedEncoding(Ints[i], TypeSig);
399193323Sed
400245431Sdim    // Check to see if we can encode it into a 32-bit word.  We can only encode
401245431Sdim    // 8 nibbles into a 32-bit word.
402245431Sdim    if (TypeSig.size() <= 8) {
403245431Sdim      bool Failed = false;
404245431Sdim      unsigned Result = 0;
405245431Sdim      for (unsigned i = 0, e = TypeSig.size(); i != e; ++i) {
406245431Sdim        // If we had an unencodable argument, bail out.
407245431Sdim        if (TypeSig[i] > 15) {
408245431Sdim          Failed = true;
409245431Sdim          break;
410245431Sdim        }
411245431Sdim        Result = (Result << 4) | TypeSig[e-i-1];
412193323Sed      }
413245431Sdim
414245431Sdim      // If this could be encoded into a 31-bit word, return it.
415245431Sdim      if (!Failed && (Result >> 31) == 0) {
416245431Sdim        FixedEncodings.push_back(Result);
417245431Sdim        continue;
418245431Sdim      }
419193323Sed    }
420193323Sed
421245431Sdim    // Otherwise, we're going to unique the sequence into the
422245431Sdim    // LongEncodingTable, and use its offset in the 32-bit table instead.
423245431Sdim    LongEncodingTable.add(TypeSig);
424193323Sed
425245431Sdim    // This is a placehold that we'll replace after the table is laid out.
426245431Sdim    FixedEncodings.push_back(~0U);
427193323Sed  }
428193323Sed
429245431Sdim  LongEncodingTable.layout();
430193323Sed
431245431Sdim  OS << "// Global intrinsic function declaration type table.\n";
432245431Sdim  OS << "#ifdef GET_INTRINSIC_GENERATOR_GLOBAL\n";
433193323Sed
434245431Sdim  OS << "static const unsigned IIT_Table[] = {\n  ";
435193323Sed
436245431Sdim  for (unsigned i = 0, e = FixedEncodings.size(); i != e; ++i) {
437245431Sdim    if ((i & 7) == 7)
438245431Sdim      OS << "\n  ";
439193323Sed
440245431Sdim    // If the entry fit in the table, just emit it.
441245431Sdim    if (FixedEncodings[i] != ~0U) {
442245431Sdim      OS << "0x" << utohexstr(FixedEncodings[i]) << ", ";
443245431Sdim      continue;
444193323Sed    }
445245431Sdim
446245431Sdim    TypeSig.clear();
447245431Sdim    ComputeFixedEncoding(Ints[i], TypeSig);
448193323Sed
449193323Sed
450245431Sdim    // Otherwise, emit the offset into the long encoding table.  We emit it this
451245431Sdim    // way so that it is easier to read the offset in the .def file.
452245431Sdim    OS << "(1U<<31) | " << LongEncodingTable.get(TypeSig) << ", ";
453245431Sdim  }
454245431Sdim
455245431Sdim  OS << "0\n};\n\n";
456245431Sdim
457245431Sdim  // Emit the shared table of register lists.
458245431Sdim  OS << "static const unsigned char IIT_LongEncodingTable[] = {\n";
459245431Sdim  if (!LongEncodingTable.empty())
460245431Sdim    LongEncodingTable.emit(OS, printIITEntry);
461245431Sdim  OS << "  255\n};\n\n";
462245431Sdim
463245431Sdim  OS << "#endif\n\n";  // End of GET_INTRINSIC_GENERATOR_GLOBAL
464245431Sdim}
465193323Sed
466245431Sdimenum ModRefKind {
467245431Sdim  MRK_none,
468245431Sdim  MRK_readonly,
469245431Sdim  MRK_readnone
470245431Sdim};
471245431Sdim
472245431Sdimstatic ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) {
473245431Sdim  switch (intrinsic.ModRef) {
474245431Sdim  case CodeGenIntrinsic::NoMem:
475245431Sdim    return MRK_readnone;
476245431Sdim  case CodeGenIntrinsic::ReadArgMem:
477245431Sdim  case CodeGenIntrinsic::ReadMem:
478245431Sdim    return MRK_readonly;
479245431Sdim  case CodeGenIntrinsic::ReadWriteArgMem:
480245431Sdim  case CodeGenIntrinsic::ReadWriteMem:
481245431Sdim    return MRK_none;
482193323Sed  }
483245431Sdim  llvm_unreachable("bad mod-ref kind");
484193323Sed}
485193323Sed
486223017Sdimnamespace {
487245431Sdimstruct AttributeComparator {
488245431Sdim  bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
489245431Sdim    // Sort throwing intrinsics after non-throwing intrinsics.
490245431Sdim    if (L->canThrow != R->canThrow)
491245431Sdim      return R->canThrow;
492223017Sdim
493245431Sdim    if (L->isNoReturn != R->isNoReturn)
494245431Sdim      return R->isNoReturn;
495223017Sdim
496245431Sdim    // Try to order by readonly/readnone attribute.
497245431Sdim    ModRefKind LK = getModRefKind(*L);
498245431Sdim    ModRefKind RK = getModRefKind(*R);
499245431Sdim    if (LK != RK) return (LK > RK);
500223017Sdim
501245431Sdim    // Order by argument attributes.
502245431Sdim    // This is reliable because each side is already sorted internally.
503245431Sdim    return (L->ArgumentAttributes < R->ArgumentAttributes);
504245431Sdim  }
505245431Sdim};
506245431Sdim} // End anonymous namespace
507223017Sdim
508193323Sed/// EmitAttributes - This emits the Intrinsic::getAttributes method.
509193323Sedvoid IntrinsicEmitter::
510195340SedEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
511193323Sed  OS << "// Add parameter attributes that are not common to all intrinsics.\n";
512193323Sed  OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
513193323Sed  if (TargetOnly)
514245431Sdim    OS << "static AttrListPtr getAttributes(LLVMContext &C, " << TargetPrefix
515223017Sdim       << "Intrinsic::ID id) {\n";
516193323Sed  else
517245431Sdim    OS << "AttrListPtr Intrinsic::getAttributes(LLVMContext &C, ID id) {\n";
518223017Sdim
519235633Sdim  // Compute the maximum number of attribute arguments and the map
520235633Sdim  typedef std::map<const CodeGenIntrinsic*, unsigned,
521235633Sdim                   AttributeComparator> UniqAttrMapTy;
522235633Sdim  UniqAttrMapTy UniqAttributes;
523223017Sdim  unsigned maxArgAttrs = 0;
524235633Sdim  unsigned AttrNum = 0;
525193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
526223017Sdim    const CodeGenIntrinsic &intrinsic = Ints[i];
527223017Sdim    maxArgAttrs =
528223017Sdim      std::max(maxArgAttrs, unsigned(intrinsic.ArgumentAttributes.size()));
529235633Sdim    unsigned &N = UniqAttributes[&intrinsic];
530235633Sdim    if (N) continue;
531235633Sdim    assert(AttrNum < 256 && "Too many unique attributes for table!");
532235633Sdim    N = ++AttrNum;
533193323Sed  }
534223017Sdim
535223017Sdim  // Emit an array of AttributeWithIndex.  Most intrinsics will have
536223017Sdim  // at least one entry, for the function itself (index ~1), which is
537223017Sdim  // usually nounwind.
538235633Sdim  OS << "  static const uint8_t IntrinsicsToAttributesMap[] = {\n";
539193323Sed
540235633Sdim  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
541235633Sdim    const CodeGenIntrinsic &intrinsic = Ints[i];
542193323Sed
543235633Sdim    OS << "    " << UniqAttributes[&intrinsic] << ", // "
544235633Sdim       << intrinsic.Name << "\n";
545235633Sdim  }
546235633Sdim  OS << "  };\n\n";
547193323Sed
548235633Sdim  OS << "  AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n";
549235633Sdim  OS << "  unsigned NumAttrs = 0;\n";
550235633Sdim  OS << "  if (id != 0) {\n";
551245431Sdim  OS << "    SmallVector<Attributes::AttrVal, 8> AttrVec;\n";
552235633Sdim  OS << "    switch(IntrinsicsToAttributesMap[id - ";
553235633Sdim  if (TargetOnly)
554235633Sdim    OS << "Intrinsic::num_intrinsics";
555235633Sdim  else
556235633Sdim    OS << "1";
557235633Sdim  OS << "]) {\n";
558235633Sdim  OS << "    default: llvm_unreachable(\"Invalid attribute number\");\n";
559235633Sdim  for (UniqAttrMapTy::const_iterator I = UniqAttributes.begin(),
560235633Sdim       E = UniqAttributes.end(); I != E; ++I) {
561235633Sdim    OS << "    case " << I->second << ":\n";
562223017Sdim
563235633Sdim    const CodeGenIntrinsic &intrinsic = *(I->first);
564223017Sdim
565223017Sdim    // Keep track of the number of attributes we're writing out.
566223017Sdim    unsigned numAttrs = 0;
567223017Sdim
568223017Sdim    // The argument attributes are alreadys sorted by argument index.
569245431Sdim    unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size();
570245431Sdim    if (ae) {
571245431Sdim      while (ai != ae) {
572245431Sdim        unsigned argNo = intrinsic.ArgumentAttributes[ai].first;
573235633Sdim
574245431Sdim        OS << "      AttrVec.clear();\n";
575193323Sed
576245431Sdim        do {
577245431Sdim          switch (intrinsic.ArgumentAttributes[ai].second) {
578245431Sdim          case CodeGenIntrinsic::NoCapture:
579245431Sdim            OS << "      AttrVec.push_back(Attributes::NoCapture);\n";
580245431Sdim            break;
581245431Sdim          }
582223017Sdim
583245431Sdim          ++ai;
584245431Sdim        } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo);
585223017Sdim
586245431Sdim        OS << "      AWI[" << numAttrs++ << "] = AttributeWithIndex::get(C, "
587245431Sdim           << argNo+1 << ", AttrVec);\n";
588245431Sdim      }
589223017Sdim    }
590223017Sdim
591223017Sdim    ModRefKind modRef = getModRefKind(intrinsic);
592223017Sdim
593245431Sdim    if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) {
594245431Sdim      OS << "      AttrVec.clear();\n";
595245431Sdim
596245431Sdim      if (!intrinsic.canThrow)
597245431Sdim        OS << "      AttrVec.push_back(Attributes::NoUnwind);\n";
598245431Sdim      if (intrinsic.isNoReturn)
599245431Sdim        OS << "      AttrVec.push_back(Attributes::NoReturn);\n";
600245431Sdim
601223017Sdim      switch (modRef) {
602223017Sdim      case MRK_none: break;
603245431Sdim      case MRK_readonly:
604245431Sdim        OS << "      AttrVec.push_back(Attributes::ReadOnly);\n";
605245431Sdim        break;
606245431Sdim      case MRK_readnone:
607245431Sdim        OS << "      AttrVec.push_back(Attributes::ReadNone);\n";
608245431Sdim        break;
609223017Sdim      }
610245431Sdim      OS << "      AWI[" << numAttrs++ << "] = AttributeWithIndex::get(C, "
611245431Sdim         << "AttrListPtr::FunctionIndex, AttrVec);\n";
612193323Sed    }
613223017Sdim
614223017Sdim    if (numAttrs) {
615235633Sdim      OS << "      NumAttrs = " << numAttrs << ";\n";
616235633Sdim      OS << "      break;\n";
617223017Sdim    } else {
618235633Sdim      OS << "      return AttrListPtr();\n";
619223017Sdim    }
620193323Sed  }
621193323Sed
622235633Sdim  OS << "    }\n";
623193323Sed  OS << "  }\n";
624245431Sdim  OS << "  return AttrListPtr::get(C, ArrayRef<AttributeWithIndex>(AWI, "
625245431Sdim             "NumAttrs));\n";
626193323Sed  OS << "}\n";
627193323Sed  OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
628193323Sed}
629193323Sed
630193323Sed/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
631193323Sedvoid IntrinsicEmitter::
632195340SedEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
633235633Sdim  OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"
634235633Sdim     << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"
635235633Sdim     << "assert(iid <= Intrinsic::" << Ints.back().EnumName << " && "
636235633Sdim     << "\"Unknown intrinsic.\");\n\n";
637235633Sdim
638235633Sdim  OS << "static const uint8_t IntrinsicModRefBehavior[] = {\n"
639235633Sdim     << "  /* invalid */ UnknownModRefBehavior,\n";
640193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
641235633Sdim    OS << "  /* " << TargetPrefix << Ints[i].EnumName << " */ ";
642193323Sed    switch (Ints[i].ModRef) {
643193323Sed    case CodeGenIntrinsic::NoMem:
644235633Sdim      OS << "DoesNotAccessMemory,\n";
645193323Sed      break;
646193323Sed    case CodeGenIntrinsic::ReadArgMem:
647235633Sdim      OS << "OnlyReadsArgumentPointees,\n";
648218893Sdim      break;
649193323Sed    case CodeGenIntrinsic::ReadMem:
650235633Sdim      OS << "OnlyReadsMemory,\n";
651193323Sed      break;
652212904Sdim    case CodeGenIntrinsic::ReadWriteArgMem:
653235633Sdim      OS << "OnlyAccessesArgumentPointees,\n";
654193323Sed      break;
655235633Sdim    case CodeGenIntrinsic::ReadWriteMem:
656235633Sdim      OS << "UnknownModRefBehavior,\n";
657235633Sdim      break;
658193323Sed    }
659193323Sed  }
660235633Sdim  OS << "};\n\n"
661235633Sdim     << "return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);\n"
662235633Sdim     << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
663193323Sed}
664193323Sed
665193323Sed/// EmitTargetBuiltins - All of the builtins in the specified map are for the
666193323Sed/// same target, and we already checked it.
667193323Sedstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
668193323Sed                               const std::string &TargetPrefix,
669195340Sed                               raw_ostream &OS) {
670193323Sed
671218893Sdim  std::vector<StringMatcher::StringPair> Results;
672193323Sed
673218893Sdim  for (std::map<std::string, std::string>::const_iterator I = BIM.begin(),
674218893Sdim       E = BIM.end(); I != E; ++I) {
675218893Sdim    std::string ResultCode =
676218893Sdim    "return " + TargetPrefix + "Intrinsic::" + I->second + ";";
677218893Sdim    Results.push_back(StringMatcher::StringPair(I->first, ResultCode));
678193323Sed  }
679218893Sdim
680218893Sdim  StringMatcher("BuiltinName", Results, OS).Emit();
681193323Sed}
682193323Sed
683193323Sed
684193323Sedvoid IntrinsicEmitter::
685193323SedEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
686195340Sed                             raw_ostream &OS) {
687193323Sed  typedef std::map<std::string, std::map<std::string, std::string> > BIMTy;
688193323Sed  BIMTy BuiltinMap;
689193323Sed  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
690193323Sed    if (!Ints[i].GCCBuiltinName.empty()) {
691193323Sed      // Get the map for this target prefix.
692193323Sed      std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix];
693193323Sed
694193323Sed      if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName,
695193323Sed                                     Ints[i].EnumName)).second)
696245431Sdim        PrintFatalError("Intrinsic '" + Ints[i].TheDef->getName() +
697245431Sdim              "': duplicate GCC builtin name!");
698193323Sed    }
699193323Sed  }
700193323Sed
701193323Sed  OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
702193323Sed  OS << "// This is used by the C front-end.  The GCC builtin name is passed\n";
703193323Sed  OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
704193323Sed  OS << "// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.\n";
705193323Sed  OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
706193323Sed
707193323Sed  if (TargetOnly) {
708193323Sed    OS << "static " << TargetPrefix << "Intrinsic::ID "
709193323Sed       << "getIntrinsicForGCCBuiltin(const char "
710218893Sdim       << "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
711193323Sed  } else {
712193323Sed    OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
713218893Sdim       << "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
714193323Sed  }
715193323Sed
716218893Sdim  OS << "  StringRef BuiltinName(BuiltinNameStr);\n";
717218893Sdim  OS << "  StringRef TargetPrefix(TargetPrefixStr);\n\n";
718193323Sed
719193323Sed  // Note: this could emit significantly better code if we cared.
720193323Sed  for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
721193323Sed    OS << "  ";
722193323Sed    if (!I->first.empty())
723218893Sdim      OS << "if (TargetPrefix == \"" << I->first << "\") ";
724193323Sed    else
725193323Sed      OS << "/* Target Independent Builtins */ ";
726193323Sed    OS << "{\n";
727193323Sed
728193323Sed    // Emit the comparisons for this target prefix.
729193323Sed    EmitTargetBuiltins(I->second, TargetPrefix, OS);
730193323Sed    OS << "  }\n";
731193323Sed  }
732218893Sdim  OS << "  return ";
733218893Sdim  if (!TargetPrefix.empty())
734218893Sdim    OS << "(" << TargetPrefix << "Intrinsic::ID)";
735218893Sdim  OS << "Intrinsic::not_intrinsic;\n";
736193323Sed  OS << "}\n";
737193323Sed  OS << "#endif\n\n";
738193323Sed}
739245431Sdim
740245431Sdimnamespace llvm {
741245431Sdim
742245431Sdimvoid EmitIntrinsics(RecordKeeper &RK, raw_ostream &OS, bool TargetOnly = false) {
743245431Sdim  IntrinsicEmitter(RK, TargetOnly).run(OS);
744245431Sdim}
745245431Sdim
746245431Sdim} // End llvm namespace
747