MIRCanonicalizerPass.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  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/Support/raw_ostream.h"
  33. #include <queue>
  34. using namespace llvm;
  35. namespace llvm {
  36. extern char &MIRCanonicalizerID;
  37. } // namespace llvm
  38. #define DEBUG_TYPE "mir-canonicalizer"
  39. static cl::opt<unsigned>
  40. CanonicalizeFunctionNumber("canon-nth-function", cl::Hidden, cl::init(~0u),
  41. cl::value_desc("N"),
  42. cl::desc("Function number to canonicalize."));
  43. static cl::opt<unsigned> CanonicalizeBasicBlockNumber(
  44. "canon-nth-basicblock", cl::Hidden, cl::init(~0u), cl::value_desc("N"),
  45. cl::desc("BasicBlock number to canonicalize."));
  46. namespace {
  47. class MIRCanonicalizer : public MachineFunctionPass {
  48. public:
  49. static char ID;
  50. MIRCanonicalizer() : MachineFunctionPass(ID) {}
  51. StringRef getPassName() const override {
  52. return "Rename register operands in a canonical ordering.";
  53. }
  54. void getAnalysisUsage(AnalysisUsage &AU) const override {
  55. AU.setPreservesCFG();
  56. MachineFunctionPass::getAnalysisUsage(AU);
  57. }
  58. bool runOnMachineFunction(MachineFunction &MF) override;
  59. };
  60. } // end anonymous namespace
  61. char MIRCanonicalizer::ID;
  62. char &llvm::MIRCanonicalizerID = MIRCanonicalizer::ID;
  63. INITIALIZE_PASS_BEGIN(MIRCanonicalizer, "mir-canonicalizer",
  64. "Rename Register Operands Canonically", false, false)
  65. INITIALIZE_PASS_END(MIRCanonicalizer, "mir-canonicalizer",
  66. "Rename Register Operands Canonically", false, false)
  67. static std::vector<MachineBasicBlock *> GetRPOList(MachineFunction &MF) {
  68. if (MF.empty())
  69. return {};
  70. ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
  71. std::vector<MachineBasicBlock *> RPOList;
  72. for (auto MBB : RPOT) {
  73. RPOList.push_back(MBB);
  74. }
  75. return RPOList;
  76. }
  77. static bool
  78. rescheduleLexographically(std::vector<MachineInstr *> instructions,
  79. MachineBasicBlock *MBB,
  80. std::function<MachineBasicBlock::iterator()> getPos) {
  81. bool Changed = false;
  82. using StringInstrPair = std::pair<std::string, MachineInstr *>;
  83. std::vector<StringInstrPair> StringInstrMap;
  84. for (auto *II : instructions) {
  85. std::string S;
  86. raw_string_ostream OS(S);
  87. II->print(OS);
  88. OS.flush();
  89. // Trim the assignment, or start from the begining in the case of a store.
  90. const size_t i = S.find("=");
  91. StringInstrMap.push_back({(i == std::string::npos) ? S : S.substr(i), II});
  92. }
  93. llvm::sort(StringInstrMap,
  94. [](const StringInstrPair &a, const StringInstrPair &b) -> bool {
  95. return (a.first < b.first);
  96. });
  97. for (auto &II : StringInstrMap) {
  98. LLVM_DEBUG({
  99. dbgs() << "Splicing ";
  100. II.second->dump();
  101. dbgs() << " right before: ";
  102. getPos()->dump();
  103. });
  104. Changed = true;
  105. MBB->splice(getPos(), MBB, II.second);
  106. }
  107. return Changed;
  108. }
  109. static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount,
  110. MachineBasicBlock *MBB) {
  111. bool Changed = false;
  112. // Calculates the distance of MI from the begining of its parent BB.
  113. auto getInstrIdx = [](const MachineInstr &MI) {
  114. unsigned i = 0;
  115. for (auto &CurMI : *MI.getParent()) {
  116. if (&CurMI == &MI)
  117. return i;
  118. i++;
  119. }
  120. return ~0U;
  121. };
  122. // Pre-Populate vector of instructions to reschedule so that we don't
  123. // clobber the iterator.
  124. std::vector<MachineInstr *> Instructions;
  125. for (auto &MI : *MBB) {
  126. Instructions.push_back(&MI);
  127. }
  128. std::map<MachineInstr *, std::vector<MachineInstr *>> MultiUsers;
  129. std::map<unsigned, MachineInstr *> MultiUserLookup;
  130. unsigned UseToBringDefCloserToCount = 0;
  131. std::vector<MachineInstr *> PseudoIdempotentInstructions;
  132. std::vector<unsigned> PhysRegDefs;
  133. for (auto *II : Instructions) {
  134. for (unsigned i = 1; i < II->getNumOperands(); i++) {
  135. MachineOperand &MO = II->getOperand(i);
  136. if (!MO.isReg())
  137. continue;
  138. if (Register::isVirtualRegister(MO.getReg()))
  139. continue;
  140. if (!MO.isDef())
  141. continue;
  142. PhysRegDefs.push_back(MO.getReg());
  143. }
  144. }
  145. for (auto *II : Instructions) {
  146. if (II->getNumOperands() == 0)
  147. continue;
  148. if (II->mayLoadOrStore())
  149. continue;
  150. MachineOperand &MO = II->getOperand(0);
  151. if (!MO.isReg() || !Register::isVirtualRegister(MO.getReg()))
  152. continue;
  153. if (!MO.isDef())
  154. continue;
  155. bool IsPseudoIdempotent = true;
  156. for (unsigned i = 1; i < II->getNumOperands(); i++) {
  157. if (II->getOperand(i).isImm()) {
  158. continue;
  159. }
  160. if (II->getOperand(i).isReg()) {
  161. if (!Register::isVirtualRegister(II->getOperand(i).getReg()))
  162. if (llvm::find(PhysRegDefs, II->getOperand(i).getReg()) ==
  163. PhysRegDefs.end()) {
  164. continue;
  165. }
  166. }
  167. IsPseudoIdempotent = false;
  168. break;
  169. }
  170. if (IsPseudoIdempotent) {
  171. PseudoIdempotentInstructions.push_back(II);
  172. continue;
  173. }
  174. LLVM_DEBUG(dbgs() << "Operand " << 0 << " of "; II->dump(); MO.dump(););
  175. MachineInstr *Def = II;
  176. unsigned Distance = ~0U;
  177. MachineInstr *UseToBringDefCloserTo = nullptr;
  178. MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
  179. for (auto &UO : MRI->use_nodbg_operands(MO.getReg())) {
  180. MachineInstr *UseInst = UO.getParent();
  181. const unsigned DefLoc = getInstrIdx(*Def);
  182. const unsigned UseLoc = getInstrIdx(*UseInst);
  183. const unsigned Delta = (UseLoc - DefLoc);
  184. if (UseInst->getParent() != Def->getParent())
  185. continue;
  186. if (DefLoc >= UseLoc)
  187. continue;
  188. if (Delta < Distance) {
  189. Distance = Delta;
  190. UseToBringDefCloserTo = UseInst;
  191. MultiUserLookup[UseToBringDefCloserToCount++] = UseToBringDefCloserTo;
  192. }
  193. }
  194. const auto BBE = MBB->instr_end();
  195. MachineBasicBlock::iterator DefI = BBE;
  196. MachineBasicBlock::iterator UseI = BBE;
  197. for (auto BBI = MBB->instr_begin(); BBI != BBE; ++BBI) {
  198. if (DefI != BBE && UseI != BBE)
  199. break;
  200. if (&*BBI == Def) {
  201. DefI = BBI;
  202. continue;
  203. }
  204. if (&*BBI == UseToBringDefCloserTo) {
  205. UseI = BBI;
  206. continue;
  207. }
  208. }
  209. if (DefI == BBE || UseI == BBE)
  210. continue;
  211. LLVM_DEBUG({
  212. dbgs() << "Splicing ";
  213. DefI->dump();
  214. dbgs() << " right before: ";
  215. UseI->dump();
  216. });
  217. MultiUsers[UseToBringDefCloserTo].push_back(Def);
  218. Changed = true;
  219. MBB->splice(UseI, MBB, DefI);
  220. }
  221. // Sort the defs for users of multiple defs lexographically.
  222. for (const auto &E : MultiUserLookup) {
  223. auto UseI =
  224. std::find_if(MBB->instr_begin(), MBB->instr_end(),
  225. [&](MachineInstr &MI) -> bool { return &MI == E.second; });
  226. if (UseI == MBB->instr_end())
  227. continue;
  228. LLVM_DEBUG(
  229. dbgs() << "Rescheduling Multi-Use Instructions Lexographically.";);
  230. Changed |= rescheduleLexographically(
  231. MultiUsers[E.second], MBB,
  232. [&]() -> MachineBasicBlock::iterator { return UseI; });
  233. }
  234. PseudoIdempotentInstCount = PseudoIdempotentInstructions.size();
  235. LLVM_DEBUG(
  236. dbgs() << "Rescheduling Idempotent Instructions Lexographically.";);
  237. Changed |= rescheduleLexographically(
  238. PseudoIdempotentInstructions, MBB,
  239. [&]() -> MachineBasicBlock::iterator { return MBB->begin(); });
  240. return Changed;
  241. }
  242. static bool propagateLocalCopies(MachineBasicBlock *MBB) {
  243. bool Changed = false;
  244. MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
  245. std::vector<MachineInstr *> Copies;
  246. for (MachineInstr &MI : MBB->instrs()) {
  247. if (MI.isCopy())
  248. Copies.push_back(&MI);
  249. }
  250. for (MachineInstr *MI : Copies) {
  251. if (!MI->getOperand(0).isReg())
  252. continue;
  253. if (!MI->getOperand(1).isReg())
  254. continue;
  255. const Register Dst = MI->getOperand(0).getReg();
  256. const Register Src = MI->getOperand(1).getReg();
  257. if (!Register::isVirtualRegister(Dst))
  258. continue;
  259. if (!Register::isVirtualRegister(Src))
  260. continue;
  261. // Not folding COPY instructions if regbankselect has not set the RCs.
  262. // Why are we only considering Register Classes? Because the verifier
  263. // sometimes gets upset if the register classes don't match even if the
  264. // types do. A future patch might add COPY folding for matching types in
  265. // pre-registerbankselect code.
  266. if (!MRI.getRegClassOrNull(Dst))
  267. continue;
  268. if (MRI.getRegClass(Dst) != MRI.getRegClass(Src))
  269. continue;
  270. std::vector<MachineOperand *> Uses;
  271. for (auto UI = MRI.use_begin(Dst); UI != MRI.use_end(); ++UI)
  272. Uses.push_back(&*UI);
  273. for (auto *MO : Uses)
  274. MO->setReg(Src);
  275. Changed = true;
  276. MI->eraseFromParent();
  277. }
  278. return Changed;
  279. }
  280. static bool doDefKillClear(MachineBasicBlock *MBB) {
  281. bool Changed = false;
  282. for (auto &MI : *MBB) {
  283. for (auto &MO : MI.operands()) {
  284. if (!MO.isReg())
  285. continue;
  286. if (!MO.isDef() && MO.isKill()) {
  287. Changed = true;
  288. MO.setIsKill(false);
  289. }
  290. if (MO.isDef() && MO.isDead()) {
  291. Changed = true;
  292. MO.setIsDead(false);
  293. }
  294. }
  295. }
  296. return Changed;
  297. }
  298. static bool runOnBasicBlock(MachineBasicBlock *MBB,
  299. std::vector<StringRef> &bbNames,
  300. unsigned &basicBlockNum, NamedVRegCursor &NVC) {
  301. if (CanonicalizeBasicBlockNumber != ~0U) {
  302. if (CanonicalizeBasicBlockNumber != basicBlockNum++)
  303. return false;
  304. LLVM_DEBUG(dbgs() << "\n Canonicalizing BasicBlock " << MBB->getName()
  305. << "\n";);
  306. }
  307. if (llvm::find(bbNames, MBB->getName()) != bbNames.end()) {
  308. LLVM_DEBUG({
  309. dbgs() << "Found potentially duplicate BasicBlocks: " << MBB->getName()
  310. << "\n";
  311. });
  312. return false;
  313. }
  314. LLVM_DEBUG({
  315. dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << " \n\n";
  316. dbgs() << "\n\n================================================\n\n";
  317. });
  318. bool Changed = false;
  319. MachineFunction &MF = *MBB->getParent();
  320. MachineRegisterInfo &MRI = MF.getRegInfo();
  321. bbNames.push_back(MBB->getName());
  322. LLVM_DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n";);
  323. LLVM_DEBUG(dbgs() << "MBB Before Canonical Copy Propagation:\n";
  324. MBB->dump(););
  325. Changed |= propagateLocalCopies(MBB);
  326. LLVM_DEBUG(dbgs() << "MBB After Canonical Copy Propagation:\n"; MBB->dump(););
  327. LLVM_DEBUG(dbgs() << "MBB Before Scheduling:\n"; MBB->dump(););
  328. unsigned IdempotentInstCount = 0;
  329. Changed |= rescheduleCanonically(IdempotentInstCount, MBB);
  330. LLVM_DEBUG(dbgs() << "MBB After Scheduling:\n"; MBB->dump(););
  331. Changed |= NVC.renameVRegs(MBB);
  332. // Here we renumber the def vregs for the idempotent instructions from the top
  333. // of the MachineBasicBlock so that they are named in the order that we sorted
  334. // them alphabetically. Eventually we wont need SkipVRegs because we will use
  335. // named vregs instead.
  336. if (IdempotentInstCount)
  337. NVC.skipVRegs();
  338. auto MII = MBB->begin();
  339. for (unsigned i = 0; i < IdempotentInstCount && MII != MBB->end(); ++i) {
  340. MachineInstr &MI = *MII++;
  341. Changed = true;
  342. Register vRegToRename = MI.getOperand(0).getReg();
  343. auto Rename = NVC.createVirtualRegister(vRegToRename);
  344. std::vector<MachineOperand *> RenameMOs;
  345. for (auto &MO : MRI.reg_operands(vRegToRename)) {
  346. RenameMOs.push_back(&MO);
  347. }
  348. for (auto *MO : RenameMOs) {
  349. MO->setReg(Rename);
  350. }
  351. }
  352. Changed |= doDefKillClear(MBB);
  353. LLVM_DEBUG(dbgs() << "Updated MachineBasicBlock:\n"; MBB->dump();
  354. dbgs() << "\n";);
  355. LLVM_DEBUG(
  356. dbgs() << "\n\n================================================\n\n");
  357. return Changed;
  358. }
  359. bool MIRCanonicalizer::runOnMachineFunction(MachineFunction &MF) {
  360. static unsigned functionNum = 0;
  361. if (CanonicalizeFunctionNumber != ~0U) {
  362. if (CanonicalizeFunctionNumber != functionNum++)
  363. return false;
  364. LLVM_DEBUG(dbgs() << "\n Canonicalizing Function " << MF.getName()
  365. << "\n";);
  366. }
  367. // we need a valid vreg to create a vreg type for skipping all those
  368. // stray vreg numbers so reach alignment/canonical vreg values.
  369. std::vector<MachineBasicBlock *> RPOList = GetRPOList(MF);
  370. LLVM_DEBUG(
  371. dbgs() << "\n\n NEW MACHINE FUNCTION: " << MF.getName() << " \n\n";
  372. dbgs() << "\n\n================================================\n\n";
  373. dbgs() << "Total Basic Blocks: " << RPOList.size() << "\n";
  374. for (auto MBB
  375. : RPOList) { dbgs() << MBB->getName() << "\n"; } dbgs()
  376. << "\n\n================================================\n\n";);
  377. std::vector<StringRef> BBNames;
  378. unsigned BBNum = 0;
  379. bool Changed = false;
  380. MachineRegisterInfo &MRI = MF.getRegInfo();
  381. NamedVRegCursor NVC(MRI);
  382. for (auto MBB : RPOList)
  383. Changed |= runOnBasicBlock(MBB, BBNames, BBNum, NVC);
  384. return Changed;
  385. }