IntrinsicEmitter.cpp revision 93dc92e412fd06250e46951bffb6040eca9baebd
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" 1718faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner#include "llvm/ADT/StringExtras.h" 1871c3bc3d966bd874f760abf055c559673f925029Jeff Cohen#include <algorithm> 199e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnerusing namespace llvm; 209e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 219e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===// 229e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner// IntrinsicEmitter Implementation 239e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner//===----------------------------------------------------------------------===// 249e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 251a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid IntrinsicEmitter::run(raw_ostream &OS) { 269e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner EmitSourceFileHeader("Intrinsic Function Source Fragment", OS); 279e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 2849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::vector<CodeGenIntrinsic> Ints = LoadIntrinsics(Records, TargetOnly); 2949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 3049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly && !Ints.empty()) 3149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen TargetPrefix = Ints[0].TargetPrefix; 329e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 339e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner // Emit the enum information. 349e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner EmitEnumInfo(Ints, OS); 35fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 36fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner // Emit the intrinsic ID -> name table. 37fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner EmitIntrinsicToNameTable(Ints, OS); 380d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 390d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang // Emit the intrinsic ID -> overload table. 400d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang EmitIntrinsicToOverloadTable(Ints, OS); 410d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 429b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner // Emit the function name recognizer. 439b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner EmitFnNameRecognizer(Ints, OS); 44fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 45f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner // Emit the intrinsic verifier. 46f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner EmitVerifier(Ints, OS); 476448ee44c6f232f215d5d9f145a0d71a983c4a3fChris Lattner 4895af592a631f403e1458ec1155f89fc31011572cJim Laskey // Emit the intrinsic declaration generator. 4995af592a631f403e1458ec1155f89fc31011572cJim Laskey EmitGenerator(Ints, OS); 5095af592a631f403e1458ec1155f89fc31011572cJim Laskey 51a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands // Emit the intrinsic parameter attributes. 52a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands EmitAttributes(Ints, OS); 53022f64fbbc4669623e79b805379266fed519017dChris Lattner 54d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands // Emit intrinsic alias analysis mod/ref behavior. 55d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands EmitModRefBehavior(Ints, OS); 56d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 57022f64fbbc4669623e79b805379266fed519017dChris Lattner // Emit a list of intrinsics with corresponding GCC builtins. 58022f64fbbc4669623e79b805379266fed519017dChris Lattner EmitGCCBuiltinList(Ints, OS); 593f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 603f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Emit code to translate GCC builtins into LLVM intrinsics. 613f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner EmitIntrinsicToGCCBuiltinMap(Ints, OS); 629e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner} 639e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner 649e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattnervoid IntrinsicEmitter::EmitEnumInfo(const std::vector<CodeGenIntrinsic> &Ints, 651a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 669b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Enum values for Intrinsics.h\n"; 679e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << "#ifdef GET_INTRINSIC_ENUM_VALUES\n"; 689e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 699e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << " " << Ints[i].EnumName; 709e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << ((i != e-1) ? ", " : " "); 719e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << std::string(40-Ints[i].EnumName.size(), ' ') 729e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner << "// " << Ints[i].Name << "\n"; 739e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner } 749e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner OS << "#endif\n\n"; 759e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner} 769b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 779b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattnervoid IntrinsicEmitter:: 789b843b249462980ae4630dc37d1bcccde884a5a7Chris LattnerEmitFnNameRecognizer(const std::vector<CodeGenIntrinsic> &Ints, 791a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 809b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner // Build a function name -> intrinsic name mapping. 81c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer std::map<std::string, unsigned> IntMapping; 829b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 83c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer IntMapping[Ints[i].Name] = i; 849b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 859b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "// Function name -> enum value recognizer code.\n"; 869b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << "#ifdef GET_FUNCTION_RECOGNIZER\n"; 879b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " switch (Name[5]) {\n"; 883b515802f652b16b05c9a8f344d219a0739b36a3Chris Lattner OS << " default:\n"; 899b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner // Emit the intrinsics in sorted order. 909b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner char LastChar = 0; 91c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer for (std::map<std::string, unsigned>::iterator I = IntMapping.begin(), 929b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner E = IntMapping.end(); I != E; ++I) { 939b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner if (I->first[5] != LastChar) { 949b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner LastChar = I->first[5]; 953b515802f652b16b05c9a8f344d219a0739b36a3Chris Lattner OS << " break;\n"; 969b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " case '" << LastChar << "':\n"; 979b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner } 989b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 99c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer // For overloaded intrinsics, only the prefix needs to match 100c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer if (Ints[I->second].isOverloaded) 1016994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << " if (Len > " << I->first.size() 1026994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth << " && !memcmp(Name, \"" << I->first << ".\", " 10349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << (I->first.size() + 1) << ")) return " << TargetPrefix << "Intrinsic::" 1046994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth << Ints[I->second].EnumName << ";\n"; 105c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer else 106c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer OS << " if (Len == " << I->first.size() 1076994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth << " && !memcmp(Name, \"" << I->first << "\", " 10849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << I->first.size() << ")) return " << TargetPrefix << "Intrinsic::" 109c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer << Ints[I->second].EnumName << ";\n"; 1109b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner } 1119b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner OS << " }\n"; 112f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 113f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner} 114f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner 115fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattnervoid IntrinsicEmitter:: 116fda6affb95e9f68278cb5cf75dc3fd3406978255Chris LattnerEmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints, 1171a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 118fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "// Intrinsic ID to name table\n"; 119fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n"; 120fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << " // Note that entry #0 is the invalid intrinsic!\n"; 121f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng for (unsigned i = 0, e = Ints.size(); i != e; ++i) 122f065a6f711dca09ba36ec8fd3556c4936cdbe621Evan Cheng OS << " \"" << Ints[i].Name << "\",\n"; 123fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner OS << "#endif\n\n"; 124fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner} 125fda6affb95e9f68278cb5cf75dc3fd3406978255Chris Lattner 1260d52ff1f7b993750a74a5d4432273092de9af069Mon P Wangvoid IntrinsicEmitter:: 1270d52ff1f7b993750a74a5d4432273092de9af069Mon P WangEmitIntrinsicToOverloadTable(const std::vector<CodeGenIntrinsic> &Ints, 1281a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 1290d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "// Intrinsic ID to overload table\n"; 1300d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#ifdef GET_INTRINSIC_OVERLOAD_TABLE\n"; 1310d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " // Note that entry #0 is the invalid intrinsic!\n"; 1320d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 1330d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << " "; 1340d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang if (Ints[i].isOverloaded) 1350d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "true"; 1360d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang else 1370d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "false"; 1380d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << ",\n"; 1390d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang } 1400d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang OS << "#endif\n\n"; 1410d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang} 1420d52ff1f7b993750a74a5d4432273092de9af069Mon P Wang 143825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Andersonstatic void EmitTypeForValueType(raw_ostream &OS, MVT::SimpleValueType VT) { 144e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson if (EVT(VT).isInteger()) { 145e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson unsigned BitWidth = EVT(VT).getSizeInBits(); 1461d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "IntegerType::get(Context, " << BitWidth << ")"; 147825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Other) { 148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::OtherVT is used to mean the empty struct type here. 149d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context)"; 150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f32) { 1511d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFloatTy(Context)"; 152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f64) { 1531d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getDoubleTy(Context)"; 154825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f80) { 1551d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getX86_FP80Ty(Context)"; 156825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::f128) { 1571d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getFP128Ty(Context)"; 158825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::ppcf128) { 1591d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getPPC_FP128Ty(Context)"; 160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 1611d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::Metadata) { 1631d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getMetadataTy(Context)"; 1646994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 1656994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(false && "Unsupported ValueType!"); 16618faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner } 16718faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner} 16818faf5d9f7f89130b9e3304965b81e1c70ebb75cChris Lattner 1691a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 170cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo); 171cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 1721a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, 173cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ArgTypes, 174cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned &ArgNo) { 17593dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.empty()) 17693dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeForValueType(OS, MVT::isVoid); 17793dc92e412fd06250e46951bffb6040eca9baebdChris Lattner 17893dc92e412fd06250e46951bffb6040eca9baebdChris Lattner if (ArgTypes.size() == 1) 17993dc92e412fd06250e46951bffb6040eca9baebdChris Lattner return EmitTypeGenerate(OS, ArgTypes.front(), ArgNo); 180cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 181d7f2a6cb3fbc012763adb42fd967f6fefbb22a37Owen Anderson OS << "StructType::get(Context, "; 182cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 183cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (std::vector<Record*>::const_iterator 18420072af3b0b22d90afbce769409f4ed822520366Bill Wendling I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) { 185cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, *I, ArgNo); 18620072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << ", "; 18720072af3b0b22d90afbce769409f4ed822520366Bill Wendling } 188cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 18920072af3b0b22d90afbce769409f4ed822520366Bill Wendling OS << " NULL)"; 190cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling} 191cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 1921a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarstatic void EmitTypeGenerate(raw_ostream &OS, const Record *ArgType, 19384c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned &ArgNo) { 194825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 1956994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 1966994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 1976994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 1986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(Number < ArgNo && "Invalid matching number!"); 199bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 200bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getExtendedElementVectorType" 201bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 202bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 203bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "VectorType::getTruncatedElementVectorType" 204bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson << "(dyn_cast<VectorType>(Tys[" << Number << "]))"; 205bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 206bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "Tys[" << Number << "]"; 207825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iAny || VT == MVT::fAny || VT == MVT::vAny) { 20884c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // NOTE: The ArgNo variable here is not the absolute argument number, it is 20984c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // the index of the "arbitrary" type in the Tys array passed to the 21084c614d1ac671b1a5524169f20028f51c30be728Reid Spencer // Intrinsic::getDeclaration function. Consequently, we only want to 2116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // increment it when we actually hit an overloaded type. Getting this wrong 2126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leads to very subtle bugs! 2136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "Tys[" << ArgNo++ << "]"; 214e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson } else if (EVT(VT).isVector()) { 215e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VVT = VT; 2169d6565a5b1fbc4286d6ee638d8f47a3171a9ed7eReid Spencer OS << "VectorType::get("; 217825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT().SimpleTy); 21883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands OS << ", " << VVT.getVectorNumElements() << ")"; 219825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTR) { 22043ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb OS << "PointerType::getUnqual("; 221c4de3dec62c3f60ae7297f93c19c799c403c2e9fReid Spencer EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 22295af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ")"; 223825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::iPTRAny) { 224e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // Make sure the user has passed us an argument type to overload. If not, 225e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // treat it as an ordinary (not overloaded) intrinsic. 226e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo 227e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang << "] : PointerType::getUnqual("; 228e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo); 229e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang OS << ")"; 230e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ++ArgNo; 231825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (VT == MVT::isVoid) { 2326994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgNo == 0) 2331d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson OS << "Type::getVoidTy(Context)"; 2346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth else 235825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // MVT::isVoid is used to mean varargs here. 2366994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << "..."; 23795af592a631f403e1458ec1155f89fc31011572cJim Laskey } else { 2386994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth EmitTypeForValueType(OS, VT); 23995af592a631f403e1458ec1155f89fc31011572cJim Laskey } 24095af592a631f403e1458ec1155f89fc31011572cJim Laskey} 24195af592a631f403e1458ec1155f89fc31011572cJim Laskey 242da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach/// RecordListComparator - Provide a deterministic comparator for lists of 243c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner/// records. 244c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattnernamespace { 245cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair; 246c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner struct RecordListComparator { 247cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling bool operator()(const RecPair &LHS, 248cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &RHS) const { 249c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner unsigned i = 0; 250cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *LHSVec = &LHS.first; 251cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> *RHSVec = &RHS.first; 252cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned RHSSize = RHSVec->size(); 253cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned LHSSize = LHSVec->size(); 254cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 25593dc92e412fd06250e46951bffb6040eca9baebdChris Lattner for (; i != LHSSize; ++i) { 256cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 257cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 258cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 25993dc92e412fd06250e46951bffb6040eca9baebdChris Lattner } 260cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 261023422a6eb9ea692a5a837dc1daf256ac75ac6b0Bill Wendling if (i != RHSSize) return true; 262cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 263cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling i = 0; 264cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSVec = &LHS.second; 265cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSVec = &RHS.second; 266cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling RHSSize = RHSVec->size(); 267cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling LHSSize = LHSVec->size(); 268cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 269cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (i = 0; i != LHSSize; ++i) { 270cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (i == RHSSize) return false; // RHS is shorter than LHS. 271cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if ((*LHSVec)[i] != (*RHSVec)[i]) 272cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName(); 273cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 274cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 275cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling return i != RHSSize; 276c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner } 277c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner }; 278c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner} 279c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 280f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattnervoid IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 2811a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 282f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "// Verifier::visitIntrinsicFunctionCall code.\n"; 283f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#ifdef GET_INTRINSIC_VERIFIER\n"; 284f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " switch (ID) {\n"; 285f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 286c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 287c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // This checking can emit a lot of very common code. To reduce the amount of 288c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // code that we emit, batch up cases that have identical types. This avoids 289c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // problems where GCC can run out of memory compiling Verifier.cpp. 290cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 291c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner MapTy UniqueArgInfos; 292c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 293c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Compute the unique argument type info. 294c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) 295cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 296cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 297c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner 298c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner // Loop through the array, emitting one comparison for each batch. 299c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner for (MapTy::iterator I = UniqueArgInfos.begin(), 300c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner E = UniqueArgInfos.end(); I != E; ++I) { 301cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 302c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner OS << " case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// " 303c4d9b240b157efa9301d451ac44c12f6b004db8fChris Lattner << Ints[I->second[i]].Name << "\n"; 304f124b46b4f18b1a8f054a1222324ae15079f6ed8Chris Lattner 305cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 306cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 307cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 30809b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson std::vector<unsigned> OverloadedTypeIndices; 309cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 310cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", " 311cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling << ParamTys.size(); 312cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 313cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit return types. 314cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = RetTys.size(); j != je; ++j) { 315cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = RetTys[j]; 316cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 317cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 3186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (ArgType->isSubClassOf("LLVMMatchType")) { 3196994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth unsigned Number = ArgType->getValueAsInt("Number"); 32009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 32109b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 32209b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 323bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 324bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 325bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 326bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 327bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 328bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 3296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } else { 330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 3316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << getEnumName(VT); 332cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 33361fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 33409b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j); 33509b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 336825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 337cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling throw "Var arg type not last argument"; 338cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 339cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } 340cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 341cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling // Emit the parameter types. 342cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) { 343cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Record *ArgType = ParamTys[j]; 344cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << ", "; 345cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 346cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling if (ArgType->isSubClassOf("LLVMMatchType")) { 347cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned Number = ArgType->getValueAsInt("Number"); 34809b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson assert(Number < OverloadedTypeIndices.size() && 34909b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson "Invalid matching number!"); 35009b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson Number = OverloadedTypeIndices[Number]; 351bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson if (ArgType->isSubClassOf("LLVMExtendedElementVectorType")) 352bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(ExtendedElementVectorType | " << Number << ")"; 353bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType")) 354bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~(TruncatedElementVectorType | " << Number << ")"; 355bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson else 356bc03979536a1ecb220f1330719f3e3973a81ab0bBob Wilson OS << "~" << Number; 357cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling } else { 358825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT")); 359cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling OS << getEnumName(VT); 360cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 36161fc4cf7aa0b87ceab62082cee8ef5ce3f574ffcBob Wilson if (EVT(VT).isOverloaded()) 36209b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson OverloadedTypeIndices.push_back(j + RetTys.size()); 36309b1366f3f310b5648aa8cd72ed16b9f19b4c68dBob Wilson 364825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (VT == MVT::isVoid && j != 0 && j != je - 1) 36595d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey throw "Var arg type not last argument"; 36695d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 36795d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey } 36895d97b90e8427255c8298f5d3a1ab605af62aab4Jim Laskey 3696994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth OS << ");\n"; 370f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " break;\n"; 371f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner } 372f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << " }\n"; 373f97a00e681c7a526d49759d0d1b9d327cbf6c04aChris Lattner OS << "#endif\n\n"; 3749b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner} 3759b843b249462980ae4630dc37d1bcccde884a5a7Chris Lattner 37695af592a631f403e1458ec1155f89fc31011572cJim Laskeyvoid IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints, 3771a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 37895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "// Code for generating Intrinsic function declarations.\n"; 37995af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#ifdef GET_INTRINSIC_GENERATOR\n"; 38095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " switch (id) {\n"; 38195af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " default: assert(0 && \"Invalid intrinsic!\");\n"; 38295af592a631f403e1458ec1155f89fc31011572cJim Laskey 38395af592a631f403e1458ec1155f89fc31011572cJim Laskey // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical 38495af592a631f403e1458ec1155f89fc31011572cJim Laskey // types. 385cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy; 38695af592a631f403e1458ec1155f89fc31011572cJim Laskey MapTy UniqueArgInfos; 38795af592a631f403e1458ec1155f89fc31011572cJim Laskey 38895af592a631f403e1458ec1155f89fc31011572cJim Laskey // Compute the unique argument type info. 38995af592a631f403e1458ec1155f89fc31011572cJim Laskey for (unsigned i = 0, e = Ints.size(); i != e; ++i) 390cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs, 391cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling Ints[i].IS.ParamTypeDefs)].push_back(i); 39295af592a631f403e1458ec1155f89fc31011572cJim Laskey 39395af592a631f403e1458ec1155f89fc31011572cJim Laskey // Loop through the array, emitting one generator for each batch. 39449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen std::string IntrinsicStr = TargetPrefix + "Intrinsic::"; 39549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 39695af592a631f403e1458ec1155f89fc31011572cJim Laskey for (MapTy::iterator I = UniqueArgInfos.begin(), 39795af592a631f403e1458ec1155f89fc31011572cJim Laskey E = UniqueArgInfos.end(); I != E; ++I) { 398cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned i = 0, e = I->second.size(); i != e; ++i) 39949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName 40049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\t\t// " << Ints[I->second[i]].Name << "\n"; 40195af592a631f403e1458ec1155f89fc31011572cJim Laskey 402cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const RecPair &ArgTypes = I->first; 403cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &RetTys = ArgTypes.first; 404cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling const std::vector<Record*> &ParamTys = ArgTypes.second; 405cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 406cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling unsigned N = ParamTys.size(); 40795af592a631f403e1458ec1155f89fc31011572cJim Laskey 4086994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (N > 1 && 409825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) { 41095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " IsVarArg = true;\n"; 41195af592a631f403e1458ec1155f89fc31011572cJim Laskey --N; 41295af592a631f403e1458ec1155f89fc31011572cJim Laskey } 413cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 41484c614d1ac671b1a5524169f20028f51c30be728Reid Spencer unsigned ArgNo = 0; 41595af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ResultTy = "; 416cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, RetTys, ArgNo); 41795af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ";\n"; 41895af592a631f403e1458ec1155f89fc31011572cJim Laskey 419cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling for (unsigned j = 0; j != N; ++j) { 42095af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " ArgTys.push_back("; 421cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling EmitTypeGenerate(OS, ParamTys[j], ArgNo); 42295af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << ");\n"; 42395af592a631f403e1458ec1155f89fc31011572cJim Laskey } 424cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 42595af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " break;\n"; 42695af592a631f403e1458ec1155f89fc31011572cJim Laskey } 427cdcc3e6e12b8b4e224bd62c96768c5f5e325aaceBill Wendling 42895af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << " }\n"; 42995af592a631f403e1458ec1155f89fc31011572cJim Laskey OS << "#endif\n\n"; 43095af592a631f403e1458ec1155f89fc31011572cJim Laskey} 43195af592a631f403e1458ec1155f89fc31011572cJim Laskey 432048ffb239c282277959463c61200b86e2380cb84Chris Lattner/// EmitAttributes - This emits the Intrinsic::getAttributes method. 4334e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattnervoid IntrinsicEmitter:: 4341a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { 435a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "// Add parameter attributes that are not common to all intrinsics.\n"; 436a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n"; 43749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) 43849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "static AttrListPtr getAttributes(" << TargetPrefix 43949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "Intrinsic::ID id) {"; 44049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen else 44149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "AttrListPtr Intrinsic::getAttributes(ID id) {"; 442048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << " // No intrinsic can throw exceptions.\n"; 443048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << " Attributes Attr = Attribute::NoUnwind;\n"; 444a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " switch (id) {\n"; 4457056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner OS << " default: break;\n"; 44610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner unsigned MaxArgAttrs = 0; 4477056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 44810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner MaxArgAttrs = 44910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::max(MaxArgAttrs, unsigned(Ints[i].ArgumentAttributes.size())); 4507056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner switch (Ints[i].ModRef) { 4517056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner default: break; 4527056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner case CodeGenIntrinsic::NoMem: 45349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 45449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 4557056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner break; 4567056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner } 4577056de375d898d9d9ecc17e170632d91d18be4a8Chris Lattner } 4580598866c052147c31b808391f58434ce3dbfb838Devang Patel OS << " Attr |= Attribute::ReadNone; // These do not access memory.\n"; 459a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " break;\n"; 4604e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 4614e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner switch (Ints[i].ModRef) { 462022f64fbbc4669623e79b805379266fed519017dChris Lattner default: break; 463022f64fbbc4669623e79b805379266fed519017dChris Lattner case CodeGenIntrinsic::ReadArgMem: 464022f64fbbc4669623e79b805379266fed519017dChris Lattner case CodeGenIntrinsic::ReadMem: 46549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 46649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 467022f64fbbc4669623e79b805379266fed519017dChris Lattner break; 4684e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 4694e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner } 4700598866c052147c31b808391f58434ce3dbfb838Devang Patel OS << " Attr |= Attribute::ReadOnly; // These do not write memory.\n"; 471a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands OS << " break;\n"; 4724e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner OS << " }\n"; 47310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " AttributeWithIndex AWI[" << MaxArgAttrs+1 << "];\n"; 474d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " unsigned NumAttrs = 0;\n"; 47510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " switch (id) {\n"; 47610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " default: break;\n"; 47710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 47810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner // Add argument attributes for any intrinsics that have them. 47910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 48010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner if (Ints[i].ArgumentAttributes.empty()) continue; 48110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 48249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 48349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << ":\n"; 48410dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 48510dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::vector<std::pair<unsigned, CodeGenIntrinsic::ArgAttribute> > ArgAttrs = 48610dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner Ints[i].ArgumentAttributes; 48710dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner // Sort by argument index. 48810dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner std::sort(ArgAttrs.begin(), ArgAttrs.end()); 48910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 49010dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner unsigned NumArgsWithAttrs = 0; 49110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 492d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner while (!ArgAttrs.empty()) { 493d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner unsigned ArgNo = ArgAttrs[0].first; 494d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 495d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " AWI[" << NumArgsWithAttrs++ << "] = AttributeWithIndex::get(" 496d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner << ArgNo+1 << ", 0"; 497d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner 498d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner while (!ArgAttrs.empty() && ArgAttrs[0].first == ArgNo) { 499d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner switch (ArgAttrs[0].second) { 500d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner default: assert(0 && "Unknown arg attribute"); 501d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner case CodeGenIntrinsic::NoCapture: 502d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "|Attribute::NoCapture"; 503d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner break; 504d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 505d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner ArgAttrs.erase(ArgAttrs.begin()); 506d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 507d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << ");\n"; 508d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner } 50910dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 510d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " NumAttrs = " << NumArgsWithAttrs << ";\n"; 51110dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " break;\n"; 51210dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner } 51310dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner 51410dae94be2ccb187bd4e3da53771be54057acd6cChris Lattner OS << " }\n"; 515d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " AWI[NumAttrs] = AttributeWithIndex::get(~0, Attr);\n"; 516d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << " return AttrListPtr::get(AWI, NumAttrs+1);\n"; 517048ffb239c282277959463c61200b86e2380cb84Chris Lattner OS << "}\n"; 518d4a2700fdc5bc8ac50084fcb39155e01e86168d5Chris Lattner OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; 5194e5f35973c1bc56cce14d44c6f8f4ad1e9f1a438Chris Lattner} 520022f64fbbc4669623e79b805379266fed519017dChris Lattner 521d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands/// EmitModRefBehavior - Determine intrinsic alias analysis mod/ref behavior. 522d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sandsvoid IntrinsicEmitter:: 5231a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 524d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "// Determine intrinsic alias analysis mod/ref behavior.\n"; 525d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n"; 5267c422ac216fe39fc9c402a704cf296cca9dc5b22Duncan Sands OS << "switch (iid) {\n"; 527d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "default:\n return UnknownModRefBehavior;\n"; 528d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 529d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem) 530d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands continue; 531d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName 532d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands << ":\n"; 533d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands switch (Ints[i].ModRef) { 534d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands default: 535d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands assert(false && "Unknown Mod/Ref type!"); 536d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::NoMem: 537d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return DoesNotAccessMemory;\n"; 538d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 539d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadArgMem: 540d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::ReadMem: 541d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return OnlyReadsMemory;\n"; 542d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 543d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands case CodeGenIntrinsic::WriteArgMem: 544d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << " return AccessesArguments;\n"; 545d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands break; 546d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 547d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands } 548d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "}\n"; 549d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands OS << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; 550d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands} 551d869b3847f1dee78e1e4e1ed3cb41bd3ab0a079cDuncan Sands 552022f64fbbc4669623e79b805379266fed519017dChris Lattnervoid IntrinsicEmitter:: 5531a55180238dbcf11113f610aea010447e51f595bDaniel DunbarEmitGCCBuiltinList(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){ 554022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; 555022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; 556022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " switch (F->getIntrinsicID()) {\n"; 557022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " default: BuiltinName = \"\"; break;\n"; 558022f64fbbc4669623e79b805379266fed519017dChris Lattner for (unsigned i = 0, e = Ints.size(); i != e; ++i) { 559022f64fbbc4669623e79b805379266fed519017dChris Lattner if (!Ints[i].GCCBuiltinName.empty()) { 560022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" 561022f64fbbc4669623e79b805379266fed519017dChris Lattner << Ints[i].GCCBuiltinName << "\"; break;\n"; 562022f64fbbc4669623e79b805379266fed519017dChris Lattner } 563022f64fbbc4669623e79b805379266fed519017dChris Lattner } 564022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << " }\n"; 565022f64fbbc4669623e79b805379266fed519017dChris Lattner OS << "#endif\n\n"; 566767a25b8788b5e313c99c16b4d359478432901f5Reid Spencer} 5673f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner 568331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified 569331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// sorted range of builtin names is equal to the current builtin. This breaks 570331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// it down into a simple tree. 571331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// 572331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// At this point, we know that all the builtins in the range have the same name 573331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// for the first 'CharStart' characters. Only the end of the name needs to be 574331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// discriminated. 575331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnertypedef std::map<std::string, std::string>::const_iterator StrMapIterator; 576331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnerstatic void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End, 577331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner unsigned CharStart, unsigned Indent, 5781a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar std::string TargetPrefix, raw_ostream &OS) { 579331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (Start == End) return; // empty range. 580331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 581331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Determine what, if anything, is the same about all these strings. 582331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner std::string CommonString = Start->first; 583331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner unsigned NumInRange = 0; 584331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) { 585331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Find the first character that doesn't match. 586331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner const std::string &ThisStr = I->first; 587331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner unsigned NonMatchChar = CharStart; 588331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner while (NonMatchChar < CommonString.size() && 589331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner NonMatchChar < ThisStr.size() && 590331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner CommonString[NonMatchChar] == ThisStr[NonMatchChar]) 591331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner ++NonMatchChar; 592331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Truncate off pieces that don't match. 593331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner CommonString.resize(NonMatchChar); 594331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 595331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 596331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Just compare the rest of the string. 597331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (NumInRange == 1) { 598331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (CharStart != CommonString.size()) { 599331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 600331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (CharStart) OS << "+" << CharStart; 601331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 602331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << CommonString.size() - CharStart << "))\n"; 603331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner ++Indent; 604331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 60549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix 60649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "Intrinsic::"; 607331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << Start->second << ";\n"; 608331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner return; 609331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 610331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 611331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // At this point, we potentially have a common prefix for these builtins, emit 612331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // a check for this common prefix. 613331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (CommonString.size() != CharStart) { 614331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName"; 615331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (CharStart) OS << "+" << CharStart; 616331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << ", \"" << (CommonString.c_str()+CharStart) << "\", "; 617331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << CommonString.size()-CharStart << ")) {\n"; 618331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 61949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1, 62049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen TargetPrefix, OS); 621331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << "}\n"; 622331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner return; 623331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 624331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 625331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Output a switch on the character that differs across the set. 626331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart 627331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner << "]) {"; 628331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (CharStart) 629331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << " // \"" << std::string(Start->first.begin(), 630331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner Start->first.begin()+CharStart) << "\""; 631331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << "\n"; 632331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 633331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner for (StrMapIterator I = Start; I != End; ) { 634331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner char ThisChar = I->first[CharStart]; 635331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n"; 636331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Figure out the range that has this common character. 637331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner StrMapIterator NextChar = I; 638331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar; 639331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner ++NextChar) 640331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner /*empty*/; 64149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS); 642331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << " break;\n"; 643331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner I = NextChar; 644331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 645331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << std::string(Indent*2, ' ') << "}\n"; 646331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner} 647331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 648331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// EmitTargetBuiltins - All of the builtins in the specified map are for the 649331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner/// same target, and we already checked it. 650331bf92fb51f058672144681b3d0e67d30f5699fChris Lattnerstatic void EmitTargetBuiltins(const std::map<std::string, std::string> &BIM, 65149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen const std::string &TargetPrefix, 6521a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &OS) { 653331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Rearrange the builtins by length. 654331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner std::vector<std::map<std::string, std::string> > BuiltinsByLen; 655331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner BuiltinsByLen.reserve(100); 656331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 657331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner for (StrMapIterator I = BIM.begin(), E = BIM.end(); I != E; ++I) { 658331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (I->first.size() >= BuiltinsByLen.size()) 659331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner BuiltinsByLen.resize(I->first.size()+1); 660331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner BuiltinsByLen[I->first.size()].insert(*I); 661331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 662331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 663331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner // Now that we have all the builtins by their length, emit a switch stmt. 664331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << " switch (strlen(BuiltinName)) {\n"; 665331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << " default: break;\n"; 666331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner for (unsigned i = 0, e = BuiltinsByLen.size(); i != e; ++i) { 667331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner if (BuiltinsByLen[i].empty()) continue; 668331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << " case " << i << ":\n"; 669331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner EmitBuiltinComparisons(BuiltinsByLen[i].begin(), BuiltinsByLen[i].end(), 67049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 0, 3, TargetPrefix, OS); 671331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << " break;\n"; 672331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner } 673331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner OS << " }\n"; 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 " 70349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "*TargetPrefix, const char *BuiltinName) {\n"; 70449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " " << TargetPrefix << "Intrinsic::ID IntrinsicID = "; 70549de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } else { 70649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "Intrinsic::ID Intrinsic::getIntrinsicForGCCBuiltin(const char " 70749de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen << "*TargetPrefix, const char *BuiltinName) {\n"; 70849de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " Intrinsic::ID IntrinsicID = "; 70949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen } 71049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 71149de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (TargetOnly) 71249de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "(" << TargetPrefix<< "Intrinsic::ID)"; 71349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen 71449de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "Intrinsic::not_intrinsic;\n"; 715331bf92fb51f058672144681b3d0e67d30f5699fChris Lattner 7163f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner // Note: this could emit significantly better code if we cared. 7173f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){ 718fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " "; 719fa0fba1c546091c485e5513eadeef181dda370abChris Lattner if (!I->first.empty()) 720fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "if (!strcmp(TargetPrefix, \"" << I->first << "\")) "; 721fa0fba1c546091c485e5513eadeef181dda370abChris Lattner else 722fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "/* Target Independent Builtins */ "; 723fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << "{\n"; 724fa0fba1c546091c485e5513eadeef181dda370abChris Lattner 725fa0fba1c546091c485e5513eadeef181dda370abChris Lattner // Emit the comparisons for this target prefix. 72649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen EmitTargetBuiltins(I->second, TargetPrefix, OS); 727fa0fba1c546091c485e5513eadeef181dda370abChris Lattner OS << " }\n"; 7283f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner } 72949de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << " return IntrinsicID;\n"; 73049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen OS << "}\n"; 7313f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner OS << "#endif\n\n"; 7323f8b8913bc9cb232871445eefa8654caf7f9986fChris Lattner} 733