IntrinsicEmitter.cpp revision 198090
1193323Sed//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This tablegen backend emits information about intrinsic functions. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "CodeGenTarget.h" 15193323Sed#include "IntrinsicEmitter.h" 16193323Sed#include "Record.h" 17193323Sed#include "llvm/ADT/StringExtras.h" 18193323Sed#include <algorithm> 19193323Sedusing namespace llvm; 20193323Sed 21193323Sed//===----------------------------------------------------------------------===// 22193323Sed// IntrinsicEmitter Implementation 23193323Sed//===----------------------------------------------------------------------===// 24193323Sed 25195340Sedvoid IntrinsicEmitter::run(raw_ostream &OS) { 26193323Sed EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); 27193323Sed 28193323Sed std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); 29193323Sed 30193323Sed if (TargetOnly && !Ints.empty()) 31193323Sed TargetPrefix = Ints[0].TargetPrefix; 32193323Sed 33193323Sed // Emit the enum information. 34193323Sed EmitEnumInfo(Ints, OS); 35193323Sed 36193323Sed // Emit the intrinsic ID -> name table. 37193323Sed EmitIntrinsicToNameTable(Ints, OS); 38193323Sed 39193323Sed // Emit the intrinsic ID -> overload table. 40193323Sed EmitIntrinsicToOverloadTable(Ints, OS); 41193323Sed 42193323Sed // Emit the function name recognizer. 43193323Sed EmitFnNameRecognizer(Ints, OS); 44193323Sed 45193323Sed // Emit the intrinsic verifier. 46193323Sed EmitVerifier(Ints, OS); 47193323Sed 48193323Sed // Emit the intrinsic declaration generator. 49193323Sed EmitGenerator(Ints, OS); 50193323Sed 51193323Sed // Emit the intrinsic parameter attributes. 52193323Sed EmitAttributes(Ints, OS); 53193323Sed 54193323Sed // Emit intrinsic alias analysis mod/ref behavior. 55193323Sed EmitModRefBehavior(Ints, OS); 56193323Sed 57193323Sed // Emit a list of intrinsics with corresponding GCC builtins. 58193323Sed EmitGCCBuiltinList(Ints, OS); 59193323Sed 60193323Sed // Emit code to translate GCC builtins into LLVM intrinsics. 61193323Sed EmitIntrinsicToGCCBuiltinMap(Ints, OS); 62193323Sed} 63193323Sed 64193323Sedvoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 65195340Sed raw_ostream &OS) { 66193323Sed OS << "// Enum values for Intrinsics.h\n"; 67193323Sed OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 68193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 69193323Sed OS << " " << Ints[i].EnumName; 70193323Sed OS << ((i != e-1) ? ", " : " "); 71193323Sed OS << std::string(40-Ints[i].EnumName.size(), ' ') 72193323Sed << "// " << Ints[i].Name << "\n"; 73193323Sed } 74193323Sed OS << "#endif\n\n"; 75193323Sed} 76193323Sed 77193323Sedvoid IntrinsicEmitter:: 78193323SedEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 79195340Sed raw_ostream &OS) { 80193323Sed // Build a function name -> intrinsic name mapping. 81193323Sed std::map<std::string, unsigned> IntMapping; 82193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 83193323Sed IntMapping[Ints[i].Name] = i; 84193323Sed 85193323Sed OS << "// Function name -> enum value recognizer code.\n"; 86193323Sed OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 87193323Sed OS << " switch (Name[5]) {\n"; 88193323Sed OS << " default:\n"; 89193323Sed // Emit the intrinsics in sorted order. 90193323Sed char LastChar = 0; 91193323Sed for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(), 92193323Sed E = IntMapping.end(); I != E; ++I) { 93193323Sed if (I->first[5] != LastChar) { 94193323Sed LastChar = I->first[5]; 95193323Sed OS << " break;\n"; 96193323Sed OS << " case '" << LastChar << "':\n"; 97193323Sed } 98193323Sed 99193323Sed // For overloaded intrinsics, only the prefix needs to match 100193323Sed if (Ints[I->second].isOverloaded) 101193323Sed OS << " if (Len > " << I->first.size() 102193323Sed << " && !memcmp(Name, \"" << I->first << ".\", " 103193323Sed << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::" 104193323Sed << Ints[I->second].EnumName << ";\n"; 105193323Sed else 106193323Sed OS << " if (Len == " << I->first.size() 107193323Sed << " && !memcmp(Name, \"" << I->first << "\", " 108193323Sed << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::" 109193323Sed << Ints[I->second].EnumName << ";\n"; 110193323Sed } 111193323Sed OS << " }\n"; 112193323Sed OS << "#endif\n\n"; 113193323Sed} 114193323Sed 115193323Sedvoid IntrinsicEmitter:: 116193323SedEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 117195340Sed raw_ostream &OS) { 118193323Sed OS << "// Intrinsic ID to name table\n"; 119193323Sed OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 120193323Sed OS << " // Note that entry #0 is the invalid intrinsic!\n"; 121193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 122193323Sed OS << " \"" << Ints[i].Name << "\",\n"; 123193323Sed OS << "#endif\n\n"; 124193323Sed} 125193323Sed 126193323Sedvoid IntrinsicEmitter:: 127193323SedEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 128195340Sed raw_ostream &OS) { 129193323Sed OS << "// Intrinsic ID to overload table\n"; 130193323Sed OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 131193323Sed OS << " // Note that entry #0 is the invalid intrinsic!\n"; 132193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 133193323Sed OS << " "; 134193323Sed if (Ints[i].isOverloaded) 135193323Sed OS << "true"; 136193323Sed else 137193323Sed OS << "false"; 138193323Sed OS << ",\n"; 139193323Sed } 140193323Sed OS << "#endif\n\n"; 141193323Sed} 142193323Sed 143195340Sedstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 144198090Srdivacky if (EVT(VT).isInteger()) { 145198090Srdivacky unsigned BitWidth = EVT(VT).getSizeInBits(); 146198090Srdivacky OS << "IntegerType::get(Context, " << BitWidth << ")"; 147193323Sed } else if (VT == MVT::Other) { 148193323Sed // MVT::OtherVT is used to mean the empty struct type here. 149198090Srdivacky OS << "StructType::get(Context)"; 150193323Sed } else if (VT == MVT::f32) { 151198090Srdivacky OS << "Type::getFloatTy(Context)"; 152193323Sed } else if (VT == MVT::f64) { 153198090Srdivacky OS << "Type::getDoubleTy(Context)"; 154193323Sed } else if (VT == MVT::f80) { 155198090Srdivacky OS << "Type::getX86_FP80Ty(Context)"; 156193323Sed } else if (VT == MVT::f128) { 157198090Srdivacky OS << "Type::getFP128Ty(Context)"; 158193323Sed } else if (VT == MVT::ppcf128) { 159198090Srdivacky OS << "Type::getPPC_FP128Ty(Context)"; 160193323Sed } else if (VT == MVT::isVoid) { 161198090Srdivacky OS << "Type::getVoidTy(Context)"; 162198090Srdivacky } else if (VT == MVT::Metadata) { 163198090Srdivacky OS << "Type::getMetadataTy(Context)"; 164193323Sed } else { 165193323Sed assert(false && "Unsupported ValueType!"); 166193323Sed } 167193323Sed} 168193323Sed 169195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 170193323Sed unsigned &ArgNo); 171193323Sed 172195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, 173193323Sed const std::vector<Record*> &ArgTypes, 174193323Sed unsigned &ArgNo) { 175193323Sed if (ArgTypes.size() == 1) { 176193323Sed EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 177193323Sed return; 178193323Sed } 179193323Sed 180198090Srdivacky OS << "StructType::get(Context, "; 181193323Sed 182193323Sed for (std::vector<Record*>::const_iterator 183193323Sed I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 184193323Sed EmitTypeGenerate(OS, *I, ArgNo); 185193323Sed OS << ", "; 186193323Sed } 187193323Sed 188193323Sed OS << " NULL)"; 189193323Sed} 190193323Sed 191195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 192193323Sed unsigned &ArgNo) { 193193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 194193323Sed 195193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 196193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 197193323Sed assert(Number < ArgNo && "Invalid matching number!"); 198193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 199193323Sed OS << "VectorType::getExtendedElementVectorType" 200193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 201193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 202193323Sed OS << "VectorType::getTruncatedElementVectorType" 203193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 204193323Sed else 205193323Sed OS << "Tys[" << Number << "]"; 206198090Srdivacky } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 207193323Sed // NOTE: The ArgNo variable here is not the absolute argument number, it is 208193323Sed // the index of the "arbitrary" type in the Tys array passed to the 209193323Sed // Intrinsic::getDeclaration function. Consequently, we only want to 210193323Sed // increment it when we actually hit an overloaded type. Getting this wrong 211193323Sed // leads to very subtle bugs! 212193323Sed OS << "Tys[" << ArgNo++ << "]"; 213198090Srdivacky } else if (EVT(VT).isVector()) { 214198090Srdivacky EVT VVT = VT; 215193323Sed OS << "VectorType::get("; 216198090Srdivacky EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 217193323Sed OS << ", " << VVT.getVectorNumElements() << ")"; 218193323Sed } else if (VT == MVT::iPTR) { 219193323Sed OS << "PointerType::getUnqual("; 220193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 221193323Sed OS << ")"; 222193323Sed } else if (VT == MVT::iPTRAny) { 223193323Sed // Make sure the user has passed us an argument type to overload. If not, 224193323Sed // treat it as an ordinary (not overloaded) intrinsic. 225193323Sed OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 226193323Sed << "] : PointerType::getUnqual("; 227193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 228193323Sed OS << ")"; 229193323Sed ++ArgNo; 230193323Sed } else if (VT == MVT::isVoid) { 231193323Sed if (ArgNo == 0) 232198090Srdivacky OS << "Type::getVoidTy(Context)"; 233193323Sed else 234193323Sed // MVT::isVoid is used to mean varargs here. 235193323Sed OS << "..."; 236193323Sed } else { 237193323Sed EmitTypeForValueType(OS, VT); 238193323Sed } 239193323Sed} 240193323Sed 241193323Sed/// RecordListComparator - Provide a deterministic comparator for lists of 242193323Sed/// records. 243193323Sednamespace { 244193323Sed typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 245193323Sed struct RecordListComparator { 246193323Sed bool operator()(const RecPair &LHS, 247193323Sed const RecPair &RHS) const { 248193323Sed unsigned i = 0; 249193323Sed const std::vector<Record*> *LHSVec = &LHS.first; 250193323Sed const std::vector<Record*> *RHSVec = &RHS.first; 251193323Sed unsigned RHSSize = RHSVec->size(); 252193323Sed unsigned LHSSize = LHSVec->size(); 253193323Sed 254193323Sed do { 255193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 256193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 257193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 258193323Sed } while (++i != LHSSize); 259193323Sed 260193323Sed if (i != RHSSize) return true; 261193323Sed 262193323Sed i = 0; 263193323Sed LHSVec = &LHS.second; 264193323Sed RHSVec = &RHS.second; 265193323Sed RHSSize = RHSVec->size(); 266193323Sed LHSSize = LHSVec->size(); 267193323Sed 268193323Sed for (i = 0; i != LHSSize; ++i) { 269193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 270193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 271193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 272193323Sed } 273193323Sed 274193323Sed return i != RHSSize; 275193323Sed } 276193323Sed }; 277193323Sed} 278193323Sed 279193323Sedvoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 280195340Sed raw_ostream &OS) { 281193323Sed OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 282193323Sed OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 283193323Sed OS << " switch (ID) {\n"; 284193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 285193323Sed 286193323Sed // This checking can emit a lot of very common code. To reduce the amount of 287193323Sed // code that we emit, batch up cases that have identical types. This avoids 288193323Sed // problems where GCC can run out of memory compiling Verifier.cpp. 289193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 290193323Sed MapTy UniqueArgInfos; 291193323Sed 292193323Sed // Compute the unique argument type info. 293193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 294193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 295193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 296193323Sed 297193323Sed // Loop through the array, emitting one comparison for each batch. 298193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 299193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 300193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 301193323Sed OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 302193323Sed << Ints[I->second[i]].Name << "\n"; 303193323Sed 304193323Sed const RecPair &ArgTypes = I->first; 305193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 306193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 307198090Srdivacky std::vector<unsigned> OverloadedTypeIndices; 308193323Sed 309193323Sed OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 310193323Sed << ParamTys.size(); 311193323Sed 312193323Sed // Emit return types. 313193323Sed for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 314193323Sed Record *ArgType = RetTys[j]; 315193323Sed OS << ", "; 316193323Sed 317193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 318193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 319198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 320198090Srdivacky "Invalid matching number!"); 321198090Srdivacky Number = OverloadedTypeIndices[Number]; 322193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 323193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 324193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 325193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 326193323Sed else 327193323Sed OS << "~" << Number; 328193323Sed } else { 329193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 330193323Sed OS << getEnumName(VT); 331193323Sed 332198090Srdivacky if (EVT(VT).isOverloaded()) 333198090Srdivacky OverloadedTypeIndices.push_back(j); 334198090Srdivacky 335193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 336193323Sed throw "Var arg type not last argument"; 337193323Sed } 338193323Sed } 339193323Sed 340193323Sed // Emit the parameter types. 341193323Sed for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 342193323Sed Record *ArgType = ParamTys[j]; 343193323Sed OS << ", "; 344193323Sed 345193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 346193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 347198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 348198090Srdivacky "Invalid matching number!"); 349198090Srdivacky Number = OverloadedTypeIndices[Number]; 350193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 351193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 352193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 353193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 354193323Sed else 355193323Sed OS << "~" << Number; 356193323Sed } else { 357193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 358193323Sed OS << getEnumName(VT); 359193323Sed 360198090Srdivacky if (EVT(VT).isOverloaded()) 361198090Srdivacky OverloadedTypeIndices.push_back(j + RetTys.size()); 362198090Srdivacky 363193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 364193323Sed throw "Var arg type not last argument"; 365193323Sed } 366193323Sed } 367193323Sed 368193323Sed OS << ");\n"; 369193323Sed OS << " break;\n"; 370193323Sed } 371193323Sed OS << " }\n"; 372193323Sed OS << "#endif\n\n"; 373193323Sed} 374193323Sed 375193323Sedvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 376195340Sed raw_ostream &OS) { 377193323Sed OS << "// Code for generating Intrinsic function declarations.\n"; 378193323Sed OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 379193323Sed OS << " switch (id) {\n"; 380193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 381193323Sed 382193323Sed // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 383193323Sed // types. 384193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 385193323Sed MapTy UniqueArgInfos; 386193323Sed 387193323Sed // Compute the unique argument type info. 388193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 389193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 390193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 391193323Sed 392193323Sed // Loop through the array, emitting one generator for each batch. 393193323Sed std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 394193323Sed 395193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 396193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 397193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 398193323Sed OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 399193323Sed << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 400193323Sed 401193323Sed const RecPair &ArgTypes = I->first; 402193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 403193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 404193323Sed 405193323Sed unsigned N = ParamTys.size(); 406193323Sed 407193323Sed if (N > 1 && 408193323Sed getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 409193323Sed OS << " IsVarArg = true;\n"; 410193323Sed --N; 411193323Sed } 412193323Sed 413193323Sed unsigned ArgNo = 0; 414193323Sed OS << " ResultTy = "; 415193323Sed EmitTypeGenerate(OS, RetTys, ArgNo); 416193323Sed OS << ";\n"; 417193323Sed 418193323Sed for (unsigned j = 0; j != N; ++j) { 419193323Sed OS << " ArgTys.push_back("; 420193323Sed EmitTypeGenerate(OS, ParamTys[j], ArgNo); 421193323Sed OS << ");\n"; 422193323Sed } 423193323Sed 424193323Sed OS << " break;\n"; 425193323Sed } 426193323Sed 427193323Sed OS << " }\n"; 428193323Sed OS << "#endif\n\n"; 429193323Sed} 430193323Sed 431193323Sed/// EmitAttributes - This emits the Intrinsic::getAttributes method. 432193323Sedvoid IntrinsicEmitter:: 433195340SedEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 434193323Sed OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 435193323Sed OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 436193323Sed if (TargetOnly) 437193323Sed OS << "static AttrListPtr getAttributes(" << TargetPrefix 438193323Sed << "Intrinsic::ID id) {"; 439193323Sed else 440193323Sed OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 441193323Sed OS << " // No intrinsic can throw exceptions.\n"; 442193323Sed OS << " Attributes Attr = Attribute::NoUnwind;\n"; 443193323Sed OS << " switch (id) {\n"; 444193323Sed OS << " default: break;\n"; 445193323Sed unsigned MaxArgAttrs = 0; 446193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 447193323Sed MaxArgAttrs = 448193323Sed std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 449193323Sed switch (Ints[i].ModRef) { 450193323Sed default: break; 451193323Sed case CodeGenIntrinsic::NoMem: 452193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 453193323Sed << ":\n"; 454193323Sed break; 455193323Sed } 456193323Sed } 457193323Sed OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 458193323Sed OS << " break;\n"; 459193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 460193323Sed switch (Ints[i].ModRef) { 461193323Sed default: break; 462193323Sed case CodeGenIntrinsic::ReadArgMem: 463193323Sed case CodeGenIntrinsic::ReadMem: 464193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 465193323Sed << ":\n"; 466193323Sed break; 467193323Sed } 468193323Sed } 469193323Sed OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 470193323Sed OS << " break;\n"; 471193323Sed OS << " }\n"; 472193323Sed OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 473193323Sed OS << " unsigned NumAttrs = 0;\n"; 474193323Sed OS << " switch (id) {\n"; 475193323Sed OS << " default: break;\n"; 476193323Sed 477193323Sed // Add argument attributes for any intrinsics that have them. 478193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 479193323Sed if (Ints[i].ArgumentAttributes.empty()) continue; 480193323Sed 481193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 482193323Sed << ":\n"; 483193323Sed 484193323Sed std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 485193323Sed Ints[i].ArgumentAttributes; 486193323Sed // Sort by argument index. 487193323Sed std::sort(ArgAttrs.begin(), ArgAttrs.end()); 488193323Sed 489193323Sed unsigned NumArgsWithAttrs = 0; 490193323Sed 491193323Sed while (!ArgAttrs.empty()) { 492193323Sed unsigned ArgNo = ArgAttrs[0].first; 493193323Sed 494193323Sed OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 495193323Sed << ArgNo+1 << ", 0"; 496193323Sed 497193323Sed while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 498193323Sed switch (ArgAttrs[0].second) { 499193323Sed default: assert(0 && "Unknown arg attribute"); 500193323Sed case CodeGenIntrinsic::NoCapture: 501193323Sed OS << "|Attribute::NoCapture"; 502193323Sed break; 503193323Sed } 504193323Sed ArgAttrs.erase(ArgAttrs.begin()); 505193323Sed } 506193323Sed OS << ");\n"; 507193323Sed } 508193323Sed 509193323Sed OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 510193323Sed OS << " break;\n"; 511193323Sed } 512193323Sed 513193323Sed OS << " }\n"; 514193323Sed OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 515193323Sed OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 516193323Sed OS << "}\n"; 517193323Sed OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 518193323Sed} 519193323Sed 520193323Sed/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 521193323Sedvoid IntrinsicEmitter:: 522195340SedEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 523193323Sed OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 524193323Sed OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 525193323Sed OS << "switch (id) {\n"; 526193323Sed OS << "default:\n return UnknownModRefBehavior;\n"; 527193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 528193323Sed if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem) 529193323Sed continue; 530193323Sed OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 531193323Sed << ":\n"; 532193323Sed switch (Ints[i].ModRef) { 533193323Sed default: 534193323Sed assert(false && "Unknown Mod/Ref type!"); 535193323Sed case CodeGenIntrinsic::NoMem: 536193323Sed OS << " return DoesNotAccessMemory;\n"; 537193323Sed break; 538193323Sed case CodeGenIntrinsic::ReadArgMem: 539193323Sed case CodeGenIntrinsic::ReadMem: 540193323Sed OS << " return OnlyReadsMemory;\n"; 541193323Sed break; 542193323Sed case CodeGenIntrinsic::WriteArgMem: 543193323Sed OS << " return AccessesArguments;\n"; 544193323Sed break; 545193323Sed } 546193323Sed } 547193323Sed OS << "}\n"; 548193323Sed OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 549193323Sed} 550193323Sed 551193323Sedvoid IntrinsicEmitter:: 552195340SedEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 553193323Sed OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 554193323Sed OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 555193323Sed OS << " switch (F->getIntrinsicID()) {\n"; 556193323Sed OS << " default: BuiltinName = \"\"; break;\n"; 557193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 558193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 559193323Sed OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 560193323Sed << Ints[i].GCCBuiltinName << "\"; break;\n"; 561193323Sed } 562193323Sed } 563193323Sed OS << " }\n"; 564193323Sed OS << "#endif\n\n"; 565193323Sed} 566193323Sed 567193323Sed/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified 568193323Sed/// sorted range of builtin names is equal to the current builtin. This breaks 569193323Sed/// it down into a simple tree. 570193323Sed/// 571193323Sed/// At this point, we know that all the builtins in the range have the same name 572193323Sed/// for the first 'CharStart' characters. Only the end of the name needs to be 573193323Sed/// discriminated. 574193323Sedtypedef std::map<std::string, std::string>::const_iterator StrMapIterator; 575193323Sedstatic void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, 576193323Sed unsigned CharStart, unsigned Indent, 577195340Sed std::string TargetPrefix, raw_ostream &OS) { 578193323Sed if (Start == End) return; // empty range. 579193323Sed 580193323Sed // Determine what, if anything, is the same about all these strings. 581193323Sed std::string CommonString = Start->first; 582193323Sed unsigned NumInRange = 0; 583193323Sed for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { 584193323Sed // Find the first character that doesn't match. 585193323Sed const std::string &ThisStr = I->first; 586193323Sed unsigned NonMatchChar = CharStart; 587193323Sed while (NonMatchChar < CommonString.size() && 588193323Sed NonMatchChar < ThisStr.size() && 589193323Sed CommonString[NonMatchChar] == ThisStr[NonMatchChar]) 590193323Sed ++NonMatchChar; 591193323Sed // Truncate off pieces that don't match. 592193323Sed CommonString.resize(NonMatchChar); 593193323Sed } 594193323Sed 595193323Sed // Just compare the rest of the string. 596193323Sed if (NumInRange == 1) { 597193323Sed if (CharStart != CommonString.size()) { 598193323Sed OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 599193323Sed if (CharStart) OS << "+" << CharStart; 600193323Sed OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 601193323Sed OS << CommonString.size() - CharStart << "))\n"; 602193323Sed ++Indent; 603193323Sed } 604193323Sed OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix 605193323Sed << "Intrinsic::"; 606193323Sed OS << Start->second << ";\n"; 607193323Sed return; 608193323Sed } 609193323Sed 610193323Sed // At this point, we potentially have a common prefix for these builtins, emit 611193323Sed // a check for this common prefix. 612193323Sed if (CommonString.size() != CharStart) { 613193323Sed OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 614193323Sed if (CharStart) OS << "+" << CharStart; 615193323Sed OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 616193323Sed OS << CommonString.size()-CharStart << ")) {\n"; 617193323Sed 618193323Sed EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 619193323Sed TargetPrefix, OS); 620193323Sed OS << std::string(Indent*2, ' ') << "}\n"; 621193323Sed return; 622193323Sed } 623193323Sed 624193323Sed // Output a switch on the character that differs across the set. 625193323Sed OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart 626193323Sed << "]) {"; 627193323Sed if (CharStart) 628193323Sed OS << " // \"" << std::string(Start->first.begin(), 629193323Sed Start->first.begin()+CharStart) << "\""; 630193323Sed OS << "\n"; 631193323Sed 632193323Sed for (StrMapIterator I = Start; I != End; ) { 633193323Sed char ThisChar = I->first[CharStart]; 634193323Sed OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; 635193323Sed // Figure out the range that has this common character. 636193323Sed StrMapIterator NextChar = I; 637193323Sed for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; 638193323Sed ++NextChar) 639193323Sed /*empty*/; 640193323Sed EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); 641193323Sed OS << std::string(Indent*2, ' ') << " break;\n"; 642193323Sed I = NextChar; 643193323Sed } 644193323Sed OS << std::string(Indent*2, ' ') << "}\n"; 645193323Sed} 646193323Sed 647193323Sed/// EmitTargetBuiltins - All of the builtins in the specified map are for the 648193323Sed/// same target, and we already checked it. 649193323Sedstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 650193323Sed const std::string &TargetPrefix, 651195340Sed raw_ostream &OS) { 652193323Sed // Rearrange the builtins by length. 653193323Sed std::vector<std::map<std::string, std::string> > BuiltinsByLen; 654193323Sed BuiltinsByLen.reserve(100); 655193323Sed 656193323Sed for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { 657193323Sed if (I->first.size() >= BuiltinsByLen.size()) 658193323Sed BuiltinsByLen.resize(I->first.size()+1); 659193323Sed BuiltinsByLen[I->first.size()].insert(*I); 660193323Sed } 661193323Sed 662193323Sed // Now that we have all the builtins by their length, emit a switch stmt. 663193323Sed OS << " switch (strlen(BuiltinName)) {\n"; 664193323Sed OS << " default: break;\n"; 665193323Sed for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { 666193323Sed if (BuiltinsByLen[i].empty()) continue; 667193323Sed OS << " case " << i << ":\n"; 668193323Sed EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), 669193323Sed 0, 3, TargetPrefix, OS); 670193323Sed OS << " break;\n"; 671193323Sed } 672193323Sed OS << " }\n"; 673193323Sed} 674193323Sed 675193323Sed 676193323Sedvoid IntrinsicEmitter:: 677193323SedEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 678195340Sed raw_ostream &OS) { 679193323Sed typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 680193323Sed BIMTy BuiltinMap; 681193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 682193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 683193323Sed // Get the map for this target prefix. 684193323Sed std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 685193323Sed 686193323Sed if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 687193323Sed Ints[i].EnumName)).second) 688193323Sed throw "Intrinsic '" + Ints[i].TheDef->getName() + 689193323Sed "': duplicate GCC builtin name!"; 690193323Sed } 691193323Sed } 692193323Sed 693193323Sed OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 694193323Sed OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 695193323Sed OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 696193323Sed OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 697193323Sed OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 698193323Sed 699193323Sed if (TargetOnly) { 700193323Sed OS << "static " << TargetPrefix << "Intrinsic::ID " 701193323Sed << "getIntrinsicForGCCBuiltin(const char " 702193323Sed << "*TargetPrefix, const char *BuiltinName) {\n"; 703193323Sed OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; 704193323Sed } else { 705193323Sed OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 706193323Sed << "*TargetPrefix, const char *BuiltinName) {\n"; 707193323Sed OS << " Intrinsic::ID IntrinsicID = "; 708193323Sed } 709193323Sed 710193323Sed if (TargetOnly) 711193323Sed OS << "(" << TargetPrefix<< "Intrinsic::ID)"; 712193323Sed 713193323Sed OS << "Intrinsic::not_intrinsic;\n"; 714193323Sed 715193323Sed // Note: this could emit significantly better code if we cared. 716193323Sed for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 717193323Sed OS << " "; 718193323Sed if (!I->first.empty()) 719193323Sed OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; 720193323Sed else 721193323Sed OS << "/* Target Independent Builtins */ "; 722193323Sed OS << "{\n"; 723193323Sed 724193323Sed // Emit the comparisons for this target prefix. 725193323Sed EmitTargetBuiltins(I->second, TargetPrefix, OS); 726193323Sed OS << " }\n"; 727193323Sed } 728193323Sed OS << " return IntrinsicID;\n"; 729193323Sed OS << "}\n"; 730193323Sed OS << "#endif\n\n"; 731193323Sed} 732