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