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> 19 using namespace llvm; 20 21 //===----------------------------------------------------------------------===// 22 // IntrinsicEmitter Implementation 23 //===----------------------------------------------------------------------===// 24 25 void 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 64 void 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 77 void IntrinsicEmitter:: 78 EmitFnNameRecognizer(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 115 void IntrinsicEmitter:: 116 EmitIntrinsicToNameTable(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 126 void IntrinsicEmitter:: 127 EmitIntrinsicToOverloadTable(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 143 static void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 144 if (MVT(VT).isInteger()) { 145 unsigned BitWidth = MVT(VT).getSizeInBits(); 146 OS << "IntegerType::get(" << BitWidth << ")"; 147 } else if (VT == MVT::Other) { 148 // MVT::OtherVT is used to mean the empty struct type here. 149 OS << "StructType::get()"; 150 } else if (VT == MVT::f32) { 151 OS << "Type::FloatTy"; 152 } else if (VT == MVT::f64) { 153 OS << "Type::DoubleTy"; 154 } else if (VT == MVT::f80) { 155 OS << "Type::X86_FP80Ty"; 156 } else if (VT == MVT::f128) { 157 OS << "Type::FP128Ty"; 158 } else if (VT == MVT::ppcf128) { 159 OS << "Type::PPC_FP128Ty"; 160 } else if (VT == MVT::isVoid) { 161 OS << "Type::VoidTy"; 162 } else if (VT == MVT::Metadata) { 163 OS << "Type::MetadataTy"; 164 } else { 165 assert(false && "Unsupported ValueType!"); 166 } 167 } 168 169 static void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 170 unsigned &ArgNo); 171 172 static 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("; 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 191 static 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) { 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 (MVT(VT).isVector()) { 214 MVT VVT = VT; 215 OS << "VectorType::get("; 216 EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT()); 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::VoidTy"; 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. 243 namespace { 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 279 void 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 308 OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 309 << ParamTys.size(); 310 311 // Emit return types. 312 for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 313 Record *ArgType = RetTys[j]; 314 OS << ", "; 315 316 if (ArgType->isSubClassOf("LLVMMatchType")) { 317 unsigned Number = ArgType->getValueAsInt("Number"); 318 if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 319 OS << "~(ExtendedElementVectorType | " << Number << ")"; 320 else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 321 OS << "~(TruncatedElementVectorType | " << Number << ")"; 322 else 323 OS << "~" << Number; 324 } else { 325 MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 326 OS << getEnumName(VT); 327 328 if (VT == MVT::isVoid && j != 0 && j != je - 1) 329 throw "Var arg type not last argument"; 330 } 331 } 332 333 // Emit the parameter types. 334 for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 335 Record *ArgType = ParamTys[j]; 336 OS << ", "; 337 338 if (ArgType->isSubClassOf("LLVMMatchType")) { 339 unsigned Number = ArgType->getValueAsInt("Number"); 340 if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 341 OS << "~(ExtendedElementVectorType | " << Number << ")"; 342 else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 343 OS << "~(TruncatedElementVectorType | " << Number << ")"; 344 else 345 OS << "~" << Number; 346 } else { 347 MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 348 OS << getEnumName(VT); 349 350 if (VT == MVT::isVoid && j != 0 && j != je - 1) 351 throw "Var arg type not last argument"; 352 } 353 } 354 355 OS << ");\n"; 356 OS << " break;\n"; 357 } 358 OS << " }\n"; 359 OS << "#endif\n\n"; 360 } 361 362 void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 363 raw_ostream &OS) { 364 OS << "// Code for generating Intrinsic function declarations.\n"; 365 OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 366 OS << " switch (id) {\n"; 367 OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 368 369 // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 370 // types. 371 typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 372 MapTy UniqueArgInfos; 373 374 // Compute the unique argument type info. 375 for (unsigned i = 0, e = Ints.size(); i != e; ++i) 376 UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 377 Ints[i].IS.ParamTypeDefs)].push_back(i); 378 379 // Loop through the array, emitting one generator for each batch. 380 std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 381 382 for (MapTy::iterator I = UniqueArgInfos.begin(), 383 E = UniqueArgInfos.end(); I != E; ++I) { 384 for (unsigned i = 0, e = I->second.size(); i != e; ++i) 385 OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 386 << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 387 388 const RecPair &ArgTypes = I->first; 389 const std::vector<Record*> &RetTys = ArgTypes.first; 390 const std::vector<Record*> &ParamTys = ArgTypes.second; 391 392 unsigned N = ParamTys.size(); 393 394 if (N > 1 && 395 getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 396 OS << " IsVarArg = true;\n"; 397 --N; 398 } 399 400 unsigned ArgNo = 0; 401 OS << " ResultTy = "; 402 EmitTypeGenerate(OS, RetTys, ArgNo); 403 OS << ";\n"; 404 405 for (unsigned j = 0; j != N; ++j) { 406 OS << " ArgTys.push_back("; 407 EmitTypeGenerate(OS, ParamTys[j], ArgNo); 408 OS << ");\n"; 409 } 410 411 OS << " break;\n"; 412 } 413 414 OS << " }\n"; 415 OS << "#endif\n\n"; 416 } 417 418 /// EmitAttributes - This emits the Intrinsic::getAttributes method. 419 void IntrinsicEmitter:: 420 EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 421 OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 422 OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 423 if (TargetOnly) 424 OS << "static AttrListPtr getAttributes(" << TargetPrefix 425 << "Intrinsic::ID id) {"; 426 else 427 OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 428 OS << " // No intrinsic can throw exceptions.\n"; 429 OS << " Attributes Attr = Attribute::NoUnwind;\n"; 430 OS << " switch (id) {\n"; 431 OS << " default: break;\n"; 432 unsigned MaxArgAttrs = 0; 433 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 434 MaxArgAttrs = 435 std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 436 switch (Ints[i].ModRef) { 437 default: break; 438 case CodeGenIntrinsic::NoMem: 439 OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 440 << ":\n"; 441 break; 442 } 443 } 444 OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 445 OS << " break;\n"; 446 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 447 switch (Ints[i].ModRef) { 448 default: break; 449 case CodeGenIntrinsic::ReadArgMem: 450 case CodeGenIntrinsic::ReadMem: 451 OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 452 << ":\n"; 453 break; 454 } 455 } 456 OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 457 OS << " break;\n"; 458 OS << " }\n"; 459 OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 460 OS << " unsigned NumAttrs = 0;\n"; 461 OS << " switch (id) {\n"; 462 OS << " default: break;\n"; 463 464 // Add argument attributes for any intrinsics that have them. 465 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 466 if (Ints[i].ArgumentAttributes.empty()) continue; 467 468 OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 469 << ":\n"; 470 471 std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 472 Ints[i].ArgumentAttributes; 473 // Sort by argument index. 474 std::sort(ArgAttrs.begin(), ArgAttrs.end()); 475 476 unsigned NumArgsWithAttrs = 0; 477 478 while (!ArgAttrs.empty()) { 479 unsigned ArgNo = ArgAttrs[0].first; 480 481 OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 482 << ArgNo+1 << ", 0"; 483 484 while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 485 switch (ArgAttrs[0].second) { 486 default: assert(0 && "Unknown arg attribute"); 487 case CodeGenIntrinsic::NoCapture: 488 OS << "|Attribute::NoCapture"; 489 break; 490 } 491 ArgAttrs.erase(ArgAttrs.begin()); 492 } 493 OS << ");\n"; 494 } 495 496 OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 497 OS << " break;\n"; 498 } 499 500 OS << " }\n"; 501 OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 502 OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 503 OS << "}\n"; 504 OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 505 } 506 507 /// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 508 void IntrinsicEmitter:: 509 EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 510 OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 511 OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 512 OS << "switch (id) {\n"; 513 OS << "default:\n return UnknownModRefBehavior;\n"; 514 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 515 if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem) 516 continue; 517 OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 518 << ":\n"; 519 switch (Ints[i].ModRef) { 520 default: 521 assert(false && "Unknown Mod/Ref type!"); 522 case CodeGenIntrinsic::NoMem: 523 OS << " return DoesNotAccessMemory;\n"; 524 break; 525 case CodeGenIntrinsic::ReadArgMem: 526 case CodeGenIntrinsic::ReadMem: 527 OS << " return OnlyReadsMemory;\n"; 528 break; 529 case CodeGenIntrinsic::WriteArgMem: 530 OS << " return AccessesArguments;\n"; 531 break; 532 } 533 } 534 OS << "}\n"; 535 OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 536 } 537 538 void IntrinsicEmitter:: 539 EmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 540 OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 541 OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 542 OS << " switch (F->getIntrinsicID()) {\n"; 543 OS << " default: BuiltinName = \"\"; break;\n"; 544 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 545 if (!Ints[i].GCCBuiltinName.empty()) { 546 OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 547 << Ints[i].GCCBuiltinName << "\"; break;\n"; 548 } 549 } 550 OS << " }\n"; 551 OS << "#endif\n\n"; 552 } 553 554 /// EmitBuiltinComparisons - Emit comparisons to determine whether the specified 555 /// sorted range of builtin names is equal to the current builtin. This breaks 556 /// it down into a simple tree. 557 /// 558 /// At this point, we know that all the builtins in the range have the same name 559 /// for the first 'CharStart' characters. Only the end of the name needs to be 560 /// discriminated. 561 typedef std::map<std::string, std::string>::const_iterator StrMapIterator; 562 static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, 563 unsigned CharStart, unsigned Indent, 564 std::string TargetPrefix, raw_ostream &OS) { 565 if (Start == End) return; // empty range. 566 567 // Determine what, if anything, is the same about all these strings. 568 std::string CommonString = Start->first; 569 unsigned NumInRange = 0; 570 for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { 571 // Find the first character that doesn't match. 572 const std::string &ThisStr = I->first; 573 unsigned NonMatchChar = CharStart; 574 while (NonMatchChar < CommonString.size() && 575 NonMatchChar < ThisStr.size() && 576 CommonString[NonMatchChar] == ThisStr[NonMatchChar]) 577 ++NonMatchChar; 578 // Truncate off pieces that don't match. 579 CommonString.resize(NonMatchChar); 580 } 581 582 // Just compare the rest of the string. 583 if (NumInRange == 1) { 584 if (CharStart != CommonString.size()) { 585 OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 586 if (CharStart) OS << "+" << CharStart; 587 OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 588 OS << CommonString.size() - CharStart << "))\n"; 589 ++Indent; 590 } 591 OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix 592 << "Intrinsic::"; 593 OS << Start->second << ";\n"; 594 return; 595 } 596 597 // At this point, we potentially have a common prefix for these builtins, emit 598 // a check for this common prefix. 599 if (CommonString.size() != CharStart) { 600 OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 601 if (CharStart) OS << "+" << CharStart; 602 OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 603 OS << CommonString.size()-CharStart << ")) {\n"; 604 605 EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 606 TargetPrefix, OS); 607 OS << std::string(Indent*2, ' ') << "}\n"; 608 return; 609 } 610 611 // Output a switch on the character that differs across the set. 612 OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart 613 << "]) {"; 614 if (CharStart) 615 OS << " // \"" << std::string(Start->first.begin(), 616 Start->first.begin()+CharStart) << "\""; 617 OS << "\n"; 618 619 for (StrMapIterator I = Start; I != End; ) { 620 char ThisChar = I->first[CharStart]; 621 OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; 622 // Figure out the range that has this common character. 623 StrMapIterator NextChar = I; 624 for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; 625 ++NextChar) 626 /*empty*/; 627 EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); 628 OS << std::string(Indent*2, ' ') << " break;\n"; 629 I = NextChar; 630 } 631 OS << std::string(Indent*2, ' ') << "}\n"; 632 } 633 634 /// EmitTargetBuiltins - All of the builtins in the specified map are for the 635 /// same target, and we already checked it. 636 static void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 637 const std::string &TargetPrefix, 638 raw_ostream &OS) { 639 // Rearrange the builtins by length. 640 std::vector<std::map<std::string, std::string> > BuiltinsByLen; 641 BuiltinsByLen.reserve(100); 642 643 for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { 644 if (I->first.size() >= BuiltinsByLen.size()) 645 BuiltinsByLen.resize(I->first.size()+1); 646 BuiltinsByLen[I->first.size()].insert(*I); 647 } 648 649 // Now that we have all the builtins by their length, emit a switch stmt. 650 OS << " switch (strlen(BuiltinName)) {\n"; 651 OS << " default: break;\n"; 652 for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { 653 if (BuiltinsByLen[i].empty()) continue; 654 OS << " case " << i << ":\n"; 655 EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), 656 0, 3, TargetPrefix, OS); 657 OS << " break;\n"; 658 } 659 OS << " }\n"; 660 } 661 662 663 void IntrinsicEmitter:: 664 EmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 665 raw_ostream &OS) { 666 typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 667 BIMTy BuiltinMap; 668 for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 669 if (!Ints[i].GCCBuiltinName.empty()) { 670 // Get the map for this target prefix. 671 std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 672 673 if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 674 Ints[i].EnumName)).second) 675 throw "Intrinsic '" + Ints[i].TheDef->getName() + 676 "': duplicate GCC builtin name!"; 677 } 678 } 679 680 OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 681 OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 682 OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 683 OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 684 OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 685 686 if (TargetOnly) { 687 OS << "static " << TargetPrefix << "Intrinsic::ID " 688 << "getIntrinsicForGCCBuiltin(const char " 689 << "*TargetPrefix, const char *BuiltinName) {\n"; 690 OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; 691 } else { 692 OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 693 << "*TargetPrefix, const char *BuiltinName) {\n"; 694 OS << " Intrinsic::ID IntrinsicID = "; 695 } 696 697 if (TargetOnly) 698 OS << "(" << TargetPrefix<< "Intrinsic::ID)"; 699 700 OS << "Intrinsic::not_intrinsic;\n"; 701 702 // Note: this could emit significantly better code if we cared. 703 for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 704 OS << " "; 705 if (!I->first.empty()) 706 OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; 707 else 708 OS << "/* Target Independent Builtins */ "; 709 OS << "{\n"; 710 711 // Emit the comparisons for this target prefix. 712 EmitTargetBuiltins(I->second, TargetPrefix, OS); 713 OS << " }\n"; 714 } 715 OS << " return IntrinsicID;\n"; 716 OS << "}\n"; 717 OS << "#endif\n\n"; 718 } 719