CallingConvEmitter.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. //===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This tablegen backend is responsible for emitting descriptions of the calling
  10. // conventions supported by this target.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "CodeGenTarget.h"
  14. #include "llvm/TableGen/Error.h"
  15. #include "llvm/TableGen/Record.h"
  16. #include "llvm/TableGen/TableGenBackend.h"
  17. using namespace llvm;
  18. namespace {
  19. class CallingConvEmitter {
  20. RecordKeeper &Records;
  21. unsigned Counter;
  22. std::string CurrentAction;
  23. bool SwiftAction;
  24. std::map<std::string, std::set<std::string>> AssignedRegsMap;
  25. std::map<std::string, std::set<std::string>> AssignedSwiftRegsMap;
  26. std::map<std::string, std::set<std::string>> DelegateToMap;
  27. public:
  28. explicit CallingConvEmitter(RecordKeeper &R) : Records(R) {}
  29. void run(raw_ostream &o);
  30. private:
  31. void EmitCallingConv(Record *CC, raw_ostream &O);
  32. void EmitAction(Record *Action, unsigned Indent, raw_ostream &O);
  33. void EmitArgRegisterLists(raw_ostream &O);
  34. };
  35. } // End anonymous namespace
  36. void CallingConvEmitter::run(raw_ostream &O) {
  37. std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");
  38. // Emit prototypes for all of the non-custom CC's so that they can forward ref
  39. // each other.
  40. Records.startTimer("Emit prototypes");
  41. O << "#ifndef GET_CC_REGISTER_LISTS\n\n";
  42. for (Record *CC : CCs) {
  43. if (!CC->getValueAsBit("Custom")) {
  44. unsigned Pad = CC->getName().size();
  45. if (CC->getValueAsBit("Entry")) {
  46. O << "bool llvm::";
  47. Pad += 12;
  48. } else {
  49. O << "static bool ";
  50. Pad += 13;
  51. }
  52. O << CC->getName() << "(unsigned ValNo, MVT ValVT,\n"
  53. << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
  54. << std::string(Pad, ' ')
  55. << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
  56. }
  57. }
  58. // Emit each non-custom calling convention description in full.
  59. Records.startTimer("Emit full descriptions");
  60. for (Record *CC : CCs) {
  61. if (!CC->getValueAsBit("Custom")) {
  62. EmitCallingConv(CC, O);
  63. }
  64. }
  65. EmitArgRegisterLists(O);
  66. O << "\n#endif // CC_REGISTER_LIST\n";
  67. }
  68. void CallingConvEmitter::EmitCallingConv(Record *CC, raw_ostream &O) {
  69. ListInit *CCActions = CC->getValueAsListInit("Actions");
  70. Counter = 0;
  71. CurrentAction = CC->getName().str();
  72. // Call upon the creation of a map entry from the void!
  73. // We want an entry in AssignedRegsMap for every action, even if that
  74. // entry is empty.
  75. AssignedRegsMap[CurrentAction] = {};
  76. O << "\n\n";
  77. unsigned Pad = CurrentAction.size();
  78. if (CC->getValueAsBit("Entry")) {
  79. O << "bool llvm::";
  80. Pad += 12;
  81. } else {
  82. O << "static bool ";
  83. Pad += 13;
  84. }
  85. O << CurrentAction << "(unsigned ValNo, MVT ValVT,\n"
  86. << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
  87. << std::string(Pad, ' ') << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
  88. // Emit all of the actions, in order.
  89. for (unsigned i = 0, e = CCActions->size(); i != e; ++i) {
  90. Record *Action = CCActions->getElementAsRecord(i);
  91. SwiftAction = llvm::any_of(Action->getSuperClasses(),
  92. [](const std::pair<Record *, SMRange> &Class) {
  93. std::string Name =
  94. Class.first->getNameInitAsString();
  95. return StringRef(Name).startswith("CCIfSwift");
  96. });
  97. O << "\n";
  98. EmitAction(Action, 2, O);
  99. }
  100. O << "\n return true; // CC didn't match.\n";
  101. O << "}\n";
  102. }
  103. void CallingConvEmitter::EmitAction(Record *Action,
  104. unsigned Indent, raw_ostream &O) {
  105. std::string IndentStr = std::string(Indent, ' ');
  106. if (Action->isSubClassOf("CCPredicateAction")) {
  107. O << IndentStr << "if (";
  108. if (Action->isSubClassOf("CCIfType")) {
  109. ListInit *VTs = Action->getValueAsListInit("VTs");
  110. for (unsigned i = 0, e = VTs->size(); i != e; ++i) {
  111. Record *VT = VTs->getElementAsRecord(i);
  112. if (i != 0) O << " ||\n " << IndentStr;
  113. O << "LocVT == " << getEnumName(getValueType(VT));
  114. }
  115. } else if (Action->isSubClassOf("CCIf")) {
  116. O << Action->getValueAsString("Predicate");
  117. } else {
  118. errs() << *Action;
  119. PrintFatalError(Action->getLoc(), "Unknown CCPredicateAction!");
  120. }
  121. O << ") {\n";
  122. EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
  123. O << IndentStr << "}\n";
  124. } else {
  125. if (Action->isSubClassOf("CCDelegateTo")) {
  126. Record *CC = Action->getValueAsDef("CC");
  127. O << IndentStr << "if (!" << CC->getName()
  128. << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
  129. << IndentStr << " return false;\n";
  130. DelegateToMap[CurrentAction].insert(CC->getName().str());
  131. } else if (Action->isSubClassOf("CCAssignToReg") ||
  132. Action->isSubClassOf("CCAssignToRegAndStack")) {
  133. ListInit *RegList = Action->getValueAsListInit("RegList");
  134. if (RegList->size() == 1) {
  135. std::string Name = getQualifiedName(RegList->getElementAsRecord(0));
  136. O << IndentStr << "if (unsigned Reg = State.AllocateReg(" << Name
  137. << ")) {\n";
  138. if (SwiftAction)
  139. AssignedSwiftRegsMap[CurrentAction].insert(Name);
  140. else
  141. AssignedRegsMap[CurrentAction].insert(Name);
  142. } else {
  143. O << IndentStr << "static const MCPhysReg RegList" << ++Counter
  144. << "[] = {\n";
  145. O << IndentStr << " ";
  146. ListSeparator LS;
  147. for (unsigned i = 0, e = RegList->size(); i != e; ++i) {
  148. std::string Name = getQualifiedName(RegList->getElementAsRecord(i));
  149. if (SwiftAction)
  150. AssignedSwiftRegsMap[CurrentAction].insert(Name);
  151. else
  152. AssignedRegsMap[CurrentAction].insert(Name);
  153. O << LS << Name;
  154. }
  155. O << "\n" << IndentStr << "};\n";
  156. O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
  157. << Counter << ")) {\n";
  158. }
  159. O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
  160. << "Reg, LocVT, LocInfo));\n";
  161. if (Action->isSubClassOf("CCAssignToRegAndStack")) {
  162. int Size = Action->getValueAsInt("Size");
  163. int Align = Action->getValueAsInt("Align");
  164. O << IndentStr << " (void)State.AllocateStack(";
  165. if (Size)
  166. O << Size << ", ";
  167. else
  168. O << "\n"
  169. << IndentStr
  170. << " State.getMachineFunction().getDataLayout()."
  171. "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
  172. " ";
  173. if (Align)
  174. O << "Align(" << Align << ")";
  175. else
  176. O << "\n"
  177. << IndentStr
  178. << " State.getMachineFunction().getDataLayout()."
  179. "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()"
  180. "))";
  181. O << ");\n";
  182. }
  183. O << IndentStr << " return false;\n";
  184. O << IndentStr << "}\n";
  185. } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
  186. ListInit *RegList = Action->getValueAsListInit("RegList");
  187. ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
  188. if (!ShadowRegList->empty() && ShadowRegList->size() != RegList->size())
  189. PrintFatalError(Action->getLoc(),
  190. "Invalid length of list of shadowed registers");
  191. if (RegList->size() == 1) {
  192. O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
  193. O << getQualifiedName(RegList->getElementAsRecord(0));
  194. O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
  195. O << ")) {\n";
  196. } else {
  197. unsigned RegListNumber = ++Counter;
  198. unsigned ShadowRegListNumber = ++Counter;
  199. O << IndentStr << "static const MCPhysReg RegList" << RegListNumber
  200. << "[] = {\n";
  201. O << IndentStr << " ";
  202. ListSeparator LS;
  203. for (unsigned i = 0, e = RegList->size(); i != e; ++i)
  204. O << LS << getQualifiedName(RegList->getElementAsRecord(i));
  205. O << "\n" << IndentStr << "};\n";
  206. O << IndentStr << "static const MCPhysReg RegList"
  207. << ShadowRegListNumber << "[] = {\n";
  208. O << IndentStr << " ";
  209. ListSeparator LSS;
  210. for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
  211. O << LSS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
  212. O << "\n" << IndentStr << "};\n";
  213. O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
  214. << RegListNumber << ", " << "RegList" << ShadowRegListNumber
  215. << ")) {\n";
  216. }
  217. O << IndentStr << " State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
  218. << "Reg, LocVT, LocInfo));\n";
  219. O << IndentStr << " return false;\n";
  220. O << IndentStr << "}\n";
  221. } else if (Action->isSubClassOf("CCAssignToStack")) {
  222. int Size = Action->getValueAsInt("Size");
  223. int Align = Action->getValueAsInt("Align");
  224. O << IndentStr << "unsigned Offset" << ++Counter
  225. << " = State.AllocateStack(";
  226. if (Size)
  227. O << Size << ", ";
  228. else
  229. O << "\n" << IndentStr
  230. << " State.getMachineFunction().getDataLayout()."
  231. "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
  232. " ";
  233. if (Align)
  234. O << "Align(" << Align << ")";
  235. else
  236. O << "\n"
  237. << IndentStr
  238. << " State.getMachineFunction().getDataLayout()."
  239. "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()"
  240. "))";
  241. O << ");\n" << IndentStr
  242. << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
  243. << Counter << ", LocVT, LocInfo));\n";
  244. O << IndentStr << "return false;\n";
  245. } else if (Action->isSubClassOf("CCAssignToStackWithShadow")) {
  246. int Size = Action->getValueAsInt("Size");
  247. int Align = Action->getValueAsInt("Align");
  248. ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
  249. unsigned ShadowRegListNumber = ++Counter;
  250. O << IndentStr << "static const MCPhysReg ShadowRegList"
  251. << ShadowRegListNumber << "[] = {\n";
  252. O << IndentStr << " ";
  253. ListSeparator LS;
  254. for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
  255. O << LS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
  256. O << "\n" << IndentStr << "};\n";
  257. O << IndentStr << "unsigned Offset" << ++Counter
  258. << " = State.AllocateStack(" << Size << ", Align(" << Align << "), "
  259. << "ShadowRegList" << ShadowRegListNumber << ");\n";
  260. O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
  261. << Counter << ", LocVT, LocInfo));\n";
  262. O << IndentStr << "return false;\n";
  263. } else if (Action->isSubClassOf("CCPromoteToType")) {
  264. Record *DestTy = Action->getValueAsDef("DestTy");
  265. MVT::SimpleValueType DestVT = getValueType(DestTy);
  266. O << IndentStr << "LocVT = " << getEnumName(DestVT) <<";\n";
  267. if (MVT(DestVT).isFloatingPoint()) {
  268. O << IndentStr << "LocInfo = CCValAssign::FPExt;\n";
  269. } else {
  270. O << IndentStr << "if (ArgFlags.isSExt())\n"
  271. << IndentStr << " LocInfo = CCValAssign::SExt;\n"
  272. << IndentStr << "else if (ArgFlags.isZExt())\n"
  273. << IndentStr << " LocInfo = CCValAssign::ZExt;\n"
  274. << IndentStr << "else\n"
  275. << IndentStr << " LocInfo = CCValAssign::AExt;\n";
  276. }
  277. } else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) {
  278. Record *DestTy = Action->getValueAsDef("DestTy");
  279. MVT::SimpleValueType DestVT = getValueType(DestTy);
  280. O << IndentStr << "LocVT = " << getEnumName(DestVT) << ";\n";
  281. if (MVT(DestVT).isFloatingPoint()) {
  282. PrintFatalError(Action->getLoc(),
  283. "CCPromoteToUpperBitsInType does not handle floating "
  284. "point");
  285. } else {
  286. O << IndentStr << "if (ArgFlags.isSExt())\n"
  287. << IndentStr << " LocInfo = CCValAssign::SExtUpper;\n"
  288. << IndentStr << "else if (ArgFlags.isZExt())\n"
  289. << IndentStr << " LocInfo = CCValAssign::ZExtUpper;\n"
  290. << IndentStr << "else\n"
  291. << IndentStr << " LocInfo = CCValAssign::AExtUpper;\n";
  292. }
  293. } else if (Action->isSubClassOf("CCBitConvertToType")) {
  294. Record *DestTy = Action->getValueAsDef("DestTy");
  295. O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
  296. O << IndentStr << "LocInfo = CCValAssign::BCvt;\n";
  297. } else if (Action->isSubClassOf("CCTruncToType")) {
  298. Record *DestTy = Action->getValueAsDef("DestTy");
  299. O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
  300. O << IndentStr << "LocInfo = CCValAssign::Trunc;\n";
  301. } else if (Action->isSubClassOf("CCPassIndirect")) {
  302. Record *DestTy = Action->getValueAsDef("DestTy");
  303. O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
  304. O << IndentStr << "LocInfo = CCValAssign::Indirect;\n";
  305. } else if (Action->isSubClassOf("CCPassByVal")) {
  306. int Size = Action->getValueAsInt("Size");
  307. int Align = Action->getValueAsInt("Align");
  308. O << IndentStr << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
  309. << Size << ", Align(" << Align << "), ArgFlags);\n";
  310. O << IndentStr << "return false;\n";
  311. } else if (Action->isSubClassOf("CCCustom")) {
  312. O << IndentStr
  313. << "if (" << Action->getValueAsString("FuncName") << "(ValNo, ValVT, "
  314. << "LocVT, LocInfo, ArgFlags, State))\n";
  315. O << IndentStr << " return false;\n";
  316. } else {
  317. errs() << *Action;
  318. PrintFatalError(Action->getLoc(), "Unknown CCAction!");
  319. }
  320. }
  321. }
  322. void CallingConvEmitter::EmitArgRegisterLists(raw_ostream &O) {
  323. // Transitively merge all delegated CCs into AssignedRegsMap.
  324. using EntryTy = std::pair<std::string, std::set<std::string>>;
  325. bool Redo;
  326. do {
  327. Redo = false;
  328. std::deque<EntryTy> Worklist(DelegateToMap.begin(), DelegateToMap.end());
  329. while (!Worklist.empty()) {
  330. EntryTy Entry = Worklist.front();
  331. Worklist.pop_front();
  332. const std::string &CCName = Entry.first;
  333. std::set<std::string> &Registers = Entry.second;
  334. if (!Registers.empty())
  335. continue;
  336. for (auto &InnerEntry : Worklist) {
  337. const std::string &InnerCCName = InnerEntry.first;
  338. std::set<std::string> &InnerRegisters = InnerEntry.second;
  339. if (InnerRegisters.find(CCName) != InnerRegisters.end()) {
  340. AssignedRegsMap[InnerCCName].insert(
  341. AssignedRegsMap[CCName].begin(),
  342. AssignedRegsMap[CCName].end());
  343. InnerRegisters.erase(CCName);
  344. }
  345. }
  346. DelegateToMap.erase(CCName);
  347. Redo = true;
  348. }
  349. } while (Redo);
  350. if (AssignedRegsMap.empty())
  351. return;
  352. O << "\n#else\n\n";
  353. for (auto &Entry : AssignedRegsMap) {
  354. const std::string &RegName = Entry.first;
  355. std::set<std::string> &Registers = Entry.second;
  356. if (RegName.empty())
  357. continue;
  358. O << "const MCRegister " << Entry.first << "_ArgRegs[] = { ";
  359. if (Registers.empty()) {
  360. O << "0";
  361. } else {
  362. ListSeparator LS;
  363. for (const std::string &Reg : Registers)
  364. O << LS << Reg;
  365. }
  366. O << " };\n";
  367. }
  368. if (AssignedSwiftRegsMap.empty())
  369. return;
  370. O << "\n// Registers used by Swift.\n";
  371. for (auto &Entry : AssignedSwiftRegsMap) {
  372. const std::string &RegName = Entry.first;
  373. std::set<std::string> &Registers = Entry.second;
  374. O << "const MCRegister " << RegName << "_Swift_ArgRegs[] = { ";
  375. ListSeparator LS;
  376. for (const std::string &Reg : Registers)
  377. O << LS << Reg;
  378. O << " };\n";
  379. }
  380. }
  381. namespace llvm {
  382. void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS) {
  383. emitSourceFileHeader("Calling Convention Implementation Fragment", OS);
  384. CallingConvEmitter(RK).run(OS);
  385. }
  386. } // End llvm namespace