IntrinsicEmitter.cpp revision 198090
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 "Record.h" 17#include "llvm/ADT/StringExtras.h" 18#include <algorithm> 19using namespace llvm; 20 21//===----------------------------------------------------------------------===// 22// IntrinsicEmitter Implementation 23//===----------------------------------------------------------------------===// 24 25void IntrinsicEmitter::run(raw_ostream &OS) { 26 EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); 27 28 std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); 29 30 if (TargetOnly && !Ints.empty()) 31 TargetPrefix = Ints[0].TargetPrefix; 32 33 // Emit the enum information. 34 EmitEnumInfo(Ints, OS); 35 36 // Emit the intrinsic ID -> name table. 37 EmitIntrinsicToNameTable(Ints, OS); 38 39 // Emit the intrinsic ID -> overload table. 40 EmitIntrinsicToOverloadTable(Ints, OS); 41 42 // Emit the function name recognizer. 43 EmitFnNameRecognizer(Ints, OS); 44 45 // Emit the intrinsic verifier. 46 EmitVerifier(Ints, OS); 47 48 // Emit the intrinsic declaration generator. 49 EmitGenerator(Ints, OS); 50 51 // Emit the intrinsic parameter attributes. 52 EmitAttributes(Ints, OS); 53 54 // Emit intrinsic alias analysis mod/ref behavior. 55 EmitModRefBehavior(Ints, OS); 56 57 // Emit a list of intrinsics with corresponding GCC builtins. 58 EmitGCCBuiltinList(Ints, OS); 59 60 // Emit code to translate GCC builtins into LLVM intrinsics. 61 EmitIntrinsicToGCCBuiltinMap(Ints, OS); 62} 63 64void IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 65 raw_ostream &OS) { 66 OS << "// Enum values for Intrinsics.h\n"; 67 OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 68 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 69 OS << " " << Ints[i].EnumName; 70 OS << ((i != e-1) ? ", " : " "); 71 OS << std::string(40-Ints[i].EnumName.size(), ' ') 72 << "// " << Ints[i].Name << "\n"; 73 } 74 OS << "#endif\n\n"; 75} 76 77void IntrinsicEmitter:: 78EmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 79 raw_ostream &OS) { 80 // Build a function name -> intrinsic name mapping. 81 std::map<std::string, unsigned> IntMapping; 82 for (unsigned i = 0, e = Ints.size(); i != e; ++i) 83 IntMapping[Ints[i].Name] = i; 84 85 OS << "// Function name -> enum value recognizer code.\n"; 86 OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 87 OS << " switch (Name[5]) {\n"; 88 OS << " default:\n"; 89 // Emit the intrinsics in sorted order. 90 char LastChar = 0; 91 for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(), 92 E = IntMapping.end(); I != E; ++I) { 93 if (I->first[5] != LastChar) { 94 LastChar = I->first[5]; 95 OS << " break;\n"; 96 OS << " case '" << LastChar << "':\n"; 97 } 98 99 // For overloaded intrinsics, only the prefix needs to match 100 if (Ints[I->second].isOverloaded) 101 OS << " if (Len > " << I->first.size() 102 << " && !memcmp(Name, \"" << I->first << ".\", " 103 << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::" 104 << Ints[I->second].EnumName << ";\n"; 105 else 106 OS << " if (Len == " << I->first.size() 107 << " && !memcmp(Name, \"" << I->first << "\", " 108 << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::" 109 << Ints[I->second].EnumName << ";\n"; 110 } 111 OS << " }\n"; 112 OS << "#endif\n\n"; 113} 114 115void IntrinsicEmitter:: 116EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 117 raw_ostream &OS) { 118 OS << "// Intrinsic ID to name table\n"; 119 OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 120 OS << " // Note that entry #0 is the invalid intrinsic!\n"; 121 for (unsigned i = 0, e = Ints.size(); i != e; ++i) 122 OS << " \"" << Ints[i].Name << "\",\n"; 123 OS << "#endif\n\n"; 124} 125 126void IntrinsicEmitter:: 127EmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 128 raw_ostream &OS) { 129 OS << "// Intrinsic ID to overload table\n"; 130 OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 131 OS << " // Note that entry #0 is the invalid intrinsic!\n"; 132 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 133 OS << " "; 134 if (Ints[i].isOverloaded) 135 OS << "true"; 136 else 137 OS << "false"; 138 OS << ",\n"; 139 } 140 OS << "#endif\n\n"; 141} 142 143static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 144 if (EVT(VT).isInteger()) { 145 unsigned BitWidth = EVT(VT).getSizeInBits(); 146 OS << "IntegerType::get(Context, " << BitWidth << ")"; 147 } else if (VT == MVT::Other) { 148 // MVT::OtherVT is used to mean the empty struct type here. 149 OS << "StructType::get(Context)"; 150 } else if (VT == MVT::f32) { 151 OS << "Type::getFloatTy(Context)"; 152 } else if (VT == MVT::f64) { 153 OS << "Type::getDoubleTy(Context)"; 154 } else if (VT == MVT::f80) { 155 OS << "Type::getX86_FP80Ty(Context)"; 156 } else if (VT == MVT::f128) { 157 OS << "Type::getFP128Ty(Context)"; 158 } else if (VT == MVT::ppcf128) { 159 OS << "Type::getPPC_FP128Ty(Context)"; 160 } else if (VT == MVT::isVoid) { 161 OS << "Type::getVoidTy(Context)"; 162 } else if (VT == MVT::Metadata) { 163 OS << "Type::getMetadataTy(Context)"; 164 } else { 165 assert(false && "Unsupported ValueType!"); 166 } 167} 168 169static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 170 unsigned &ArgNo); 171 172static void EmitTypeGenerate(raw_ostream &OS, 173 const std::vector<Record*> &ArgTypes, 174 unsigned &ArgNo) { 175 if (ArgTypes.size() == 1) { 176 EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 177 return; 178 } 179 180 OS << "StructType::get(Context, "; 181 182 for (std::vector<Record*>::const_iterator 183 I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 184 EmitTypeGenerate(OS, *I, ArgNo); 185 OS << ", "; 186 } 187 188 OS << " NULL)"; 189} 190 191static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 192 unsigned &ArgNo) { 193 MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 194 195 if (ArgType->isSubClassOf("LLVMMatchType")) { 196 unsigned Number = ArgType->getValueAsInt("Number"); 197 assert(Number < ArgNo && "Invalid matching number!"); 198 if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 199 OS << "VectorType::getExtendedElementVectorType" 200 << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 201 else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 202 OS << "VectorType::getTruncatedElementVectorType" 203 << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 204 else 205 OS << "Tys[" << Number << "]"; 206 } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 207 // NOTE: The ArgNo variable here is not the absolute argument number, it is 208 // the index of the "arbitrary" type in the Tys array passed to the 209 // Intrinsic::getDeclaration function. Consequently, we only want to 210 // increment it when we actually hit an overloaded type. Getting this wrong 211 // leads to very subtle bugs! 212 OS << "Tys[" << ArgNo++ << "]"; 213 } else if (EVT(VT).isVector()) { 214 EVT VVT = VT; 215 OS << "VectorType::get("; 216 EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 217 OS << ", " << VVT.getVectorNumElements() << ")"; 218 } else if (VT == MVT::iPTR) { 219 OS << "PointerType::getUnqual("; 220 EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 221 OS << ")"; 222 } else if (VT == MVT::iPTRAny) { 223 // Make sure the user has passed us an argument type to overload. If not, 224 // treat it as an ordinary (not overloaded) intrinsic. 225 OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 226 << "] : PointerType::getUnqual("; 227 EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 228 OS << ")"; 229 ++ArgNo; 230 } else if (VT == MVT::isVoid) { 231 if (ArgNo == 0) 232 OS << "Type::getVoidTy(Context)"; 233 else 234 // MVT::isVoid is used to mean varargs here. 235 OS << "..."; 236 } else { 237 EmitTypeForValueType(OS, VT); 238 } 239} 240 241/// RecordListComparator - Provide a deterministic comparator for lists of 242/// records. 243namespace { 244 typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 245 struct RecordListComparator { 246 bool operator()(const RecPair &LHS, 247 const RecPair &RHS) const { 248 unsigned i = 0; 249 const std::vector<Record*> *LHSVec = &LHS.first; 250 const std::vector<Record*> *RHSVec = &RHS.first; 251 unsigned RHSSize = RHSVec->size(); 252 unsigned LHSSize = LHSVec->size(); 253 254 do { 255 if (i == RHSSize) return false; // RHS is shorter than LHS. 256 if ((*LHSVec)[i] != (*RHSVec)[i]) 257 return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 258 } while (++i != LHSSize); 259 260 if (i != RHSSize) return true; 261 262 i = 0; 263 LHSVec = &LHS.second; 264 RHSVec = &RHS.second; 265 RHSSize = RHSVec->size(); 266 LHSSize = LHSVec->size(); 267 268 for (i = 0; i != LHSSize; ++i) { 269 if (i == RHSSize) return false; // RHS is shorter than LHS. 270 if ((*LHSVec)[i] != (*RHSVec)[i]) 271 return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 272 } 273 274 return i != RHSSize; 275 } 276 }; 277} 278 279void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 280 raw_ostream &OS) { 281 OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 282 OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 283 OS << " switch (ID) {\n"; 284 OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 285 286 // This checking can emit a lot of very common code. To reduce the amount of 287 // code that we emit, batch up cases that have identical types. This avoids 288 // problems where GCC can run out of memory compiling Verifier.cpp. 289 typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 290 MapTy UniqueArgInfos; 291 292 // Compute the unique argument type info. 293 for (unsigned i = 0, e = Ints.size(); i != e; ++i) 294 UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 295 Ints[i].IS.ParamTypeDefs)].push_back(i); 296 297 // Loop through the array, emitting one comparison for each batch. 298 for (MapTy::iterator I = UniqueArgInfos.begin(), 299 E = UniqueArgInfos.end(); I != E; ++I) { 300 for (unsigned i = 0, e = I->second.size(); i != e; ++i) 301 OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 302 << Ints[I->second[i]].Name << "\n"; 303 304 const RecPair &ArgTypes = I->first; 305 const std::vector<Record*> &RetTys = ArgTypes.first; 306 const std::vector<Record*> &ParamTys = ArgTypes.second; 307 std::vector<unsigned> OverloadedTypeIndices; 308 309 OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 310 << ParamTys.size(); 311 312 // Emit return types. 313 for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 314 Record *ArgType = RetTys[j]; 315 OS << ", "; 316 317 if (ArgType->isSubClassOf("LLVMMatchType")) { 318 unsigned Number = ArgType->getValueAsInt("Number"); 319 assert(Number < OverloadedTypeIndices.size() && 320 "Invalid matching number!"); 321 Number = OverloadedTypeIndices[Number]; 322 if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 323 OS << "~(ExtendedElementVectorType | " << Number << ")"; 324 else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 325 OS << "~(TruncatedElementVectorType | " << Number << ")"; 326 else 327 OS << "~" << Number; 328 } else { 329 MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 330 OS << getEnumName(VT); 331 332 if (EVT(VT).isOverloaded()) 333 OverloadedTypeIndices.push_back(j); 334 335 if (VT == MVT::isVoid && j != 0 && j != je - 1) 336 throw "Var arg type not last argument"; 337 } 338 } 339 340 // Emit the parameter types. 341 for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 342 Record *ArgType = ParamTys[j]; 343 OS << ", "; 344 345 if (ArgType->isSubClassOf("LLVMMatchType")) { 346 unsigned Number = ArgType->getValueAsInt("Number"); 347 assert(Number < OverloadedTypeIndices.size() && 348 "Invalid matching number!"); 349 Number = OverloadedTypeIndices[Number]; 350 if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 351 OS << "~(ExtendedElementVectorType | " << Number << ")"; 352 else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 353 OS << "~(TruncatedElementVectorType | " << Number << ")"; 354 else 355 OS << "~" << Number; 356 } else { 357 MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 358 OS << getEnumName(VT); 359 360 if (EVT(VT).isOverloaded()) 361 OverloadedTypeIndices.push_back(j + RetTys.size()); 362 363 if (VT == MVT::isVoid && j != 0 && j != je - 1) 364 throw "Var arg type not last argument"; 365 } 366 } 367 368 OS << ");\n"; 369 OS << " break;\n"; 370 } 371 OS << " }\n"; 372 OS << "#endif\n\n"; 373} 374 375void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 376 raw_ostream &OS) { 377 OS << "// Code for generating Intrinsic function declarations.\n"; 378 OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 379 OS << " switch (id) {\n"; 380 OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 381 382 // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 383 // types. 384 typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 385 MapTy UniqueArgInfos; 386 387 // Compute the unique argument type info. 388 for (unsigned i = 0, e = Ints.size(); i != e; ++i) 389 UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 390 Ints[i].IS.ParamTypeDefs)].push_back(i); 391 392 // Loop through the array, emitting one generator for each batch. 393 std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 394 395 for (MapTy::iterator I = UniqueArgInfos.begin(), 396 E = UniqueArgInfos.end(); I != E; ++I) { 397 for (unsigned i = 0, e = I->second.size(); i != e; ++i) 398 OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 399 << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 400 401 const RecPair &ArgTypes = I->first; 402 const std::vector<Record*> &RetTys = ArgTypes.first; 403 const std::vector<Record*> &ParamTys = ArgTypes.second; 404 405 unsigned N = ParamTys.size(); 406 407 if (N > 1 && 408 getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 409 OS << " IsVarArg = true;\n"; 410 --N; 411 } 412 413 unsigned ArgNo = 0; 414 OS << " ResultTy = "; 415 EmitTypeGenerate(OS, RetTys, ArgNo); 416 OS << ";\n"; 417 418 for (unsigned j = 0; j != N; ++j) { 419 OS << " ArgTys.push_back("; 420 EmitTypeGenerate(OS, ParamTys[j], ArgNo); 421 OS << ");\n"; 422 } 423 424 OS << " break;\n"; 425 } 426 427 OS << " }\n"; 428 OS << "#endif\n\n"; 429} 430 431/// EmitAttributes - This emits the Intrinsic::getAttributes method. 432void IntrinsicEmitter:: 433EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 434 OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 435 OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 436 if (TargetOnly) 437 OS << "static AttrListPtr getAttributes(" << TargetPrefix 438 << "Intrinsic::ID id) {"; 439 else 440 OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 441 OS << " // No intrinsic can throw exceptions.\n"; 442 OS << " Attributes Attr = Attribute::NoUnwind;\n"; 443 OS << " switch (id) {\n"; 444 OS << " default: break;\n"; 445 unsigned MaxArgAttrs = 0; 446 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 447 MaxArgAttrs = 448 std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 449 switch (Ints[i].ModRef) { 450 default: break; 451 case CodeGenIntrinsic::NoMem: 452 OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 453 << ":\n"; 454 break; 455 } 456 } 457 OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 458 OS << " break;\n"; 459 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 460 switch (Ints[i].ModRef) { 461 default: break; 462 case CodeGenIntrinsic::ReadArgMem: 463 case CodeGenIntrinsic::ReadMem: 464 OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 465 << ":\n"; 466 break; 467 } 468 } 469 OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 470 OS << " break;\n"; 471 OS << " }\n"; 472 OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 473 OS << " unsigned NumAttrs = 0;\n"; 474 OS << " switch (id) {\n"; 475 OS << " default: break;\n"; 476 477 // Add argument attributes for any intrinsics that have them. 478 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 479 if (Ints[i].ArgumentAttributes.empty()) continue; 480 481 OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 482 << ":\n"; 483 484 std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 485 Ints[i].ArgumentAttributes; 486 // Sort by argument index. 487 std::sort(ArgAttrs.begin(), ArgAttrs.end()); 488 489 unsigned NumArgsWithAttrs = 0; 490 491 while (!ArgAttrs.empty()) { 492 unsigned ArgNo = ArgAttrs[0].first; 493 494 OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 495 << ArgNo+1 << ", 0"; 496 497 while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 498 switch (ArgAttrs[0].second) { 499 default: assert(0 && "Unknown arg attribute"); 500 case CodeGenIntrinsic::NoCapture: 501 OS << "|Attribute::NoCapture"; 502 break; 503 } 504 ArgAttrs.erase(ArgAttrs.begin()); 505 } 506 OS << ");\n"; 507 } 508 509 OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 510 OS << " break;\n"; 511 } 512 513 OS << " }\n"; 514 OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 515 OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 516 OS << "}\n"; 517 OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 518} 519 520/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 521void IntrinsicEmitter:: 522EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 523 OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 524 OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 525 OS << "switch (id) {\n"; 526 OS << "default:\n return UnknownModRefBehavior;\n"; 527 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 528 if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem) 529 continue; 530 OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 531 << ":\n"; 532 switch (Ints[i].ModRef) { 533 default: 534 assert(false && "Unknown Mod/Ref type!"); 535 case CodeGenIntrinsic::NoMem: 536 OS << " return DoesNotAccessMemory;\n"; 537 break; 538 case CodeGenIntrinsic::ReadArgMem: 539 case CodeGenIntrinsic::ReadMem: 540 OS << " return OnlyReadsMemory;\n"; 541 break; 542 case CodeGenIntrinsic::WriteArgMem: 543 OS << " return AccessesArguments;\n"; 544 break; 545 } 546 } 547 OS << "}\n"; 548 OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 549} 550 551void IntrinsicEmitter:: 552EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 553 OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 554 OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 555 OS << " switch (F->getIntrinsicID()) {\n"; 556 OS << " default: BuiltinName = \"\"; break;\n"; 557 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 558 if (!Ints[i].GCCBuiltinName.empty()) { 559 OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 560 << Ints[i].GCCBuiltinName << "\"; break;\n"; 561 } 562 } 563 OS << " }\n"; 564 OS << "#endif\n\n"; 565} 566 567/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified 568/// sorted range of builtin names is equal to the current builtin. This breaks 569/// it down into a simple tree. 570/// 571/// At this point, we know that all the builtins in the range have the same name 572/// for the first 'CharStart' characters. Only the end of the name needs to be 573/// discriminated. 574typedef std::map<std::string, std::string>::const_iterator StrMapIterator; 575static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, 576 unsigned CharStart, unsigned Indent, 577 std::string TargetPrefix, raw_ostream &OS) { 578 if (Start == End) return; // empty range. 579 580 // Determine what, if anything, is the same about all these strings. 581 std::string CommonString = Start->first; 582 unsigned NumInRange = 0; 583 for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { 584 // Find the first character that doesn't match. 585 const std::string &ThisStr = I->first; 586 unsigned NonMatchChar = CharStart; 587 while (NonMatchChar < CommonString.size() && 588 NonMatchChar < ThisStr.size() && 589 CommonString[NonMatchChar] == ThisStr[NonMatchChar]) 590 ++NonMatchChar; 591 // Truncate off pieces that don't match. 592 CommonString.resize(NonMatchChar); 593 } 594 595 // Just compare the rest of the string. 596 if (NumInRange == 1) { 597 if (CharStart != CommonString.size()) { 598 OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 599 if (CharStart) OS << "+" << CharStart; 600 OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 601 OS << CommonString.size() - CharStart << "))\n"; 602 ++Indent; 603 } 604 OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix 605 << "Intrinsic::"; 606 OS << Start->second << ";\n"; 607 return; 608 } 609 610 // At this point, we potentially have a common prefix for these builtins, emit 611 // a check for this common prefix. 612 if (CommonString.size() != CharStart) { 613 OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 614 if (CharStart) OS << "+" << CharStart; 615 OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 616 OS << CommonString.size()-CharStart << ")) {\n"; 617 618 EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 619 TargetPrefix, OS); 620 OS << std::string(Indent*2, ' ') << "}\n"; 621 return; 622 } 623 624 // Output a switch on the character that differs across the set. 625 OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart 626 << "]) {"; 627 if (CharStart) 628 OS << " // \"" << std::string(Start->first.begin(), 629 Start->first.begin()+CharStart) << "\""; 630 OS << "\n"; 631 632 for (StrMapIterator I = Start; I != End; ) { 633 char ThisChar = I->first[CharStart]; 634 OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; 635 // Figure out the range that has this common character. 636 StrMapIterator NextChar = I; 637 for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; 638 ++NextChar) 639 /*empty*/; 640 EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); 641 OS << std::string(Indent*2, ' ') << " break;\n"; 642 I = NextChar; 643 } 644 OS << std::string(Indent*2, ' ') << "}\n"; 645} 646 647/// EmitTargetBuiltins - All of the builtins in the specified map are for the 648/// same target, and we already checked it. 649static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 650 const std::string &TargetPrefix, 651 raw_ostream &OS) { 652 // Rearrange the builtins by length. 653 std::vector<std::map<std::string, std::string> > BuiltinsByLen; 654 BuiltinsByLen.reserve(100); 655 656 for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { 657 if (I->first.size() >= BuiltinsByLen.size()) 658 BuiltinsByLen.resize(I->first.size()+1); 659 BuiltinsByLen[I->first.size()].insert(*I); 660 } 661 662 // Now that we have all the builtins by their length, emit a switch stmt. 663 OS << " switch (strlen(BuiltinName)) {\n"; 664 OS << " default: break;\n"; 665 for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { 666 if (BuiltinsByLen[i].empty()) continue; 667 OS << " case " << i << ":\n"; 668 EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), 669 0, 3, TargetPrefix, OS); 670 OS << " break;\n"; 671 } 672 OS << " }\n"; 673} 674 675 676void IntrinsicEmitter:: 677EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 678 raw_ostream &OS) { 679 typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 680 BIMTy BuiltinMap; 681 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 682 if (!Ints[i].GCCBuiltinName.empty()) { 683 // Get the map for this target prefix. 684 std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 685 686 if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 687 Ints[i].EnumName)).second) 688 throw "Intrinsic '" + Ints[i].TheDef->getName() + 689 "': duplicate GCC builtin name!"; 690 } 691 } 692 693 OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 694 OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 695 OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 696 OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 697 OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 698 699 if (TargetOnly) { 700 OS << "static " << TargetPrefix << "Intrinsic::ID " 701 << "getIntrinsicForGCCBuiltin(const char " 702 << "*TargetPrefix, const char *BuiltinName) {\n"; 703 OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; 704 } else { 705 OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 706 << "*TargetPrefix, const char *BuiltinName) {\n"; 707 OS << " Intrinsic::ID IntrinsicID = "; 708 } 709 710 if (TargetOnly) 711 OS << "(" << TargetPrefix<< "Intrinsic::ID)"; 712 713 OS << "Intrinsic::not_intrinsic;\n"; 714 715 // Note: this could emit significantly better code if we cared. 716 for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 717 OS << " "; 718 if (!I->first.empty()) 719 OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; 720 else 721 OS << "/* Target Independent Builtins */ "; 722 OS << "{\n"; 723 724 // Emit the comparisons for this target prefix. 725 EmitTargetBuiltins(I->second, TargetPrefix, OS); 726 OS << " }\n"; 727 } 728 OS << " return IntrinsicID;\n"; 729 OS << "}\n"; 730 OS << "#endif\n\n"; 731} 732