MIRCanonicalizerPass.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. //===-------------- MIRCanonicalizer.cpp - MIR Canonicalizer --------------===//
  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. // The purpose of this pass is to employ a canonical code transformation so
  10. // that code compiled with slightly different IR passes can be diffed more
  11. // effectively than otherwise. This is done by renaming vregs in a given
  12. // LiveRange in a canonical way. This pass also does a pseudo-scheduling to
  13. // move defs closer to their use inorder to reduce diffs caused by slightly
  14. // different schedules.
  15. //
  16. // Basic Usage:
  17. //
  18. // llc -o - -run-pass mir-canonicalizer example.mir
  19. //
  20. // Reorders instructions canonically.
  21. // Renames virtual register operands canonically.
  22. // Strips certain MIR artifacts (optionally).
  23. //
  24. //===----------------------------------------------------------------------===//
  25. #include "MIRVRegNamerUtils.h"
  26. #include "llvm/ADT/PostOrderIterator.h"
  27. #include "llvm/ADT/STLExtras.h"
  28. #include "llvm/CodeGen/MachineFunctionPass.h"
  29. #include "llvm/CodeGen/MachineInstrBuilder.h"
  30. #include "llvm/CodeGen/MachineRegisterInfo.h"
  31. #include "llvm/CodeGen/Passes.h"
  32. #include "llvm/InitializePasses.h"
  33. #include "llvm/Support/Debug.h"
  34. #include "llvm/Support/raw_ostream.h"
  35. #include <queue>
  36. using namespace llvm;
  37. #define DEBUG_TYPE "mir-canonicalizer"
  38. static cl::opt<unsigned>
  39. CanonicalizeFunctionNumber("canon-nth-function", cl::Hidden, cl::init(~0u),
  40. cl::value_desc("N"),
  41. cl::desc("Function number to canonicalize."));
  42. namespace {
  43. class MIRCanonicalizer : public MachineFunctionPass {
  44. public:
  45. static char ID;
  46. MIRCanonicalizer() : MachineFunctionPass(ID) {}
  47. StringRef getPassName() const override {
  48. return "Rename register operands in a canonical ordering.";
  49. }
  50. void getAnalysisUsage(AnalysisUsage &AU) const override {
  51. AU.setPreservesCFG();
  52. MachineFunctionPass::getAnalysisUsage(AU);
  53. }
  54. bool runOnMachineFunction(MachineFunction &MF) override;
  55. };
  56. } // end anonymous namespace
  57. char MIRCanonicalizer::ID;
  58. char &llvm::MIRCanonicalizerID = MIRCanonicalizer::ID;
  59. INITIALIZE_PASS_BEGIN(MIRCanonicalizer, "mir-canonicalizer",
  60. "Rename Register Operands Canonically", false, false)
  61. INITIALIZE_PASS_END(MIRCanonicalizer, "mir-canonicalizer",
  62. "Rename Register Operands Canonically", false, false)
  63. static std::vector<MachineBasicBlock *> GetRPOList(MachineFunction &MF) {
  64. if (MF.empty())
  65. return {};
  66. ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
  67. std::vector<MachineBasicBlock *> RPOList;
  68. append_range(RPOList, RPOT);
  69. return RPOList;
  70. }
  71. static bool
  72. rescheduleLexographically(std::vector<MachineInstr *> instructions,
  73. MachineBasicBlock *MBB,
  74. std::function<MachineBasicBlock::iterator()> getPos) {
  75. bool Changed = false;
  76. using StringInstrPair = std::pair<std::string, MachineInstr *>;
  77. std::vector<StringInstrPair> StringInstrMap;
  78. for (auto *II : instructions) {
  79. std::string S;
  80. raw_string_ostream OS(S);
  81. II->print(OS);
  82. OS.flush();
  83. // Trim the assignment, or start from the beginning in the case of a store.
  84. const size_t i = S.find('=');
  85. StringInstrMap.push_back({(i == std::string::npos) ? S : S.substr(i), II});
  86. }
  87. llvm::sort(StringInstrMap,
  88. [](const StringInstrPair &a, const StringInstrPair &b) -> bool {
  89. return (a.first < b.first);
  90. });
  91. for (auto &II : StringInstrMap) {
  92. LLVM_DEBUG({
  93. dbgs() << "Splicing ";
  94. II.second->dump();
  95. dbgs() << " right before: ";
  96. getPos()->dump();
  97. });
  98. Changed = true;
  99. MBB->splice(getPos(), MBB, II.second);
  100. }
  101. return Changed;
  102. }
  103. static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount,
  104. MachineBasicBlock *MBB) {
  105. bool Changed = false;
  106. // Calculates the distance of MI from the beginning of its parent BB.
  107. auto getInstrIdx = [](const MachineInstr &MI) {
  108. unsigned i = 0;
  109. for (auto &CurMI : *MI.getParent()) {
  110. if (&CurMI == &MI)
  111. return i;
  112. i++;
  113. }
  114. return ~0U;
  115. };
  116. // Pre-Populate vector of instructions to reschedule so that we don't
  117. // clobber the iterator.
  118. std::vector<MachineInstr *> Instructions;
  119. for (auto &MI : *MBB) {
  120. Instructions.push_back(&MI);
  121. }
  122. std::map<MachineInstr *, std::vector<MachineInstr *>> MultiUsers;
  123. std::map<unsigned, MachineInstr *> MultiUserLookup;
  124. unsigned UseToBringDefCloserToCount = 0;
  125. std::vector<MachineInstr *> PseudoIdempotentInstructions;
  126. std::vector<unsigned> PhysRegDefs;
  127. for (auto *II : Instructions) {
  128. for (unsigned i = 1; i < II->getNumOperands(); i++) {
  129. MachineOperand &MO = II->getOperand(i);
  130. if (!MO.isReg())
  131. continue;
  132. if (Register::isVirtualRegister(MO.getReg()))
  133. continue;
  134. if (!MO.isDef())
  135. continue;
  136. PhysRegDefs.push_back(MO.getReg());
  137. }
  138. }
  139. for (auto *II : Instructions) {
  140. if (II->getNumOperands() == 0)
  141. continue;
  142. if (II->mayLoadOrStore())
  143. continue;
  144. MachineOperand &MO = II->getOperand(0);
  145. if (!MO.isReg() || !Register::isVirtualRegister(MO.getReg()))
  146. continue;
  147. if (!MO.isDef())
  148. continue;
  149. bool IsPseudoIdempotent = true;
  150. for (unsigned i = 1; i < II->getNumOperands(); i++) {
  151. if (II->getOperand(i).isImm()) {
  152. continue;
  153. }
  154. if (II->getOperand(i).isReg()) {
  155. if (!Register::isVirtualRegister(II->getOperand(i).getReg()))
  156. if (!llvm::is_contained(PhysRegDefs, II->getOperand(i).getReg())) {
  157. continue;
  158. }
  159. }
  160. IsPseudoIdempotent = false;
  161. break;
  162. }
  163. if (IsPseudoIdempotent) {
  164. PseudoIdempotentInstructions.push_back(II);
  165. continue;
  166. }
  167. LLVM_DEBUG(dbgs() << "Operand " << 0 << " of "; II->dump(); MO.dump(););
  168. MachineInstr *Def = II;
  169. unsigned Distance = ~0U;
  170. MachineInstr *UseToBringDefCloserTo = nullptr;
  171. MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
  172. for (auto &UO : MRI->use_nodbg_operands(MO.getReg())) {
  173. MachineInstr *UseInst = UO.getParent();
  174. const unsigned DefLoc = getInstrIdx(*Def);
  175. const unsigned UseLoc = getInstrIdx(*UseInst);
  176. const unsigned Delta = (UseLoc - DefLoc);
  177. if (UseInst->getParent() != Def->getParent())
  178. continue;
  179. if (DefLoc >= UseLoc)
  180. continue;
  181. if (Delta < Distance) {
  182. Distance = Delta;
  183. UseToBringDefCloserTo = UseInst;
  184. MultiUserLookup[UseToBringDefCloserToCount++] = UseToBringDefCloserTo;
  185. }
  186. }
  187. const auto BBE = MBB->instr_end();
  188. MachineBasicBlock::iterator DefI = BBE;
  189. MachineBasicBlock::iterator UseI = BBE;
  190. for (auto BBI = MBB->instr_begin(); BBI != BBE; ++BBI) {
  191. if (DefI != BBE && UseI != BBE)
  192. break;
  193. if (&*BBI == Def) {
  194. DefI = BBI;
  195. continue;
  196. }
  197. if (&*BBI == UseToBringDefCloserTo) {
  198. UseI = BBI;
  199. continue;
  200. }
  201. }
  202. if (DefI == BBE || UseI == BBE)
  203. continue;
  204. LLVM_DEBUG({
  205. dbgs() << "Splicing ";
  206. DefI->dump();
  207. dbgs() << " right before: ";
  208. UseI->dump();
  209. });
  210. MultiUsers[UseToBringDefCloserTo].push_back(Def);
  211. Changed = true;
  212. MBB->splice(UseI, MBB, DefI);
  213. }
  214. // Sort the defs for users of multiple defs lexographically.
  215. for (const auto &E : MultiUserLookup) {
  216. auto UseI = llvm::find_if(MBB->instrs(), [&](MachineInstr &MI) -> bool {
  217. return &MI == E.second;
  218. });
  219. if (UseI == MBB->instr_end())
  220. continue;
  221. LLVM_DEBUG(
  222. dbgs() << "Rescheduling Multi-Use Instructions Lexographically.";);
  223. Changed |= rescheduleLexographically(
  224. MultiUsers[E.second], MBB,
  225. [&]() -> MachineBasicBlock::iterator { return UseI; });
  226. }
  227. PseudoIdempotentInstCount = PseudoIdempotentInstructions.size();
  228. LLVM_DEBUG(
  229. dbgs() << "Rescheduling Idempotent Instructions Lexographically.";);
  230. Changed |= rescheduleLexographically(
  231. PseudoIdempotentInstructions, MBB,
  232. [&]() -> MachineBasicBlock::iterator { return MBB->begin(); });
  233. return Changed;
  234. }
  235. static bool propagateLocalCopies(MachineBasicBlock *MBB) {
  236. bool Changed = false;
  237. MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
  238. std::vector<MachineInstr *> Copies;
  239. for (MachineInstr &MI : MBB->instrs()) {
  240. if (MI.isCopy())
  241. Copies.push_back(&MI);
  242. }
  243. for (MachineInstr *MI : Copies) {
  244. if (!MI->getOperand(0).isReg())
  245. continue;
  246. if (!MI->getOperand(1).isReg())
  247. continue;
  248. const Register Dst = MI->getOperand(0).getReg();
  249. const Register Src = MI->getOperand(1).getReg();
  250. if (!Register::isVirtualRegister(Dst))
  251. continue;
  252. if (!Register::isVirtualRegister(Src))
  253. continue;
  254. // Not folding COPY instructions if regbankselect has not set the RCs.
  255. // Why are we only considering Register Classes? Because the verifier
  256. // sometimes gets upset if the register classes don't match even if the
  257. // types do. A future patch might add COPY folding for matching types in
  258. // pre-registerbankselect code.
  259. if (!MRI.getRegClassOrNull(Dst))
  260. continue;
  261. if (MRI.getRegClass(Dst) != MRI.getRegClass(Src))
  262. continue;
  263. std::vector<MachineOperand *> Uses;
  264. for (MachineOperand &MO : MRI.use_operands(Dst))
  265. Uses.push_back(&MO);
  266. for (auto *MO : Uses)
  267. MO->setReg(Src);
  268. Changed = true;
  269. MI->eraseFromParent();
  270. }
  271. return Changed;
  272. }
  273. static bool doDefKillClear(MachineBasicBlock *MBB) {
  274. bool Changed = false;
  275. for (auto &MI : *MBB) {
  276. for (auto &MO : MI.operands()) {
  277. if (!MO.isReg())
  278. continue;
  279. if (!MO.isDef() && MO.isKill()) {
  280. Changed = true;
  281. MO.setIsKill(false);
  282. }
  283. if (MO.isDef() && MO.isDead()) {
  284. Changed = true;
  285. MO.setIsDead(false);
  286. }
  287. }
  288. }
  289. return Changed;
  290. }
  291. static bool runOnBasicBlock(MachineBasicBlock *MBB,
  292. unsigned BasicBlockNum, VRegRenamer &Renamer) {
  293. LLVM_DEBUG({
  294. dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << " \n\n";
  295. dbgs() << "\n\n================================================\n\n";
  296. });
  297. bool Changed = false;
  298. LLVM_DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n";);
  299. LLVM_DEBUG(dbgs() << "MBB Before Canonical Copy Propagation:\n";
  300. MBB->dump(););
  301. Changed |= propagateLocalCopies(MBB);
  302. LLVM_DEBUG(dbgs() << "MBB After Canonical Copy Propagation:\n"; MBB->dump(););
  303. LLVM_DEBUG(dbgs() << "MBB Before Scheduling:\n"; MBB->dump(););
  304. unsigned IdempotentInstCount = 0;
  305. Changed |= rescheduleCanonically(IdempotentInstCount, MBB);
  306. LLVM_DEBUG(dbgs() << "MBB After Scheduling:\n"; MBB->dump(););
  307. Changed |= Renamer.renameVRegs(MBB, BasicBlockNum);
  308. // TODO: Consider dropping this. Dropping kill defs is probably not
  309. // semantically sound.
  310. Changed |= doDefKillClear(MBB);
  311. LLVM_DEBUG(dbgs() << "Updated MachineBasicBlock:\n"; MBB->dump();
  312. dbgs() << "\n";);
  313. LLVM_DEBUG(
  314. dbgs() << "\n\n================================================\n\n");
  315. return Changed;
  316. }
  317. bool MIRCanonicalizer::runOnMachineFunction(MachineFunction &MF) {
  318. static unsigned functionNum = 0;
  319. if (CanonicalizeFunctionNumber != ~0U) {
  320. if (CanonicalizeFunctionNumber != functionNum++)
  321. return false;
  322. LLVM_DEBUG(dbgs() << "\n Canonicalizing Function " << MF.getName()
  323. << "\n";);
  324. }
  325. // we need a valid vreg to create a vreg type for skipping all those
  326. // stray vreg numbers so reach alignment/canonical vreg values.
  327. std::vector<MachineBasicBlock *> RPOList = GetRPOList(MF);
  328. LLVM_DEBUG(
  329. dbgs() << "\n\n NEW MACHINE FUNCTION: " << MF.getName() << " \n\n";
  330. dbgs() << "\n\n================================================\n\n";
  331. dbgs() << "Total Basic Blocks: " << RPOList.size() << "\n";
  332. for (auto MBB
  333. : RPOList) { dbgs() << MBB->getName() << "\n"; } dbgs()
  334. << "\n\n================================================\n\n";);
  335. unsigned BBNum = 0;
  336. bool Changed = false;
  337. MachineRegisterInfo &MRI = MF.getRegInfo();
  338. VRegRenamer Renamer(MRI);
  339. for (auto MBB : RPOList)
  340. Changed |= runOnBasicBlock(MBB, BBNum++, Renamer);
  341. return Changed;
  342. }