IntrinsicEmitter.cpp revision 206083
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) { 175206083Srdivacky if (ArgTypes.empty()) 176206083Srdivacky return EmitTypeForValueType(OS, MVT::isVoid); 177206083Srdivacky 178206083Srdivacky if (ArgTypes.size() == 1) 179206083Srdivacky return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 180193323Sed 181198090Srdivacky OS << "StructType::get(Context, "; 182193323Sed 183193323Sed for (std::vector<Record*>::const_iterator 184193323Sed I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 185193323Sed EmitTypeGenerate(OS, *I, ArgNo); 186193323Sed OS << ", "; 187193323Sed } 188193323Sed 189193323Sed OS << " NULL)"; 190193323Sed} 191193323Sed 192195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 193193323Sed unsigned &ArgNo) { 194193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 195193323Sed 196193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 197193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 198193323Sed assert(Number < ArgNo && "Invalid matching number!"); 199193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 200193323Sed OS << "VectorType::getExtendedElementVectorType" 201193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 202193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 203193323Sed OS << "VectorType::getTruncatedElementVectorType" 204193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 205193323Sed else 206193323Sed OS << "Tys[" << Number << "]"; 207198090Srdivacky } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 208193323Sed // NOTE: The ArgNo variable here is not the absolute argument number, it is 209193323Sed // the index of the "arbitrary" type in the Tys array passed to the 210193323Sed // Intrinsic::getDeclaration function. Consequently, we only want to 211193323Sed // increment it when we actually hit an overloaded type. Getting this wrong 212193323Sed // leads to very subtle bugs! 213193323Sed OS << "Tys[" << ArgNo++ << "]"; 214198090Srdivacky } else if (EVT(VT).isVector()) { 215198090Srdivacky EVT VVT = VT; 216193323Sed OS << "VectorType::get("; 217198090Srdivacky EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 218193323Sed OS << ", " << VVT.getVectorNumElements() << ")"; 219193323Sed } else if (VT == MVT::iPTR) { 220193323Sed OS << "PointerType::getUnqual("; 221193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 222193323Sed OS << ")"; 223193323Sed } else if (VT == MVT::iPTRAny) { 224193323Sed // Make sure the user has passed us an argument type to overload. If not, 225193323Sed // treat it as an ordinary (not overloaded) intrinsic. 226193323Sed OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 227193323Sed << "] : PointerType::getUnqual("; 228193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 229193323Sed OS << ")"; 230193323Sed ++ArgNo; 231193323Sed } else if (VT == MVT::isVoid) { 232193323Sed if (ArgNo == 0) 233198090Srdivacky OS << "Type::getVoidTy(Context)"; 234193323Sed else 235193323Sed // MVT::isVoid is used to mean varargs here. 236193323Sed OS << "..."; 237193323Sed } else { 238193323Sed EmitTypeForValueType(OS, VT); 239193323Sed } 240193323Sed} 241193323Sed 242193323Sed/// RecordListComparator - Provide a deterministic comparator for lists of 243193323Sed/// records. 244193323Sednamespace { 245193323Sed typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 246193323Sed struct RecordListComparator { 247193323Sed bool operator()(const RecPair &LHS, 248193323Sed const RecPair &RHS) const { 249193323Sed unsigned i = 0; 250193323Sed const std::vector<Record*> *LHSVec = &LHS.first; 251193323Sed const std::vector<Record*> *RHSVec = &RHS.first; 252193323Sed unsigned RHSSize = RHSVec->size(); 253193323Sed unsigned LHSSize = LHSVec->size(); 254193323Sed 255206083Srdivacky for (; i != LHSSize; ++i) { 256193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 257193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 258193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 259206083Srdivacky } 260193323Sed 261193323Sed if (i != RHSSize) return true; 262193323Sed 263193323Sed i = 0; 264193323Sed LHSVec = &LHS.second; 265193323Sed RHSVec = &RHS.second; 266193323Sed RHSSize = RHSVec->size(); 267193323Sed LHSSize = LHSVec->size(); 268193323Sed 269193323Sed for (i = 0; i != LHSSize; ++i) { 270193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 271193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 272193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 273193323Sed } 274193323Sed 275193323Sed return i != RHSSize; 276193323Sed } 277193323Sed }; 278193323Sed} 279193323Sed 280193323Sedvoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 281195340Sed raw_ostream &OS) { 282193323Sed OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 283193323Sed OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 284193323Sed OS << " switch (ID) {\n"; 285193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 286193323Sed 287193323Sed // This checking can emit a lot of very common code. To reduce the amount of 288193323Sed // code that we emit, batch up cases that have identical types. This avoids 289193323Sed // problems where GCC can run out of memory compiling Verifier.cpp. 290193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 291193323Sed MapTy UniqueArgInfos; 292193323Sed 293193323Sed // Compute the unique argument type info. 294193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 295193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 296193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 297193323Sed 298193323Sed // Loop through the array, emitting one comparison for each batch. 299193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 300193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 301193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 302193323Sed OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 303193323Sed << Ints[I->second[i]].Name << "\n"; 304193323Sed 305193323Sed const RecPair &ArgTypes = I->first; 306193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 307193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 308198090Srdivacky std::vector<unsigned> OverloadedTypeIndices; 309193323Sed 310193323Sed OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 311193323Sed << ParamTys.size(); 312193323Sed 313193323Sed // Emit return types. 314193323Sed for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 315193323Sed Record *ArgType = RetTys[j]; 316193323Sed OS << ", "; 317193323Sed 318193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 319193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 320198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 321198090Srdivacky "Invalid matching number!"); 322198090Srdivacky Number = OverloadedTypeIndices[Number]; 323193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 324193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 325193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 326193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 327193323Sed else 328193323Sed OS << "~" << Number; 329193323Sed } else { 330193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 331193323Sed OS << getEnumName(VT); 332193323Sed 333198090Srdivacky if (EVT(VT).isOverloaded()) 334198090Srdivacky OverloadedTypeIndices.push_back(j); 335198090Srdivacky 336193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 337193323Sed throw "Var arg type not last argument"; 338193323Sed } 339193323Sed } 340193323Sed 341193323Sed // Emit the parameter types. 342193323Sed for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 343193323Sed Record *ArgType = ParamTys[j]; 344193323Sed OS << ", "; 345193323Sed 346193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 347193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 348198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 349198090Srdivacky "Invalid matching number!"); 350198090Srdivacky Number = OverloadedTypeIndices[Number]; 351193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 352193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 353193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 354193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 355193323Sed else 356193323Sed OS << "~" << Number; 357193323Sed } else { 358193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 359193323Sed OS << getEnumName(VT); 360193323Sed 361198090Srdivacky if (EVT(VT).isOverloaded()) 362198090Srdivacky OverloadedTypeIndices.push_back(j + RetTys.size()); 363198090Srdivacky 364193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 365193323Sed throw "Var arg type not last argument"; 366193323Sed } 367193323Sed } 368193323Sed 369193323Sed OS << ");\n"; 370193323Sed OS << " break;\n"; 371193323Sed } 372193323Sed OS << " }\n"; 373193323Sed OS << "#endif\n\n"; 374193323Sed} 375193323Sed 376193323Sedvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 377195340Sed raw_ostream &OS) { 378193323Sed OS << "// Code for generating Intrinsic function declarations.\n"; 379193323Sed OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 380193323Sed OS << " switch (id) {\n"; 381193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 382193323Sed 383193323Sed // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 384193323Sed // types. 385193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 386193323Sed MapTy UniqueArgInfos; 387193323Sed 388193323Sed // Compute the unique argument type info. 389193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 390193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 391193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 392193323Sed 393193323Sed // Loop through the array, emitting one generator for each batch. 394193323Sed std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 395193323Sed 396193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 397193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 398193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 399193323Sed OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 400193323Sed << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 401193323Sed 402193323Sed const RecPair &ArgTypes = I->first; 403193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 404193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 405193323Sed 406193323Sed unsigned N = ParamTys.size(); 407193323Sed 408193323Sed if (N > 1 && 409193323Sed getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 410193323Sed OS << " IsVarArg = true;\n"; 411193323Sed --N; 412193323Sed } 413193323Sed 414193323Sed unsigned ArgNo = 0; 415193323Sed OS << " ResultTy = "; 416193323Sed EmitTypeGenerate(OS, RetTys, ArgNo); 417193323Sed OS << ";\n"; 418193323Sed 419193323Sed for (unsigned j = 0; j != N; ++j) { 420193323Sed OS << " ArgTys.push_back("; 421193323Sed EmitTypeGenerate(OS, ParamTys[j], ArgNo); 422193323Sed OS << ");\n"; 423193323Sed } 424193323Sed 425193323Sed OS << " break;\n"; 426193323Sed } 427193323Sed 428193323Sed OS << " }\n"; 429193323Sed OS << "#endif\n\n"; 430193323Sed} 431193323Sed 432193323Sed/// EmitAttributes - This emits the Intrinsic::getAttributes method. 433193323Sedvoid IntrinsicEmitter:: 434195340SedEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 435193323Sed OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 436193323Sed OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 437193323Sed if (TargetOnly) 438193323Sed OS << "static AttrListPtr getAttributes(" << TargetPrefix 439193323Sed << "Intrinsic::ID id) {"; 440193323Sed else 441193323Sed OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 442193323Sed OS << " // No intrinsic can throw exceptions.\n"; 443193323Sed OS << " Attributes Attr = Attribute::NoUnwind;\n"; 444193323Sed OS << " switch (id) {\n"; 445193323Sed OS << " default: break;\n"; 446193323Sed unsigned MaxArgAttrs = 0; 447193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 448193323Sed MaxArgAttrs = 449193323Sed std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 450193323Sed switch (Ints[i].ModRef) { 451193323Sed default: break; 452193323Sed case CodeGenIntrinsic::NoMem: 453193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 454193323Sed << ":\n"; 455193323Sed break; 456193323Sed } 457193323Sed } 458193323Sed OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 459193323Sed OS << " break;\n"; 460193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 461193323Sed switch (Ints[i].ModRef) { 462193323Sed default: break; 463193323Sed case CodeGenIntrinsic::ReadArgMem: 464193323Sed case CodeGenIntrinsic::ReadMem: 465193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 466193323Sed << ":\n"; 467193323Sed break; 468193323Sed } 469193323Sed } 470193323Sed OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 471193323Sed OS << " break;\n"; 472193323Sed OS << " }\n"; 473193323Sed OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 474193323Sed OS << " unsigned NumAttrs = 0;\n"; 475193323Sed OS << " switch (id) {\n"; 476193323Sed OS << " default: break;\n"; 477193323Sed 478193323Sed // Add argument attributes for any intrinsics that have them. 479193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 480193323Sed if (Ints[i].ArgumentAttributes.empty()) continue; 481193323Sed 482193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 483193323Sed << ":\n"; 484193323Sed 485193323Sed std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 486193323Sed Ints[i].ArgumentAttributes; 487193323Sed // Sort by argument index. 488193323Sed std::sort(ArgAttrs.begin(), ArgAttrs.end()); 489193323Sed 490193323Sed unsigned NumArgsWithAttrs = 0; 491193323Sed 492193323Sed while (!ArgAttrs.empty()) { 493193323Sed unsigned ArgNo = ArgAttrs[0].first; 494193323Sed 495193323Sed OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 496193323Sed << ArgNo+1 << ", 0"; 497193323Sed 498193323Sed while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 499193323Sed switch (ArgAttrs[0].second) { 500193323Sed default: assert(0 && "Unknown arg attribute"); 501193323Sed case CodeGenIntrinsic::NoCapture: 502193323Sed OS << "|Attribute::NoCapture"; 503193323Sed break; 504193323Sed } 505193323Sed ArgAttrs.erase(ArgAttrs.begin()); 506193323Sed } 507193323Sed OS << ");\n"; 508193323Sed } 509193323Sed 510193323Sed OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 511193323Sed OS << " break;\n"; 512193323Sed } 513193323Sed 514193323Sed OS << " }\n"; 515193323Sed OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 516193323Sed OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 517193323Sed OS << "}\n"; 518193323Sed OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 519193323Sed} 520193323Sed 521193323Sed/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 522193323Sedvoid IntrinsicEmitter:: 523195340SedEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 524193323Sed OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 525193323Sed OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 526202375Srdivacky OS << "switch (iid) {\n"; 527193323Sed OS << "default:\n return UnknownModRefBehavior;\n"; 528193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 529193323Sed if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem) 530193323Sed continue; 531193323Sed OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 532193323Sed << ":\n"; 533193323Sed switch (Ints[i].ModRef) { 534193323Sed default: 535193323Sed assert(false && "Unknown Mod/Ref type!"); 536193323Sed case CodeGenIntrinsic::NoMem: 537193323Sed OS << " return DoesNotAccessMemory;\n"; 538193323Sed break; 539193323Sed case CodeGenIntrinsic::ReadArgMem: 540193323Sed case CodeGenIntrinsic::ReadMem: 541193323Sed OS << " return OnlyReadsMemory;\n"; 542193323Sed break; 543193323Sed case CodeGenIntrinsic::WriteArgMem: 544193323Sed OS << " return AccessesArguments;\n"; 545193323Sed break; 546193323Sed } 547193323Sed } 548193323Sed OS << "}\n"; 549193323Sed OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 550193323Sed} 551193323Sed 552193323Sedvoid IntrinsicEmitter:: 553195340SedEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 554193323Sed OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 555193323Sed OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 556193323Sed OS << " switch (F->getIntrinsicID()) {\n"; 557193323Sed OS << " default: BuiltinName = \"\"; break;\n"; 558193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 559193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 560193323Sed OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 561193323Sed << Ints[i].GCCBuiltinName << "\"; break;\n"; 562193323Sed } 563193323Sed } 564193323Sed OS << " }\n"; 565193323Sed OS << "#endif\n\n"; 566193323Sed} 567193323Sed 568193323Sed/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified 569193323Sed/// sorted range of builtin names is equal to the current builtin. This breaks 570193323Sed/// it down into a simple tree. 571193323Sed/// 572193323Sed/// At this point, we know that all the builtins in the range have the same name 573193323Sed/// for the first 'CharStart' characters. Only the end of the name needs to be 574193323Sed/// discriminated. 575193323Sedtypedef std::map<std::string, std::string>::const_iterator StrMapIterator; 576193323Sedstatic void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, 577193323Sed unsigned CharStart, unsigned Indent, 578195340Sed std::string TargetPrefix, raw_ostream &OS) { 579193323Sed if (Start == End) return; // empty range. 580193323Sed 581193323Sed // Determine what, if anything, is the same about all these strings. 582193323Sed std::string CommonString = Start->first; 583193323Sed unsigned NumInRange = 0; 584193323Sed for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { 585193323Sed // Find the first character that doesn't match. 586193323Sed const std::string &ThisStr = I->first; 587193323Sed unsigned NonMatchChar = CharStart; 588193323Sed while (NonMatchChar < CommonString.size() && 589193323Sed NonMatchChar < ThisStr.size() && 590193323Sed CommonString[NonMatchChar] == ThisStr[NonMatchChar]) 591193323Sed ++NonMatchChar; 592193323Sed // Truncate off pieces that don't match. 593193323Sed CommonString.resize(NonMatchChar); 594193323Sed } 595193323Sed 596193323Sed // Just compare the rest of the string. 597193323Sed if (NumInRange == 1) { 598193323Sed if (CharStart != CommonString.size()) { 599193323Sed OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 600193323Sed if (CharStart) OS << "+" << CharStart; 601193323Sed OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 602193323Sed OS << CommonString.size() - CharStart << "))\n"; 603193323Sed ++Indent; 604193323Sed } 605193323Sed OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix 606193323Sed << "Intrinsic::"; 607193323Sed OS << Start->second << ";\n"; 608193323Sed return; 609193323Sed } 610193323Sed 611193323Sed // At this point, we potentially have a common prefix for these builtins, emit 612193323Sed // a check for this common prefix. 613193323Sed if (CommonString.size() != CharStart) { 614193323Sed OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 615193323Sed if (CharStart) OS << "+" << CharStart; 616193323Sed OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 617193323Sed OS << CommonString.size()-CharStart << ")) {\n"; 618193323Sed 619193323Sed EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 620193323Sed TargetPrefix, OS); 621193323Sed OS << std::string(Indent*2, ' ') << "}\n"; 622193323Sed return; 623193323Sed } 624193323Sed 625193323Sed // Output a switch on the character that differs across the set. 626193323Sed OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart 627193323Sed << "]) {"; 628193323Sed if (CharStart) 629193323Sed OS << " // \"" << std::string(Start->first.begin(), 630193323Sed Start->first.begin()+CharStart) << "\""; 631193323Sed OS << "\n"; 632193323Sed 633193323Sed for (StrMapIterator I = Start; I != End; ) { 634193323Sed char ThisChar = I->first[CharStart]; 635193323Sed OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; 636193323Sed // Figure out the range that has this common character. 637193323Sed StrMapIterator NextChar = I; 638193323Sed for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; 639193323Sed ++NextChar) 640193323Sed /*empty*/; 641193323Sed EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); 642193323Sed OS << std::string(Indent*2, ' ') << " break;\n"; 643193323Sed I = NextChar; 644193323Sed } 645193323Sed OS << std::string(Indent*2, ' ') << "}\n"; 646193323Sed} 647193323Sed 648193323Sed/// EmitTargetBuiltins - All of the builtins in the specified map are for the 649193323Sed/// same target, and we already checked it. 650193323Sedstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 651193323Sed const std::string &TargetPrefix, 652195340Sed raw_ostream &OS) { 653193323Sed // Rearrange the builtins by length. 654193323Sed std::vector<std::map<std::string, std::string> > BuiltinsByLen; 655193323Sed BuiltinsByLen.reserve(100); 656193323Sed 657193323Sed for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { 658193323Sed if (I->first.size() >= BuiltinsByLen.size()) 659193323Sed BuiltinsByLen.resize(I->first.size()+1); 660193323Sed BuiltinsByLen[I->first.size()].insert(*I); 661193323Sed } 662193323Sed 663193323Sed // Now that we have all the builtins by their length, emit a switch stmt. 664193323Sed OS << " switch (strlen(BuiltinName)) {\n"; 665193323Sed OS << " default: break;\n"; 666193323Sed for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { 667193323Sed if (BuiltinsByLen[i].empty()) continue; 668193323Sed OS << " case " << i << ":\n"; 669193323Sed EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), 670193323Sed 0, 3, TargetPrefix, OS); 671193323Sed OS << " break;\n"; 672193323Sed } 673193323Sed OS << " }\n"; 674193323Sed} 675193323Sed 676193323Sed 677193323Sedvoid IntrinsicEmitter:: 678193323SedEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 679195340Sed raw_ostream &OS) { 680193323Sed typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 681193323Sed BIMTy BuiltinMap; 682193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 683193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 684193323Sed // Get the map for this target prefix. 685193323Sed std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 686193323Sed 687193323Sed if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 688193323Sed Ints[i].EnumName)).second) 689193323Sed throw "Intrinsic '" + Ints[i].TheDef->getName() + 690193323Sed "': duplicate GCC builtin name!"; 691193323Sed } 692193323Sed } 693193323Sed 694193323Sed OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 695193323Sed OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 696193323Sed OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 697193323Sed OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 698193323Sed OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 699193323Sed 700193323Sed if (TargetOnly) { 701193323Sed OS << "static " << TargetPrefix << "Intrinsic::ID " 702193323Sed << "getIntrinsicForGCCBuiltin(const char " 703193323Sed << "*TargetPrefix, const char *BuiltinName) {\n"; 704193323Sed OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; 705193323Sed } else { 706193323Sed OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 707193323Sed << "*TargetPrefix, const char *BuiltinName) {\n"; 708193323Sed OS << " Intrinsic::ID IntrinsicID = "; 709193323Sed } 710193323Sed 711193323Sed if (TargetOnly) 712193323Sed OS << "(" << TargetPrefix<< "Intrinsic::ID)"; 713193323Sed 714193323Sed OS << "Intrinsic::not_intrinsic;\n"; 715193323Sed 716193323Sed // Note: this could emit significantly better code if we cared. 717193323Sed for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 718193323Sed OS << " "; 719193323Sed if (!I->first.empty()) 720193323Sed OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; 721193323Sed else 722193323Sed OS << "/* Target Independent Builtins */ "; 723193323Sed OS << "{\n"; 724193323Sed 725193323Sed // Emit the comparisons for this target prefix. 726193323Sed EmitTargetBuiltins(I->second, TargetPrefix, OS); 727193323Sed OS << " }\n"; 728193323Sed } 729193323Sed OS << " return IntrinsicID;\n"; 730193323Sed OS << "}\n"; 731193323Sed OS << "#endif\n\n"; 732193323Sed} 733