IntrinsicEmitter.cpp revision bd0fa4c00d7870b1da36eac7b2181700381f2f96
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" 711f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer "#if defined(_MSC_VER) && defined(setjmp) && \\\n" 721f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer " !defined(setjmp_undefined_for_msvc)\n" 7308047f616977f204df6054c481601f2237cc308dMichael J. Spencer "# pragma push_macro(\"setjmp\")\n" 7408047f616977f204df6054c481601f2237cc308dMichael J. Spencer "# undef setjmp\n" 751f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer "# define setjmp_undefined_for_msvc\n" 767d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#endif\n\n"; 777d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor} 787d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 797d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregorvoid IntrinsicEmitter::EmitSuffix(raw_ostream &OS) { 801f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer OS << "#if defined(_MSC_VER) && defined(setjmp_undefined_for_msvc)\n" 817d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "// let's return it to _setjmp state\n" 8208047f616977f204df6054c481601f2237cc308dMichael J. Spencer "# pragma pop_macro(\"setjmp\")\n" 831f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer "# undef setjmp_undefined_for_msvc\n" 847d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor "#endif\n\n"; 859e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner} 869e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 879e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnervoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 881a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 899b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Enum values for Intrinsics.h\n"; 909e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 919e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 929e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << " " << Ints[i].EnumName; 939e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << ((i != e-1) ? ", " : " "); 949e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << std::string(40-Ints[i].EnumName.size(), ' ') 959e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner << "// " << Ints[i].Name << "\n"; 969e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner } 979e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << "#endif\n\n"; 989e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner} 999b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 1009b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattnervoid IntrinsicEmitter:: 1019b843b249462980ae4630dc37d1bcccde884a5a7Chris LattnerEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 1021a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 103cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Build a 'first character of function name' -> intrinsic # mapping. 104cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::map<char, std::vector<unsigned> > IntMapping; 1059b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 106cc67c75b67d22653ea9380020e9a40381233901dChris Lattner IntMapping[Ints[i].Name[5]].push_back(i); 107cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 1089b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Function name -> enum value recognizer code.\n"; 1099b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 110cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " StringRef NameR(Name+6, Len-6); // Skip over 'llvm.'\n"; 111cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " switch (Name[5]) { // Dispatch on first letter.\n"; 112cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " default: break;\n"; 113cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Emit the intrinsic matching stuff by first letter. 114cc67c75b67d22653ea9380020e9a40381233901dChris Lattner for (std::map<char, std::vector<unsigned> >::iterator I = IntMapping.begin(), 1159b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner E = IntMapping.end(); I != E; ++I) { 116cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " case '" << I->first << "':\n"; 117cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::vector<unsigned> &IntList = I->second; 118cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 119cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Emit all the overloaded intrinsics first, build a table of the 120cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // non-overloaded ones. 121cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::vector<StringMatcher::StringPair> MatchTable; 1229b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 123cc67c75b67d22653ea9380020e9a40381233901dChris Lattner for (unsigned i = 0, e = IntList.size(); i != e; ++i) { 124cc67c75b67d22653ea9380020e9a40381233901dChris Lattner unsigned IntNo = IntList[i]; 125cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::string Result = "return " + TargetPrefix + "Intrinsic::" + 126cc67c75b67d22653ea9380020e9a40381233901dChris Lattner Ints[IntNo].EnumName + ";"; 127cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 128cc67c75b67d22653ea9380020e9a40381233901dChris Lattner if (!Ints[IntNo].isOverloaded) { 129cc67c75b67d22653ea9380020e9a40381233901dChris Lattner MatchTable.push_back(std::make_pair(Ints[IntNo].Name.substr(6),Result)); 130cc67c75b67d22653ea9380020e9a40381233901dChris Lattner continue; 131cc67c75b67d22653ea9380020e9a40381233901dChris Lattner } 132cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 133cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // For overloaded intrinsics, only the prefix needs to match 134cc67c75b67d22653ea9380020e9a40381233901dChris Lattner std::string TheStr = Ints[IntNo].Name.substr(6); 1352738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner TheStr += '.'; // Require "bswap." instead of bswap. 136cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " if (NameR.startswith(\"" << TheStr << "\")) " 137cc67c75b67d22653ea9380020e9a40381233901dChris Lattner << Result << '\n'; 1382738ff9c22d27ce3e4aee6f250eb68f594db1ce9Chris Lattner } 139cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 140cc67c75b67d22653ea9380020e9a40381233901dChris Lattner // Emit the matcher logic for the fixed length strings. 141cc67c75b67d22653ea9380020e9a40381233901dChris Lattner StringMatcher("NameR", MatchTable, OS).Emit(1); 142cc67c75b67d22653ea9380020e9a40381233901dChris Lattner OS << " break; // end of '" << I->first << "' case.\n"; 1439b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner } 144cc67c75b67d22653ea9380020e9a40381233901dChris Lattner 1459b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " }\n"; 146f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 147f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner} 148f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner 149fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattnervoid IntrinsicEmitter:: 150fda6affb95e9f68278cb5cf75dc3fd3406978255Chris LattnerEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 1511a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 152fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "// Intrinsic ID to name table\n"; 153fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 154fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << " // Note that entry #0 is the invalid intrinsic!\n"; 155f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng for (unsigned i = 0, e = Ints.size(); i != e; ++i) 156f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng OS << " \"" << Ints[i].Name << "\",\n"; 157fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#endif\n\n"; 158fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner} 159fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 1600d52ff1f7b993750a74a5d4432273092de9af069Mon P Wangvoid IntrinsicEmitter:: 1610d52ff1f7b993750a74a5d4432273092de9af069Mon P WangEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 1621a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 1630d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "// Intrinsic ID to overload table\n"; 1640d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 1650d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " // Note that entry #0 is the invalid intrinsic!\n"; 1660d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 1670d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " "; 1680d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang if (Ints[i].isOverloaded) 1690d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "true"; 1700d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang else 1710d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "false"; 1720d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << ",\n"; 1730d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang } 1740d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#endif\n\n"; 1750d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang} 1760d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 177825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 178e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (EVT(VT).isInteger()) { 179e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson unsigned BitWidth = EVT(VT).getSizeInBits(); 1801d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "IntegerType::get(Context, " << BitWidth << ")"; 181825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Other) { 182825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::OtherVT is used to mean the empty struct type here. 183d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context)"; 184825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f32) { 1851d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFloatTy(Context)"; 186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f64) { 1871d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getDoubleTy(Context)"; 188825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f80) { 1891d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getX86_FP80Ty(Context)"; 190825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f128) { 1911d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFP128Ty(Context)"; 192825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::ppcf128) { 1931d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getPPC_FP128Ty(Context)"; 194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 1951d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 196825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Metadata) { 1971d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getMetadataTy(Context)"; 1988be452545a1d3921f006c4d5673f14165ceead82Dale Johannesen } else if (VT == MVT::x86mmx) { 1998be452545a1d3921f006c4d5673f14165ceead82Dale Johannesen OS << "Type::getX86_MMXTy(Context)"; 2006994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 2016994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(false && "Unsupported ValueType!"); 20218faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner } 20318faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner} 20418faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner 2051a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 206cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo); 207cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2081a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, 209cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ArgTypes, 210cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo) { 21193dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.empty()) 21293dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeForValueType(OS, MVT::isVoid); 21393dc92e412fd06250e46951bffb6040eca9baebdChris Lattner 21493dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.size() == 1) 21593dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 216cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 217d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context, "; 218cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 219cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (std::vector<Record*>::const_iterator 22020072af3b0b22d90afbce769409f4ed822520366Bill Wendling I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 221cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, *I, ArgNo); 22220072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << ", "; 22320072af3b0b22d90afbce769409f4ed822520366Bill Wendling } 224cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 22520072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << " NULL)"; 226cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling} 227cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 2281a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 22984c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned &ArgNo) { 230825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 2316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2326994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 2336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 2346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(Number < ArgNo && "Invalid matching number!"); 235bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 236bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getExtendedElementVectorType" 237bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 238bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 239bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getTruncatedElementVectorType" 240bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 241bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 242bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "Tys[" << Number << "]"; 243825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 24484c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // NOTE: The ArgNo variable here is not the absolute argument number, it is 24584c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // the index of the "arbitrary" type in the Tys array passed to the 24684c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // Intrinsic::getDeclaration function. Consequently, we only want to 2476994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // increment it when we actually hit an overloaded type. Getting this wrong 2486994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leads to very subtle bugs! 2496994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "Tys[" << ArgNo++ << "]"; 250e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } else if (EVT(VT).isVector()) { 251e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VVT = VT; 2529d6565a5b1fbc4286d6ee638d8f47a3171a9ed7eReid Spencer OS << "VectorType::get("; 253825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 25483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands OS << ", " << VVT.getVectorNumElements() << ")"; 255825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTR) { 25643ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb OS << "PointerType::getUnqual("; 257c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 25895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ")"; 259825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTRAny) { 260e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // Make sure the user has passed us an argument type to overload. If not, 261e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // treat it as an ordinary (not overloaded) intrinsic. 262e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 263e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang << "] : PointerType::getUnqual("; 264e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 265e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << ")"; 266e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ++ArgNo; 267825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 2686994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgNo == 0) 2691d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 2706994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth else 271825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::isVoid is used to mean varargs here. 2726994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "..."; 27395af592a631f403e1458ec1155f89fc31011572cJim Laskey } else { 2746994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth EmitTypeForValueType(OS, VT); 27595af592a631f403e1458ec1155f89fc31011572cJim Laskey } 27695af592a631f403e1458ec1155f89fc31011572cJim Laskey} 27795af592a631f403e1458ec1155f89fc31011572cJim Laskey 278da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach/// RecordListComparator - Provide a deterministic comparator for lists of 279c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner/// records. 280c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattnernamespace { 281cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 282c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner struct RecordListComparator { 283cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling bool operator()(const RecPair &LHS, 284cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &RHS) const { 285c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner unsigned i = 0; 286cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *LHSVec = &LHS.first; 287cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *RHSVec = &RHS.first; 288cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned RHSSize = RHSVec->size(); 289cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned LHSSize = LHSVec->size(); 290cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 29193dc92e412fd06250e46951bffb6040eca9baebdChris Lattner for (; 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(); 29593dc92e412fd06250e46951bffb6040eca9baebdChris Lattner } 296cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 297023422a6eb9ea692a5a837dc1daf256ac75ac6b0Bill Wendling if (i != RHSSize) return true; 298cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 299cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling i = 0; 300cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSVec = &LHS.second; 301cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSVec = &RHS.second; 302cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSSize = RHSVec->size(); 303cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSSize = LHSVec->size(); 304cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 305cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (i = 0; i != LHSSize; ++i) { 306cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 307cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 308cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 309cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 310cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 311cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return i != RHSSize; 312c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner } 313c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner }; 314c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner} 315c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 316f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattnervoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 3171a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 318f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 319f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 320f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " switch (ID) {\n"; 321f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 322c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 323c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // This checking can emit a lot of very common code. To reduce the amount of 324c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // code that we emit, batch up cases that have identical types. This avoids 325c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // problems where GCC can run out of memory compiling Verifier.cpp. 326cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 327c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner MapTy UniqueArgInfos; 328c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 329c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Compute the unique argument type info. 330c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 331cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 332cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 333c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 334c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Loop through the array, emitting one comparison for each batch. 335c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (MapTy::iterator I = UniqueArgInfos.begin(), 336c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner E = UniqueArgInfos.end(); I != E; ++I) { 337cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 338c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 339c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner << Ints[I->second[i]].Name << "\n"; 340f124b46b4f18b1a8f054a1222324ae15079f6ed8Chris Lattner 341cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 342cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 343cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 34409b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson std::vector<unsigned> OverloadedTypeIndices; 345cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 346cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 347cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling << ParamTys.size(); 348cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 349cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit return types. 350cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 351cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = RetTys[j]; 352cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 353cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 3546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 3556994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 35609b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 35709b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 35809b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 359bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 360bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 361bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 362bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 363bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 364bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 3656994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 366825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 3676994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << getEnumName(VT); 368cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 36961fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 37009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j); 37109b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 372825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 373cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling throw "Var arg type not last argument"; 374cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 375cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 376cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 377cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit the parameter types. 378cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 379cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = ParamTys[j]; 380cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 381cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 382cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (ArgType->isSubClassOf("LLVMMatchType")) { 383cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned Number = ArgType->getValueAsInt("Number"); 38409b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 38509b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 38609b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 387bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 388bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 389bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 390bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 391bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 392bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 393cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } else { 394825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 395cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << getEnumName(VT); 396cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 39761fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 39809b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j + RetTys.size()); 39909b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 400825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 40195d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey throw "Var arg type not last argument"; 40295d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 40395d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 40495d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey 4056994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << ");\n"; 406f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " break;\n"; 407f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner } 408f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " }\n"; 409f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 4109b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner} 4119b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 41295af592a631f403e1458ec1155f89fc31011572cJim Laskeyvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 4131a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 41495af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "// Code for generating Intrinsic function declarations.\n"; 41595af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 41695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " switch (id) {\n"; 41795af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 41895af592a631f403e1458ec1155f89fc31011572cJim Laskey 41995af592a631f403e1458ec1155f89fc31011572cJim Laskey // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 42095af592a631f403e1458ec1155f89fc31011572cJim Laskey // types. 421cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 42295af592a631f403e1458ec1155f89fc31011572cJim Laskey MapTy UniqueArgInfos; 42395af592a631f403e1458ec1155f89fc31011572cJim Laskey 42495af592a631f403e1458ec1155f89fc31011572cJim Laskey // Compute the unique argument type info. 42595af592a631f403e1458ec1155f89fc31011572cJim Laskey for (unsigned i = 0, e = Ints.size(); i != e; ++i) 426cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 427cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 42895af592a631f403e1458ec1155f89fc31011572cJim Laskey 42995af592a631f403e1458ec1155f89fc31011572cJim Laskey // Loop through the array, emitting one generator for each batch. 43049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 43149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 43295af592a631f403e1458ec1155f89fc31011572cJim Laskey for (MapTy::iterator I = UniqueArgInfos.begin(), 43395af592a631f403e1458ec1155f89fc31011572cJim Laskey E = UniqueArgInfos.end(); I != E; ++I) { 434cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 43549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 43649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 43795af592a631f403e1458ec1155f89fc31011572cJim Laskey 438cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 439cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 440cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 441cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 442cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned N = ParamTys.size(); 44395af592a631f403e1458ec1155f89fc31011572cJim Laskey 4446994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (N > 1 && 445825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 44695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " IsVarArg = true;\n"; 44795af592a631f403e1458ec1155f89fc31011572cJim Laskey --N; 44895af592a631f403e1458ec1155f89fc31011572cJim Laskey } 449cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 45084c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned ArgNo = 0; 45195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ResultTy = "; 452cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, RetTys, ArgNo); 45395af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ";\n"; 45495af592a631f403e1458ec1155f89fc31011572cJim Laskey 455cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0; j != N; ++j) { 45695af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ArgTys.push_back("; 457cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, ParamTys[j], ArgNo); 45895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ");\n"; 45995af592a631f403e1458ec1155f89fc31011572cJim Laskey } 460cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 46195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " break;\n"; 46295af592a631f403e1458ec1155f89fc31011572cJim Laskey } 463cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 46495af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " }\n"; 46595af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#endif\n\n"; 46695af592a631f403e1458ec1155f89fc31011572cJim Laskey} 46795af592a631f403e1458ec1155f89fc31011572cJim Laskey 468bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCallnamespace { 469bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall enum ModRefKind { 470bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall MRK_none, 471bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall MRK_readonly, 472bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall MRK_readnone 473bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall }; 474bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 475bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind getModRefKind(const CodeGenIntrinsic &intrinsic) { 476bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall switch (intrinsic.ModRef) { 477bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::NoMem: 478bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_readnone; 479bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadArgMem: 480bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadMem: 481bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_readonly; 482bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadWriteArgMem: 483bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case CodeGenIntrinsic::ReadWriteMem: 484bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_none; 485bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 486bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall assert(0 && "bad mod-ref kind"); 487bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return MRK_none; 488bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 489bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 490bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall struct AttributeComparator { 491bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall bool operator()(const CodeGenIntrinsic *L, const CodeGenIntrinsic *R) const { 492bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Sort throwing intrinsics after non-throwing intrinsics. 493bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (L->canThrow != R->canThrow) 494bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return R->canThrow; 495bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 496bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Try to order by readonly/readnone attribute. 497bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind LK = getModRefKind(*L); 498bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind RK = getModRefKind(*R); 499bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (LK != RK) return (LK > RK); 500bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 501bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Order by argument attributes. 502bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // This is reliable because each side is already sorted internally. 503bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall return (L->ArgumentAttributes < R->ArgumentAttributes); 504bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 505bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall }; 506bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall} 507bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 508048ffb239c282277959463c61200b86e2380cb84Chris Lattner/// EmitAttributes - This emits the Intrinsic::getAttributes method. 5094e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattnervoid IntrinsicEmitter:: 5101a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 511a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 512a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 51349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) 51449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static AttrListPtr getAttributes(" << TargetPrefix 515bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall << "Intrinsic::ID id) {\n"; 51649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen else 517bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << "AttrListPtr Intrinsic::getAttributes(ID id) {\n"; 518bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 519bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Compute the maximum number of attribute arguments. 520bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall std::vector<const CodeGenIntrinsic*> sortedIntrinsics(Ints.size()); 521bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall unsigned maxArgAttrs = 0; 5224e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 523bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall const CodeGenIntrinsic &intrinsic = Ints[i]; 524bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall sortedIntrinsics[i] = &intrinsic; 525bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall maxArgAttrs = 526bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall std::max(maxArgAttrs, unsigned(intrinsic.ArgumentAttributes.size())); 5274e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 528bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 529bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Emit an array of AttributeWithIndex. Most intrinsics will have 530bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // at least one entry, for the function itself (index ~1), which is 531bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // usually nounwind. 532bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n"; 533d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " unsigned NumAttrs = 0;\n"; 53410dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " switch (id) {\n"; 535bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " default: break;\n"; 536bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 537bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall AttributeComparator precedes; 538bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 539bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall std::stable_sort(sortedIntrinsics.begin(), sortedIntrinsics.end(), precedes); 54010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 541bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall for (unsigned i = 0, e = sortedIntrinsics.size(); i != e; ++i) { 542bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall const CodeGenIntrinsic &intrinsic = *sortedIntrinsics[i]; 543bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " case " << TargetPrefix << "Intrinsic::" 544bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall << intrinsic.EnumName << ":\n"; 54510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 546bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Fill out the case if this is the last case for this range of 547bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // intrinsics. 548bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (i + 1 != e && !precedes(&intrinsic, sortedIntrinsics[i + 1])) 549bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall continue; 550bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 551bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // Keep track of the number of attributes we're writing out. 552bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall unsigned numAttrs = 0; 55310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 554bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall // The argument attributes are alreadys sorted by argument index. 555bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall for (unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size(); ai != ae;) { 556bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall unsigned argNo = intrinsic.ArgumentAttributes[ai].first; 557d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 558bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(" 559bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall << argNo+1 << ", "; 560bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 561bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall bool moreThanOne = false; 562d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 563bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall do { 564bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (moreThanOne) OS << '|'; 565bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 566bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall switch (intrinsic.ArgumentAttributes[ai].second) { 567d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner case CodeGenIntrinsic::NoCapture: 568bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << "Attribute::NoCapture"; 569d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner break; 570d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 571bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 572bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ++ai; 573bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall moreThanOne = true; 574bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo); 575bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 576bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << ");\n"; 577bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 578bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 579bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall ModRefKind modRef = getModRefKind(intrinsic); 580bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 581bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (!intrinsic.canThrow || modRef) { 582bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, "; 583bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (!intrinsic.canThrow) { 584bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << "Attribute::NoUnwind"; 585bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (modRef) OS << '|'; 586bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 587bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall switch (modRef) { 588bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case MRK_none: break; 589bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case MRK_readonly: OS << "Attribute::ReadOnly"; break; 590bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall case MRK_readnone: OS << "Attribute::ReadNone"; break; 591d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 592d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << ");\n"; 593d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 594bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall 595bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall if (numAttrs) { 596bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " NumAttrs = " << numAttrs << ";\n"; 597bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " break;\n"; 598bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } else { 599bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " return AttrListPtr();\n"; 600bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall } 60110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner } 60210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 60310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " }\n"; 604bd0fa4c00d7870b1da36eac7b2181700381f2f96John McCall OS << " return AttrListPtr::get(AWI, NumAttrs);\n"; 605048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << "}\n"; 606d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 6074e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner} 608022f64fbbc4669623e79b805379266fed519017dChris Lattner 609d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 610d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sandsvoid IntrinsicEmitter:: 6111a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 612d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 613d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 6147c422ac216fe39fc9c402a704cf296cca9dc5b22Duncan Sands OS << "switch (iid) {\n"; 615d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "default:\n return UnknownModRefBehavior;\n"; 616d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 6177365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem) 618d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands continue; 619d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 620d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands << ":\n"; 621d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands switch (Ints[i].ModRef) { 622d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands default: 623d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands assert(false && "Unknown Mod/Ref type!"); 624d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::NoMem: 625d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return DoesNotAccessMemory;\n"; 626d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 627d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadArgMem: 628e88ccb545d0e03fd4445d361100fc95f350c6663Dan Gohman OS << " return OnlyReadsArgumentPointees;\n"; 6299423f633654af6045b1efa7795edfe8ea0533d7eDan Gohman break; 630d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadMem: 631d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return OnlyReadsMemory;\n"; 632d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 6337365c091f92db5e68c98d7faedc6c34e1bbbc898Dan Gohman case CodeGenIntrinsic::ReadWriteArgMem: 634e88ccb545d0e03fd4445d361100fc95f350c6663Dan Gohman OS << " return OnlyAccessesArgumentPointees;\n"; 635d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 636d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 637d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 638d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "}\n"; 639d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 640d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands} 641d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 642022f64fbbc4669623e79b805379266fed519017dChris Lattnervoid IntrinsicEmitter:: 6431a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 644022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 645022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 646022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " switch (F->getIntrinsicID()) {\n"; 647022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " default: BuiltinName = \"\"; break;\n"; 648022f64fbbc4669623e79b805379266fed519017dChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 649022f64fbbc4669623e79b805379266fed519017dChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 650022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 651022f64fbbc4669623e79b805379266fed519017dChris Lattner << Ints[i].GCCBuiltinName << "\"; break;\n"; 652022f64fbbc4669623e79b805379266fed519017dChris Lattner } 653022f64fbbc4669623e79b805379266fed519017dChris Lattner } 654022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " }\n"; 655022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#endif\n\n"; 656767a25b8788b5e313c99c16b4d359478432901f5Reid Spencer} 6573f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 658331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// EmitTargetBuiltins - All of the builtins in the specified map are for the 659331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// same target, and we already checked it. 660331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnerstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 66149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen const std::string &TargetPrefix, 6621a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 663331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 664298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::vector<StringMatcher::StringPair> Results; 665331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 666298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner for (std::map<std::string, std::string>::const_iterator I = BIM.begin(), 667298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner E = BIM.end(); I != E; ++I) { 668298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner std::string ResultCode = 669298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner "return " + TargetPrefix + "Intrinsic::" + I->second + ";"; 670298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner Results.push_back(StringMatcher::StringPair(I->first, ResultCode)); 671331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 672298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner 673298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner StringMatcher("BuiltinName", Results, OS).Emit(); 674331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner} 675331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 676331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 6773f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattnervoid IntrinsicEmitter:: 6783f8b8913bc9cb232871445eefa8654caf7f9986fChris LattnerEmitIntrinsicToGCCBuiltinMap(const std::vector<CodeGenIntrinsic> &Ints, 6791a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 680fa0fba1c546091c485e5513eadeef181dda370abChris Lattner typedef std::map<std::string, std::map<std::string, std::string> > BIMTy; 6813f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner BIMTy BuiltinMap; 6823f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 6833f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 684fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Get the map for this target prefix. 685fa0fba1c546091c485e5513eadeef181dda370abChris Lattner std::map<std::string, std::string> &BIM =BuiltinMap[Ints[i].TargetPrefix]; 686fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 687fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!BIM.insert(std::make_pair(Ints[i].GCCBuiltinName, 688fa0fba1c546091c485e5513eadeef181dda370abChris Lattner Ints[i].EnumName)).second) 6893f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner throw "Intrinsic '" + Ints[i].TheDef->getName() + 6903f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner "': duplicate GCC builtin name!"; 6913f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6923f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 6933f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 6943f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// Get the LLVM intrinsic that corresponds to a GCC builtin.\n"; 6953f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// This is used by the C front-end. The GCC builtin name is passed\n"; 6963f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n"; 6973f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n"; 6983f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#ifdef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN\n"; 69949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 70049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) { 70149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static " << TargetPrefix << "Intrinsic::ID " 70249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "getIntrinsicForGCCBuiltin(const char " 703298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 70449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } else { 70549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 706298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner << "*TargetPrefixStr, const char *BuiltinNameStr) {\n"; 70749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } 70849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 709298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef BuiltinName(BuiltinNameStr);\n"; 710298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n"; 711331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 7123f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Note: this could emit significantly better code if we cared. 7133f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 714fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " "; 715fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!I->first.empty()) 716298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "if (TargetPrefix == \"" << I->first << "\") "; 717fa0fba1c546091c485e5513eadeef181dda370abChris Lattner else 718fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "/* Target Independent Builtins */ "; 719fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "{\n"; 720fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 721fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Emit the comparisons for this target prefix. 72249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitTargetBuiltins(I->second, TargetPrefix, OS); 723fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " }\n"; 7243f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 725298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << " return "; 726298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner if (!TargetPrefix.empty()) 727298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "(" << TargetPrefix << "Intrinsic::ID)"; 728298b176559d5c76d7d9f7fdd06429a75892de043Chris Lattner OS << "Intrinsic::not_intrinsic;\n"; 72949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "}\n"; 7303f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#endif\n\n"; 7313f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner} 732