IntrinsicEmitter.cpp revision cc67c75b67d22653ea9380020e9a40381233901d
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" 169e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner#include "Record.h" 17298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner#include "StringMatcher.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 60022f64fbbc4669623e79b805379266fed519017dChris Lattner // Emit a list of intrinsics with corresponding GCC builtins. 61022f64fbbc4669623e79b805379266fed519017dChris Lattner EmitGCCBuiltinList(Ints, OS); 623f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 633f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Emit code to translate GCC builtins into LLVM intrinsics. 643f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner EmitIntrinsicToGCCBuiltinMap(Ints, OS); 657d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 667d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor EmitSuffix(OS); 677d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor} 687d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 697d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregorvoid IntrinsicEmitter::EmitPrefix(raw_ostream &OS) { 707d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor OS << "// VisualStudio defines setjmp as _setjmp\n" 717d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#if defined(_MSC_VER) && defined(setjmp)\n" 727d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#define setjmp_undefined_for_visual_studio\n" 737d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#undef setjmp\n" 747d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#endif\n\n"; 757d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor} 767d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 777d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregorvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { 787d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_visual_studio)\n" 797d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "// let's return it to _setjmp state\n" 807d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#define setjmp _setjmp\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) { 1600d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "// Intrinsic ID to overload table\n"; 1610d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 1620d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " // Note that entry #0 is the invalid intrinsic!\n"; 1630d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 1640d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " "; 1650d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang if (Ints[i].isOverloaded) 1660d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "true"; 1670d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang else 1680d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "false"; 1690d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << ",\n"; 1700d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang } 1710d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#endif\n\n"; 1720d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang} 1730d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 174825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 175e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (EVT(VT).isInteger()) { 176e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson unsigned BitWidth = EVT(VT).getSizeInBits(); 1771d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "IntegerType::get(Context, " << BitWidth << ")"; 178825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Other) { 179825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::OtherVT is used to mean the empty struct type here. 180d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context)"; 181825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f32) { 1821d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFloatTy(Context)"; 183825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f64) { 1841d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getDoubleTy(Context)"; 185825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f80) { 1861d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getX86_FP80Ty(Context)"; 187825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f128) { 1881d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFP128Ty(Context)"; 189825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::ppcf128) { 1901d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getPPC_FP128Ty(Context)"; 191825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 1921d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 193825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Metadata) { 1941d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getMetadataTy(Context)"; 1956994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 1966994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(false && "Unsupported ValueType!"); 19718faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner } 19818faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner} 19918faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner 2001a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 201cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo); 202cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2031a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, 204cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ArgTypes, 205cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo) { 20693dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.empty()) 20793dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeForValueType(OS, MVT::isVoid); 20893dc92e412fd06250e46951bffb6040eca9baebdChris Lattner 20993dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.size() == 1) 21093dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 211cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 212d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context, "; 213cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 214cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (std::vector<Record*>::const_iterator 21520072af3b0b22d90afbce769409f4ed822520366Bill Wendling I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 216cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, *I, ArgNo); 21720072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << ", "; 21820072af3b0b22d90afbce769409f4ed822520366Bill Wendling } 219cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 22020072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << " NULL)"; 221cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling} 222cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2231a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 22484c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned &ArgNo) { 225825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 2266994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2276994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 2286994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 2296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(Number < ArgNo && "Invalid matching number!"); 230bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 231bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getExtendedElementVectorType" 232bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 233bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 234bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getTruncatedElementVectorType" 235bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 236bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 237bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "Tys[" << Number << "]"; 238825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 23984c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // NOTE: The ArgNo variable here is not the absolute argument number, it is 24084c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // the index of the "arbitrary" type in the Tys array passed to the 24184c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // Intrinsic::getDeclaration function. Consequently, we only want to 2426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // increment it when we actually hit an overloaded type. Getting this wrong 2436994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leads to very subtle bugs! 2446994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "Tys[" << ArgNo++ << "]"; 245e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } else if (EVT(VT).isVector()) { 246e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VVT = VT; 2479d6565a5b1fbc4286d6ee638d8f47a3171a9ed7eReid Spencer OS << "VectorType::get("; 248825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 24983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands OS << ", " << VVT.getVectorNumElements() << ")"; 250825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTR) { 25143ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb OS << "PointerType::getUnqual("; 252c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 25395af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ")"; 254825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTRAny) { 255e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // Make sure the user has passed us an argument type to overload. If not, 256e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // treat it as an ordinary (not overloaded) intrinsic. 257e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 258e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang << "] : PointerType::getUnqual("; 259e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 260e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << ")"; 261e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ++ArgNo; 262825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 2636994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgNo == 0) 2641d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 2656994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth else 266825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::isVoid is used to mean varargs here. 2676994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "..."; 26895af592a631f403e1458ec1155f89fc31011572cJim Laskey } else { 2696994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth EmitTypeForValueType(OS, VT); 27095af592a631f403e1458ec1155f89fc31011572cJim Laskey } 27195af592a631f403e1458ec1155f89fc31011572cJim Laskey} 27295af592a631f403e1458ec1155f89fc31011572cJim Laskey 273da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach/// RecordListComparator - Provide a deterministic comparator for lists of 274c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner/// records. 275c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattnernamespace { 276cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 277c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner struct RecordListComparator { 278cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling bool operator()(const RecPair &LHS, 279cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &RHS) const { 280c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner unsigned i = 0; 281cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *LHSVec = &LHS.first; 282cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *RHSVec = &RHS.first; 283cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned RHSSize = RHSVec->size(); 284cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned LHSSize = LHSVec->size(); 285cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 28693dc92e412fd06250e46951bffb6040eca9baebdChris Lattner for (; i != LHSSize; ++i) { 287cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 288cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 289cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 29093dc92e412fd06250e46951bffb6040eca9baebdChris Lattner } 291cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 292023422a6eb9ea692a5a837dc1daf256ac75ac6b0Bill Wendling if (i != RHSSize) return true; 293cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 294cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling i = 0; 295cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSVec = &LHS.second; 296cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSVec = &RHS.second; 297cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSSize = RHSVec->size(); 298cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSSize = LHSVec->size(); 299cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 300cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (i = 0; i != LHSSize; ++i) { 301cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 302cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 303cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 304cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 305cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 306cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return i != RHSSize; 307c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner } 308c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner }; 309c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner} 310c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 311f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattnervoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 3121a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 313f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 314f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 315f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " switch (ID) {\n"; 316f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 317c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 318c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // This checking can emit a lot of very common code. To reduce the amount of 319c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // code that we emit, batch up cases that have identical types. This avoids 320c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // problems where GCC can run out of memory compiling Verifier.cpp. 321cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 322c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner MapTy UniqueArgInfos; 323c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 324c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Compute the unique argument type info. 325c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 326cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 327cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 328c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 329c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Loop through the array, emitting one comparison for each batch. 330c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (MapTy::iterator I = UniqueArgInfos.begin(), 331c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner E = UniqueArgInfos.end(); I != E; ++I) { 332cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 333c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 334c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner << Ints[I->second[i]].Name << "\n"; 335f124b46b4f18b1a8f054a1222324ae15079f6ed8Chris Lattner 336cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 337cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 338cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 33909b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson std::vector<unsigned> OverloadedTypeIndices; 340cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 341cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 342cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling << ParamTys.size(); 343cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 344cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit return types. 345cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 346cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = RetTys[j]; 347cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 348cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 3496994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 3506994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 35109b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 35209b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 35309b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 354bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 355bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 356bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 357bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 358bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 359bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 3606994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 361825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 3626994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << getEnumName(VT); 363cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 36461fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 36509b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j); 36609b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 367825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 368cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling throw "Var arg type not last argument"; 369cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 370cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 371cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 372cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit the parameter types. 373cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 374cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = ParamTys[j]; 375cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 376cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 377cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (ArgType->isSubClassOf("LLVMMatchType")) { 378cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned Number = ArgType->getValueAsInt("Number"); 37909b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 38009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 38109b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 382bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 383bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 384bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 385bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 386bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 387bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 388cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } else { 389825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 390cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << getEnumName(VT); 391cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 39261fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 39309b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j + RetTys.size()); 39409b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 395825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 39695d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey throw "Var arg type not last argument"; 39795d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 39895d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 39995d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey 4006994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << ");\n"; 401f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " break;\n"; 402f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner } 403f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " }\n"; 404f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 4059b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner} 4069b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 40795af592a631f403e1458ec1155f89fc31011572cJim Laskeyvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 4081a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 40995af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "// Code for generating Intrinsic function declarations.\n"; 41095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 41195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " switch (id) {\n"; 41295af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 41395af592a631f403e1458ec1155f89fc31011572cJim Laskey 41495af592a631f403e1458ec1155f89fc31011572cJim Laskey // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 41595af592a631f403e1458ec1155f89fc31011572cJim Laskey // types. 416cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 41795af592a631f403e1458ec1155f89fc31011572cJim Laskey MapTy UniqueArgInfos; 41895af592a631f403e1458ec1155f89fc31011572cJim Laskey 41995af592a631f403e1458ec1155f89fc31011572cJim Laskey // Compute the unique argument type info. 42095af592a631f403e1458ec1155f89fc31011572cJim Laskey for (unsigned i = 0, e = Ints.size(); i != e; ++i) 421cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 422cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 42395af592a631f403e1458ec1155f89fc31011572cJim Laskey 42495af592a631f403e1458ec1155f89fc31011572cJim Laskey // Loop through the array, emitting one generator for each batch. 42549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 42649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 42795af592a631f403e1458ec1155f89fc31011572cJim Laskey for (MapTy::iterator I = UniqueArgInfos.begin(), 42895af592a631f403e1458ec1155f89fc31011572cJim Laskey E = UniqueArgInfos.end(); I != E; ++I) { 429cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 43049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 43149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 43295af592a631f403e1458ec1155f89fc31011572cJim Laskey 433cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 434cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 435cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 436cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 437cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned N = ParamTys.size(); 43895af592a631f403e1458ec1155f89fc31011572cJim Laskey 4396994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (N > 1 && 440825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 44195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " IsVarArg = true;\n"; 44295af592a631f403e1458ec1155f89fc31011572cJim Laskey --N; 44395af592a631f403e1458ec1155f89fc31011572cJim Laskey } 444cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 44584c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned ArgNo = 0; 44695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ResultTy = "; 447cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, RetTys, ArgNo); 44895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ";\n"; 44995af592a631f403e1458ec1155f89fc31011572cJim Laskey 450cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0; j != N; ++j) { 45195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ArgTys.push_back("; 452cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, ParamTys[j], ArgNo); 45395af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ");\n"; 45495af592a631f403e1458ec1155f89fc31011572cJim Laskey } 455cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 45695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " break;\n"; 45795af592a631f403e1458ec1155f89fc31011572cJim Laskey } 458cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 45995af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " }\n"; 46095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#endif\n\n"; 46195af592a631f403e1458ec1155f89fc31011572cJim Laskey} 46295af592a631f403e1458ec1155f89fc31011572cJim Laskey 463048ffb239c282277959463c61200b86e2380cb84Chris Lattner/// EmitAttributes - This emits the Intrinsic::getAttributes method. 4644e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattnervoid IntrinsicEmitter:: 4651a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 466a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 467a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 46849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) 46949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static AttrListPtr getAttributes(" << TargetPrefix 47049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "Intrinsic::ID id) {"; 47149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen else 47249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 473048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << " // No intrinsic can throw exceptions.\n"; 474048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << " Attributes Attr = Attribute::NoUnwind;\n"; 475a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " switch (id) {\n"; 4767056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner OS << " default: break;\n"; 47710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner unsigned MaxArgAttrs = 0; 4787056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 47910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner MaxArgAttrs = 48010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 4817056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner switch (Ints[i].ModRef) { 4827056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner default: break; 4837056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner case CodeGenIntrinsic::NoMem: 48449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 48549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 4867056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner break; 4877056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner } 4887056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner } 4890598866c052147c31b808391f58434ce3dbfb838Devang Patel OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 490a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " break;\n"; 4914e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 4924e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner switch (Ints[i].ModRef) { 493022f64fbbc4669623e79b805379266fed519017dChris Lattner default: break; 494022f64fbbc4669623e79b805379266fed519017dChris Lattner case CodeGenIntrinsic::ReadArgMem: 495022f64fbbc4669623e79b805379266fed519017dChris Lattner case CodeGenIntrinsic::ReadMem: 49649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 49749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 498022f64fbbc4669623e79b805379266fed519017dChris Lattner break; 4994e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 5004e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 5010598866c052147c31b808391f58434ce3dbfb838Devang Patel OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 502a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " break;\n"; 5034e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner OS << " }\n"; 50410dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 505d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " unsigned NumAttrs = 0;\n"; 50610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " switch (id) {\n"; 50710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " default: break;\n"; 50810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 50910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner // Add argument attributes for any intrinsics that have them. 51010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 51110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner if (Ints[i].ArgumentAttributes.empty()) continue; 51210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 51349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 51449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 51510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 51610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 51710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner Ints[i].ArgumentAttributes; 51810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner // Sort by argument index. 51910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::sort(ArgAttrs.begin(), ArgAttrs.end()); 52010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 52110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner unsigned NumArgsWithAttrs = 0; 52210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 523d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner while (!ArgAttrs.empty()) { 524d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner unsigned ArgNo = ArgAttrs[0].first; 525d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 526d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 527d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner << ArgNo+1 << ", 0"; 528d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 529d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 530d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner switch (ArgAttrs[0].second) { 531d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner default: assert(0 && "Unknown arg attribute"); 532d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner case CodeGenIntrinsic::NoCapture: 533d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "|Attribute::NoCapture"; 534d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner break; 535d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 536d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner ArgAttrs.erase(ArgAttrs.begin()); 537d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 538d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << ");\n"; 539d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 54010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 541d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 54210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " break;\n"; 54310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner } 54410dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 54510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " }\n"; 546d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 547d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 548048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << "}\n"; 549d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 5504e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner} 551022f64fbbc4669623e79b805379266fed519017dChris Lattner 552d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 553d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sandsvoid IntrinsicEmitter:: 5541a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 555d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 556d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 5577c422ac216fe39fc9c402a704cf296cca9dc5b22Duncan Sands OS << "switch (iid) {\n"; 558d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "default:\n return UnknownModRefBehavior;\n"; 559d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 5607365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem) 561d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands continue; 562d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 563d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands << ":\n"; 564d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands switch (Ints[i].ModRef) { 565d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands default: 566d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands assert(false && "Unknown Mod/Ref type!"); 567d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::NoMem: 568d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return DoesNotAccessMemory;\n"; 569d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 570d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadArgMem: 571d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadMem: 572d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return OnlyReadsMemory;\n"; 573d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 5747365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman case CodeGenIntrinsic::ReadWriteArgMem: 575d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return AccessesArguments;\n"; 576d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 577d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 578d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 579d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "}\n"; 580d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 581d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands} 582d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 583022f64fbbc4669623e79b805379266fed519017dChris Lattnervoid IntrinsicEmitter:: 5841a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 585022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 586022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 587022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " switch (F->getIntrinsicID()) {\n"; 588022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " default: BuiltinName = \"\"; break;\n"; 589022f64fbbc4669623e79b805379266fed519017dChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 590022f64fbbc4669623e79b805379266fed519017dChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 591022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 592022f64fbbc4669623e79b805379266fed519017dChris Lattner << Ints[i].GCCBuiltinName << "\"; break;\n"; 593022f64fbbc4669623e79b805379266fed519017dChris Lattner } 594022f64fbbc4669623e79b805379266fed519017dChris Lattner } 595022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " }\n"; 596022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#endif\n\n"; 597767a25b8788b5e313c99c16b4d359478432901f5Reid Spencer} 5983f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 599331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// EmitTargetBuiltins - All of the builtins in the specified map are for the 600331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// same target, and we already checked it. 601331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnerstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 60249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen const std::string &TargetPrefix, 6031a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 604331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 605298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::vector<StringMatcher::StringPair> Results; 606331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 607298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), 608298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner E = BIM.end(); I != E; ++I) { 609298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::string ResultCode = 610298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner "return " + TargetPrefix + "Intrinsic::" + I->second + ";"; 611298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner Results.push_back(StringMatcher::StringPair(I->first, ResultCode)); 612331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 613298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner 614298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner StringMatcher("BuiltinName", Results, OS).Emit(); 615331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner} 616331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 617331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 6183f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattnervoid IntrinsicEmitter:: 6193f8b8913bc9cb232871445eefa8654caf7f9986fChris LattnerEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 6201a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 621fa0fba1c546091c485e5513eadeef181dda370abChris Lattner typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 6223f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner BIMTy BuiltinMap; 6233f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 6243f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 625fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Get the map for this target prefix. 626fa0fba1c546091c485e5513eadeef181dda370abChris Lattner std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 627fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 628fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 629fa0fba1c546091c485e5513eadeef181dda370abChris Lattner Ints[i].EnumName)).second) 6303f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner throw "Intrinsic '" + Ints[i].TheDef->getName() + 6313f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner "': duplicate GCC builtin name!"; 6323f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6333f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6343f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 6353f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 6363f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 6373f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 6383f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 6393f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 64049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 64149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) { 64249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static " << TargetPrefix << "Intrinsic::ID " 64349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "getIntrinsicForGCCBuiltin(const char " 644298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 64549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } else { 64649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 647298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 64849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } 64949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 650298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef BuiltinName(BuiltinNameStr);\n"; 651298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; 652331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 6533f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Note: this could emit significantly better code if we cared. 6543f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 655fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " "; 656fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!I->first.empty()) 657298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "if (TargetPrefix == \"" << I->first << "\") "; 658fa0fba1c546091c485e5513eadeef181dda370abChris Lattner else 659fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "/* Target Independent Builtins */ "; 660fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "{\n"; 661fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 662fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Emit the comparisons for this target prefix. 66349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitTargetBuiltins(I->second, TargetPrefix, OS); 664fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " }\n"; 6653f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 666298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " return "; 667298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner if (!TargetPrefix.empty()) 668298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "(" << TargetPrefix << "Intrinsic::ID)"; 669298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "Intrinsic::not_intrinsic;\n"; 67049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "}\n"; 6713f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#endif\n\n"; 6723f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner} 673