IntrinsicEmitter.cpp revision 208599
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 33208599Srdivacky EmitPrefix(OS); 34208599Srdivacky 35193323Sed // Emit the enum information. 36193323Sed EmitEnumInfo(Ints, OS); 37193323Sed 38193323Sed // Emit the intrinsic ID -> name table. 39193323Sed EmitIntrinsicToNameTable(Ints, OS); 40193323Sed 41193323Sed // Emit the intrinsic ID -> overload table. 42193323Sed EmitIntrinsicToOverloadTable(Ints, OS); 43193323Sed 44193323Sed // Emit the function name recognizer. 45193323Sed EmitFnNameRecognizer(Ints, OS); 46193323Sed 47193323Sed // Emit the intrinsic verifier. 48193323Sed EmitVerifier(Ints, OS); 49193323Sed 50193323Sed // Emit the intrinsic declaration generator. 51193323Sed EmitGenerator(Ints, OS); 52193323Sed 53193323Sed // Emit the intrinsic parameter attributes. 54193323Sed EmitAttributes(Ints, OS); 55193323Sed 56193323Sed // Emit intrinsic alias analysis mod/ref behavior. 57193323Sed EmitModRefBehavior(Ints, OS); 58193323Sed 59193323Sed // Emit a list of intrinsics with corresponding GCC builtins. 60193323Sed EmitGCCBuiltinList(Ints, OS); 61193323Sed 62193323Sed // Emit code to translate GCC builtins into LLVM intrinsics. 63193323Sed EmitIntrinsicToGCCBuiltinMap(Ints, OS); 64208599Srdivacky 65208599Srdivacky EmitSuffix(OS); 66193323Sed} 67193323Sed 68208599Srdivackyvoid IntrinsicEmitter::EmitPrefix(raw_ostream &OS) { 69208599Srdivacky OS << "// VisualStudio defines setjmp as _setjmp\n" 70208599Srdivacky "#if defined(_MSC_VER) && defined(setjmp)\n" 71208599Srdivacky "#define setjmp_undefined_for_visual_studio\n" 72208599Srdivacky "#undef setjmp\n" 73208599Srdivacky "#endif\n\n"; 74208599Srdivacky} 75208599Srdivacky 76208599Srdivackyvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { 77208599Srdivacky OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_visual_studio)\n" 78208599Srdivacky "// let's return it to _setjmp state\n" 79208599Srdivacky "#define setjmp _setjmp\n" 80208599Srdivacky "#endif\n\n"; 81208599Srdivacky} 82208599Srdivacky 83193323Sedvoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 84195340Sed raw_ostream &OS) { 85193323Sed OS << "// Enum values for Intrinsics.h\n"; 86193323Sed OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 87193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 88193323Sed OS << " " << Ints[i].EnumName; 89193323Sed OS << ((i != e-1) ? ", " : " "); 90193323Sed OS << std::string(40-Ints[i].EnumName.size(), ' ') 91193323Sed << "// " << Ints[i].Name << "\n"; 92193323Sed } 93193323Sed OS << "#endif\n\n"; 94193323Sed} 95193323Sed 96193323Sedvoid IntrinsicEmitter:: 97193323SedEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 98195340Sed raw_ostream &OS) { 99193323Sed // Build a function name -> intrinsic name mapping. 100193323Sed std::map<std::string, unsigned> IntMapping; 101193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 102193323Sed IntMapping[Ints[i].Name] = i; 103193323Sed 104193323Sed OS << "// Function name -> enum value recognizer code.\n"; 105193323Sed OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 106193323Sed OS << " switch (Name[5]) {\n"; 107193323Sed OS << " default:\n"; 108193323Sed // Emit the intrinsics in sorted order. 109193323Sed char LastChar = 0; 110193323Sed for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(), 111193323Sed E = IntMapping.end(); I != E; ++I) { 112193323Sed if (I->first[5] != LastChar) { 113193323Sed LastChar = I->first[5]; 114193323Sed OS << " break;\n"; 115193323Sed OS << " case '" << LastChar << "':\n"; 116193323Sed } 117193323Sed 118193323Sed // For overloaded intrinsics, only the prefix needs to match 119193323Sed if (Ints[I->second].isOverloaded) 120193323Sed OS << " if (Len > " << I->first.size() 121193323Sed << " && !memcmp(Name, \"" << I->first << ".\", " 122193323Sed << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::" 123193323Sed << Ints[I->second].EnumName << ";\n"; 124193323Sed else 125193323Sed OS << " if (Len == " << I->first.size() 126193323Sed << " && !memcmp(Name, \"" << I->first << "\", " 127193323Sed << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::" 128193323Sed << Ints[I->second].EnumName << ";\n"; 129193323Sed } 130193323Sed OS << " }\n"; 131193323Sed OS << "#endif\n\n"; 132193323Sed} 133193323Sed 134193323Sedvoid IntrinsicEmitter:: 135193323SedEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 136195340Sed raw_ostream &OS) { 137193323Sed OS << "// Intrinsic ID to name table\n"; 138193323Sed OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 139193323Sed OS << " // Note that entry #0 is the invalid intrinsic!\n"; 140193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 141193323Sed OS << " \"" << Ints[i].Name << "\",\n"; 142193323Sed OS << "#endif\n\n"; 143193323Sed} 144193323Sed 145193323Sedvoid IntrinsicEmitter:: 146193323SedEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 147195340Sed raw_ostream &OS) { 148193323Sed OS << "// Intrinsic ID to overload table\n"; 149193323Sed OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 150193323Sed OS << " // Note that entry #0 is the invalid intrinsic!\n"; 151193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 152193323Sed OS << " "; 153193323Sed if (Ints[i].isOverloaded) 154193323Sed OS << "true"; 155193323Sed else 156193323Sed OS << "false"; 157193323Sed OS << ",\n"; 158193323Sed } 159193323Sed OS << "#endif\n\n"; 160193323Sed} 161193323Sed 162195340Sedstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 163198090Srdivacky if (EVT(VT).isInteger()) { 164198090Srdivacky unsigned BitWidth = EVT(VT).getSizeInBits(); 165198090Srdivacky OS << "IntegerType::get(Context, " << BitWidth << ")"; 166193323Sed } else if (VT == MVT::Other) { 167193323Sed // MVT::OtherVT is used to mean the empty struct type here. 168198090Srdivacky OS << "StructType::get(Context)"; 169193323Sed } else if (VT == MVT::f32) { 170198090Srdivacky OS << "Type::getFloatTy(Context)"; 171193323Sed } else if (VT == MVT::f64) { 172198090Srdivacky OS << "Type::getDoubleTy(Context)"; 173193323Sed } else if (VT == MVT::f80) { 174198090Srdivacky OS << "Type::getX86_FP80Ty(Context)"; 175193323Sed } else if (VT == MVT::f128) { 176198090Srdivacky OS << "Type::getFP128Ty(Context)"; 177193323Sed } else if (VT == MVT::ppcf128) { 178198090Srdivacky OS << "Type::getPPC_FP128Ty(Context)"; 179193323Sed } else if (VT == MVT::isVoid) { 180198090Srdivacky OS << "Type::getVoidTy(Context)"; 181198090Srdivacky } else if (VT == MVT::Metadata) { 182198090Srdivacky OS << "Type::getMetadataTy(Context)"; 183193323Sed } else { 184193323Sed assert(false && "Unsupported ValueType!"); 185193323Sed } 186193323Sed} 187193323Sed 188195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 189193323Sed unsigned &ArgNo); 190193323Sed 191195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, 192193323Sed const std::vector<Record*> &ArgTypes, 193193323Sed unsigned &ArgNo) { 194206083Srdivacky if (ArgTypes.empty()) 195206083Srdivacky return EmitTypeForValueType(OS, MVT::isVoid); 196206083Srdivacky 197206083Srdivacky if (ArgTypes.size() == 1) 198206083Srdivacky return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 199193323Sed 200198090Srdivacky OS << "StructType::get(Context, "; 201193323Sed 202193323Sed for (std::vector<Record*>::const_iterator 203193323Sed I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 204193323Sed EmitTypeGenerate(OS, *I, ArgNo); 205193323Sed OS << ", "; 206193323Sed } 207193323Sed 208193323Sed OS << " NULL)"; 209193323Sed} 210193323Sed 211195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 212193323Sed unsigned &ArgNo) { 213193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 214193323Sed 215193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 216193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 217193323Sed assert(Number < ArgNo && "Invalid matching number!"); 218193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 219193323Sed OS << "VectorType::getExtendedElementVectorType" 220193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 221193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 222193323Sed OS << "VectorType::getTruncatedElementVectorType" 223193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 224193323Sed else 225193323Sed OS << "Tys[" << Number << "]"; 226198090Srdivacky } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 227193323Sed // NOTE: The ArgNo variable here is not the absolute argument number, it is 228193323Sed // the index of the "arbitrary" type in the Tys array passed to the 229193323Sed // Intrinsic::getDeclaration function. Consequently, we only want to 230193323Sed // increment it when we actually hit an overloaded type. Getting this wrong 231193323Sed // leads to very subtle bugs! 232193323Sed OS << "Tys[" << ArgNo++ << "]"; 233198090Srdivacky } else if (EVT(VT).isVector()) { 234198090Srdivacky EVT VVT = VT; 235193323Sed OS << "VectorType::get("; 236198090Srdivacky EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 237193323Sed OS << ", " << VVT.getVectorNumElements() << ")"; 238193323Sed } else if (VT == MVT::iPTR) { 239193323Sed OS << "PointerType::getUnqual("; 240193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 241193323Sed OS << ")"; 242193323Sed } else if (VT == MVT::iPTRAny) { 243193323Sed // Make sure the user has passed us an argument type to overload. If not, 244193323Sed // treat it as an ordinary (not overloaded) intrinsic. 245193323Sed OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 246193323Sed << "] : PointerType::getUnqual("; 247193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 248193323Sed OS << ")"; 249193323Sed ++ArgNo; 250193323Sed } else if (VT == MVT::isVoid) { 251193323Sed if (ArgNo == 0) 252198090Srdivacky OS << "Type::getVoidTy(Context)"; 253193323Sed else 254193323Sed // MVT::isVoid is used to mean varargs here. 255193323Sed OS << "..."; 256193323Sed } else { 257193323Sed EmitTypeForValueType(OS, VT); 258193323Sed } 259193323Sed} 260193323Sed 261193323Sed/// RecordListComparator - Provide a deterministic comparator for lists of 262193323Sed/// records. 263193323Sednamespace { 264193323Sed typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 265193323Sed struct RecordListComparator { 266193323Sed bool operator()(const RecPair &LHS, 267193323Sed const RecPair &RHS) const { 268193323Sed unsigned i = 0; 269193323Sed const std::vector<Record*> *LHSVec = &LHS.first; 270193323Sed const std::vector<Record*> *RHSVec = &RHS.first; 271193323Sed unsigned RHSSize = RHSVec->size(); 272193323Sed unsigned LHSSize = LHSVec->size(); 273193323Sed 274206083Srdivacky for (; i != LHSSize; ++i) { 275193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 276193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 277193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 278206083Srdivacky } 279193323Sed 280193323Sed if (i != RHSSize) return true; 281193323Sed 282193323Sed i = 0; 283193323Sed LHSVec = &LHS.second; 284193323Sed RHSVec = &RHS.second; 285193323Sed RHSSize = RHSVec->size(); 286193323Sed LHSSize = LHSVec->size(); 287193323Sed 288193323Sed for (i = 0; i != LHSSize; ++i) { 289193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 290193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 291193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 292193323Sed } 293193323Sed 294193323Sed return i != RHSSize; 295193323Sed } 296193323Sed }; 297193323Sed} 298193323Sed 299193323Sedvoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 300195340Sed raw_ostream &OS) { 301193323Sed OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 302193323Sed OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 303193323Sed OS << " switch (ID) {\n"; 304193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 305193323Sed 306193323Sed // This checking can emit a lot of very common code. To reduce the amount of 307193323Sed // code that we emit, batch up cases that have identical types. This avoids 308193323Sed // problems where GCC can run out of memory compiling Verifier.cpp. 309193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 310193323Sed MapTy UniqueArgInfos; 311193323Sed 312193323Sed // Compute the unique argument type info. 313193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 314193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 315193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 316193323Sed 317193323Sed // Loop through the array, emitting one comparison for each batch. 318193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 319193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 320193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 321193323Sed OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 322193323Sed << Ints[I->second[i]].Name << "\n"; 323193323Sed 324193323Sed const RecPair &ArgTypes = I->first; 325193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 326193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 327198090Srdivacky std::vector<unsigned> OverloadedTypeIndices; 328193323Sed 329193323Sed OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 330193323Sed << ParamTys.size(); 331193323Sed 332193323Sed // Emit return types. 333193323Sed for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 334193323Sed Record *ArgType = RetTys[j]; 335193323Sed OS << ", "; 336193323Sed 337193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 338193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 339198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 340198090Srdivacky "Invalid matching number!"); 341198090Srdivacky Number = OverloadedTypeIndices[Number]; 342193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 343193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 344193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 345193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 346193323Sed else 347193323Sed OS << "~" << Number; 348193323Sed } else { 349193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 350193323Sed OS << getEnumName(VT); 351193323Sed 352198090Srdivacky if (EVT(VT).isOverloaded()) 353198090Srdivacky OverloadedTypeIndices.push_back(j); 354198090Srdivacky 355193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 356193323Sed throw "Var arg type not last argument"; 357193323Sed } 358193323Sed } 359193323Sed 360193323Sed // Emit the parameter types. 361193323Sed for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 362193323Sed Record *ArgType = ParamTys[j]; 363193323Sed OS << ", "; 364193323Sed 365193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 366193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 367198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 368198090Srdivacky "Invalid matching number!"); 369198090Srdivacky Number = OverloadedTypeIndices[Number]; 370193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 371193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 372193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 373193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 374193323Sed else 375193323Sed OS << "~" << Number; 376193323Sed } else { 377193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 378193323Sed OS << getEnumName(VT); 379193323Sed 380198090Srdivacky if (EVT(VT).isOverloaded()) 381198090Srdivacky OverloadedTypeIndices.push_back(j + RetTys.size()); 382198090Srdivacky 383193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 384193323Sed throw "Var arg type not last argument"; 385193323Sed } 386193323Sed } 387193323Sed 388193323Sed OS << ");\n"; 389193323Sed OS << " break;\n"; 390193323Sed } 391193323Sed OS << " }\n"; 392193323Sed OS << "#endif\n\n"; 393193323Sed} 394193323Sed 395193323Sedvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 396195340Sed raw_ostream &OS) { 397193323Sed OS << "// Code for generating Intrinsic function declarations.\n"; 398193323Sed OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 399193323Sed OS << " switch (id) {\n"; 400193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 401193323Sed 402193323Sed // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 403193323Sed // types. 404193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 405193323Sed MapTy UniqueArgInfos; 406193323Sed 407193323Sed // Compute the unique argument type info. 408193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 409193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 410193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 411193323Sed 412193323Sed // Loop through the array, emitting one generator for each batch. 413193323Sed std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 414193323Sed 415193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 416193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 417193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 418193323Sed OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 419193323Sed << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 420193323Sed 421193323Sed const RecPair &ArgTypes = I->first; 422193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 423193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 424193323Sed 425193323Sed unsigned N = ParamTys.size(); 426193323Sed 427193323Sed if (N > 1 && 428193323Sed getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 429193323Sed OS << " IsVarArg = true;\n"; 430193323Sed --N; 431193323Sed } 432193323Sed 433193323Sed unsigned ArgNo = 0; 434193323Sed OS << " ResultTy = "; 435193323Sed EmitTypeGenerate(OS, RetTys, ArgNo); 436193323Sed OS << ";\n"; 437193323Sed 438193323Sed for (unsigned j = 0; j != N; ++j) { 439193323Sed OS << " ArgTys.push_back("; 440193323Sed EmitTypeGenerate(OS, ParamTys[j], ArgNo); 441193323Sed OS << ");\n"; 442193323Sed } 443193323Sed 444193323Sed OS << " break;\n"; 445193323Sed } 446193323Sed 447193323Sed OS << " }\n"; 448193323Sed OS << "#endif\n\n"; 449193323Sed} 450193323Sed 451193323Sed/// EmitAttributes - This emits the Intrinsic::getAttributes method. 452193323Sedvoid IntrinsicEmitter:: 453195340SedEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 454193323Sed OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 455193323Sed OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 456193323Sed if (TargetOnly) 457193323Sed OS << "static AttrListPtr getAttributes(" << TargetPrefix 458193323Sed << "Intrinsic::ID id) {"; 459193323Sed else 460193323Sed OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 461193323Sed OS << " // No intrinsic can throw exceptions.\n"; 462193323Sed OS << " Attributes Attr = Attribute::NoUnwind;\n"; 463193323Sed OS << " switch (id) {\n"; 464193323Sed OS << " default: break;\n"; 465193323Sed unsigned MaxArgAttrs = 0; 466193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 467193323Sed MaxArgAttrs = 468193323Sed std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 469193323Sed switch (Ints[i].ModRef) { 470193323Sed default: break; 471193323Sed case CodeGenIntrinsic::NoMem: 472193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 473193323Sed << ":\n"; 474193323Sed break; 475193323Sed } 476193323Sed } 477193323Sed OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 478193323Sed OS << " break;\n"; 479193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 480193323Sed switch (Ints[i].ModRef) { 481193323Sed default: break; 482193323Sed case CodeGenIntrinsic::ReadArgMem: 483193323Sed case CodeGenIntrinsic::ReadMem: 484193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 485193323Sed << ":\n"; 486193323Sed break; 487193323Sed } 488193323Sed } 489193323Sed OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 490193323Sed OS << " break;\n"; 491193323Sed OS << " }\n"; 492193323Sed OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 493193323Sed OS << " unsigned NumAttrs = 0;\n"; 494193323Sed OS << " switch (id) {\n"; 495193323Sed OS << " default: break;\n"; 496193323Sed 497193323Sed // Add argument attributes for any intrinsics that have them. 498193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 499193323Sed if (Ints[i].ArgumentAttributes.empty()) continue; 500193323Sed 501193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 502193323Sed << ":\n"; 503193323Sed 504193323Sed std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 505193323Sed Ints[i].ArgumentAttributes; 506193323Sed // Sort by argument index. 507193323Sed std::sort(ArgAttrs.begin(), ArgAttrs.end()); 508193323Sed 509193323Sed unsigned NumArgsWithAttrs = 0; 510193323Sed 511193323Sed while (!ArgAttrs.empty()) { 512193323Sed unsigned ArgNo = ArgAttrs[0].first; 513193323Sed 514193323Sed OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 515193323Sed << ArgNo+1 << ", 0"; 516193323Sed 517193323Sed while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 518193323Sed switch (ArgAttrs[0].second) { 519193323Sed default: assert(0 && "Unknown arg attribute"); 520193323Sed case CodeGenIntrinsic::NoCapture: 521193323Sed OS << "|Attribute::NoCapture"; 522193323Sed break; 523193323Sed } 524193323Sed ArgAttrs.erase(ArgAttrs.begin()); 525193323Sed } 526193323Sed OS << ");\n"; 527193323Sed } 528193323Sed 529193323Sed OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 530193323Sed OS << " break;\n"; 531193323Sed } 532193323Sed 533193323Sed OS << " }\n"; 534193323Sed OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 535193323Sed OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 536193323Sed OS << "}\n"; 537193323Sed OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 538193323Sed} 539193323Sed 540193323Sed/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 541193323Sedvoid IntrinsicEmitter:: 542195340SedEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 543193323Sed OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 544193323Sed OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 545202375Srdivacky OS << "switch (iid) {\n"; 546193323Sed OS << "default:\n return UnknownModRefBehavior;\n"; 547193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 548193323Sed if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem) 549193323Sed continue; 550193323Sed OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 551193323Sed << ":\n"; 552193323Sed switch (Ints[i].ModRef) { 553193323Sed default: 554193323Sed assert(false && "Unknown Mod/Ref type!"); 555193323Sed case CodeGenIntrinsic::NoMem: 556193323Sed OS << " return DoesNotAccessMemory;\n"; 557193323Sed break; 558193323Sed case CodeGenIntrinsic::ReadArgMem: 559193323Sed case CodeGenIntrinsic::ReadMem: 560193323Sed OS << " return OnlyReadsMemory;\n"; 561193323Sed break; 562193323Sed case CodeGenIntrinsic::WriteArgMem: 563193323Sed OS << " return AccessesArguments;\n"; 564193323Sed break; 565193323Sed } 566193323Sed } 567193323Sed OS << "}\n"; 568193323Sed OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 569193323Sed} 570193323Sed 571193323Sedvoid IntrinsicEmitter:: 572195340SedEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 573193323Sed OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 574193323Sed OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 575193323Sed OS << " switch (F->getIntrinsicID()) {\n"; 576193323Sed OS << " default: BuiltinName = \"\"; break;\n"; 577193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 578193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 579193323Sed OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 580193323Sed << Ints[i].GCCBuiltinName << "\"; break;\n"; 581193323Sed } 582193323Sed } 583193323Sed OS << " }\n"; 584193323Sed OS << "#endif\n\n"; 585193323Sed} 586193323Sed 587193323Sed/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified 588193323Sed/// sorted range of builtin names is equal to the current builtin. This breaks 589193323Sed/// it down into a simple tree. 590193323Sed/// 591193323Sed/// At this point, we know that all the builtins in the range have the same name 592193323Sed/// for the first 'CharStart' characters. Only the end of the name needs to be 593193323Sed/// discriminated. 594193323Sedtypedef std::map<std::string, std::string>::const_iterator StrMapIterator; 595193323Sedstatic void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, 596193323Sed unsigned CharStart, unsigned Indent, 597195340Sed std::string TargetPrefix, raw_ostream &OS) { 598193323Sed if (Start == End) return; // empty range. 599193323Sed 600193323Sed // Determine what, if anything, is the same about all these strings. 601193323Sed std::string CommonString = Start->first; 602193323Sed unsigned NumInRange = 0; 603193323Sed for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { 604193323Sed // Find the first character that doesn't match. 605193323Sed const std::string &ThisStr = I->first; 606193323Sed unsigned NonMatchChar = CharStart; 607193323Sed while (NonMatchChar < CommonString.size() && 608193323Sed NonMatchChar < ThisStr.size() && 609193323Sed CommonString[NonMatchChar] == ThisStr[NonMatchChar]) 610193323Sed ++NonMatchChar; 611193323Sed // Truncate off pieces that don't match. 612193323Sed CommonString.resize(NonMatchChar); 613193323Sed } 614193323Sed 615193323Sed // Just compare the rest of the string. 616193323Sed if (NumInRange == 1) { 617193323Sed if (CharStart != CommonString.size()) { 618193323Sed OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 619193323Sed if (CharStart) OS << "+" << CharStart; 620193323Sed OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 621193323Sed OS << CommonString.size() - CharStart << "))\n"; 622193323Sed ++Indent; 623193323Sed } 624193323Sed OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix 625193323Sed << "Intrinsic::"; 626193323Sed OS << Start->second << ";\n"; 627193323Sed return; 628193323Sed } 629193323Sed 630193323Sed // At this point, we potentially have a common prefix for these builtins, emit 631193323Sed // a check for this common prefix. 632193323Sed if (CommonString.size() != CharStart) { 633193323Sed OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 634193323Sed if (CharStart) OS << "+" << CharStart; 635193323Sed OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 636193323Sed OS << CommonString.size()-CharStart << ")) {\n"; 637193323Sed 638193323Sed EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 639193323Sed TargetPrefix, OS); 640193323Sed OS << std::string(Indent*2, ' ') << "}\n"; 641193323Sed return; 642193323Sed } 643193323Sed 644193323Sed // Output a switch on the character that differs across the set. 645193323Sed OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart 646193323Sed << "]) {"; 647193323Sed if (CharStart) 648193323Sed OS << " // \"" << std::string(Start->first.begin(), 649193323Sed Start->first.begin()+CharStart) << "\""; 650193323Sed OS << "\n"; 651193323Sed 652193323Sed for (StrMapIterator I = Start; I != End; ) { 653193323Sed char ThisChar = I->first[CharStart]; 654193323Sed OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; 655193323Sed // Figure out the range that has this common character. 656193323Sed StrMapIterator NextChar = I; 657193323Sed for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; 658193323Sed ++NextChar) 659193323Sed /*empty*/; 660193323Sed EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); 661193323Sed OS << std::string(Indent*2, ' ') << " break;\n"; 662193323Sed I = NextChar; 663193323Sed } 664193323Sed OS << std::string(Indent*2, ' ') << "}\n"; 665193323Sed} 666193323Sed 667193323Sed/// EmitTargetBuiltins - All of the builtins in the specified map are for the 668193323Sed/// same target, and we already checked it. 669193323Sedstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 670193323Sed const std::string &TargetPrefix, 671195340Sed raw_ostream &OS) { 672193323Sed // Rearrange the builtins by length. 673193323Sed std::vector<std::map<std::string, std::string> > BuiltinsByLen; 674193323Sed BuiltinsByLen.reserve(100); 675193323Sed 676193323Sed for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { 677193323Sed if (I->first.size() >= BuiltinsByLen.size()) 678193323Sed BuiltinsByLen.resize(I->first.size()+1); 679193323Sed BuiltinsByLen[I->first.size()].insert(*I); 680193323Sed } 681193323Sed 682193323Sed // Now that we have all the builtins by their length, emit a switch stmt. 683193323Sed OS << " switch (strlen(BuiltinName)) {\n"; 684193323Sed OS << " default: break;\n"; 685193323Sed for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { 686193323Sed if (BuiltinsByLen[i].empty()) continue; 687193323Sed OS << " case " << i << ":\n"; 688193323Sed EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), 689193323Sed 0, 3, TargetPrefix, OS); 690193323Sed OS << " break;\n"; 691193323Sed } 692193323Sed OS << " }\n"; 693193323Sed} 694193323Sed 695193323Sed 696193323Sedvoid IntrinsicEmitter:: 697193323SedEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 698195340Sed raw_ostream &OS) { 699193323Sed typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 700193323Sed BIMTy BuiltinMap; 701193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 702193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 703193323Sed // Get the map for this target prefix. 704193323Sed std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 705193323Sed 706193323Sed if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 707193323Sed Ints[i].EnumName)).second) 708193323Sed throw "Intrinsic '" + Ints[i].TheDef->getName() + 709193323Sed "': duplicate GCC builtin name!"; 710193323Sed } 711193323Sed } 712193323Sed 713193323Sed OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 714193323Sed OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 715193323Sed OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 716193323Sed OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 717193323Sed OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 718193323Sed 719193323Sed if (TargetOnly) { 720193323Sed OS << "static " << TargetPrefix << "Intrinsic::ID " 721193323Sed << "getIntrinsicForGCCBuiltin(const char " 722193323Sed << "*TargetPrefix, const char *BuiltinName) {\n"; 723193323Sed OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; 724193323Sed } else { 725193323Sed OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 726193323Sed << "*TargetPrefix, const char *BuiltinName) {\n"; 727193323Sed OS << " Intrinsic::ID IntrinsicID = "; 728193323Sed } 729193323Sed 730193323Sed if (TargetOnly) 731193323Sed OS << "(" << TargetPrefix<< "Intrinsic::ID)"; 732193323Sed 733193323Sed OS << "Intrinsic::not_intrinsic;\n"; 734193323Sed 735193323Sed // Note: this could emit significantly better code if we cared. 736193323Sed for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 737193323Sed OS << " "; 738193323Sed if (!I->first.empty()) 739193323Sed OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; 740193323Sed else 741193323Sed OS << "/* Target Independent Builtins */ "; 742193323Sed OS << "{\n"; 743193323Sed 744193323Sed // Emit the comparisons for this target prefix. 745193323Sed EmitTargetBuiltins(I->second, TargetPrefix, OS); 746193323Sed OS << " }\n"; 747193323Sed } 748193323Sed OS << " return IntrinsicID;\n"; 749193323Sed OS << "}\n"; 750193323Sed OS << "#endif\n\n"; 751193323Sed} 752