IntrinsicEmitter.cpp revision 298b176559d5c76d7d9f7fdd06429a75892de043
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) { 1009b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner // Build a function name -> intrinsic name mapping. 101c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer std::map<std::string, unsigned> IntMapping; 1029b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 1032738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner IntMapping[Ints[i].Name.substr(5)] = i; 1049b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 1059b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Function name -> enum value recognizer code.\n"; 1069b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 1072738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner OS << " Name += 5; Len -= 5; // Skip over 'llvm.'\n"; 1082738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner OS << " switch (*Name) { // Dispatch on first letter.\n"; 1093b515802f652b16b05c9a8f344d219a0739b36a3Chris Lattner OS << " default:\n"; 1109b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner // Emit the intrinsics in sorted order. 1119b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner char LastChar = 0; 112c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(), 1139b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner E = IntMapping.end(); I != E; ++I) { 1142738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner if (I->first[0] != LastChar) { 1152738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner LastChar = I->first[0]; 1163b515802f652b16b05c9a8f344d219a0739b36a3Chris Lattner OS << " break;\n"; 1179b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " case '" << LastChar << "':\n"; 1189b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner } 1199b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 120c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer // For overloaded intrinsics, only the prefix needs to match 1212738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner std::string TheStr = I->first; 1222738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner if (Ints[I->second].isOverloaded) { 1232738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner TheStr += '.'; // Require "bswap." instead of bswap. 1242738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner OS << " if (Len > " << I->first.size(); 1252738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner } else { 1262738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner OS << " if (Len == " << I->first.size(); 1272738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner } 1282738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner 1292738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner OS << " && !memcmp(Name, \"" << TheStr << "\", " 1302738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner << TheStr.size() << ")) return " << TargetPrefix << "Intrinsic::" 1316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth << Ints[I->second].EnumName << ";\n"; 1329b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner } 1339b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " }\n"; 134f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 135f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner} 136f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner 137fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattnervoid IntrinsicEmitter:: 138fda6affb95e9f68278cb5cf75dc3fd3406978255Chris LattnerEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 1391a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 140fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "// Intrinsic ID to name table\n"; 141fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 142fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << " // Note that entry #0 is the invalid intrinsic!\n"; 143f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng for (unsigned i = 0, e = Ints.size(); i != e; ++i) 144f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng OS << " \"" << Ints[i].Name << "\",\n"; 145fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#endif\n\n"; 146fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner} 147fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 1480d52ff1f7b993750a74a5d4432273092de9af069Mon P Wangvoid IntrinsicEmitter:: 1490d52ff1f7b993750a74a5d4432273092de9af069Mon P WangEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 1501a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 1510d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "// Intrinsic ID to overload table\n"; 1520d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 1530d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " // Note that entry #0 is the invalid intrinsic!\n"; 1540d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 1550d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " "; 1560d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang if (Ints[i].isOverloaded) 1570d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "true"; 1580d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang else 1590d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "false"; 1600d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << ",\n"; 1610d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang } 1620d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#endif\n\n"; 1630d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang} 1640d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 166e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (EVT(VT).isInteger()) { 167e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson unsigned BitWidth = EVT(VT).getSizeInBits(); 1681d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "IntegerType::get(Context, " << BitWidth << ")"; 169825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Other) { 170825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::OtherVT is used to mean the empty struct type here. 171d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context)"; 172825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f32) { 1731d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFloatTy(Context)"; 174825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f64) { 1751d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getDoubleTy(Context)"; 176825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f80) { 1771d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getX86_FP80Ty(Context)"; 178825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f128) { 1791d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFP128Ty(Context)"; 180825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::ppcf128) { 1811d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getPPC_FP128Ty(Context)"; 182825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 1831d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Metadata) { 1851d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getMetadataTy(Context)"; 1866994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 1876994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(false && "Unsupported ValueType!"); 18818faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner } 18918faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner} 19018faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner 1911a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 192cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo); 193cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 1941a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, 195cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ArgTypes, 196cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo) { 19793dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.empty()) 19893dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeForValueType(OS, MVT::isVoid); 19993dc92e412fd06250e46951bffb6040eca9baebdChris Lattner 20093dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.size() == 1) 20193dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 202cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 203d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context, "; 204cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 205cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (std::vector<Record*>::const_iterator 20620072af3b0b22d90afbce769409f4ed822520366Bill Wendling I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 207cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, *I, ArgNo); 20820072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << ", "; 20920072af3b0b22d90afbce769409f4ed822520366Bill Wendling } 210cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 21120072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << " NULL)"; 212cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling} 213cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2141a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 21584c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned &ArgNo) { 216825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 2176994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 2196994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 2206994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(Number < ArgNo && "Invalid matching number!"); 221bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 222bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getExtendedElementVectorType" 223bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 224bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 225bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getTruncatedElementVectorType" 226bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 227bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 228bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "Tys[" << Number << "]"; 229825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 23084c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // NOTE: The ArgNo variable here is not the absolute argument number, it is 23184c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // the index of the "arbitrary" type in the Tys array passed to the 23284c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // Intrinsic::getDeclaration function. Consequently, we only want to 2336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // increment it when we actually hit an overloaded type. Getting this wrong 2346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leads to very subtle bugs! 2356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "Tys[" << ArgNo++ << "]"; 236e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } else if (EVT(VT).isVector()) { 237e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VVT = VT; 2389d6565a5b1fbc4286d6ee638d8f47a3171a9ed7eReid Spencer OS << "VectorType::get("; 239825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 24083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands OS << ", " << VVT.getVectorNumElements() << ")"; 241825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTR) { 24243ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb OS << "PointerType::getUnqual("; 243c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 24495af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ")"; 245825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTRAny) { 246e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // Make sure the user has passed us an argument type to overload. If not, 247e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // treat it as an ordinary (not overloaded) intrinsic. 248e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 249e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang << "] : PointerType::getUnqual("; 250e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 251e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << ")"; 252e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ++ArgNo; 253825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 2546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgNo == 0) 2551d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 2566994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth else 257825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::isVoid is used to mean varargs here. 2586994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "..."; 25995af592a631f403e1458ec1155f89fc31011572cJim Laskey } else { 2606994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth EmitTypeForValueType(OS, VT); 26195af592a631f403e1458ec1155f89fc31011572cJim Laskey } 26295af592a631f403e1458ec1155f89fc31011572cJim Laskey} 26395af592a631f403e1458ec1155f89fc31011572cJim Laskey 264da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach/// RecordListComparator - Provide a deterministic comparator for lists of 265c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner/// records. 266c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattnernamespace { 267cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 268c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner struct RecordListComparator { 269cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling bool operator()(const RecPair &LHS, 270cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &RHS) const { 271c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner unsigned i = 0; 272cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *LHSVec = &LHS.first; 273cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *RHSVec = &RHS.first; 274cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned RHSSize = RHSVec->size(); 275cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned LHSSize = LHSVec->size(); 276cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 27793dc92e412fd06250e46951bffb6040eca9baebdChris Lattner for (; i != LHSSize; ++i) { 278cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 279cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 280cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 28193dc92e412fd06250e46951bffb6040eca9baebdChris Lattner } 282cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 283023422a6eb9ea692a5a837dc1daf256ac75ac6b0Bill Wendling if (i != RHSSize) return true; 284cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 285cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling i = 0; 286cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSVec = &LHS.second; 287cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSVec = &RHS.second; 288cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSSize = RHSVec->size(); 289cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSSize = LHSVec->size(); 290cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 291cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (i = 0; i != LHSSize; ++i) { 292cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 293cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 294cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 295cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 296cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 297cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return i != RHSSize; 298c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner } 299c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner }; 300c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner} 301c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 302f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattnervoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 3031a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 304f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 305f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 306f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " switch (ID) {\n"; 307f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 308c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 309c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // This checking can emit a lot of very common code. To reduce the amount of 310c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // code that we emit, batch up cases that have identical types. This avoids 311c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // problems where GCC can run out of memory compiling Verifier.cpp. 312cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 313c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner MapTy UniqueArgInfos; 314c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 315c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Compute the unique argument type info. 316c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 317cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 318cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 319c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 320c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Loop through the array, emitting one comparison for each batch. 321c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (MapTy::iterator I = UniqueArgInfos.begin(), 322c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner E = UniqueArgInfos.end(); I != E; ++I) { 323cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 324c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 325c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner << Ints[I->second[i]].Name << "\n"; 326f124b46b4f18b1a8f054a1222324ae15079f6ed8Chris Lattner 327cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 328cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 329cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 33009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson std::vector<unsigned> OverloadedTypeIndices; 331cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 332cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 333cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling << ParamTys.size(); 334cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 335cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit return types. 336cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 337cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = RetTys[j]; 338cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 339cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 3406994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 3416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 34209b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 34309b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 34409b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 345bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 346bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 347bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 348bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 349bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 350bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 3516994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 352825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 3536994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << getEnumName(VT); 354cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 35561fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 35609b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j); 35709b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 358825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 359cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling throw "Var arg type not last argument"; 360cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 361cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 362cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 363cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit the parameter types. 364cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 365cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = ParamTys[j]; 366cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 367cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 368cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (ArgType->isSubClassOf("LLVMMatchType")) { 369cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned Number = ArgType->getValueAsInt("Number"); 37009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 37109b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 37209b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 373bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 374bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 375bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 376bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 377bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 378bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 379cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } else { 380825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 381cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << getEnumName(VT); 382cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 38361fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 38409b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j + RetTys.size()); 38509b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 386825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 38795d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey throw "Var arg type not last argument"; 38895d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 38995d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 39095d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey 3916994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << ");\n"; 392f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " break;\n"; 393f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner } 394f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " }\n"; 395f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 3969b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner} 3979b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 39895af592a631f403e1458ec1155f89fc31011572cJim Laskeyvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 3991a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 40095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "// Code for generating Intrinsic function declarations.\n"; 40195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 40295af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " switch (id) {\n"; 40395af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 40495af592a631f403e1458ec1155f89fc31011572cJim Laskey 40595af592a631f403e1458ec1155f89fc31011572cJim Laskey // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 40695af592a631f403e1458ec1155f89fc31011572cJim Laskey // types. 407cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 40895af592a631f403e1458ec1155f89fc31011572cJim Laskey MapTy UniqueArgInfos; 40995af592a631f403e1458ec1155f89fc31011572cJim Laskey 41095af592a631f403e1458ec1155f89fc31011572cJim Laskey // Compute the unique argument type info. 41195af592a631f403e1458ec1155f89fc31011572cJim Laskey for (unsigned i = 0, e = Ints.size(); i != e; ++i) 412cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 413cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 41495af592a631f403e1458ec1155f89fc31011572cJim Laskey 41595af592a631f403e1458ec1155f89fc31011572cJim Laskey // Loop through the array, emitting one generator for each batch. 41649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 41749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 41895af592a631f403e1458ec1155f89fc31011572cJim Laskey for (MapTy::iterator I = UniqueArgInfos.begin(), 41995af592a631f403e1458ec1155f89fc31011572cJim Laskey E = UniqueArgInfos.end(); I != E; ++I) { 420cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 42149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 42249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 42395af592a631f403e1458ec1155f89fc31011572cJim Laskey 424cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 425cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 426cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 427cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 428cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned N = ParamTys.size(); 42995af592a631f403e1458ec1155f89fc31011572cJim Laskey 4306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (N > 1 && 431825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 43295af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " IsVarArg = true;\n"; 43395af592a631f403e1458ec1155f89fc31011572cJim Laskey --N; 43495af592a631f403e1458ec1155f89fc31011572cJim Laskey } 435cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 43684c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned ArgNo = 0; 43795af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ResultTy = "; 438cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, RetTys, ArgNo); 43995af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ";\n"; 44095af592a631f403e1458ec1155f89fc31011572cJim Laskey 441cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0; j != N; ++j) { 44295af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ArgTys.push_back("; 443cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, ParamTys[j], ArgNo); 44495af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ");\n"; 44595af592a631f403e1458ec1155f89fc31011572cJim Laskey } 446cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 44795af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " break;\n"; 44895af592a631f403e1458ec1155f89fc31011572cJim Laskey } 449cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 45095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " }\n"; 45195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#endif\n\n"; 45295af592a631f403e1458ec1155f89fc31011572cJim Laskey} 45395af592a631f403e1458ec1155f89fc31011572cJim Laskey 454048ffb239c282277959463c61200b86e2380cb84Chris Lattner/// EmitAttributes - This emits the Intrinsic::getAttributes method. 4554e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattnervoid IntrinsicEmitter:: 4561a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 457a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 458a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 45949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) 46049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static AttrListPtr getAttributes(" << TargetPrefix 46149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "Intrinsic::ID id) {"; 46249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen else 46349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 464048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << " // No intrinsic can throw exceptions.\n"; 465048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << " Attributes Attr = Attribute::NoUnwind;\n"; 466a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " switch (id) {\n"; 4677056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner OS << " default: break;\n"; 46810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner unsigned MaxArgAttrs = 0; 4697056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 47010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner MaxArgAttrs = 47110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 4727056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner switch (Ints[i].ModRef) { 4737056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner default: break; 4747056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner case CodeGenIntrinsic::NoMem: 47549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 47649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 4777056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner break; 4787056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner } 4797056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner } 4800598866c052147c31b808391f58434ce3dbfb838Devang Patel OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 481a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " break;\n"; 4824e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 4834e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner switch (Ints[i].ModRef) { 484022f64fbbc4669623e79b805379266fed519017dChris Lattner default: break; 485022f64fbbc4669623e79b805379266fed519017dChris Lattner case CodeGenIntrinsic::ReadArgMem: 486022f64fbbc4669623e79b805379266fed519017dChris Lattner case CodeGenIntrinsic::ReadMem: 48749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 48849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 489022f64fbbc4669623e79b805379266fed519017dChris Lattner break; 4904e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 4914e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 4920598866c052147c31b808391f58434ce3dbfb838Devang Patel OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 493a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " break;\n"; 4944e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner OS << " }\n"; 49510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 496d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " unsigned NumAttrs = 0;\n"; 49710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " switch (id) {\n"; 49810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " default: break;\n"; 49910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 50010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner // Add argument attributes for any intrinsics that have them. 50110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 50210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner if (Ints[i].ArgumentAttributes.empty()) continue; 50310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 50449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 50549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 50610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 50710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 50810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner Ints[i].ArgumentAttributes; 50910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner // Sort by argument index. 51010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::sort(ArgAttrs.begin(), ArgAttrs.end()); 51110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 51210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner unsigned NumArgsWithAttrs = 0; 51310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 514d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner while (!ArgAttrs.empty()) { 515d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner unsigned ArgNo = ArgAttrs[0].first; 516d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 517d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 518d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner << ArgNo+1 << ", 0"; 519d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 520d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 521d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner switch (ArgAttrs[0].second) { 522d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner default: assert(0 && "Unknown arg attribute"); 523d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner case CodeGenIntrinsic::NoCapture: 524d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "|Attribute::NoCapture"; 525d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner break; 526d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 527d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner ArgAttrs.erase(ArgAttrs.begin()); 528d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 529d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << ");\n"; 530d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 53110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 532d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 53310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " break;\n"; 53410dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner } 53510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 53610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " }\n"; 537d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 538d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 539048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << "}\n"; 540d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 5414e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner} 542022f64fbbc4669623e79b805379266fed519017dChris Lattner 543d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 544d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sandsvoid IntrinsicEmitter:: 5451a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 546d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 547d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 5487c422ac216fe39fc9c402a704cf296cca9dc5b22Duncan Sands OS << "switch (iid) {\n"; 549d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "default:\n return UnknownModRefBehavior;\n"; 550d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 5517365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem) 552d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands continue; 553d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 554d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands << ":\n"; 555d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands switch (Ints[i].ModRef) { 556d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands default: 557d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands assert(false && "Unknown Mod/Ref type!"); 558d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::NoMem: 559d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return DoesNotAccessMemory;\n"; 560d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 561d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadArgMem: 562d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadMem: 563d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return OnlyReadsMemory;\n"; 564d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 5657365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman case CodeGenIntrinsic::ReadWriteArgMem: 566d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return AccessesArguments;\n"; 567d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 568d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 569d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 570d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "}\n"; 571d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 572d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands} 573d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 574022f64fbbc4669623e79b805379266fed519017dChris Lattnervoid IntrinsicEmitter:: 5751a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 576022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 577022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 578022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " switch (F->getIntrinsicID()) {\n"; 579022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " default: BuiltinName = \"\"; break;\n"; 580022f64fbbc4669623e79b805379266fed519017dChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 581022f64fbbc4669623e79b805379266fed519017dChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 582022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 583022f64fbbc4669623e79b805379266fed519017dChris Lattner << Ints[i].GCCBuiltinName << "\"; break;\n"; 584022f64fbbc4669623e79b805379266fed519017dChris Lattner } 585022f64fbbc4669623e79b805379266fed519017dChris Lattner } 586022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " }\n"; 587022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#endif\n\n"; 588767a25b8788b5e313c99c16b4d359478432901f5Reid Spencer} 5893f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 590331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// EmitTargetBuiltins - All of the builtins in the specified map are for the 591331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// same target, and we already checked it. 592331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnerstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 59349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen const std::string &TargetPrefix, 5941a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 595331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 596298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::vector<StringMatcher::StringPair> Results; 597331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 598298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), 599298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner E = BIM.end(); I != E; ++I) { 600298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::string ResultCode = 601298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner "return " + TargetPrefix + "Intrinsic::" + I->second + ";"; 602298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner Results.push_back(StringMatcher::StringPair(I->first, ResultCode)); 603331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 604298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner 605298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner StringMatcher("BuiltinName", Results, OS).Emit(); 606331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner} 607331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 608331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 6093f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattnervoid IntrinsicEmitter:: 6103f8b8913bc9cb232871445eefa8654caf7f9986fChris LattnerEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 6111a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 612fa0fba1c546091c485e5513eadeef181dda370abChris Lattner typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 6133f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner BIMTy BuiltinMap; 6143f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 6153f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 616fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Get the map for this target prefix. 617fa0fba1c546091c485e5513eadeef181dda370abChris Lattner std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 618fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 619fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 620fa0fba1c546091c485e5513eadeef181dda370abChris Lattner Ints[i].EnumName)).second) 6213f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner throw "Intrinsic '" + Ints[i].TheDef->getName() + 6223f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner "': duplicate GCC builtin name!"; 6233f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6243f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6253f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 6263f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 6273f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 6283f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 6293f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 6303f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 63149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 63249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) { 63349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static " << TargetPrefix << "Intrinsic::ID " 63449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "getIntrinsicForGCCBuiltin(const char " 635298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 63649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } else { 63749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 638298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 63949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } 64049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 641298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef BuiltinName(BuiltinNameStr);\n"; 642298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; 643331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 6443f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Note: this could emit significantly better code if we cared. 6453f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 646fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " "; 647fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!I->first.empty()) 648298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "if (TargetPrefix == \"" << I->first << "\") "; 649fa0fba1c546091c485e5513eadeef181dda370abChris Lattner else 650fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "/* Target Independent Builtins */ "; 651fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "{\n"; 652fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 653fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Emit the comparisons for this target prefix. 65449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitTargetBuiltins(I->second, TargetPrefix, OS); 655fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " }\n"; 6563f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 657298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " return "; 658298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner if (!TargetPrefix.empty()) 659298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "(" << TargetPrefix << "Intrinsic::ID)"; 660298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "Intrinsic::not_intrinsic;\n"; 66149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "}\n"; 6623f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#endif\n\n"; 6633f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner} 664