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