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