IntrinsicEmitter.cpp revision 223017
1135446Strhodes//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
2262706Serwin//
3135446Strhodes//                     The LLVM Compiler Infrastructure
4135446Strhodes//
5174187Sdougb// This file is distributed under the University of Illinois Open Source
6135446Strhodes// License. See LICENSE.TXT for details.
7135446Strhodes//
8135446Strhodes//===----------------------------------------------------------------------===//
9135446Strhodes//
10135446Strhodes// This tablegen backend emits information about intrinsic functions.
11135446Strhodes//
12135446Strhodes//===----------------------------------------------------------------------===//
13135446Strhodes
14135446Strhodes#include "CodeGenTarget.h"
15135446Strhodes#include "IntrinsicEmitter.h"
16135446Strhodes#include "Record.h"
17135446Strhodes#include "StringMatcher.h"
18254897Serwin#include "llvm/ADT/StringExtras.h"
19135446Strhodes#include <algorithm>
20186462Sdougbusing namespace llvm;
21135446Strhodes
22170222Sdougb//===----------------------------------------------------------------------===//
23135446Strhodes// IntrinsicEmitter Implementation
24135446Strhodes//===----------------------------------------------------------------------===//
25135446Strhodes
26135446Strhodesvoid IntrinsicEmitter::run(raw_ostream &OS) {
27135446Strhodes  EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
28135446Strhodes
29135446Strhodes  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly);
30135446Strhodes
31135446Strhodes  if (TargetOnly && !Ints.empty())
32135446Strhodes    TargetPrefix = Ints[0].TargetPrefix;
33135446Strhodes
34135446Strhodes  EmitPrefix(OS);
35135446Strhodes
36193149Sdougb  // Emit the enum information.
37193149Sdougb  EmitEnumInfo(Ints, OS);
38135446Strhodes
39135446Strhodes  // Emit the intrinsic ID -> name table.
40135446Strhodes  EmitIntrinsicToNameTable(Ints, OS);
41135446Strhodes
42135446Strhodes  // Emit the intrinsic ID -> overload table.
43135446Strhodes  EmitIntrinsicToOverloadTable(Ints, OS);
44135446Strhodes
45135446Strhodes  // Emit the function name recognizer.
46135446Strhodes  EmitFnNameRecognizer(Ints, OS);
47135446Strhodes
48170222Sdougb  // Emit the intrinsic verifier.
49135446Strhodes  EmitVerifier(Ints, OS);
50135446Strhodes
51193149Sdougb  // Emit the intrinsic declaration generator.
52135446Strhodes  EmitGenerator(Ints, OS);
53193149Sdougb
54193149Sdougb  // Emit the intrinsic parameter attributes.
55193149Sdougb  EmitAttributes(Ints, OS);
56193149Sdougb
57193149Sdougb  // Emit intrinsic alias analysis mod/ref behavior.
58135446Strhodes  EmitModRefBehavior(Ints, OS);
59193149Sdougb
60170222Sdougb  // Emit a list of intrinsics with corresponding GCC builtins.
61193149Sdougb  EmitGCCBuiltinList(Ints, OS);
62193149Sdougb
63193149Sdougb  // Emit code to translate GCC builtins into LLVM intrinsics.
64193149Sdougb  EmitIntrinsicToGCCBuiltinMap(Ints, OS);
65193149Sdougb
66193149Sdougb  EmitSuffix(OS);
67135446Strhodes}
68186462Sdougb
69135446Strhodesvoid IntrinsicEmitter::EmitPrefix(raw_ostream &OS) {
70135446Strhodes  OS << "// VisualStudio defines setjmp as _setjmp\n"
71135446Strhodes        "#if defined(_MSC_VER) && defined(setjmp) && \\\n"
72135446Strhodes        "                         !defined(setjmp_undefined_for_msvc)\n"
73135446Strhodes        "#  pragma push_macro(\"setjmp\")\n"
74193149Sdougb        "#  undef setjmp\n"
75193149Sdougb        "#  define setjmp_undefined_for_msvc\n"
76193149Sdougb        "#endif\n\n";
77135446Strhodes}
78170222Sdougb
79193149Sdougbvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) {
80193149Sdougb  OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n"
81193149Sdougb        "// let's return it to _setjmp state\n"
82135446Strhodes        "#  pragma pop_macro(\"setjmp\")\n"
83193149Sdougb        "#  undef setjmp_undefined_for_msvc\n"
84193149Sdougb        "#endif\n\n";
85193149Sdougb}
86135446Strhodes
87193149Sdougbvoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
88193149Sdougb                                    raw_ostream &OS) {
89135446Strhodes  OS << "// Enum values for Intrinsics.h\n";
90193149Sdougb  OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
91135446Strhodes  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
92254402Serwin    OS << "    " << Ints[i].EnumName;
93135446Strhodes    OS << ((i != e-1) ? ", " : "  ");
94135446Strhodes    OS << std::string(40-Ints[i].EnumName.size(), ' ')
95135446Strhodes      << "// " << Ints[i].Name << "\n";
96135446Strhodes  }
97170222Sdougb  OS << "#endif\n\n";
98135446Strhodes}
99135446Strhodes
100135446Strhodesvoid IntrinsicEmitter::
101135446StrhodesEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
102170222Sdougb                     raw_ostream &OS) {
103135446Strhodes  // Build a 'first character of function name' -> intrinsic # mapping.
104193149Sdougb  std::map<char, std::vector<unsigned> > IntMapping;
105135446Strhodes  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
106193149Sdougb    IntMapping[Ints[i].Name[5]].push_back(i);
107193149Sdougb
108186462Sdougb  OS << "// Function name -> enum value recognizer code.\n";
109193149Sdougb  OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
110193149Sdougb  OS << "  StringRef NameR(Name+6, Len-6);   // Skip over 'llvm.'\n";
111135446Strhodes  OS << "  switch (Name[5]) {                  // Dispatch on first letter.\n";
112193149Sdougb  OS << "  default: break;\n";
113193149Sdougb  // Emit the intrinsic matching stuff by first letter.
114245163Serwin  for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(),
115135446Strhodes       E = IntMapping.end(); I != E; ++I) {
116193149Sdougb    OS << "  case '" << I->first << "':\n";
117193149Sdougb    std::vector<unsigned> &IntList = I->second;
118135446Strhodes
119193149Sdougb    // Emit all the overloaded intrinsics first, build a table of the
120193149Sdougb    // non-overloaded ones.
121135446Strhodes    std::vector<StringMatcher::StringPair> MatchTable;
122193149Sdougb
123193149Sdougb    for (unsigned i = 0, e = IntList.size(); i != e; ++i) {
124193149Sdougb      unsigned IntNo = IntList[i];
125193149Sdougb      std::string Result = "return " + TargetPrefix + "Intrinsic::" +
126193149Sdougb        Ints[IntNo].EnumName + ";";
127193149Sdougb
128193149Sdougb      if (!Ints[IntNo].isOverloaded) {
129193149Sdougb        MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result));
130193149Sdougb        continue;
131170222Sdougb      }
132135446Strhodes
133135446Strhodes      // For overloaded intrinsics, only the prefix needs to match
134135446Strhodes      std::string TheStr = Ints[IntNo].Name.substr(6);
135135446Strhodes      TheStr += '.';  // Require "bswap." instead of bswap.
136224092Sdougb      OS << "    if (NameR.startswith(\"" << TheStr << "\")) "
137224092Sdougb         << Result << '\n';
138224092Sdougb    }
139224092Sdougb
140224092Sdougb    // Emit the matcher logic for the fixed length strings.
141224092Sdougb    StringMatcher("NameR", MatchTable, OS).Emit(1);
142224092Sdougb    OS << "    break;  // end of '" << I->first << "' case.\n";
143224092Sdougb  }
144135446Strhodes
145170222Sdougb  OS << "  }\n";
146224092Sdougb  OS << "#endif\n\n";
147135446Strhodes}
148135446Strhodes
149135446Strhodesvoid IntrinsicEmitter::
150224092SdougbEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints,
151224092Sdougb                         raw_ostream &OS) {
152224092Sdougb  OS << "// Intrinsic ID to name table\n";
153224092Sdougb  OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n";
154224092Sdougb  OS << "  // Note that entry #0 is the invalid intrinsic!\n";
155224092Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
156224092Sdougb    OS << "  \"" << Ints[i].Name << "\",\n";
157224092Sdougb  OS << "#endif\n\n";
158135446Strhodes}
159193149Sdougb
160193149Sdougbvoid IntrinsicEmitter::
161193149SdougbEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints,
162193149Sdougb                         raw_ostream &OS) {
163224092Sdougb  OS << "// Intrinsic ID to overload table\n";
164224092Sdougb  OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n";
165224092Sdougb  OS << "  // Note that entry #0 is the invalid intrinsic!\n";
166224092Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
167135446Strhodes    OS << "  ";
168135446Strhodes    if (Ints[i].isOverloaded)
169135446Strhodes      OS << "true";
170135446Strhodes    else
171135446Strhodes      OS << "false";
172135446Strhodes    OS << ",\n";
173170222Sdougb  }
174135446Strhodes  OS << "#endif\n\n";
175193149Sdougb}
176193149Sdougb
177193149Sdougbstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
178193149Sdougb  if (EVT(VT).isInteger()) {
179193149Sdougb    unsigned BitWidth = EVT(VT).getSizeInBits();
180193149Sdougb    OS << "IntegerType::get(Context, " << BitWidth << ")";
181193149Sdougb  } else if (VT == MVT::Other) {
182193149Sdougb    // MVT::OtherVT is used to mean the empty struct type here.
183193149Sdougb    OS << "StructType::get(Context)";
184193149Sdougb  } else if (VT == MVT::f32) {
185193149Sdougb    OS << "Type::getFloatTy(Context)";
186193149Sdougb  } else if (VT == MVT::f64) {
187193149Sdougb    OS << "Type::getDoubleTy(Context)";
188193149Sdougb  } else if (VT == MVT::f80) {
189193149Sdougb    OS << "Type::getX86_FP80Ty(Context)";
190193149Sdougb  } else if (VT == MVT::f128) {
191193149Sdougb    OS << "Type::getFP128Ty(Context)";
192193149Sdougb  } else if (VT == MVT::ppcf128) {
193193149Sdougb    OS << "Type::getPPC_FP128Ty(Context)";
194193149Sdougb  } else if (VT == MVT::isVoid) {
195193149Sdougb    OS << "Type::getVoidTy(Context)";
196193149Sdougb  } else if (VT == MVT::Metadata) {
197135446Strhodes    OS << "Type::getMetadataTy(Context)";
198135446Strhodes  } else if (VT == MVT::x86mmx) {
199170222Sdougb    OS << "Type::getX86_MMXTy(Context)";
200135446Strhodes  } else {
201193149Sdougb    assert(false && "Unsupported ValueType!");
202193149Sdougb  }
203193149Sdougb}
204275672Sdelphij
205135446Strhodesstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
206135446Strhodes                             unsigned &ArgNo);
207170222Sdougb
208135446Strhodesstatic void EmitTypeGenerate(raw_ostream &OS,
209135446Strhodes                             const std::vector<Record*> &ArgTypes,
210135446Strhodes                             unsigned &ArgNo) {
211135446Strhodes  if (ArgTypes.empty())
212135446Strhodes    return EmitTypeForValueType(OS, MVT::isVoid);
213193149Sdougb
214193149Sdougb  if (ArgTypes.size() == 1)
215193149Sdougb    return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
216135446Strhodes
217135446Strhodes  OS << "StructType::get(Context, ";
218170222Sdougb
219170222Sdougb  for (std::vector<Record*>::const_iterator
220135446Strhodes         I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) {
221135446Strhodes    EmitTypeGenerate(OS, *I, ArgNo);
222135446Strhodes    OS << ", ";
223170222Sdougb  }
224193149Sdougb
225135446Strhodes  OS << " NULL)";
226193149Sdougb}
227193149Sdougb
228193149Sdougbstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType,
229135446Strhodes                             unsigned &ArgNo) {
230193149Sdougb  MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
231135446Strhodes
232135446Strhodes  if (ArgType->isSubClassOf("LLVMMatchType")) {
233170222Sdougb    unsigned Number = ArgType->getValueAsInt("Number");
234135446Strhodes    assert(Number < ArgNo && "Invalid matching number!");
235135446Strhodes    if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
236135446Strhodes      OS << "VectorType::getExtendedElementVectorType"
237135446Strhodes         << "(dyn_cast<VectorType>(Tys[" << Number << "]))";
238135446Strhodes    else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
239193149Sdougb      OS << "VectorType::getTruncatedElementVectorType"
240135446Strhodes         << "(dyn_cast<VectorType>(Tys[" << Number << "]))";
241193149Sdougb    else
242193149Sdougb      OS << "Tys[" << Number << "]";
243135446Strhodes  } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) {
244193149Sdougb    // NOTE: The ArgNo variable here is not the absolute argument number, it is
245193149Sdougb    // the index of the "arbitrary" type in the Tys array passed to the
246193149Sdougb    // Intrinsic::getDeclaration function. Consequently, we only want to
247135446Strhodes    // increment it when we actually hit an overloaded type. Getting this wrong
248193149Sdougb    // leads to very subtle bugs!
249170222Sdougb    OS << "Tys[" << ArgNo++ << "]";
250135446Strhodes  } else if (EVT(VT).isVector()) {
251135446Strhodes    EVT VVT = VT;
252135446Strhodes    OS << "VectorType::get(";
253135446Strhodes    EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy);
254135446Strhodes    OS << ", " << VVT.getVectorNumElements() << ")";
255135446Strhodes  } else if (VT == MVT::iPTR) {
256135446Strhodes    OS << "PointerType::getUnqual(";
257193149Sdougb    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
258193149Sdougb    OS << ")";
259234010Sdougb  } else if (VT == MVT::iPTRAny) {
260135446Strhodes    // Make sure the user has passed us an argument type to overload. If not,
261135446Strhodes    // treat it as an ordinary (not overloaded) intrinsic.
262135446Strhodes    OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo
263135446Strhodes    << "] : PointerType::getUnqual(";
264135446Strhodes    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
265135446Strhodes    OS << ")";
266135446Strhodes    ++ArgNo;
267135446Strhodes  } else if (VT == MVT::isVoid) {
268135446Strhodes    if (ArgNo == 0)
269135446Strhodes      OS << "Type::getVoidTy(Context)";
270170222Sdougb    else
271170222Sdougb      // MVT::isVoid is used to mean varargs here.
272170222Sdougb      OS << "...";
273135446Strhodes  } else {
274135446Strhodes    EmitTypeForValueType(OS, VT);
275135446Strhodes  }
276135446Strhodes}
277135446Strhodes
278135446Strhodes/// RecordListComparator - Provide a deterministic comparator for lists of
279135446Strhodes/// records.
280135446Strhodesnamespace {
281135446Strhodes  typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair;
282135446Strhodes  struct RecordListComparator {
283135446Strhodes    bool operator()(const RecPair &LHS,
284193149Sdougb                    const RecPair &RHS) const {
285193149Sdougb      unsigned i = 0;
286143731Sdougb      const std::vector<Record*> *LHSVec = &LHS.first;
287135446Strhodes      const std::vector<Record*> *RHSVec = &RHS.first;
288135446Strhodes      unsigned RHSSize = RHSVec->size();
289135446Strhodes      unsigned LHSSize = LHSVec->size();
290135446Strhodes
291135446Strhodes      for (; i != LHSSize; ++i) {
292135446Strhodes        if (i == RHSSize) return false;  // RHS is shorter than LHS.
293135446Strhodes        if ((*LHSVec)[i] != (*RHSVec)[i])
294135446Strhodes          return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
295135446Strhodes      }
296135446Strhodes
297135446Strhodes      if (i != RHSSize) return true;
298135446Strhodes
299214586Sdougb      i = 0;
300214586Sdougb      LHSVec = &LHS.second;
301135446Strhodes      RHSVec = &RHS.second;
302135446Strhodes      RHSSize = RHSVec->size();
303135446Strhodes      LHSSize = LHSVec->size();
304135446Strhodes
305275672Sdelphij      for (i = 0; i != LHSSize; ++i) {
306193149Sdougb        if (i == RHSSize) return false;  // RHS is shorter than LHS.
307193149Sdougb        if ((*LHSVec)[i] != (*RHSVec)[i])
308193149Sdougb          return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
309135446Strhodes      }
310135446Strhodes
311135446Strhodes      return i != RHSSize;
312135446Strhodes    }
313275672Sdelphij  };
314135446Strhodes}
315135446Strhodes
316135446Strhodesvoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
317135446Strhodes                                    raw_ostream &OS) {
318135446Strhodes  OS << "// Verifier::visitIntrinsicFunctionCall code.\n";
319135446Strhodes  OS << "#ifdef GET_INTRINSIC_VERIFIER\n";
320135446Strhodes  OS << "  switch (ID) {\n";
321135446Strhodes  OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
322135446Strhodes
323143731Sdougb  // This checking can emit a lot of very common code.  To reduce the amount of
324143731Sdougb  // code that we emit, batch up cases that have identical types.  This avoids
325135446Strhodes  // problems where GCC can run out of memory compiling Verifier.cpp.
326135446Strhodes  typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
327135446Strhodes  MapTy UniqueArgInfos;
328135446Strhodes
329193149Sdougb  // Compute the unique argument type info.
330193149Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
331193149Sdougb    UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
332193149Sdougb                             Ints[i].IS.ParamTypeDefs)].push_back(i);
333135446Strhodes
334193149Sdougb  // Loop through the array, emitting one comparison for each batch.
335193149Sdougb  for (MapTy::iterator I = UniqueArgInfos.begin(),
336193149Sdougb       E = UniqueArgInfos.end(); I != E; ++I) {
337193149Sdougb    for (unsigned i = 0, e = I->second.size(); i != e; ++i)
338193149Sdougb      OS << "  case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
339193149Sdougb         << Ints[I->second[i]].Name << "\n";
340193149Sdougb
341193149Sdougb    const RecPair &ArgTypes = I->first;
342193149Sdougb    const std::vector<Record*> &RetTys = ArgTypes.first;
343135446Strhodes    const std::vector<Record*> &ParamTys = ArgTypes.second;
344135446Strhodes    std::vector<unsigned> OverloadedTypeIndices;
345193149Sdougb
346193149Sdougb    OS << "    VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", "
347193149Sdougb       << ParamTys.size();
348193149Sdougb
349193149Sdougb    // Emit return types.
350193149Sdougb    for (unsigned j = 0, je = RetTys.size(); j != je; ++j) {
351135446Strhodes      Record *ArgType = RetTys[j];
352135446Strhodes      OS << ", ";
353135446Strhodes
354193149Sdougb      if (ArgType->isSubClassOf("LLVMMatchType")) {
355193149Sdougb        unsigned Number = ArgType->getValueAsInt("Number");
356193149Sdougb        assert(Number < OverloadedTypeIndices.size() &&
357135446Strhodes               "Invalid matching number!");
358135446Strhodes        Number = OverloadedTypeIndices[Number];
359135446Strhodes        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
360135446Strhodes          OS << "~(ExtendedElementVectorType | " << Number << ")";
361135446Strhodes        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
362135446Strhodes          OS << "~(TruncatedElementVectorType | " << Number << ")";
363135446Strhodes        else
364135446Strhodes          OS << "~" << Number;
365193149Sdougb      } else {
366193149Sdougb        MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
367193149Sdougb        OS << getEnumName(VT);
368193149Sdougb
369193149Sdougb        if (EVT(VT).isOverloaded())
370135446Strhodes          OverloadedTypeIndices.push_back(j);
371135446Strhodes
372135446Strhodes        if (VT == MVT::isVoid && j != 0 && j != je - 1)
373135446Strhodes          throw "Var arg type not last argument";
374193149Sdougb      }
375193149Sdougb    }
376193149Sdougb
377135446Strhodes    // Emit the parameter types.
378193149Sdougb    for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) {
379135446Strhodes      Record *ArgType = ParamTys[j];
380193149Sdougb      OS << ", ";
381193149Sdougb
382193149Sdougb      if (ArgType->isSubClassOf("LLVMMatchType")) {
383193149Sdougb        unsigned Number = ArgType->getValueAsInt("Number");
384135446Strhodes        assert(Number < OverloadedTypeIndices.size() &&
385135446Strhodes               "Invalid matching number!");
386135446Strhodes        Number = OverloadedTypeIndices[Number];
387135446Strhodes        if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
388135446Strhodes          OS << "~(ExtendedElementVectorType | " << Number << ")";
389193149Sdougb        else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
390193149Sdougb          OS << "~(TruncatedElementVectorType | " << Number << ")";
391135446Strhodes        else
392193149Sdougb          OS << "~" << Number;
393135446Strhodes      } else {
394135446Strhodes        MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
395135446Strhodes        OS << getEnumName(VT);
396135446Strhodes
397135446Strhodes        if (EVT(VT).isOverloaded())
398135446Strhodes          OverloadedTypeIndices.push_back(j + RetTys.size());
399135446Strhodes
400135446Strhodes        if (VT == MVT::isVoid && j != 0 && j != je - 1)
401135446Strhodes          throw "Var arg type not last argument";
402135446Strhodes      }
403135446Strhodes    }
404135446Strhodes
405193149Sdougb    OS << ");\n";
406193149Sdougb    OS << "    break;\n";
407193149Sdougb  }
408193149Sdougb  OS << "  }\n";
409193149Sdougb  OS << "#endif\n\n";
410135446Strhodes}
411193149Sdougb
412135446Strhodesvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
413193149Sdougb                                     raw_ostream &OS) {
414135446Strhodes  OS << "// Code for generating Intrinsic function declarations.\n";
415193149Sdougb  OS << "#ifdef GET_INTRINSIC_GENERATOR\n";
416135446Strhodes  OS << "  switch (id) {\n";
417193149Sdougb  OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
418135446Strhodes
419135446Strhodes  // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
420135446Strhodes  // types.
421135446Strhodes  typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
422135446Strhodes  MapTy UniqueArgInfos;
423135446Strhodes
424135446Strhodes  // Compute the unique argument type info.
425193149Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
426193149Sdougb    UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
427193149Sdougb                             Ints[i].IS.ParamTypeDefs)].push_back(i);
428193149Sdougb
429193149Sdougb  // Loop through the array, emitting one generator for each batch.
430193149Sdougb  std::string IntrinsicStr = TargetPrefix + "Intrinsic::";
431193149Sdougb
432193149Sdougb  for (MapTy::iterator I = UniqueArgInfos.begin(),
433135446Strhodes       E = UniqueArgInfos.end(); I != E; ++I) {
434135446Strhodes    for (unsigned i = 0, e = I->second.size(); i != e; ++i)
435135446Strhodes      OS << "  case " << IntrinsicStr << Ints[I->second[i]].EnumName
436135446Strhodes         << ":\t\t// " << Ints[I->second[i]].Name << "\n";
437135446Strhodes
438135446Strhodes    const RecPair &ArgTypes = I->first;
439135446Strhodes    const std::vector<Record*> &RetTys = ArgTypes.first;
440135446Strhodes    const std::vector<Record*> &ParamTys = ArgTypes.second;
441135446Strhodes
442135446Strhodes    unsigned N = ParamTys.size();
443135446Strhodes
444193149Sdougb    if (N > 1 &&
445135446Strhodes        getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) {
446135446Strhodes      OS << "    IsVarArg = true;\n";
447135446Strhodes      --N;
448135446Strhodes    }
449135446Strhodes
450135446Strhodes    unsigned ArgNo = 0;
451135446Strhodes    OS << "    ResultTy = ";
452135446Strhodes    EmitTypeGenerate(OS, RetTys, ArgNo);
453193149Sdougb    OS << ";\n";
454135446Strhodes
455135446Strhodes    for (unsigned j = 0; j != N; ++j) {
456135446Strhodes      OS << "    ArgTys.push_back(";
457135446Strhodes      EmitTypeGenerate(OS, ParamTys[j], ArgNo);
458135446Strhodes      OS << ");\n";
459135446Strhodes    }
460135446Strhodes
461135446Strhodes    OS << "    break;\n";
462135446Strhodes  }
463135446Strhodes
464135446Strhodes  OS << "  }\n";
465135446Strhodes  OS << "#endif\n\n";
466135446Strhodes}
467135446Strhodes
468135446Strhodesnamespace {
469135446Strhodes  enum ModRefKind {
470193149Sdougb    MRK_none,
471193149Sdougb    MRK_readonly,
472193149Sdougb    MRK_readnone
473193149Sdougb  };
474193149Sdougb
475193149Sdougb  ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) {
476193149Sdougb    switch (intrinsic.ModRef) {
477193149Sdougb    case CodeGenIntrinsic::NoMem:
478193149Sdougb      return MRK_readnone;
479135446Strhodes    case CodeGenIntrinsic::ReadArgMem:
480135446Strhodes    case CodeGenIntrinsic::ReadMem:
481135446Strhodes      return MRK_readonly;
482135446Strhodes    case CodeGenIntrinsic::ReadWriteArgMem:
483135446Strhodes    case CodeGenIntrinsic::ReadWriteMem:
484135446Strhodes      return MRK_none;
485135446Strhodes    }
486135446Strhodes    assert(0 && "bad mod-ref kind");
487135446Strhodes    return MRK_none;
488135446Strhodes  }
489135446Strhodes
490224092Sdougb  struct AttributeComparator {
491224092Sdougb    bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const {
492224092Sdougb      // Sort throwing intrinsics after non-throwing intrinsics.
493224092Sdougb      if (L->canThrow != R->canThrow)
494224092Sdougb        return R->canThrow;
495224092Sdougb
496224092Sdougb      // Try to order by readonly/readnone attribute.
497224092Sdougb      ModRefKind LK = getModRefKind(*L);
498224092Sdougb      ModRefKind RK = getModRefKind(*R);
499224092Sdougb      if (LK != RK) return (LK > RK);
500224092Sdougb
501224092Sdougb      // Order by argument attributes.
502224092Sdougb      // This is reliable because each side is already sorted internally.
503224092Sdougb      return (L->ArgumentAttributes < R->ArgumentAttributes);
504224092Sdougb    }
505224092Sdougb  };
506224092Sdougb}
507224092Sdougb
508224092Sdougb/// EmitAttributes - This emits the Intrinsic::getAttributes method.
509224092Sdougbvoid IntrinsicEmitter::
510224092SdougbEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
511224092Sdougb  OS << "// Add parameter attributes that are not common to all intrinsics.\n";
512224092Sdougb  OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
513224092Sdougb  if (TargetOnly)
514224092Sdougb    OS << "static AttrListPtr getAttributes(" << TargetPrefix
515224092Sdougb       << "Intrinsic::ID id) {\n";
516224092Sdougb  else
517224092Sdougb    OS << "AttrListPtr Intrinsic::getAttributes(ID id) {\n";
518224092Sdougb
519224092Sdougb  // Compute the maximum number of attribute arguments.
520224092Sdougb  std::vector<const CodeGenIntrinsic*> sortedIntrinsics(Ints.size());
521224092Sdougb  unsigned maxArgAttrs = 0;
522254402Serwin  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
523254402Serwin    const CodeGenIntrinsic &intrinsic = Ints[i];
524254402Serwin    sortedIntrinsics[i] = &intrinsic;
525224092Sdougb    maxArgAttrs =
526224092Sdougb      std::max(maxArgAttrs, unsigned(intrinsic.ArgumentAttributes.size()));
527224092Sdougb  }
528224092Sdougb
529224092Sdougb  // Emit an array of AttributeWithIndex.  Most intrinsics will have
530224092Sdougb  // at least one entry, for the function itself (index ~1), which is
531224092Sdougb  // usually nounwind.
532224092Sdougb  OS << "  AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n";
533224092Sdougb  OS << "  unsigned NumAttrs = 0;\n";
534224092Sdougb  OS << "  switch (id) {\n";
535224092Sdougb  OS << "    default: break;\n";
536224092Sdougb
537224092Sdougb  AttributeComparator precedes;
538224092Sdougb
539224092Sdougb  std::stable_sort(sortedIntrinsics.begin(), sortedIntrinsics.end(), precedes);
540224092Sdougb
541224092Sdougb  for (unsigned i = 0, e = sortedIntrinsics.size(); i != e; ++i) {
542224092Sdougb    const CodeGenIntrinsic &intrinsic = *sortedIntrinsics[i];
543224092Sdougb    OS << "  case " << TargetPrefix << "Intrinsic::"
544224092Sdougb       << intrinsic.EnumName << ":\n";
545224092Sdougb
546224092Sdougb    // Fill out the case if this is the last case for this range of
547224092Sdougb    // intrinsics.
548224092Sdougb    if (i + 1 != e && !precedes(&intrinsic, sortedIntrinsics[i + 1]))
549224092Sdougb      continue;
550224092Sdougb
551224092Sdougb    // Keep track of the number of attributes we're writing out.
552224092Sdougb    unsigned numAttrs = 0;
553224092Sdougb
554224092Sdougb    // The argument attributes are alreadys sorted by argument index.
555224092Sdougb    for (unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size(); ai != ae;) {
556224092Sdougb      unsigned argNo = intrinsic.ArgumentAttributes[ai].first;
557224092Sdougb
558224092Sdougb      OS << "    AWI[" << numAttrs++ << "] = AttributeWithIndex::get("
559224092Sdougb         << argNo+1 << ", ";
560224092Sdougb
561224092Sdougb      bool moreThanOne = false;
562224092Sdougb
563224092Sdougb      do {
564224092Sdougb        if (moreThanOne) OS << '|';
565224092Sdougb
566224092Sdougb        switch (intrinsic.ArgumentAttributes[ai].second) {
567224092Sdougb        case CodeGenIntrinsic::NoCapture:
568224092Sdougb          OS << "Attribute::NoCapture";
569224092Sdougb          break;
570224092Sdougb        }
571224092Sdougb
572224092Sdougb        ++ai;
573224092Sdougb        moreThanOne = true;
574224092Sdougb      } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo);
575224092Sdougb
576224092Sdougb      OS << ");\n";
577224092Sdougb    }
578224092Sdougb
579224092Sdougb    ModRefKind modRef = getModRefKind(intrinsic);
580224092Sdougb
581224092Sdougb    if (!intrinsic.canThrow || modRef) {
582224092Sdougb      OS << "    AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, ";
583224092Sdougb      if (!intrinsic.canThrow) {
584224092Sdougb        OS << "Attribute::NoUnwind";
585224092Sdougb        if (modRef) OS << '|';
586224092Sdougb      }
587224092Sdougb      switch (modRef) {
588224092Sdougb      case MRK_none: break;
589224092Sdougb      case MRK_readonly: OS << "Attribute::ReadOnly"; break;
590224092Sdougb      case MRK_readnone: OS << "Attribute::ReadNone"; break;
591224092Sdougb      }
592224092Sdougb      OS << ");\n";
593224092Sdougb    }
594224092Sdougb
595224092Sdougb    if (numAttrs) {
596224092Sdougb      OS << "    NumAttrs = " << numAttrs << ";\n";
597224092Sdougb      OS << "    break;\n";
598224092Sdougb    } else {
599224092Sdougb      OS << "    return AttrListPtr();\n";
600224092Sdougb    }
601224092Sdougb  }
602224092Sdougb
603224092Sdougb  OS << "  }\n";
604224092Sdougb  OS << "  return AttrListPtr::get(AWI, NumAttrs);\n";
605224092Sdougb  OS << "}\n";
606224092Sdougb  OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
607224092Sdougb}
608224092Sdougb
609224092Sdougb/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior.
610224092Sdougbvoid IntrinsicEmitter::
611224092SdougbEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
612224092Sdougb  OS << "// Determine intrinsic alias analysis mod/ref behavior.\n";
613224092Sdougb  OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n";
614224092Sdougb  OS << "switch (iid) {\n";
615224092Sdougb  OS << "default:\n    return UnknownModRefBehavior;\n";
616224092Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
617224092Sdougb    if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem)
618224092Sdougb      continue;
619224092Sdougb    OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName
620224092Sdougb      << ":\n";
621224092Sdougb    switch (Ints[i].ModRef) {
622224092Sdougb    default:
623224092Sdougb      assert(false && "Unknown Mod/Ref type!");
624224092Sdougb    case CodeGenIntrinsic::NoMem:
625224092Sdougb      OS << "  return DoesNotAccessMemory;\n";
626224092Sdougb      break;
627224092Sdougb    case CodeGenIntrinsic::ReadArgMem:
628224092Sdougb      OS << "  return OnlyReadsArgumentPointees;\n";
629224092Sdougb      break;
630224092Sdougb    case CodeGenIntrinsic::ReadMem:
631224092Sdougb      OS << "  return OnlyReadsMemory;\n";
632224092Sdougb      break;
633224092Sdougb    case CodeGenIntrinsic::ReadWriteArgMem:
634224092Sdougb      OS << "  return OnlyAccessesArgumentPointees;\n";
635224092Sdougb      break;
636224092Sdougb    }
637224092Sdougb  }
638224092Sdougb  OS << "}\n";
639224092Sdougb  OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n";
640224092Sdougb}
641224092Sdougb
642224092Sdougbvoid IntrinsicEmitter::
643224092SdougbEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
644224092Sdougb  OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n";
645224092Sdougb  OS << "#ifdef GET_GCC_BUILTIN_NAME\n";
646224092Sdougb  OS << "  switch (F->getIntrinsicID()) {\n";
647224092Sdougb  OS << "  default: BuiltinName = \"\"; break;\n";
648224092Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
649224092Sdougb    if (!Ints[i].GCCBuiltinName.empty()) {
650224092Sdougb      OS << "  case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \""
651224092Sdougb         << Ints[i].GCCBuiltinName << "\"; break;\n";
652254402Serwin    }
653224092Sdougb  }
654224092Sdougb  OS << "  }\n";
655224092Sdougb  OS << "#endif\n\n";
656224092Sdougb}
657224092Sdougb
658224092Sdougb/// EmitTargetBuiltins - All of the builtins in the specified map are for the
659224092Sdougb/// same target, and we already checked it.
660224092Sdougbstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM,
661224092Sdougb                               const std::string &TargetPrefix,
662224092Sdougb                               raw_ostream &OS) {
663224092Sdougb
664224092Sdougb  std::vector<StringMatcher::StringPair> Results;
665224092Sdougb
666224092Sdougb  for (std::map<std::string, std::string>::const_iterator I = BIM.begin(),
667224092Sdougb       E = BIM.end(); I != E; ++I) {
668224092Sdougb    std::string ResultCode =
669224092Sdougb    "return " + TargetPrefix + "Intrinsic::" + I->second + ";";
670224092Sdougb    Results.push_back(StringMatcher::StringPair(I->first, ResultCode));
671224092Sdougb  }
672224092Sdougb
673224092Sdougb  StringMatcher("BuiltinName", Results, OS).Emit();
674224092Sdougb}
675224092Sdougb
676224092Sdougb
677254402Serwinvoid IntrinsicEmitter::
678254402SerwinEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
679254402Serwin                             raw_ostream &OS) {
680224092Sdougb  typedef std::map<std::string, std::map<std::string, std::string> > BIMTy;
681224092Sdougb  BIMTy BuiltinMap;
682224092Sdougb  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
683224092Sdougb    if (!Ints[i].GCCBuiltinName.empty()) {
684224092Sdougb      // Get the map for this target prefix.
685224092Sdougb      std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix];
686224092Sdougb
687224092Sdougb      if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName,
688224092Sdougb                                     Ints[i].EnumName)).second)
689224092Sdougb        throw "Intrinsic '" + Ints[i].TheDef->getName() +
690224092Sdougb              "': duplicate GCC builtin name!";
691224092Sdougb    }
692224092Sdougb  }
693224092Sdougb
694224092Sdougb  OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
695224092Sdougb  OS << "// This is used by the C front-end.  The GCC builtin name is passed\n";
696224092Sdougb  OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
697224092Sdougb  OS << "// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.\n";
698224092Sdougb  OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
699224092Sdougb
700224092Sdougb  if (TargetOnly) {
701224092Sdougb    OS << "static " << TargetPrefix << "Intrinsic::ID "
702224092Sdougb       << "getIntrinsicForGCCBuiltin(const char "
703224092Sdougb       << "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
704224092Sdougb  } else {
705224092Sdougb    OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char "
706224092Sdougb       << "*TargetPrefixStr, const char *BuiltinNameStr) {\n";
707224092Sdougb  }
708224092Sdougb
709224092Sdougb  OS << "  StringRef BuiltinName(BuiltinNameStr);\n";
710224092Sdougb  OS << "  StringRef TargetPrefix(TargetPrefixStr);\n\n";
711224092Sdougb
712224092Sdougb  // Note: this could emit significantly better code if we cared.
713224092Sdougb  for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
714224092Sdougb    OS << "  ";
715224092Sdougb    if (!I->first.empty())
716224092Sdougb      OS << "if (TargetPrefix == \"" << I->first << "\") ";
717224092Sdougb    else
718224092Sdougb      OS << "/* Target Independent Builtins */ ";
719224092Sdougb    OS << "{\n";
720224092Sdougb
721224092Sdougb    // Emit the comparisons for this target prefix.
722224092Sdougb    EmitTargetBuiltins(I->second, TargetPrefix, OS);
723224092Sdougb    OS << "  }\n";
724224092Sdougb  }
725224092Sdougb  OS << "  return ";
726224092Sdougb  if (!TargetPrefix.empty())
727224092Sdougb    OS << "(" << TargetPrefix << "Intrinsic::ID)";
728224092Sdougb  OS << "Intrinsic::not_intrinsic;\n";
729224092Sdougb  OS << "}\n";
730224092Sdougb  OS << "#endif\n\n";
731224092Sdougb}
732224092Sdougb