switch AttrListPtr::get to take an ArrayRef, simplifying a lot of clients.
[oota-llvm.git] / utils / TableGen / IntrinsicEmitter.cpp
1 //===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This tablegen backend emits information about intrinsic functions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CodeGenTarget.h"
15 #include "IntrinsicEmitter.h"
16 #include "SequenceToOffsetTable.h"
17 #include "llvm/TableGen/Record.h"
18 #include "llvm/TableGen/StringMatcher.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include <algorithm>
21 using namespace llvm;
22
23 //===----------------------------------------------------------------------===//
24 // IntrinsicEmitter Implementation
25 //===----------------------------------------------------------------------===//
26
27 void IntrinsicEmitter::run(raw_ostream &OS) {
28   EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
29   
30   std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly);
31   
32   if (TargetOnly && !Ints.empty())
33     TargetPrefix = Ints[0].TargetPrefix;
34
35   EmitPrefix(OS);
36
37   // Emit the enum information.
38   EmitEnumInfo(Ints, OS);
39
40   // Emit the intrinsic ID -> name table.
41   EmitIntrinsicToNameTable(Ints, OS);
42
43   // Emit the intrinsic ID -> overload table.
44   EmitIntrinsicToOverloadTable(Ints, OS);
45
46   // Emit the function name recognizer.
47   EmitFnNameRecognizer(Ints, OS);
48   
49   // Emit the intrinsic declaration generator.
50   EmitGenerator(Ints, OS);
51   
52   // Emit the intrinsic parameter attributes.
53   EmitAttributes(Ints, OS);
54
55   // Emit intrinsic alias analysis mod/ref behavior.
56   EmitModRefBehavior(Ints, OS);
57
58   // Emit code to translate GCC builtins into LLVM intrinsics.
59   EmitIntrinsicToGCCBuiltinMap(Ints, OS);
60
61   EmitSuffix(OS);
62 }
63
64 void IntrinsicEmitter::EmitPrefix(raw_ostream &OS) {
65   OS << "// VisualStudio defines setjmp as _setjmp\n"
66         "#if defined(_MSC_VER) && defined(setjmp) && \\\n"
67         "                         !defined(setjmp_undefined_for_msvc)\n"
68         "#  pragma push_macro(\"setjmp\")\n"
69         "#  undef setjmp\n"
70         "#  define setjmp_undefined_for_msvc\n"
71         "#endif\n\n";
72 }
73
74 void IntrinsicEmitter::EmitSuffix(raw_ostream &OS) {
75   OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n"
76         "// let's return it to _setjmp state\n"
77         "#  pragma pop_macro(\"setjmp\")\n"
78         "#  undef setjmp_undefined_for_msvc\n"
79         "#endif\n\n";
80 }
81
82 void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
83                                     raw_ostream &OS) {
84   OS << "// Enum values for Intrinsics.h\n";
85   OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
86   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
87     OS << "    " << Ints[i].EnumName;
88     OS << ((i != e-1) ? ", " : "  ");
89     OS << std::string(40-Ints[i].EnumName.size(), ' ') 
90       << "// " << Ints[i].Name << "\n";
91   }
92   OS << "#endif\n\n";
93 }
94
95 void IntrinsicEmitter::
96 EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 
97                      raw_ostream &OS) {
98   // Build a 'first character of function name' -> intrinsic # mapping.
99   std::map<char, std::vector<unsigned> > IntMapping;
100   for (unsigned i = 0, e = Ints.size(); i != e; ++i)
101     IntMapping[Ints[i].Name[5]].push_back(i);
102   
103   OS << "// Function name -> enum value recognizer code.\n";
104   OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
105   OS << "  StringRef NameR(Name+6, Len-6);   // Skip over 'llvm.'\n";
106   OS << "  switch (Name[5]) {                  // Dispatch on first letter.\n";
107   OS << "  default: break;\n";
108   // Emit the intrinsic matching stuff by first letter.
109   for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(),
110        E = IntMapping.end(); I != E; ++I) {
111     OS << "  case '" << I->first << "':\n";
112     std::vector<unsigned> &IntList = I->second;
113
114     // Emit all the overloaded intrinsics first, build a table of the
115     // non-overloaded ones.
116     std::vector<StringMatcher::StringPair> MatchTable;
117     
118     for (unsigned i = 0, e = IntList.size(); i != e; ++i) {
119       unsigned IntNo = IntList[i];
120       std::string Result = "return " + TargetPrefix + "Intrinsic::" +
121         Ints[IntNo].EnumName + ";";
122
123       if (!Ints[IntNo].isOverloaded) {
124         MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result));
125         continue;
126       }
127
128       // For overloaded intrinsics, only the prefix needs to match
129       std::string TheStr = Ints[IntNo].Name.substr(6);
130       TheStr += '.';  // Require "bswap." instead of bswap.
131       OS << "    if (NameR.startswith(\"" << TheStr << "\")) "
132          << Result << '\n';
133     }
134     
135     // Emit the matcher logic for the fixed length strings.
136     StringMatcher("NameR", MatchTable, OS).Emit(1);
137     OS << "    break;  // end of '" << I->first << "' case.\n";
138   }
139   
140   OS << "  }\n";
141   OS << "#endif\n\n";
142 }
143
144 void IntrinsicEmitter::
145 EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 
146                          raw_ostream &OS) {
147   OS << "// Intrinsic ID to name table\n";
148   OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n";
149   OS << "  // Note that entry #0 is the invalid intrinsic!\n";
150   for (unsigned i = 0, e = Ints.size(); i != e; ++i)
151     OS << "  \"" << Ints[i].Name << "\",\n";
152   OS << "#endif\n\n";
153 }
154
155 void IntrinsicEmitter::
156 EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 
157                          raw_ostream &OS) {
158   OS << "// Intrinsic ID to overload bitset\n";
159   OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n";
160   OS << "static const uint8_t OTable[] = {\n";
161   OS << "  0";
162   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
163     // Add one to the index so we emit a null bit for the invalid #0 intrinsic.
164     if ((i+1)%8 == 0)
165       OS << ",\n  0";
166     if (Ints[i].isOverloaded)
167       OS << " | (1<<" << (i+1)%8 << ')';
168   }
169   OS << "\n};\n\n";
170   // OTable contains a true bit at the position if the intrinsic is overloaded.
171   OS << "return (OTable[id/8] & (1 << (id%8))) != 0;\n";
172   OS << "#endif\n\n";
173 }
174
175
176 // NOTE: This must be kept in synch with the copy in lib/VMCore/Function.cpp!
177 enum IIT_Info {
178   // Common values should be encoded with 0-15.
179   IIT_Done = 0,
180   IIT_I1   = 1,
181   IIT_I8   = 2,
182   IIT_I16  = 3,
183   IIT_I32  = 4,
184   IIT_I64  = 5,
185   IIT_F32  = 6,
186   IIT_F64  = 7,
187   IIT_V2   = 8,
188   IIT_V4   = 9,
189   IIT_V8   = 10,
190   IIT_V16  = 11,
191   IIT_V32  = 12,
192   IIT_MMX  = 13,
193   IIT_PTR  = 14,
194   IIT_ARG  = 15,
195   
196   // Values from 16+ are only encodable with the inefficient encoding.
197   IIT_METADATA = 16,
198   IIT_EMPTYSTRUCT = 17,
199   IIT_STRUCT2 = 18,
200   IIT_STRUCT3 = 19,
201   IIT_STRUCT4 = 20,
202   IIT_STRUCT5 = 21,
203   IIT_EXTEND_VEC_ARG = 22,
204   IIT_TRUNC_VEC_ARG = 23,
205   IIT_ANYPTR = 24
206 };
207
208
209 static void EncodeFixedValueType(MVT::SimpleValueType VT,
210                                  std::vector<unsigned char> &Sig) {
211   if (EVT(VT).isInteger()) {
212     unsigned BitWidth = EVT(VT).getSizeInBits();
213     switch (BitWidth) {
214     default: throw "unhandled integer type width in intrinsic!";
215     case 1: return Sig.push_back(IIT_I1);
216     case 8: return Sig.push_back(IIT_I8);
217     case 16: return Sig.push_back(IIT_I16);
218     case 32: return Sig.push_back(IIT_I32);
219     case 64: return Sig.push_back(IIT_I64);
220     }
221   }
222   
223   switch (VT) {
224   default: throw "unhandled MVT in intrinsic!";
225   case MVT::f32: return Sig.push_back(IIT_F32);
226   case MVT::f64: return Sig.push_back(IIT_F64);
227   case MVT::Metadata: return Sig.push_back(IIT_METADATA);
228   case MVT::x86mmx: return Sig.push_back(IIT_MMX);
229   // MVT::OtherVT is used to mean the empty struct type here.
230   case MVT::Other: return Sig.push_back(IIT_EMPTYSTRUCT);
231   }
232 }
233
234 #ifdef _MSC_VER
235 #pragma optimize("",off) // MSVC 2010 optimizer can't deal with this function.
236 #endif 
237
238 static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
239                             std::vector<unsigned char> &Sig) {
240   
241   if (R->isSubClassOf("LLVMMatchType")) {
242     unsigned Number = R->getValueAsInt("Number");
243     assert(Number < ArgCodes.size() && "Invalid matching number!");
244     if (R->isSubClassOf("LLVMExtendedElementVectorType"))
245       Sig.push_back(IIT_EXTEND_VEC_ARG);
246     else if (R->isSubClassOf("LLVMTruncatedElementVectorType"))
247       Sig.push_back(IIT_TRUNC_VEC_ARG);
248     else
249       Sig.push_back(IIT_ARG);
250     return Sig.push_back((Number << 2) | ArgCodes[Number]);
251   }
252   
253   MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT"));
254
255   unsigned Tmp = 0;
256   switch (VT) {
257   default: break;
258   case MVT::iPTRAny: ++Tmp; // FALL THROUGH.
259   case MVT::vAny: ++Tmp; // FALL THROUGH.
260   case MVT::fAny: ++Tmp; // FALL THROUGH.
261   case MVT::iAny: {
262     // If this is an "any" valuetype, then the type is the type of the next
263     // type in the list specified to getIntrinsic().  
264     Sig.push_back(IIT_ARG);
265     
266     // Figure out what arg # this is consuming, and remember what kind it was.
267     unsigned ArgNo = ArgCodes.size();
268     ArgCodes.push_back(Tmp);
269     
270     // Encode what sort of argument it must be in the low 2 bits of the ArgNo.
271     return Sig.push_back((ArgNo << 2) | Tmp);
272   }
273   
274   case MVT::iPTR: {
275     unsigned AddrSpace = 0;
276     if (R->isSubClassOf("LLVMQualPointerType")) {
277       AddrSpace = R->getValueAsInt("AddrSpace");
278       assert(AddrSpace < 256 && "Address space exceeds 255");
279     }
280     if (AddrSpace) {
281       Sig.push_back(IIT_ANYPTR);
282       Sig.push_back(AddrSpace);
283     } else {
284       Sig.push_back(IIT_PTR);
285     }
286     return EncodeFixedType(R->getValueAsDef("ElTy"), ArgCodes, Sig);
287   }
288   }
289   
290   if (EVT(VT).isVector()) {
291     EVT VVT = VT;
292     switch (VVT.getVectorNumElements()) {
293     default: throw "unhandled vector type width in intrinsic!";
294     case 2: Sig.push_back(IIT_V2); break;
295     case 4: Sig.push_back(IIT_V4); break;
296     case 8: Sig.push_back(IIT_V8); break;
297     case 16: Sig.push_back(IIT_V16); break;
298     case 32: Sig.push_back(IIT_V32); break;
299     }
300     
301     return EncodeFixedValueType(VVT.getVectorElementType().
302                                 getSimpleVT().SimpleTy, Sig);
303   }
304
305   EncodeFixedValueType(VT, Sig);
306 }
307
308 #ifdef _MSC_VER
309 #pragma optimize("",on)
310 #endif
311
312 /// ComputeFixedEncoding - If we can encode the type signature for this
313 /// intrinsic into 32 bits, return it.  If not, return ~0U.
314 static void ComputeFixedEncoding(const CodeGenIntrinsic &Int,
315                                  std::vector<unsigned char> &TypeSig) {
316   std::vector<unsigned char> ArgCodes;
317   
318   if (Int.IS.RetVTs.empty())
319     TypeSig.push_back(IIT_Done);
320   else if (Int.IS.RetVTs.size() == 1 &&
321            Int.IS.RetVTs[0] == MVT::isVoid)
322     TypeSig.push_back(IIT_Done);
323   else {
324     switch (Int.IS.RetVTs.size()) {
325       case 1: break;
326       case 2: TypeSig.push_back(IIT_STRUCT2); break;
327       case 3: TypeSig.push_back(IIT_STRUCT3); break;
328       case 4: TypeSig.push_back(IIT_STRUCT4); break;
329       case 5: TypeSig.push_back(IIT_STRUCT5); break;
330       default: assert(0 && "Unhandled case in struct");
331     }
332     
333     for (unsigned i = 0, e = Int.IS.RetVTs.size(); i != e; ++i)
334       EncodeFixedType(Int.IS.RetTypeDefs[i], ArgCodes, TypeSig);
335   }
336   
337   for (unsigned i = 0, e = Int.IS.ParamTypeDefs.size(); i != e; ++i)
338     EncodeFixedType(Int.IS.ParamTypeDefs[i], ArgCodes, TypeSig);
339 }
340
341 void printIITEntry(raw_ostream &OS, unsigned char X) {
342   OS << (unsigned)X;
343 }
344
345 void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 
346                                      raw_ostream &OS) {
347   // If we can compute a 32-bit fixed encoding for this intrinsic, do so and
348   // capture it in this vector, otherwise store a ~0U.
349   std::vector<unsigned> FixedEncodings;
350   
351   SequenceToOffsetTable<std::vector<unsigned char> > LongEncodingTable;
352   
353   std::vector<unsigned char> TypeSig;
354   
355   // Compute the unique argument type info.
356   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
357     // Get the signature for the intrinsic.
358     TypeSig.clear();
359     ComputeFixedEncoding(Ints[i], TypeSig);
360
361     // Check to see if we can encode it into a 32-bit word.  We can only encode
362     // 8 nibbles into a 32-bit word.
363     if (TypeSig.size() <= 8) {
364       bool Failed = false;
365       unsigned Result = 0;
366       for (unsigned i = 0, e = TypeSig.size(); i != e; ++i) {
367         // If we had an unencodable argument, bail out.
368         if (TypeSig[i] > 15) {
369           Failed = true;
370           break;
371         }
372         Result = (Result << 4) | TypeSig[e-i-1];
373       }
374       
375       // If this could be encoded into a 31-bit word, return it.
376       if (!Failed && (Result >> 31) == 0) {
377         FixedEncodings.push_back(Result);
378         continue;
379       }
380     }
381
382     // Otherwise, we're going to unique the sequence into the
383     // LongEncodingTable, and use its offset in the 32-bit table instead.
384     LongEncodingTable.add(TypeSig);
385       
386     // This is a placehold that we'll replace after the table is laid out.
387     FixedEncodings.push_back(~0U);
388   }
389   
390   LongEncodingTable.layout();
391   
392   OS << "// Global intrinsic function declaration type table.\n";
393   OS << "#ifdef GET_INTRINSIC_GENERATOR_GLOBAL\n";
394
395   OS << "static const unsigned IIT_Table[] = {\n  ";
396   
397   for (unsigned i = 0, e = FixedEncodings.size(); i != e; ++i) {
398     if ((i & 7) == 7)
399       OS << "\n  ";
400     
401     // If the entry fit in the table, just emit it.
402     if (FixedEncodings[i] != ~0U) {
403       OS << "0x" << utohexstr(FixedEncodings[i]) << ", ";
404       continue;
405     }
406     
407     TypeSig.clear();
408     ComputeFixedEncoding(Ints[i], TypeSig);
409
410     
411     // Otherwise, emit the offset into the long encoding table.  We emit it this
412     // way so that it is easier to read the offset in the .def file.
413     OS << "(1U<<31) | " << LongEncodingTable.get(TypeSig) << ", ";
414   }
415   
416   OS << "0\n};\n\n";
417   
418   // Emit the shared table of register lists.
419   OS << "static const unsigned char IIT_LongEncodingTable[] = {\n";
420   if (!LongEncodingTable.empty())
421     LongEncodingTable.emit(OS, printIITEntry);
422   OS << "  255\n};\n\n";
423   
424   OS << "#endif\n\n";  // End of GET_INTRINSIC_GENERATOR_GLOBAL
425 }
426
427 namespace {
428   enum ModRefKind {
429     MRK_none,
430     MRK_readonly,
431     MRK_readnone
432   };
433
434   ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) {
435     switch (intrinsic.ModRef) {
436     case CodeGenIntrinsic::NoMem:
437       return MRK_readnone;
438     case CodeGenIntrinsic::ReadArgMem:
439     case CodeGenIntrinsic::ReadMem:
440       return MRK_readonly;
441     case CodeGenIntrinsic::ReadWriteArgMem:
442     case CodeGenIntrinsic::ReadWriteMem:
443       return MRK_none;
444     }
445     llvm_unreachable("bad mod-ref kind");
446   }
447
448   struct AttributeComparator {
449     bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
450       // Sort throwing intrinsics after non-throwing intrinsics.
451       if (L->canThrow != R->canThrow)
452         return R->canThrow;
453
454       if (L->isNoReturn != R->isNoReturn)
455         return R->isNoReturn;
456
457       // Try to order by readonly/readnone attribute.
458       ModRefKind LK = getModRefKind(*L);
459       ModRefKind RK = getModRefKind(*R);
460       if (LK != RK) return (LK > RK);
461
462       // Order by argument attributes.
463       // This is reliable because each side is already sorted internally.
464       return (L->ArgumentAttributes < R->ArgumentAttributes);
465     }
466   };
467 }
468
469 /// EmitAttributes - This emits the Intrinsic::getAttributes method.
470 void IntrinsicEmitter::
471 EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
472   OS << "// Add parameter attributes that are not common to all intrinsics.\n";
473   OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
474   if (TargetOnly)
475     OS << "static AttrListPtr getAttributes(" << TargetPrefix 
476        << "Intrinsic::ID id) {\n";
477   else
478     OS << "AttrListPtr Intrinsic::getAttributes(ID id) {\n";
479
480   // Compute the maximum number of attribute arguments and the map
481   typedef std::map<const CodeGenIntrinsic*, unsigned,
482                    AttributeComparator> UniqAttrMapTy;
483   UniqAttrMapTy UniqAttributes;
484   unsigned maxArgAttrs = 0;
485   unsigned AttrNum = 0;
486   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
487     const CodeGenIntrinsic &intrinsic = Ints[i];
488     maxArgAttrs =
489       std::max(maxArgAttrs, unsigned(intrinsic.ArgumentAttributes.size()));
490     unsigned &N = UniqAttributes[&intrinsic];
491     if (N) continue;
492     assert(AttrNum < 256 && "Too many unique attributes for table!");
493     N = ++AttrNum;
494   }
495
496   // Emit an array of AttributeWithIndex.  Most intrinsics will have
497   // at least one entry, for the function itself (index ~1), which is
498   // usually nounwind.
499   OS << "  static const uint8_t IntrinsicsToAttributesMap[] = {\n";
500
501   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
502     const CodeGenIntrinsic &intrinsic = Ints[i];
503
504     OS << "    " << UniqAttributes[&intrinsic] << ", // "
505        << intrinsic.Name << "\n";
506   }
507   OS << "  };\n\n";
508
509   OS << "  AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n";
510   OS << "  unsigned NumAttrs = 0;\n";
511   OS << "  if (id != 0) {\n";
512   OS << "    switch(IntrinsicsToAttributesMap[id - ";
513   if (TargetOnly)
514     OS << "Intrinsic::num_intrinsics";
515   else
516     OS << "1";
517   OS << "]) {\n";
518   OS << "    default: llvm_unreachable(\"Invalid attribute number\");\n";
519   for (UniqAttrMapTy::const_iterator I = UniqAttributes.begin(),
520        E = UniqAttributes.end(); I != E; ++I) {
521     OS << "    case " << I->second << ":\n";
522
523     const CodeGenIntrinsic &intrinsic = *(I->first);
524
525     // Keep track of the number of attributes we're writing out.
526     unsigned numAttrs = 0;
527
528     // The argument attributes are alreadys sorted by argument index.
529     for (unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size(); ai != ae;) {
530       unsigned argNo = intrinsic.ArgumentAttributes[ai].first;
531
532       OS << "      AWI[" << numAttrs++ << "] = AttributeWithIndex::get("
533          << argNo+1 << ", ";
534
535       bool moreThanOne = false;
536
537       do {
538         if (moreThanOne) OS << '|';
539
540         switch (intrinsic.ArgumentAttributes[ai].second) {
541         case CodeGenIntrinsic::NoCapture:
542           OS << "Attribute::NoCapture";
543           break;
544         }
545
546         ++ai;
547         moreThanOne = true;
548       } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo);
549
550       OS << ");\n";
551     }
552
553     ModRefKind modRef = getModRefKind(intrinsic);
554
555     if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) {
556       OS << "      AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, ";
557       bool Emitted = false;
558       if (!intrinsic.canThrow) {
559         OS << "Attribute::NoUnwind";
560         Emitted = true;
561       }
562       
563       if (intrinsic.isNoReturn) {
564         if (Emitted) OS << '|';
565         OS << "Attribute::NoReturn";
566         Emitted = true;
567       }
568
569       switch (modRef) {
570       case MRK_none: break;
571       case MRK_readonly:
572         if (Emitted) OS << '|';
573         OS << "Attribute::ReadOnly";
574         break;
575       case MRK_readnone:
576         if (Emitted) OS << '|';
577         OS << "Attribute::ReadNone"; 
578         break;
579       }
580       OS << ");\n";
581     }
582
583     if (numAttrs) {
584       OS << "      NumAttrs = " << numAttrs << ";\n";
585       OS << "      break;\n";
586     } else {
587       OS << "      return AttrListPtr();\n";
588     }
589   }
590   
591   OS << "    }\n";
592   OS << "  }\n";
593   OS << "  return AttrListPtr::get(ArrayRef<AttributeWithIndex>(AWI, "
594              "NumAttrs));\n";
595   OS << "}\n";
596   OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
597 }
598
599 /// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
600 void IntrinsicEmitter::
601 EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
602   OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"
603      << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"
604      << "assert(iid <= Intrinsic::" << Ints.back().EnumName << " && "
605      << "\"Unknown intrinsic.\");\n\n";
606
607   OS << "static const uint8_t IntrinsicModRefBehavior[] = {\n"
608      << "  /* invalid */ UnknownModRefBehavior,\n";
609   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
610     OS << "  /* " << TargetPrefix << Ints[i].EnumName << " */ ";
611     switch (Ints[i].ModRef) {
612     case CodeGenIntrinsic::NoMem:
613       OS << "DoesNotAccessMemory,\n";
614       break;
615     case CodeGenIntrinsic::ReadArgMem:
616       OS << "OnlyReadsArgumentPointees,\n";
617       break;
618     case CodeGenIntrinsic::ReadMem:
619       OS << "OnlyReadsMemory,\n";
620       break;
621     case CodeGenIntrinsic::ReadWriteArgMem:
622       OS << "OnlyAccessesArgumentPointees,\n";
623       break;
624     case CodeGenIntrinsic::ReadWriteMem:
625       OS << "UnknownModRefBehavior,\n";
626       break;
627     }
628   }
629   OS << "};\n\n"
630      << "return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);\n"
631      << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
632 }
633
634 /// EmitTargetBuiltins - All of the builtins in the specified map are for the
635 /// same target, and we already checked it.
636 static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
637                                const std::string &TargetPrefix,
638                                raw_ostream &OS) {
639   
640   std::vector<StringMatcher::StringPair> Results;
641   
642   for (std::map<std::string, std::string>::const_iterator I = BIM.begin(),
643        E = BIM.end(); I != E; ++I) {
644     std::string ResultCode =
645     "return " + TargetPrefix + "Intrinsic::" + I->second + ";";
646     Results.push_back(StringMatcher::StringPair(I->first, ResultCode));
647   }
648
649   StringMatcher("BuiltinName", Results, OS).Emit();
650 }
651
652         
653 void IntrinsicEmitter::
654 EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 
655                              raw_ostream &OS) {
656   typedef std::map<std::string, std::map<std::string, std::string> > BIMTy;
657   BIMTy BuiltinMap;
658   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
659     if (!Ints[i].GCCBuiltinName.empty()) {
660       // Get the map for this target prefix.
661       std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix];
662       
663       if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName,
664                                      Ints[i].EnumName)).second)
665         throw "Intrinsic '" + Ints[i].TheDef->getName() +
666               "': duplicate GCC builtin name!";
667     }
668   }
669   
670   OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
671   OS << "// This is used by the C front-end.  The GCC builtin name is passed\n";
672   OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
673   OS << "// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.\n";
674   OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
675   
676   if (TargetOnly) {
677     OS << "static " << TargetPrefix << "Intrinsic::ID "
678        << "getIntrinsicForGCCBuiltin(const char "
679        << "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
680   } else {
681     OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
682        << "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
683   }
684   
685   OS << "  StringRef BuiltinName(BuiltinNameStr);\n";
686   OS << "  StringRef TargetPrefix(TargetPrefixStr);\n\n";
687   
688   // Note: this could emit significantly better code if we cared.
689   for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
690     OS << "  ";
691     if (!I->first.empty())
692       OS << "if (TargetPrefix == \"" << I->first << "\") ";
693     else
694       OS << "/* Target Independent Builtins */ ";
695     OS << "{\n";
696
697     // Emit the comparisons for this target prefix.
698     EmitTargetBuiltins(I->second, TargetPrefix, OS);
699     OS << "  }\n";
700   }
701   OS << "  return ";
702   if (!TargetPrefix.empty())
703     OS << "(" << TargetPrefix << "Intrinsic::ID)";
704   OS << "Intrinsic::not_intrinsic;\n";
705   OS << "}\n";
706   OS << "#endif\n\n";
707 }