IntrinsicEmitter.cpp revision 218893
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" 17218893Sdim#include "StringMatcher.h" 18193323Sed#include "llvm/ADT/StringExtras.h" 19193323Sed#include <algorithm> 20193323Sedusing namespace llvm; 21193323Sed 22193323Sed//===----------------------------------------------------------------------===// 23193323Sed// IntrinsicEmitter Implementation 24193323Sed//===----------------------------------------------------------------------===// 25193323Sed 26195340Sedvoid IntrinsicEmitter::run(raw_ostream &OS) { 27193323Sed EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); 28193323Sed 29193323Sed std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); 30193323Sed 31193323Sed if (TargetOnly && !Ints.empty()) 32193323Sed TargetPrefix = Ints[0].TargetPrefix; 33193323Sed 34208599Srdivacky EmitPrefix(OS); 35208599Srdivacky 36193323Sed // Emit the enum information. 37193323Sed EmitEnumInfo(Ints, OS); 38193323Sed 39193323Sed // Emit the intrinsic ID -> name table. 40193323Sed EmitIntrinsicToNameTable(Ints, OS); 41193323Sed 42193323Sed // Emit the intrinsic ID -> overload table. 43193323Sed EmitIntrinsicToOverloadTable(Ints, OS); 44193323Sed 45193323Sed // Emit the function name recognizer. 46193323Sed EmitFnNameRecognizer(Ints, OS); 47193323Sed 48193323Sed // Emit the intrinsic verifier. 49193323Sed EmitVerifier(Ints, OS); 50193323Sed 51193323Sed // Emit the intrinsic declaration generator. 52193323Sed EmitGenerator(Ints, OS); 53193323Sed 54193323Sed // Emit the intrinsic parameter attributes. 55193323Sed EmitAttributes(Ints, OS); 56193323Sed 57193323Sed // Emit intrinsic alias analysis mod/ref behavior. 58193323Sed EmitModRefBehavior(Ints, OS); 59193323Sed 60193323Sed // Emit a list of intrinsics with corresponding GCC builtins. 61193323Sed EmitGCCBuiltinList(Ints, OS); 62193323Sed 63193323Sed // Emit code to translate GCC builtins into LLVM intrinsics. 64193323Sed EmitIntrinsicToGCCBuiltinMap(Ints, OS); 65208599Srdivacky 66208599Srdivacky EmitSuffix(OS); 67193323Sed} 68193323Sed 69208599Srdivackyvoid IntrinsicEmitter::EmitPrefix(raw_ostream &OS) { 70208599Srdivacky OS << "// VisualStudio defines setjmp as _setjmp\n" 71218893Sdim "#if defined(_MSC_VER) && defined(setjmp) && \\\n" 72218893Sdim " !defined(setjmp_undefined_for_msvc)\n" 73218893Sdim "# pragma push_macro(\"setjmp\")\n" 74218893Sdim "# undef setjmp\n" 75218893Sdim "# define setjmp_undefined_for_msvc\n" 76208599Srdivacky "#endif\n\n"; 77208599Srdivacky} 78208599Srdivacky 79208599Srdivackyvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { 80218893Sdim OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n" 81208599Srdivacky "// let's return it to _setjmp state\n" 82218893Sdim "# pragma pop_macro(\"setjmp\")\n" 83218893Sdim "# undef setjmp_undefined_for_msvc\n" 84208599Srdivacky "#endif\n\n"; 85208599Srdivacky} 86208599Srdivacky 87193323Sedvoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 88195340Sed raw_ostream &OS) { 89193323Sed OS << "// Enum values for Intrinsics.h\n"; 90193323Sed OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 91193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 92193323Sed OS << " " << Ints[i].EnumName; 93193323Sed OS << ((i != e-1) ? ", " : " "); 94193323Sed OS << std::string(40-Ints[i].EnumName.size(), ' ') 95193323Sed << "// " << Ints[i].Name << "\n"; 96193323Sed } 97193323Sed OS << "#endif\n\n"; 98193323Sed} 99193323Sed 100193323Sedvoid IntrinsicEmitter:: 101193323SedEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 102195340Sed raw_ostream &OS) { 103218893Sdim // Build a 'first character of function name' -> intrinsic # mapping. 104218893Sdim std::map<char, std::vector<unsigned> > IntMapping; 105193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 106218893Sdim IntMapping[Ints[i].Name[5]].push_back(i); 107218893Sdim 108193323Sed OS << "// Function name -> enum value recognizer code.\n"; 109193323Sed OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 110218893Sdim OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n"; 111218893Sdim OS << " switch (Name[5]) { // Dispatch on first letter.\n"; 112218893Sdim OS << " default: break;\n"; 113218893Sdim // Emit the intrinsic matching stuff by first letter. 114218893Sdim for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(), 115193323Sed E = IntMapping.end(); I != E; ++I) { 116218893Sdim OS << " case '" << I->first << "':\n"; 117218893Sdim std::vector<unsigned> &IntList = I->second; 118218893Sdim 119218893Sdim // Emit all the overloaded intrinsics first, build a table of the 120218893Sdim // non-overloaded ones. 121218893Sdim std::vector<StringMatcher::StringPair> MatchTable; 122218893Sdim 123218893Sdim for (unsigned i = 0, e = IntList.size(); i != e; ++i) { 124218893Sdim unsigned IntNo = IntList[i]; 125218893Sdim std::string Result = "return " + TargetPrefix + "Intrinsic::" + 126218893Sdim Ints[IntNo].EnumName + ";"; 127218893Sdim 128218893Sdim if (!Ints[IntNo].isOverloaded) { 129218893Sdim MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result)); 130218893Sdim continue; 131218893Sdim } 132218893Sdim 133218893Sdim // For overloaded intrinsics, only the prefix needs to match 134218893Sdim std::string TheStr = Ints[IntNo].Name.substr(6); 135218893Sdim TheStr += '.'; // Require "bswap." instead of bswap. 136218893Sdim OS << " if (NameR.startswith(\"" << TheStr << "\")) " 137218893Sdim << Result << '\n'; 138193323Sed } 139193323Sed 140218893Sdim // Emit the matcher logic for the fixed length strings. 141218893Sdim StringMatcher("NameR", MatchTable, OS).Emit(1); 142218893Sdim OS << " break; // end of '" << I->first << "' case.\n"; 143193323Sed } 144218893Sdim 145193323Sed OS << " }\n"; 146193323Sed OS << "#endif\n\n"; 147193323Sed} 148193323Sed 149193323Sedvoid IntrinsicEmitter:: 150193323SedEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 151195340Sed raw_ostream &OS) { 152193323Sed OS << "// Intrinsic ID to name table\n"; 153193323Sed OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 154193323Sed OS << " // Note that entry #0 is the invalid intrinsic!\n"; 155193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 156193323Sed OS << " \"" << Ints[i].Name << "\",\n"; 157193323Sed OS << "#endif\n\n"; 158193323Sed} 159193323Sed 160193323Sedvoid IntrinsicEmitter:: 161193323SedEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 162195340Sed raw_ostream &OS) { 163193323Sed OS << "// Intrinsic ID to overload table\n"; 164193323Sed OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 165193323Sed OS << " // Note that entry #0 is the invalid intrinsic!\n"; 166193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 167193323Sed OS << " "; 168193323Sed if (Ints[i].isOverloaded) 169193323Sed OS << "true"; 170193323Sed else 171193323Sed OS << "false"; 172193323Sed OS << ",\n"; 173193323Sed } 174193323Sed OS << "#endif\n\n"; 175193323Sed} 176193323Sed 177195340Sedstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 178198090Srdivacky if (EVT(VT).isInteger()) { 179198090Srdivacky unsigned BitWidth = EVT(VT).getSizeInBits(); 180198090Srdivacky OS << "IntegerType::get(Context, " << BitWidth << ")"; 181193323Sed } else if (VT == MVT::Other) { 182193323Sed // MVT::OtherVT is used to mean the empty struct type here. 183198090Srdivacky OS << "StructType::get(Context)"; 184193323Sed } else if (VT == MVT::f32) { 185198090Srdivacky OS << "Type::getFloatTy(Context)"; 186193323Sed } else if (VT == MVT::f64) { 187198090Srdivacky OS << "Type::getDoubleTy(Context)"; 188193323Sed } else if (VT == MVT::f80) { 189198090Srdivacky OS << "Type::getX86_FP80Ty(Context)"; 190193323Sed } else if (VT == MVT::f128) { 191198090Srdivacky OS << "Type::getFP128Ty(Context)"; 192193323Sed } else if (VT == MVT::ppcf128) { 193198090Srdivacky OS << "Type::getPPC_FP128Ty(Context)"; 194193323Sed } else if (VT == MVT::isVoid) { 195198090Srdivacky OS << "Type::getVoidTy(Context)"; 196198090Srdivacky } else if (VT == MVT::Metadata) { 197198090Srdivacky OS << "Type::getMetadataTy(Context)"; 198218893Sdim } else if (VT == MVT::x86mmx) { 199218893Sdim OS << "Type::getX86_MMXTy(Context)"; 200193323Sed } else { 201193323Sed assert(false && "Unsupported ValueType!"); 202193323Sed } 203193323Sed} 204193323Sed 205195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 206193323Sed unsigned &ArgNo); 207193323Sed 208195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, 209193323Sed const std::vector<Record*> &ArgTypes, 210193323Sed unsigned &ArgNo) { 211206083Srdivacky if (ArgTypes.empty()) 212206083Srdivacky return EmitTypeForValueType(OS, MVT::isVoid); 213206083Srdivacky 214206083Srdivacky if (ArgTypes.size() == 1) 215206083Srdivacky return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 216193323Sed 217198090Srdivacky OS << "StructType::get(Context, "; 218193323Sed 219193323Sed for (std::vector<Record*>::const_iterator 220193323Sed I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 221193323Sed EmitTypeGenerate(OS, *I, ArgNo); 222193323Sed OS << ", "; 223193323Sed } 224193323Sed 225193323Sed OS << " NULL)"; 226193323Sed} 227193323Sed 228195340Sedstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 229193323Sed unsigned &ArgNo) { 230193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 231193323Sed 232193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 233193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 234193323Sed assert(Number < ArgNo && "Invalid matching number!"); 235193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 236193323Sed OS << "VectorType::getExtendedElementVectorType" 237193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 238193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 239193323Sed OS << "VectorType::getTruncatedElementVectorType" 240193323Sed << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 241193323Sed else 242193323Sed OS << "Tys[" << Number << "]"; 243198090Srdivacky } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 244193323Sed // NOTE: The ArgNo variable here is not the absolute argument number, it is 245193323Sed // the index of the "arbitrary" type in the Tys array passed to the 246193323Sed // Intrinsic::getDeclaration function. Consequently, we only want to 247193323Sed // increment it when we actually hit an overloaded type. Getting this wrong 248193323Sed // leads to very subtle bugs! 249193323Sed OS << "Tys[" << ArgNo++ << "]"; 250198090Srdivacky } else if (EVT(VT).isVector()) { 251198090Srdivacky EVT VVT = VT; 252193323Sed OS << "VectorType::get("; 253198090Srdivacky EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 254193323Sed OS << ", " << VVT.getVectorNumElements() << ")"; 255193323Sed } else if (VT == MVT::iPTR) { 256193323Sed OS << "PointerType::getUnqual("; 257193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 258193323Sed OS << ")"; 259193323Sed } else if (VT == MVT::iPTRAny) { 260193323Sed // Make sure the user has passed us an argument type to overload. If not, 261193323Sed // treat it as an ordinary (not overloaded) intrinsic. 262193323Sed OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 263193323Sed << "] : PointerType::getUnqual("; 264193323Sed EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 265193323Sed OS << ")"; 266193323Sed ++ArgNo; 267193323Sed } else if (VT == MVT::isVoid) { 268193323Sed if (ArgNo == 0) 269198090Srdivacky OS << "Type::getVoidTy(Context)"; 270193323Sed else 271193323Sed // MVT::isVoid is used to mean varargs here. 272193323Sed OS << "..."; 273193323Sed } else { 274193323Sed EmitTypeForValueType(OS, VT); 275193323Sed } 276193323Sed} 277193323Sed 278193323Sed/// RecordListComparator - Provide a deterministic comparator for lists of 279193323Sed/// records. 280193323Sednamespace { 281193323Sed typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 282193323Sed struct RecordListComparator { 283193323Sed bool operator()(const RecPair &LHS, 284193323Sed const RecPair &RHS) const { 285193323Sed unsigned i = 0; 286193323Sed const std::vector<Record*> *LHSVec = &LHS.first; 287193323Sed const std::vector<Record*> *RHSVec = &RHS.first; 288193323Sed unsigned RHSSize = RHSVec->size(); 289193323Sed unsigned LHSSize = LHSVec->size(); 290193323Sed 291206083Srdivacky for (; i != LHSSize; ++i) { 292193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 293193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 294193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 295206083Srdivacky } 296193323Sed 297193323Sed if (i != RHSSize) return true; 298193323Sed 299193323Sed i = 0; 300193323Sed LHSVec = &LHS.second; 301193323Sed RHSVec = &RHS.second; 302193323Sed RHSSize = RHSVec->size(); 303193323Sed LHSSize = LHSVec->size(); 304193323Sed 305193323Sed for (i = 0; i != LHSSize; ++i) { 306193323Sed if (i == RHSSize) return false; // RHS is shorter than LHS. 307193323Sed if ((*LHSVec)[i] != (*RHSVec)[i]) 308193323Sed return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 309193323Sed } 310193323Sed 311193323Sed return i != RHSSize; 312193323Sed } 313193323Sed }; 314193323Sed} 315193323Sed 316193323Sedvoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 317195340Sed raw_ostream &OS) { 318193323Sed OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 319193323Sed OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 320193323Sed OS << " switch (ID) {\n"; 321193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 322193323Sed 323193323Sed // This checking can emit a lot of very common code. To reduce the amount of 324193323Sed // code that we emit, batch up cases that have identical types. This avoids 325193323Sed // problems where GCC can run out of memory compiling Verifier.cpp. 326193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 327193323Sed MapTy UniqueArgInfos; 328193323Sed 329193323Sed // Compute the unique argument type info. 330193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 331193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 332193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 333193323Sed 334193323Sed // Loop through the array, emitting one comparison for each batch. 335193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 336193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 337193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 338193323Sed OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 339193323Sed << Ints[I->second[i]].Name << "\n"; 340193323Sed 341193323Sed const RecPair &ArgTypes = I->first; 342193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 343193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 344198090Srdivacky std::vector<unsigned> OverloadedTypeIndices; 345193323Sed 346193323Sed OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 347193323Sed << ParamTys.size(); 348193323Sed 349193323Sed // Emit return types. 350193323Sed for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 351193323Sed Record *ArgType = RetTys[j]; 352193323Sed OS << ", "; 353193323Sed 354193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 355193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 356198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 357198090Srdivacky "Invalid matching number!"); 358198090Srdivacky Number = OverloadedTypeIndices[Number]; 359193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 360193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 361193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 362193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 363193323Sed else 364193323Sed OS << "~" << Number; 365193323Sed } else { 366193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 367193323Sed OS << getEnumName(VT); 368193323Sed 369198090Srdivacky if (EVT(VT).isOverloaded()) 370198090Srdivacky OverloadedTypeIndices.push_back(j); 371198090Srdivacky 372193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 373193323Sed throw "Var arg type not last argument"; 374193323Sed } 375193323Sed } 376193323Sed 377193323Sed // Emit the parameter types. 378193323Sed for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 379193323Sed Record *ArgType = ParamTys[j]; 380193323Sed OS << ", "; 381193323Sed 382193323Sed if (ArgType->isSubClassOf("LLVMMatchType")) { 383193323Sed unsigned Number = ArgType->getValueAsInt("Number"); 384198090Srdivacky assert(Number < OverloadedTypeIndices.size() && 385198090Srdivacky "Invalid matching number!"); 386198090Srdivacky Number = OverloadedTypeIndices[Number]; 387193323Sed if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 388193323Sed OS << "~(ExtendedElementVectorType | " << Number << ")"; 389193323Sed else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 390193323Sed OS << "~(TruncatedElementVectorType | " << Number << ")"; 391193323Sed else 392193323Sed OS << "~" << Number; 393193323Sed } else { 394193323Sed MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 395193323Sed OS << getEnumName(VT); 396193323Sed 397198090Srdivacky if (EVT(VT).isOverloaded()) 398198090Srdivacky OverloadedTypeIndices.push_back(j + RetTys.size()); 399198090Srdivacky 400193323Sed if (VT == MVT::isVoid && j != 0 && j != je - 1) 401193323Sed throw "Var arg type not last argument"; 402193323Sed } 403193323Sed } 404193323Sed 405193323Sed OS << ");\n"; 406193323Sed OS << " break;\n"; 407193323Sed } 408193323Sed OS << " }\n"; 409193323Sed OS << "#endif\n\n"; 410193323Sed} 411193323Sed 412193323Sedvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 413195340Sed raw_ostream &OS) { 414193323Sed OS << "// Code for generating Intrinsic function declarations.\n"; 415193323Sed OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 416193323Sed OS << " switch (id) {\n"; 417193323Sed OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 418193323Sed 419193323Sed // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 420193323Sed // types. 421193323Sed typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 422193323Sed MapTy UniqueArgInfos; 423193323Sed 424193323Sed // Compute the unique argument type info. 425193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) 426193323Sed UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 427193323Sed Ints[i].IS.ParamTypeDefs)].push_back(i); 428193323Sed 429193323Sed // Loop through the array, emitting one generator for each batch. 430193323Sed std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 431193323Sed 432193323Sed for (MapTy::iterator I = UniqueArgInfos.begin(), 433193323Sed E = UniqueArgInfos.end(); I != E; ++I) { 434193323Sed for (unsigned i = 0, e = I->second.size(); i != e; ++i) 435193323Sed OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 436193323Sed << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 437193323Sed 438193323Sed const RecPair &ArgTypes = I->first; 439193323Sed const std::vector<Record*> &RetTys = ArgTypes.first; 440193323Sed const std::vector<Record*> &ParamTys = ArgTypes.second; 441193323Sed 442193323Sed unsigned N = ParamTys.size(); 443193323Sed 444193323Sed if (N > 1 && 445193323Sed getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 446193323Sed OS << " IsVarArg = true;\n"; 447193323Sed --N; 448193323Sed } 449193323Sed 450193323Sed unsigned ArgNo = 0; 451193323Sed OS << " ResultTy = "; 452193323Sed EmitTypeGenerate(OS, RetTys, ArgNo); 453193323Sed OS << ";\n"; 454193323Sed 455193323Sed for (unsigned j = 0; j != N; ++j) { 456193323Sed OS << " ArgTys.push_back("; 457193323Sed EmitTypeGenerate(OS, ParamTys[j], ArgNo); 458193323Sed OS << ");\n"; 459193323Sed } 460193323Sed 461193323Sed OS << " break;\n"; 462193323Sed } 463193323Sed 464193323Sed OS << " }\n"; 465193323Sed OS << "#endif\n\n"; 466193323Sed} 467193323Sed 468193323Sed/// EmitAttributes - This emits the Intrinsic::getAttributes method. 469193323Sedvoid IntrinsicEmitter:: 470195340SedEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 471193323Sed OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 472193323Sed OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 473193323Sed if (TargetOnly) 474193323Sed OS << "static AttrListPtr getAttributes(" << TargetPrefix 475193323Sed << "Intrinsic::ID id) {"; 476193323Sed else 477193323Sed OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 478193323Sed OS << " // No intrinsic can throw exceptions.\n"; 479193323Sed OS << " Attributes Attr = Attribute::NoUnwind;\n"; 480193323Sed OS << " switch (id) {\n"; 481193323Sed OS << " default: break;\n"; 482193323Sed unsigned MaxArgAttrs = 0; 483193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 484193323Sed MaxArgAttrs = 485193323Sed std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 486193323Sed switch (Ints[i].ModRef) { 487193323Sed default: break; 488193323Sed case CodeGenIntrinsic::NoMem: 489193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 490193323Sed << ":\n"; 491193323Sed break; 492193323Sed } 493193323Sed } 494193323Sed OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 495193323Sed OS << " break;\n"; 496193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 497193323Sed switch (Ints[i].ModRef) { 498193323Sed default: break; 499193323Sed case CodeGenIntrinsic::ReadArgMem: 500193323Sed case CodeGenIntrinsic::ReadMem: 501193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 502193323Sed << ":\n"; 503193323Sed break; 504193323Sed } 505193323Sed } 506193323Sed OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 507193323Sed OS << " break;\n"; 508193323Sed OS << " }\n"; 509193323Sed OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 510193323Sed OS << " unsigned NumAttrs = 0;\n"; 511193323Sed OS << " switch (id) {\n"; 512193323Sed OS << " default: break;\n"; 513193323Sed 514193323Sed // Add argument attributes for any intrinsics that have them. 515193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 516193323Sed if (Ints[i].ArgumentAttributes.empty()) continue; 517193323Sed 518193323Sed OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 519193323Sed << ":\n"; 520193323Sed 521193323Sed std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 522193323Sed Ints[i].ArgumentAttributes; 523193323Sed // Sort by argument index. 524193323Sed std::sort(ArgAttrs.begin(), ArgAttrs.end()); 525193323Sed 526193323Sed unsigned NumArgsWithAttrs = 0; 527193323Sed 528193323Sed while (!ArgAttrs.empty()) { 529193323Sed unsigned ArgNo = ArgAttrs[0].first; 530193323Sed 531193323Sed OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 532193323Sed << ArgNo+1 << ", 0"; 533193323Sed 534193323Sed while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 535193323Sed switch (ArgAttrs[0].second) { 536193323Sed default: assert(0 && "Unknown arg attribute"); 537193323Sed case CodeGenIntrinsic::NoCapture: 538193323Sed OS << "|Attribute::NoCapture"; 539193323Sed break; 540193323Sed } 541193323Sed ArgAttrs.erase(ArgAttrs.begin()); 542193323Sed } 543193323Sed OS << ");\n"; 544193323Sed } 545193323Sed 546193323Sed OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 547193323Sed OS << " break;\n"; 548193323Sed } 549193323Sed 550193323Sed OS << " }\n"; 551193323Sed OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 552193323Sed OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 553193323Sed OS << "}\n"; 554193323Sed OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 555193323Sed} 556193323Sed 557193323Sed/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 558193323Sedvoid IntrinsicEmitter:: 559195340SedEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 560193323Sed OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 561193323Sed OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 562202375Srdivacky OS << "switch (iid) {\n"; 563193323Sed OS << "default:\n return UnknownModRefBehavior;\n"; 564193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 565212904Sdim if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem) 566193323Sed continue; 567193323Sed OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 568193323Sed << ":\n"; 569193323Sed switch (Ints[i].ModRef) { 570193323Sed default: 571193323Sed assert(false && "Unknown Mod/Ref type!"); 572193323Sed case CodeGenIntrinsic::NoMem: 573193323Sed OS << " return DoesNotAccessMemory;\n"; 574193323Sed break; 575193323Sed case CodeGenIntrinsic::ReadArgMem: 576218893Sdim OS << " return OnlyReadsArgumentPointees;\n"; 577218893Sdim break; 578193323Sed case CodeGenIntrinsic::ReadMem: 579193323Sed OS << " return OnlyReadsMemory;\n"; 580193323Sed break; 581212904Sdim case CodeGenIntrinsic::ReadWriteArgMem: 582218893Sdim OS << " return OnlyAccessesArgumentPointees;\n"; 583193323Sed break; 584193323Sed } 585193323Sed } 586193323Sed OS << "}\n"; 587193323Sed OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 588193323Sed} 589193323Sed 590193323Sedvoid IntrinsicEmitter:: 591195340SedEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 592193323Sed OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 593193323Sed OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 594193323Sed OS << " switch (F->getIntrinsicID()) {\n"; 595193323Sed OS << " default: BuiltinName = \"\"; break;\n"; 596193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 597193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 598193323Sed OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 599193323Sed << Ints[i].GCCBuiltinName << "\"; break;\n"; 600193323Sed } 601193323Sed } 602193323Sed OS << " }\n"; 603193323Sed OS << "#endif\n\n"; 604193323Sed} 605193323Sed 606193323Sed/// EmitTargetBuiltins - All of the builtins in the specified map are for the 607193323Sed/// same target, and we already checked it. 608193323Sedstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 609193323Sed const std::string &TargetPrefix, 610195340Sed raw_ostream &OS) { 611193323Sed 612218893Sdim std::vector<StringMatcher::StringPair> Results; 613193323Sed 614218893Sdim for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), 615218893Sdim E = BIM.end(); I != E; ++I) { 616218893Sdim std::string ResultCode = 617218893Sdim "return " + TargetPrefix + "Intrinsic::" + I->second + ";"; 618218893Sdim Results.push_back(StringMatcher::StringPair(I->first, ResultCode)); 619193323Sed } 620218893Sdim 621218893Sdim StringMatcher("BuiltinName", Results, OS).Emit(); 622193323Sed} 623193323Sed 624193323Sed 625193323Sedvoid IntrinsicEmitter:: 626193323SedEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 627195340Sed raw_ostream &OS) { 628193323Sed typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 629193323Sed BIMTy BuiltinMap; 630193323Sed for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 631193323Sed if (!Ints[i].GCCBuiltinName.empty()) { 632193323Sed // Get the map for this target prefix. 633193323Sed std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 634193323Sed 635193323Sed if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 636193323Sed Ints[i].EnumName)).second) 637193323Sed throw "Intrinsic '" + Ints[i].TheDef->getName() + 638193323Sed "': duplicate GCC builtin name!"; 639193323Sed } 640193323Sed } 641193323Sed 642193323Sed OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 643193323Sed OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 644193323Sed OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 645193323Sed OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 646193323Sed OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 647193323Sed 648193323Sed if (TargetOnly) { 649193323Sed OS << "static " << TargetPrefix << "Intrinsic::ID " 650193323Sed << "getIntrinsicForGCCBuiltin(const char " 651218893Sdim << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 652193323Sed } else { 653193323Sed OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 654218893Sdim << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 655193323Sed } 656193323Sed 657218893Sdim OS << " StringRef BuiltinName(BuiltinNameStr);\n"; 658218893Sdim OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; 659193323Sed 660193323Sed // Note: this could emit significantly better code if we cared. 661193323Sed for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 662193323Sed OS << " "; 663193323Sed if (!I->first.empty()) 664218893Sdim OS << "if (TargetPrefix == \"" << I->first << "\") "; 665193323Sed else 666193323Sed OS << "/* Target Independent Builtins */ "; 667193323Sed OS << "{\n"; 668193323Sed 669193323Sed // Emit the comparisons for this target prefix. 670193323Sed EmitTargetBuiltins(I->second, TargetPrefix, OS); 671193323Sed OS << " }\n"; 672193323Sed } 673218893Sdim OS << " return "; 674218893Sdim if (!TargetPrefix.empty()) 675218893Sdim OS << "(" << TargetPrefix << "Intrinsic::ID)"; 676218893Sdim OS << "Intrinsic::not_intrinsic;\n"; 677193323Sed OS << "}\n"; 678193323Sed OS << "#endif\n\n"; 679193323Sed} 680