19e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===- IntrinsicEmitter.cpp - Generate intrinsic information --------------===// 29e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// 39e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// The LLVM Compiler Infrastructure 49e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// 53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source 63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details. 79e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// 89e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===// 99e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// 109e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// This tablegen backend emits information about intrinsic functions. 119e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// 129e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===// 139e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "CodeGenTarget.h" 159e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner#include "IntrinsicEmitter.h" 16298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner#include "StringMatcher.h" 177c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h" 1818faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner#include "llvm/ADT/StringExtras.h" 1971c3bc3d966bd874f760abf055c559673f925029Jeff Cohen#include <algorithm> 209e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnerusing namespace llvm; 219e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 229e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===// 239e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// IntrinsicEmitter Implementation 249e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===// 259e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 261a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid IntrinsicEmitter::run(raw_ostream &OS) { 279e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); 289e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 2949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); 3049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 3149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly && !Ints.empty()) 3249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen TargetPrefix = Ints[0].TargetPrefix; 339e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 347d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor EmitPrefix(OS); 357d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 369e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner // Emit the enum information. 379e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner EmitEnumInfo(Ints, OS); 38fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 39fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner // Emit the intrinsic ID -> name table. 40fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner EmitIntrinsicToNameTable(Ints, OS); 410d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 420d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang // Emit the intrinsic ID -> overload table. 430d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang EmitIntrinsicToOverloadTable(Ints, OS); 440d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 459b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner // Emit the function name recognizer. 469b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner EmitFnNameRecognizer(Ints, OS); 47fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 48f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner // Emit the intrinsic verifier. 49f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner EmitVerifier(Ints, OS); 506448ee44c6f232f215d5d9f145a0d71a983c4a3fChris Lattner 5195af592a631f403e1458ec1155f89fc31011572cJim Laskey // Emit the intrinsic declaration generator. 5295af592a631f403e1458ec1155f89fc31011572cJim Laskey EmitGenerator(Ints, OS); 5395af592a631f403e1458ec1155f89fc31011572cJim Laskey 54a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands // Emit the intrinsic parameter attributes. 55a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands EmitAttributes(Ints, OS); 56022f64fbbc4669623e79b805379266fed519017dChris Lattner 57d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands // Emit intrinsic alias analysis mod/ref behavior. 58d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands EmitModRefBehavior(Ints, OS); 59d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 603f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Emit code to translate GCC builtins into LLVM intrinsics. 613f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner EmitIntrinsicToGCCBuiltinMap(Ints, OS); 627d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 637d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor EmitSuffix(OS); 647d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor} 657d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 667d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregorvoid IntrinsicEmitter::EmitPrefix(raw_ostream &OS) { 677d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor OS << "// VisualStudio defines setjmp as _setjmp\n" 681f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer "#if defined(_MSC_VER) && defined(setjmp) && \\\n" 691f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer " !defined(setjmp_undefined_for_msvc)\n" 7008047f616977f204df6054c481601f2237cc308dMichael J. Spencer "# pragma push_macro(\"setjmp\")\n" 7108047f616977f204df6054c481601f2237cc308dMichael J. Spencer "# undef setjmp\n" 721f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer "# define setjmp_undefined_for_msvc\n" 737d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#endif\n\n"; 747d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor} 757d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 767d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregorvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { 771f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n" 787d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "// let's return it to _setjmp state\n" 7908047f616977f204df6054c481601f2237cc308dMichael J. Spencer "# pragma pop_macro(\"setjmp\")\n" 801f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer "# undef setjmp_undefined_for_msvc\n" 817d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#endif\n\n"; 829e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner} 839e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 849e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnervoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 851a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 869b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Enum values for Intrinsics.h\n"; 879e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 889e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 899e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << " " << Ints[i].EnumName; 909e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << ((i != e-1) ? ", " : " "); 919e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << std::string(40-Ints[i].EnumName.size(), ' ') 929e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner << "// " << Ints[i].Name << "\n"; 939e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner } 949e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << "#endif\n\n"; 959e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner} 969b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 979b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattnervoid IntrinsicEmitter:: 989b843b249462980ae4630dc37d1bcccde884a5a7Chris LattnerEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 991a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 100cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Build a 'first character of function name' -> intrinsic # mapping. 101cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::map<char, std::vector<unsigned> > IntMapping; 1029b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 103cc67c75b67d22653ea9380020e9a40381233901dChris Lattner IntMapping[Ints[i].Name[5]].push_back(i); 104cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 1059b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Function name -> enum value recognizer code.\n"; 1069b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 107cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n"; 108cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " switch (Name[5]) { // Dispatch on first letter.\n"; 109cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " default: break;\n"; 110cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Emit the intrinsic matching stuff by first letter. 111cc67c75b67d22653ea9380020e9a40381233901dChris Lattner for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(), 1129b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner E = IntMapping.end(); I != E; ++I) { 113cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " case '" << I->first << "':\n"; 114cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::vector<unsigned> &IntList = I->second; 115cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 116cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Emit all the overloaded intrinsics first, build a table of the 117cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // non-overloaded ones. 118cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::vector<StringMatcher::StringPair> MatchTable; 1199b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 120cc67c75b67d22653ea9380020e9a40381233901dChris Lattner for (unsigned i = 0, e = IntList.size(); i != e; ++i) { 121cc67c75b67d22653ea9380020e9a40381233901dChris Lattner unsigned IntNo = IntList[i]; 122cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::string Result = "return " + TargetPrefix + "Intrinsic::" + 123cc67c75b67d22653ea9380020e9a40381233901dChris Lattner Ints[IntNo].EnumName + ";"; 124cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 125cc67c75b67d22653ea9380020e9a40381233901dChris Lattner if (!Ints[IntNo].isOverloaded) { 126cc67c75b67d22653ea9380020e9a40381233901dChris Lattner MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result)); 127cc67c75b67d22653ea9380020e9a40381233901dChris Lattner continue; 128cc67c75b67d22653ea9380020e9a40381233901dChris Lattner } 129cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 130cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // For overloaded intrinsics, only the prefix needs to match 131cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::string TheStr = Ints[IntNo].Name.substr(6); 1322738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner TheStr += '.'; // Require "bswap." instead of bswap. 133cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " if (NameR.startswith(\"" << TheStr << "\")) " 134cc67c75b67d22653ea9380020e9a40381233901dChris Lattner << Result << '\n'; 1352738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner } 136cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 137cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Emit the matcher logic for the fixed length strings. 138cc67c75b67d22653ea9380020e9a40381233901dChris Lattner StringMatcher("NameR", MatchTable, OS).Emit(1); 139cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " break; // end of '" << I->first << "' case.\n"; 1409b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner } 141cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 1429b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " }\n"; 143f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 144f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner} 145f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner 146fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattnervoid IntrinsicEmitter:: 147fda6affb95e9f68278cb5cf75dc3fd3406978255Chris LattnerEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 1481a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 149fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "// Intrinsic ID to name table\n"; 150fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 151fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << " // Note that entry #0 is the invalid intrinsic!\n"; 152f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng for (unsigned i = 0, e = Ints.size(); i != e; ++i) 153f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng OS << " \"" << Ints[i].Name << "\",\n"; 154fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#endif\n\n"; 155fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner} 156fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 1570d52ff1f7b993750a74a5d4432273092de9af069Mon P Wangvoid IntrinsicEmitter:: 1580d52ff1f7b993750a74a5d4432273092de9af069Mon P WangEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 1591a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 16036a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << "// Intrinsic ID to overload bitset\n"; 1610d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 16236a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << "static const uint8_t OTable[] = {\n"; 16336a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << " 0"; 1640d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 16536a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer // Add one to the index so we emit a null bit for the invalid #0 intrinsic. 16636a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer if ((i+1)%8 == 0) 16736a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << ",\n 0"; 1680d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang if (Ints[i].isOverloaded) 16936a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << " | (1<<" << (i+1)%8 << ')'; 1700d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang } 17136a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << "\n};\n\n"; 17236a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer // OTable contains a true bit at the position if the intrinsic is overloaded. 17336a2138cce66a164f08a36c4c5820b133c4590fdBenjamin Kramer OS << "return (OTable[id/8] & (1 << (id%8))) != 0;\n"; 1740d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#endif\n\n"; 1750d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang} 1760d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 177825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 178e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (EVT(VT).isInteger()) { 179e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson unsigned BitWidth = EVT(VT).getSizeInBits(); 1801d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "IntegerType::get(Context, " << BitWidth << ")"; 181825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Other) { 182825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::OtherVT is used to mean the empty struct type here. 183d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context)"; 184e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman } else if (VT == MVT::f16) { 185e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman OS << "Type::getHalfTy(Context)"; 186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f32) { 1871d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFloatTy(Context)"; 188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f64) { 1891d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getDoubleTy(Context)"; 190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f80) { 1911d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getX86_FP80Ty(Context)"; 192825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f128) { 1931d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFP128Ty(Context)"; 194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::ppcf128) { 1951d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getPPC_FP128Ty(Context)"; 196825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 1971d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 198825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Metadata) { 1991d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getMetadataTy(Context)"; 2008be452545a1d3921f006c4d5673f14165ceead82Dale Johannesen } else if (VT == MVT::x86mmx) { 2018be452545a1d3921f006c4d5673f14165ceead82Dale Johannesen OS << "Type::getX86_MMXTy(Context)"; 2026994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 2036994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(false && "Unsupported ValueType!"); 20418faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner } 20518faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner} 20618faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner 2071a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 208cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo); 209cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2101a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, 211cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ArgTypes, 212cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo) { 21393dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.empty()) 21493dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeForValueType(OS, MVT::isVoid); 21593dc92e412fd06250e46951bffb6040eca9baebdChris Lattner 21693dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.size() == 1) 21793dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 218cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 219b2318662b6d2e6d9ea9917fd280dde0ba9a938adChris Lattner OS << "StructType::get("; 220cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 221cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (std::vector<Record*>::const_iterator 22220072af3b0b22d90afbce769409f4ed822520366Bill Wendling I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 223cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, *I, ArgNo); 22420072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << ", "; 22520072af3b0b22d90afbce769409f4ed822520366Bill Wendling } 226cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 22720072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << " NULL)"; 228cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling} 229cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2301a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 23184c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned &ArgNo) { 232825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 2336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 2356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 2366994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(Number < ArgNo && "Invalid matching number!"); 237bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 238bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getExtendedElementVectorType" 239bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 240bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 241bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getTruncatedElementVectorType" 242bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 243bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 244bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "Tys[" << Number << "]"; 245825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 24684c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // NOTE: The ArgNo variable here is not the absolute argument number, it is 24784c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // the index of the "arbitrary" type in the Tys array passed to the 24884c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // Intrinsic::getDeclaration function. Consequently, we only want to 2496994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // increment it when we actually hit an overloaded type. Getting this wrong 2506994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leads to very subtle bugs! 2516994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "Tys[" << ArgNo++ << "]"; 252e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } else if (EVT(VT).isVector()) { 253e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VVT = VT; 2549d6565a5b1fbc4286d6ee638d8f47a3171a9ed7eReid Spencer OS << "VectorType::get("; 255825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 25683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands OS << ", " << VVT.getVectorNumElements() << ")"; 257825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTR) { 25843ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb OS << "PointerType::getUnqual("; 259c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 26095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ")"; 261825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTRAny) { 262e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // Make sure the user has passed us an argument type to overload. If not, 263e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // treat it as an ordinary (not overloaded) intrinsic. 264eb9a85f09e18b3fe88499710404b38d3a9128f62Benjamin Kramer OS << "(" << ArgNo << " < Tys.size()) ? Tys[" << ArgNo 265e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang << "] : PointerType::getUnqual("; 266e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 267e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << ")"; 268e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ++ArgNo; 269825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 2706994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgNo == 0) 2711d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 2726994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth else 273825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::isVoid is used to mean varargs here. 2746994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "..."; 27595af592a631f403e1458ec1155f89fc31011572cJim Laskey } else { 2766994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth EmitTypeForValueType(OS, VT); 27795af592a631f403e1458ec1155f89fc31011572cJim Laskey } 27895af592a631f403e1458ec1155f89fc31011572cJim Laskey} 27995af592a631f403e1458ec1155f89fc31011572cJim Laskey 280da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach/// RecordListComparator - Provide a deterministic comparator for lists of 281c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner/// records. 282c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattnernamespace { 283cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 284c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner struct RecordListComparator { 285cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling bool operator()(const RecPair &LHS, 286cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &RHS) const { 287c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner unsigned i = 0; 288cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *LHSVec = &LHS.first; 289cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *RHSVec = &RHS.first; 290cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned RHSSize = RHSVec->size(); 291cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned LHSSize = LHSVec->size(); 292cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 29393dc92e412fd06250e46951bffb6040eca9baebdChris Lattner for (; i != LHSSize; ++i) { 294cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 295cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 296cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 29793dc92e412fd06250e46951bffb6040eca9baebdChris Lattner } 298cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 299023422a6eb9ea692a5a837dc1daf256ac75ac6b0Bill Wendling if (i != RHSSize) return true; 300cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 301cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling i = 0; 302cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSVec = &LHS.second; 303cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSVec = &RHS.second; 304cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSSize = RHSVec->size(); 305cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSSize = LHSVec->size(); 306cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 307cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (i = 0; i != LHSSize; ++i) { 308cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 309cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 310cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 311cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 312cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 313cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return i != RHSSize; 314c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner } 315c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner }; 316c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner} 317c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 318f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattnervoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 3191a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 320f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 321f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 322f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " switch (ID) {\n"; 323655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper OS << " default: llvm_unreachable(\"Invalid intrinsic!\");\n"; 324c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 325c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // This checking can emit a lot of very common code. To reduce the amount of 326c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // code that we emit, batch up cases that have identical types. This avoids 327c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // problems where GCC can run out of memory compiling Verifier.cpp. 328cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 329c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner MapTy UniqueArgInfos; 330c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 331c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Compute the unique argument type info. 332c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 333cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 334cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 335c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 336c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Loop through the array, emitting one comparison for each batch. 337c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (MapTy::iterator I = UniqueArgInfos.begin(), 338c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner E = UniqueArgInfos.end(); I != E; ++I) { 339cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 340c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 341c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner << Ints[I->second[i]].Name << "\n"; 342f124b46b4f18b1a8f054a1222324ae15079f6ed8Chris Lattner 343cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 344cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 345cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 34609b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson std::vector<unsigned> OverloadedTypeIndices; 347cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 348cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 349cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling << ParamTys.size(); 350cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 351cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit return types. 352cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 353cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = RetTys[j]; 354cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 355cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 3566994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 3576994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 35809b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 35909b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 36009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 361bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 362bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 363bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 364bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 365bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 366bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 3676994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 368825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 3696994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << getEnumName(VT); 370cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 37161fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 37209b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j); 37309b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 374825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 375cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling throw "Var arg type not last argument"; 376cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 377cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 378cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 379cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit the parameter types. 380cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 381cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = ParamTys[j]; 382cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 383cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 384cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (ArgType->isSubClassOf("LLVMMatchType")) { 385cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned Number = ArgType->getValueAsInt("Number"); 38609b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 38709b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 38809b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 389bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 390bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 391bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 392bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 393bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 394bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 395cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } else { 396825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 397cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << getEnumName(VT); 398cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 39961fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 40009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j + RetTys.size()); 40109b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 402825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 40395d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey throw "Var arg type not last argument"; 40495d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 40595d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 40695d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey 4076994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << ");\n"; 408f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " break;\n"; 409f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner } 410f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " }\n"; 411f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 4129b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner} 4139b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 41495af592a631f403e1458ec1155f89fc31011572cJim Laskeyvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 4151a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 41695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "// Code for generating Intrinsic function declarations.\n"; 41795af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 41895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " switch (id) {\n"; 419655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper OS << " default: llvm_unreachable(\"Invalid intrinsic!\");\n"; 42095af592a631f403e1458ec1155f89fc31011572cJim Laskey 42195af592a631f403e1458ec1155f89fc31011572cJim Laskey // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 42295af592a631f403e1458ec1155f89fc31011572cJim Laskey // types. 423cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 42495af592a631f403e1458ec1155f89fc31011572cJim Laskey MapTy UniqueArgInfos; 42595af592a631f403e1458ec1155f89fc31011572cJim Laskey 42695af592a631f403e1458ec1155f89fc31011572cJim Laskey // Compute the unique argument type info. 42795af592a631f403e1458ec1155f89fc31011572cJim Laskey for (unsigned i = 0, e = Ints.size(); i != e; ++i) 428cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 429cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 43095af592a631f403e1458ec1155f89fc31011572cJim Laskey 43195af592a631f403e1458ec1155f89fc31011572cJim Laskey // Loop through the array, emitting one generator for each batch. 43249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 43349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 43495af592a631f403e1458ec1155f89fc31011572cJim Laskey for (MapTy::iterator I = UniqueArgInfos.begin(), 43595af592a631f403e1458ec1155f89fc31011572cJim Laskey E = UniqueArgInfos.end(); I != E; ++I) { 436cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 43749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 43849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 43995af592a631f403e1458ec1155f89fc31011572cJim Laskey 440cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 441cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 442cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 443cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 444cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned N = ParamTys.size(); 44595af592a631f403e1458ec1155f89fc31011572cJim Laskey 4466994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (N > 1 && 447825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 44895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " IsVarArg = true;\n"; 44995af592a631f403e1458ec1155f89fc31011572cJim Laskey --N; 45095af592a631f403e1458ec1155f89fc31011572cJim Laskey } 451cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 45284c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned ArgNo = 0; 45395af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ResultTy = "; 454cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, RetTys, ArgNo); 45595af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ";\n"; 45695af592a631f403e1458ec1155f89fc31011572cJim Laskey 457cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0; j != N; ++j) { 45895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ArgTys.push_back("; 459cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, ParamTys[j], ArgNo); 46095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ");\n"; 46195af592a631f403e1458ec1155f89fc31011572cJim Laskey } 462cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 46395af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " break;\n"; 46495af592a631f403e1458ec1155f89fc31011572cJim Laskey } 465cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 46695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " }\n"; 46795af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#endif\n\n"; 46895af592a631f403e1458ec1155f89fc31011572cJim Laskey} 46995af592a631f403e1458ec1155f89fc31011572cJim Laskey 470bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCallnamespace { 471bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall enum ModRefKind { 472bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall MRK_none, 473bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall MRK_readonly, 474bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall MRK_readnone 475bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall }; 476bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 477bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) { 478bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall switch (intrinsic.ModRef) { 479bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::NoMem: 480bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_readnone; 481bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadArgMem: 482bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadMem: 483bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_readonly; 484bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadWriteArgMem: 485bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadWriteMem: 486bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_none; 487bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 488655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("bad mod-ref kind"); 489bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 490bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 491bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall struct AttributeComparator { 492bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { 493bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Sort throwing intrinsics after non-throwing intrinsics. 494bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (L->canThrow != R->canThrow) 495bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return R->canThrow; 496bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 497bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Try to order by readonly/readnone attribute. 498bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind LK = getModRefKind(*L); 499bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind RK = getModRefKind(*R); 500bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (LK != RK) return (LK > RK); 501bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 502bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Order by argument attributes. 503bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // This is reliable because each side is already sorted internally. 504bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return (L->ArgumentAttributes < R->ArgumentAttributes); 505bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 506bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall }; 507bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall} 508bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 509048ffb239c282277959463c61200b86e2380cb84Chris Lattner/// EmitAttributes - This emits the Intrinsic::getAttributes method. 5104e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattnervoid IntrinsicEmitter:: 5111a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 512a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 513a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 51449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) 51549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static AttrListPtr getAttributes(" << TargetPrefix 516bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall << "Intrinsic::ID id) {\n"; 51749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen else 518bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << "AttrListPtr Intrinsic::getAttributes(ID id) {\n"; 519bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 5201f5952352146f229cbc249405fbe9898d168089bCraig Topper // Compute the maximum number of attribute arguments and the map 5211f5952352146f229cbc249405fbe9898d168089bCraig Topper typedef std::map<const CodeGenIntrinsic*, unsigned, 5221f5952352146f229cbc249405fbe9898d168089bCraig Topper AttributeComparator> UniqAttrMapTy; 5231f5952352146f229cbc249405fbe9898d168089bCraig Topper UniqAttrMapTy UniqAttributes; 524bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall unsigned maxArgAttrs = 0; 5251f5952352146f229cbc249405fbe9898d168089bCraig Topper unsigned AttrNum = 0; 5264e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 527bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall const CodeGenIntrinsic &intrinsic = Ints[i]; 528bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall maxArgAttrs = 529bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall std::max(maxArgAttrs, unsigned(intrinsic.ArgumentAttributes.size())); 5301f5952352146f229cbc249405fbe9898d168089bCraig Topper unsigned &N = UniqAttributes[&intrinsic]; 5311f5952352146f229cbc249405fbe9898d168089bCraig Topper if (N) continue; 5321f5952352146f229cbc249405fbe9898d168089bCraig Topper assert(AttrNum < 256 && "Too many unique attributes for table!"); 5331f5952352146f229cbc249405fbe9898d168089bCraig Topper N = ++AttrNum; 5344e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 535bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 536bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Emit an array of AttributeWithIndex. Most intrinsics will have 537bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // at least one entry, for the function itself (index ~1), which is 538bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // usually nounwind. 5391f5952352146f229cbc249405fbe9898d168089bCraig Topper OS << " static const uint8_t IntrinsicsToAttributesMap[] = {\n"; 540bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 5411f5952352146f229cbc249405fbe9898d168089bCraig Topper for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 5421f5952352146f229cbc249405fbe9898d168089bCraig Topper const CodeGenIntrinsic &intrinsic = Ints[i]; 543bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 5441f5952352146f229cbc249405fbe9898d168089bCraig Topper OS << " " << UniqAttributes[&intrinsic] << ", // " 5451f5952352146f229cbc249405fbe9898d168089bCraig Topper << intrinsic.Name << "\n"; 5461f5952352146f229cbc249405fbe9898d168089bCraig Topper } 5471f5952352146f229cbc249405fbe9898d168089bCraig Topper OS << " };\n\n"; 54810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 5491f5952352146f229cbc249405fbe9898d168089bCraig Topper OS << " AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n"; 5501f5952352146f229cbc249405fbe9898d168089bCraig Topper OS << " unsigned NumAttrs = 0;\n"; 551b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " if (id != 0) {\n"; 552b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " switch(IntrinsicsToAttributesMap[id - "; 553b57b170317f12370183111fc458de3352c5f71dcCraig Topper if (TargetOnly) 554b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << "Intrinsic::num_intrinsics"; 555b57b170317f12370183111fc458de3352c5f71dcCraig Topper else 556b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << "1"; 557b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << "]) {\n"; 558b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " default: llvm_unreachable(\"Invalid attribute number\");\n"; 5591f5952352146f229cbc249405fbe9898d168089bCraig Topper for (UniqAttrMapTy::const_iterator I = UniqAttributes.begin(), 5601f5952352146f229cbc249405fbe9898d168089bCraig Topper E = UniqAttributes.end(); I != E; ++I) { 561b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " case " << I->second << ":\n"; 56210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 5631f5952352146f229cbc249405fbe9898d168089bCraig Topper const CodeGenIntrinsic &intrinsic = *(I->first); 564bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 565bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Keep track of the number of attributes we're writing out. 566bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall unsigned numAttrs = 0; 56710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 568bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // The argument attributes are alreadys sorted by argument index. 569bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall for (unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size(); ai != ae;) { 570bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall unsigned argNo = intrinsic.ArgumentAttributes[ai].first; 5711f5952352146f229cbc249405fbe9898d168089bCraig Topper 572b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(" 573bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall << argNo+1 << ", "; 574bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 575bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall bool moreThanOne = false; 576d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 577bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall do { 578bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (moreThanOne) OS << '|'; 579bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 580bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall switch (intrinsic.ArgumentAttributes[ai].second) { 581d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner case CodeGenIntrinsic::NoCapture: 582bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << "Attribute::NoCapture"; 583d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner break; 584d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 585bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 586bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ++ai; 587bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall moreThanOne = true; 588bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo); 589bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 590bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << ");\n"; 591bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 592bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 593bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind modRef = getModRefKind(intrinsic); 594bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 595bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (!intrinsic.canThrow || modRef) { 596b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, "; 597bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (!intrinsic.canThrow) { 598bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << "Attribute::NoUnwind"; 599bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (modRef) OS << '|'; 600bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 601bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall switch (modRef) { 602bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case MRK_none: break; 603bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case MRK_readonly: OS << "Attribute::ReadOnly"; break; 604bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case MRK_readnone: OS << "Attribute::ReadNone"; break; 605d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 606d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << ");\n"; 607d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 608bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 609bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (numAttrs) { 610b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " NumAttrs = " << numAttrs << ";\n"; 611b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " break;\n"; 612bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } else { 613b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " return AttrListPtr();\n"; 614bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 61510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner } 61610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 617b57b170317f12370183111fc458de3352c5f71dcCraig Topper OS << " }\n"; 61810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " }\n"; 619bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " return AttrListPtr::get(AWI, NumAttrs);\n"; 620048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << "}\n"; 621d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 6224e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner} 623022f64fbbc4669623e79b805379266fed519017dChris Lattner 624d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 625d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sandsvoid IntrinsicEmitter:: 6261a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 627b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "// Determine intrinsic alias analysis mod/ref behavior.\n" 628b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n" 629b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer << "assert(iid <= Intrinsic::" << Ints.back().EnumName << " && " 630b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer << "\"Unknown intrinsic.\");\n\n"; 631b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer 632b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "static const uint8_t IntrinsicModRefBehavior[] = {\n" 633b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer << " /* invalid */ UnknownModRefBehavior,\n"; 634d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 635b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << " /* " << TargetPrefix << Ints[i].EnumName << " */ "; 636d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands switch (Ints[i].ModRef) { 637d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::NoMem: 638b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "DoesNotAccessMemory,\n"; 639d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 640d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadArgMem: 641b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "OnlyReadsArgumentPointees,\n"; 6429423f633654af6045b1efa7795edfe8ea0533d7eDan Gohman break; 643d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadMem: 644b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "OnlyReadsMemory,\n"; 645d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 6467365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman case CodeGenIntrinsic::ReadWriteArgMem: 647b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "OnlyAccessesArgumentPointees,\n"; 648b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer break; 649b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer case CodeGenIntrinsic::ReadWriteMem: 650b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "UnknownModRefBehavior,\n"; 651d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 652d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 653d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 654b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer OS << "};\n\n" 655b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer << "return static_cast<ModRefBehavior>(IntrinsicModRefBehavior[iid]);\n" 656b519a0fe0ee02804cc77cb9c40ded6604341b71cBenjamin Kramer << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 657d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands} 658d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 659331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// EmitTargetBuiltins - All of the builtins in the specified map are for the 660331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// same target, and we already checked it. 661331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnerstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 66249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen const std::string &TargetPrefix, 6631a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 664331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 665298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::vector<StringMatcher::StringPair> Results; 666331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 667298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), 668298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner E = BIM.end(); I != E; ++I) { 669298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::string ResultCode = 670298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner "return " + TargetPrefix + "Intrinsic::" + I->second + ";"; 671298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner Results.push_back(StringMatcher::StringPair(I->first, ResultCode)); 672331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 673298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner 674298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner StringMatcher("BuiltinName", Results, OS).Emit(); 675331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner} 676331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 677331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 6783f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattnervoid IntrinsicEmitter:: 6793f8b8913bc9cb232871445eefa8654caf7f9986fChris LattnerEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 6801a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 681fa0fba1c546091c485e5513eadeef181dda370abChris Lattner typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 6823f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner BIMTy BuiltinMap; 6833f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 6843f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 685fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Get the map for this target prefix. 686fa0fba1c546091c485e5513eadeef181dda370abChris Lattner std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 687fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 688fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 689fa0fba1c546091c485e5513eadeef181dda370abChris Lattner Ints[i].EnumName)).second) 6903f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner throw "Intrinsic '" + Ints[i].TheDef->getName() + 6913f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner "': duplicate GCC builtin name!"; 6923f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6933f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6943f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 6953f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 6963f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 6973f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 6983f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 6993f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 70049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 70149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) { 70249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static " << TargetPrefix << "Intrinsic::ID " 70349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "getIntrinsicForGCCBuiltin(const char " 704298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 70549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } else { 70649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 707298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 70849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } 70949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 710298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef BuiltinName(BuiltinNameStr);\n"; 711298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; 712331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 7133f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Note: this could emit significantly better code if we cared. 7143f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 715fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " "; 716fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!I->first.empty()) 717298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "if (TargetPrefix == \"" << I->first << "\") "; 718fa0fba1c546091c485e5513eadeef181dda370abChris Lattner else 719fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "/* Target Independent Builtins */ "; 720fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "{\n"; 721fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 722fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Emit the comparisons for this target prefix. 72349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitTargetBuiltins(I->second, TargetPrefix, OS); 724fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " }\n"; 7253f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 726298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " return "; 727298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner if (!TargetPrefix.empty()) 728298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "(" << TargetPrefix << "Intrinsic::ID)"; 729298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "Intrinsic::not_intrinsic;\n"; 73049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "}\n"; 7313f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#endif\n\n"; 7323f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner} 733