IntrinsicEmitter.cpp revision 43ad6b3e0d6ada51e9b23aab3e061187f1f5710c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was developed by Chris Lattner and is distributed under
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the University of Illinois Open Source License. See LICENSE.TXT for details.
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tablegen backend emits information about intrinsic functions.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CodeGenTarget.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "IntrinsicEmitter.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Record.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/StringExtras.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IntrinsicEmitter Implementation
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IntrinsicEmitter::run(std::ostream &OS) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitSourceFileHeader("Intrinsic Function Source Fragment", OS);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit the enum information.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitEnumInfo(Ints, OS);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit the intrinsic ID -> name table.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitIntrinsicToNameTable(Ints, OS);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit the function name recognizer.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitFnNameRecognizer(Ints, OS);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Emit the intrinsic verifier.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitVerifier(Ints, OS);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Emit the intrinsic declaration generator.
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EmitGenerator(Ints, OS);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit the intrinsic parameter attributes.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EmitAttributes(Ints, OS);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48  // Emit a list of intrinsics with corresponding GCC builtins.
49  EmitGCCBuiltinList(Ints, OS);
50
51  // Emit code to translate GCC builtins into LLVM intrinsics.
52  EmitIntrinsicToGCCBuiltinMap(Ints, OS);
53}
54
55void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints,
56                                    std::ostream &OS) {
57  OS << "// Enum values for Intrinsics.h\n";
58  OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n";
59  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
60    OS << "    " << Ints[i].EnumName;
61    OS << ((i != e-1) ? ", " : "  ");
62    OS << std::string(40-Ints[i].EnumName.size(), ' ')
63      << "// " << Ints[i].Name << "\n";
64  }
65  OS << "#endif\n\n";
66}
67
68void IntrinsicEmitter::
69EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints,
70                     std::ostream &OS) {
71  // Build a function name -> intrinsic name mapping.
72  std::map<std::string, unsigned> IntMapping;
73  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
74    IntMapping[Ints[i].Name] = i;
75
76  OS << "// Function name -> enum value recognizer code.\n";
77  OS << "#ifdef GET_FUNCTION_RECOGNIZER\n";
78  OS << "  switch (Name[5]) {\n";
79  OS << "  default:\n";
80  // Emit the intrinsics in sorted order.
81  char LastChar = 0;
82  for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(),
83       E = IntMapping.end(); I != E; ++I) {
84    if (I->first[5] != LastChar) {
85      LastChar = I->first[5];
86      OS << "    break;\n";
87      OS << "  case '" << LastChar << "':\n";
88    }
89
90    // For overloaded intrinsics, only the prefix needs to match
91    if (Ints[I->second].isOverloaded)
92      OS << "    if (Len > " << I->first.size()
93       << " && !memcmp(Name, \"" << I->first << ".\", "
94       << (I->first.size() + 1) << ")) return Intrinsic::"
95       << Ints[I->second].EnumName << ";\n";
96    else
97      OS << "    if (Len == " << I->first.size()
98         << " && !memcmp(Name, \"" << I->first << "\", "
99         << I->first.size() << ")) return Intrinsic::"
100         << Ints[I->second].EnumName << ";\n";
101  }
102  OS << "  }\n";
103  OS << "#endif\n\n";
104}
105
106void IntrinsicEmitter::
107EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints,
108                         std::ostream &OS) {
109  OS << "// Intrinsic ID to name table\n";
110  OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n";
111  OS << "  // Note that entry #0 is the invalid intrinsic!\n";
112  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
113    OS << "  \"" << Ints[i].Name << "\",\n";
114  OS << "#endif\n\n";
115}
116
117static void EmitTypeForValueType(std::ostream &OS, MVT::ValueType VT) {
118  if (MVT::isInteger(VT)) {
119    unsigned BitWidth = MVT::getSizeInBits(VT);
120    OS << "IntegerType::get(" << BitWidth << ")";
121  } else if (VT == MVT::Other) {
122    // MVT::OtherVT is used to mean the empty struct type here.
123    OS << "StructType::get(std::vector<const Type *>())";
124  } else if (VT == MVT::f32) {
125    OS << "Type::FloatTy";
126  } else if (VT == MVT::f64) {
127    OS << "Type::DoubleTy";
128  } else if (VT == MVT::f80) {
129    OS << "Type::X86_FP80Ty";
130  } else if (VT == MVT::f128) {
131    OS << "Type::FP128Ty";
132  } else if (VT == MVT::ppcf128) {
133    OS << "Type::PPC_FP128Ty";
134  } else if (VT == MVT::isVoid) {
135    OS << "Type::VoidTy";
136  } else {
137    assert(false && "Unsupported ValueType!");
138  }
139}
140
141static void EmitTypeGenerate(std::ostream &OS, Record *ArgType,
142                             unsigned &ArgNo) {
143  MVT::ValueType VT = getValueType(ArgType->getValueAsDef("VT"));
144
145  if (ArgType->isSubClassOf("LLVMMatchType")) {
146    unsigned Number = ArgType->getValueAsInt("Number");
147    assert(Number < ArgNo && "Invalid matching number!");
148    OS << "Tys[" << Number << "]";
149  } else if (VT == MVT::iAny || VT == MVT::fAny) {
150    // NOTE: The ArgNo variable here is not the absolute argument number, it is
151    // the index of the "arbitrary" type in the Tys array passed to the
152    // Intrinsic::getDeclaration function. Consequently, we only want to
153    // increment it when we actually hit an overloaded type. Getting this wrong
154    // leads to very subtle bugs!
155    OS << "Tys[" << ArgNo++ << "]";
156  } else if (MVT::isVector(VT)) {
157    OS << "VectorType::get(";
158    EmitTypeForValueType(OS, MVT::getVectorElementType(VT));
159    OS << ", " << MVT::getVectorNumElements(VT) << ")";
160  } else if (VT == MVT::iPTR) {
161    OS << "PointerType::getUnqual(";
162    EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
163    OS << ")";
164  } else if (VT == MVT::isVoid) {
165    if (ArgNo == 0)
166      OS << "Type::VoidTy";
167    else
168      // MVT::isVoid is used to mean varargs here.
169      OS << "...";
170  } else {
171    EmitTypeForValueType(OS, VT);
172  }
173}
174
175/// RecordListComparator - Provide a determinstic comparator for lists of
176/// records.
177namespace {
178  struct RecordListComparator {
179    bool operator()(const std::vector<Record*> &LHS,
180                    const std::vector<Record*> &RHS) const {
181      unsigned i = 0;
182      do {
183        if (i == RHS.size()) return false;  // RHS is shorter than LHS.
184        if (LHS[i] != RHS[i])
185          return LHS[i]->getName() < RHS[i]->getName();
186      } while (++i != LHS.size());
187
188      return i != RHS.size();
189    }
190  };
191}
192
193void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints,
194                                    std::ostream &OS) {
195  OS << "// Verifier::visitIntrinsicFunctionCall code.\n";
196  OS << "#ifdef GET_INTRINSIC_VERIFIER\n";
197  OS << "  switch (ID) {\n";
198  OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
199
200  // This checking can emit a lot of very common code.  To reduce the amount of
201  // code that we emit, batch up cases that have identical types.  This avoids
202  // problems where GCC can run out of memory compiling Verifier.cpp.
203  typedef std::map<std::vector<Record*>, std::vector<unsigned>,
204    RecordListComparator> MapTy;
205  MapTy UniqueArgInfos;
206
207  // Compute the unique argument type info.
208  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
209    UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
210
211  // Loop through the array, emitting one comparison for each batch.
212  for (MapTy::iterator I = UniqueArgInfos.begin(),
213       E = UniqueArgInfos.end(); I != E; ++I) {
214    for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
215      OS << "  case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
216         << Ints[I->second[i]].Name << "\n";
217    }
218
219    const std::vector<Record*> &ArgTypes = I->first;
220    OS << "    VerifyIntrinsicPrototype(ID, IF, " << ArgTypes.size() << ", ";
221    for (unsigned j = 0; j != ArgTypes.size(); ++j) {
222      Record *ArgType = ArgTypes[j];
223      if (ArgType->isSubClassOf("LLVMMatchType")) {
224        unsigned Number = ArgType->getValueAsInt("Number");
225        assert(Number < j && "Invalid matching number!");
226        OS << "~" << Number;
227      } else {
228        MVT::ValueType VT = getValueType(ArgType->getValueAsDef("VT"));
229        OS << getEnumName(VT);
230        if (VT == MVT::isVoid && j != 0 && j != ArgTypes.size()-1)
231          throw "Var arg type not last argument";
232      }
233      if (j != ArgTypes.size()-1)
234        OS << ", ";
235    }
236
237    OS << ");\n";
238    OS << "    break;\n";
239  }
240  OS << "  }\n";
241  OS << "#endif\n\n";
242}
243
244void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
245                                     std::ostream &OS) {
246  OS << "// Code for generating Intrinsic function declarations.\n";
247  OS << "#ifdef GET_INTRINSIC_GENERATOR\n";
248  OS << "  switch (id) {\n";
249  OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
250
251  // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
252  // types.
253  typedef std::map<std::vector<Record*>, std::vector<unsigned>,
254    RecordListComparator> MapTy;
255  MapTy UniqueArgInfos;
256
257  // Compute the unique argument type info.
258  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
259    UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
260
261  // Loop through the array, emitting one generator for each batch.
262  for (MapTy::iterator I = UniqueArgInfos.begin(),
263       E = UniqueArgInfos.end(); I != E; ++I) {
264    for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
265      OS << "  case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
266         << Ints[I->second[i]].Name << "\n";
267    }
268
269    const std::vector<Record*> &ArgTypes = I->first;
270    unsigned N = ArgTypes.size();
271
272    if (N > 1 &&
273        getValueType(ArgTypes[N-1]->getValueAsDef("VT")) == MVT::isVoid) {
274      OS << "    IsVarArg = true;\n";
275      --N;
276    }
277
278    unsigned ArgNo = 0;
279    OS << "    ResultTy = ";
280    EmitTypeGenerate(OS, ArgTypes[0], ArgNo);
281    OS << ";\n";
282
283    for (unsigned j = 1; j != N; ++j) {
284      OS << "    ArgTys.push_back(";
285      EmitTypeGenerate(OS, ArgTypes[j], ArgNo);
286      OS << ");\n";
287    }
288    OS << "    break;\n";
289  }
290  OS << "  }\n";
291  OS << "#endif\n\n";
292}
293
294void IntrinsicEmitter::
295EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS) {
296  OS << "// Add parameter attributes that are not common to all intrinsics.\n";
297  OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
298  OS << "  switch (id) {\n";
299  OS << "  default: break;\n";
300  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
301    switch (Ints[i].ModRef) {
302    default: break;
303    case CodeGenIntrinsic::NoMem:
304      OS << "  case Intrinsic::" << Ints[i].EnumName << ":\n";
305      break;
306    }
307  }
308  OS << "    Attr |= ParamAttr::ReadNone; // These do not access memory.\n";
309  OS << "    break;\n";
310  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
311    switch (Ints[i].ModRef) {
312    default: break;
313    case CodeGenIntrinsic::ReadArgMem:
314    case CodeGenIntrinsic::ReadMem:
315      OS << "  case Intrinsic::" << Ints[i].EnumName << ":\n";
316      break;
317    }
318  }
319  OS << "    Attr |= ParamAttr::ReadOnly; // These do not write memory.\n";
320  OS << "    break;\n";
321  OS << "  }\n";
322  OS << "#endif\n\n";
323}
324
325void IntrinsicEmitter::
326EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, std::ostream &OS){
327  OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n";
328  OS << "#ifdef GET_GCC_BUILTIN_NAME\n";
329  OS << "  switch (F->getIntrinsicID()) {\n";
330  OS << "  default: BuiltinName = \"\"; break;\n";
331  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
332    if (!Ints[i].GCCBuiltinName.empty()) {
333      OS << "  case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \""
334         << Ints[i].GCCBuiltinName << "\"; break;\n";
335    }
336  }
337  OS << "  }\n";
338  OS << "#endif\n\n";
339}
340
341void IntrinsicEmitter::
342EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints,
343                             std::ostream &OS) {
344  typedef std::map<std::pair<std::string, std::string>, std::string> BIMTy;
345  BIMTy BuiltinMap;
346  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
347    if (!Ints[i].GCCBuiltinName.empty()) {
348      std::pair<std::string, std::string> Key(Ints[i].GCCBuiltinName,
349                                              Ints[i].TargetPrefix);
350      if (!BuiltinMap.insert(std::make_pair(Key, Ints[i].EnumName)).second)
351        throw "Intrinsic '" + Ints[i].TheDef->getName() +
352              "': duplicate GCC builtin name!";
353    }
354  }
355
356  OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n";
357  OS << "// This is used by the C front-end.  The GCC builtin name is passed\n";
358  OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
359  OS << "// in as TargetPrefix.  The result is assigned to 'IntrinsicID'.\n";
360  OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n";
361  OS << "  if (0);\n";
362  // Note: this could emit significantly better code if we cared.
363  for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
364    OS << "  else if (";
365    if (!I->first.second.empty()) {
366      // Emit this as a strcmp, so it can be constant folded by the FE.
367      OS << "!strcmp(TargetPrefix, \"" << I->first.second << "\") &&\n"
368         << "           ";
369    }
370    OS << "!strcmp(BuiltinName, \"" << I->first.first << "\"))\n";
371    OS << "    IntrinsicID = Intrinsic::" << I->second << ";\n";
372  }
373  OS << "  else\n";
374  OS << "    IntrinsicID = Intrinsic::not_intrinsic;\n";
375  OS << "#endif\n\n";
376}
377