1 //===-------------- MIRCanonicalizer.cpp - MIR Canonicalizer --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // The purpose of this pass is to employ a canonical code transformation so 11 // that code compiled with slightly different IR passes can be diffed more 12 // effectively than otherwise. This is done by renaming vregs in a given 13 // LiveRange in a canonical way. This pass also does a pseudo-scheduling to 14 // move defs closer to their use inorder to reduce diffs caused by slightly 15 // different schedules. 16 // 17 // Basic Usage: 18 // 19 // llc -o - -run-pass mir-canonicalizer example.mir 20 // 21 // Reorders instructions canonically. 22 // Renames virtual register operands canonically. 23 // Strips certain MIR artifacts (optionally). 24 // 25 //===----------------------------------------------------------------------===// 26 27 #include "llvm/ADT/PostOrderIterator.h" 28 #include "llvm/ADT/STLExtras.h" 29 #include "llvm/CodeGen/MachineFunctionPass.h" 30 #include "llvm/CodeGen/MachineInstrBuilder.h" 31 #include "llvm/CodeGen/MachineRegisterInfo.h" 32 #include "llvm/CodeGen/Passes.h" 33 #include "llvm/Support/raw_ostream.h" 34 35 #include <queue> 36 37 using namespace llvm; 38 39 namespace llvm { 40 extern char &MIRCanonicalizerID; 41 } // namespace llvm 42 43 #define DEBUG_TYPE "mir-canonicalizer" 44 45 static cl::opt<unsigned> 46 CanonicalizeFunctionNumber("canon-nth-function", cl::Hidden, cl::init(~0u), 47 cl::value_desc("N"), 48 cl::desc("Function number to canonicalize.")); 49 50 static cl::opt<unsigned> 51 CanonicalizeBasicBlockNumber("canon-nth-basicblock", cl::Hidden, cl::init(~0u), 52 cl::value_desc("N"), 53 cl::desc("BasicBlock number to canonicalize.")); 54 55 namespace { 56 57 class MIRCanonicalizer : public MachineFunctionPass { 58 public: 59 static char ID; 60 MIRCanonicalizer() : MachineFunctionPass(ID) {} 61 62 StringRef getPassName() const override { 63 return "Rename register operands in a canonical ordering."; 64 } 65 66 void getAnalysisUsage(AnalysisUsage &AU) const override { 67 AU.setPreservesCFG(); 68 MachineFunctionPass::getAnalysisUsage(AU); 69 } 70 71 bool runOnMachineFunction(MachineFunction &MF) override; 72 }; 73 74 } // end anonymous namespace 75 76 enum VRType { RSE_Reg = 0, RSE_FrameIndex, RSE_NewCandidate }; 77 class TypedVReg { 78 VRType type; 79 unsigned reg; 80 81 public: 82 TypedVReg(unsigned reg) : type(RSE_Reg), reg(reg) {} 83 TypedVReg(VRType type) : type(type), reg(~0U) { 84 assert(type != RSE_Reg && "Expected a non-register type."); 85 } 86 87 bool isReg() const { return type == RSE_Reg; } 88 bool isFrameIndex() const { return type == RSE_FrameIndex; } 89 bool isCandidate() const { return type == RSE_NewCandidate; } 90 91 VRType getType() const { return type; } 92 unsigned getReg() const { 93 assert(this->isReg() && "Expected a virtual or physical register."); 94 return reg; 95 } 96 }; 97 98 char MIRCanonicalizer::ID; 99 100 char &llvm::MIRCanonicalizerID = MIRCanonicalizer::ID; 101 102 INITIALIZE_PASS_BEGIN(MIRCanonicalizer, "mir-canonicalizer", 103 "Rename Register Operands Canonically", false, false) 104 105 INITIALIZE_PASS_END(MIRCanonicalizer, "mir-canonicalizer", 106 "Rename Register Operands Canonically", false, false) 107 108 static std::vector<MachineBasicBlock *> GetRPOList(MachineFunction &MF) { 109 ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin()); 110 std::vector<MachineBasicBlock *> RPOList; 111 for (auto MBB : RPOT) { 112 RPOList.push_back(MBB); 113 } 114 115 return RPOList; 116 } 117 118 static bool 119 rescheduleLexographically(std::vector<MachineInstr *> instructions, 120 MachineBasicBlock *MBB, 121 std::function<MachineBasicBlock::iterator()> getPos) { 122 123 bool Changed = false; 124 std::map<std::string, MachineInstr*> StringInstrMap; 125 126 for (auto *II : instructions) { 127 std::string S; 128 raw_string_ostream OS(S); 129 II->print(OS); 130 OS.flush(); 131 132 // Trim the assignment, or start from the begining in the case of a store. 133 const size_t i = S.find("="); 134 StringInstrMap.insert({(i == std::string::npos) ? S : S.substr(i), II}); 135 } 136 137 for (auto &II : StringInstrMap) { 138 139 DEBUG({ 140 dbgs() << "Splicing "; 141 II.second->dump(); 142 dbgs() << " right before: "; 143 getPos()->dump(); 144 }); 145 146 Changed = true; 147 MBB->splice(getPos(), MBB, II.second); 148 } 149 150 return Changed; 151 } 152 153 static bool rescheduleCanonically(unsigned &PseudoIdempotentInstCount, 154 MachineBasicBlock *MBB) { 155 156 bool Changed = false; 157 158 // Calculates the distance of MI from the begining of its parent BB. 159 auto getInstrIdx = [](const MachineInstr &MI) { 160 unsigned i = 0; 161 for (auto &CurMI : *MI.getParent()) { 162 if (&CurMI == &MI) 163 return i; 164 i++; 165 } 166 return ~0U; 167 }; 168 169 // Pre-Populate vector of instructions to reschedule so that we don't 170 // clobber the iterator. 171 std::vector<MachineInstr *> Instructions; 172 for (auto &MI : *MBB) { 173 Instructions.push_back(&MI); 174 } 175 176 std::map<MachineInstr *, std::vector<MachineInstr *>> MultiUsers; 177 std::vector<MachineInstr *> PseudoIdempotentInstructions; 178 std::vector<unsigned> PhysRegDefs; 179 for (auto *II : Instructions) { 180 for (unsigned i = 1; i < II->getNumOperands(); i++) { 181 MachineOperand &MO = II->getOperand(i); 182 if (!MO.isReg()) 183 continue; 184 185 if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) 186 continue; 187 188 if (!MO.isDef()) 189 continue; 190 191 PhysRegDefs.push_back(MO.getReg()); 192 } 193 } 194 195 for (auto *II : Instructions) { 196 if (II->getNumOperands() == 0) 197 continue; 198 if (II->mayLoadOrStore()) 199 continue; 200 201 MachineOperand &MO = II->getOperand(0); 202 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg())) 203 continue; 204 if (!MO.isDef()) 205 continue; 206 207 bool IsPseudoIdempotent = true; 208 for (unsigned i = 1; i < II->getNumOperands(); i++) { 209 210 if (II->getOperand(i).isImm()) { 211 continue; 212 } 213 214 if (II->getOperand(i).isReg()) { 215 if (!TargetRegisterInfo::isVirtualRegister(II->getOperand(i).getReg())) 216 if (llvm::find(PhysRegDefs, II->getOperand(i).getReg()) == 217 PhysRegDefs.end()) { 218 continue; 219 } 220 } 221 222 IsPseudoIdempotent = false; 223 break; 224 } 225 226 if (IsPseudoIdempotent) { 227 PseudoIdempotentInstructions.push_back(II); 228 continue; 229 } 230 231 DEBUG(dbgs() << "Operand " << 0 << " of "; II->dump(); MO.dump();); 232 233 MachineInstr *Def = II; 234 unsigned Distance = ~0U; 235 MachineInstr *UseToBringDefCloserTo = nullptr; 236 MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo(); 237 for (auto &UO : MRI->use_nodbg_operands(MO.getReg())) { 238 MachineInstr *UseInst = UO.getParent(); 239 240 const unsigned DefLoc = getInstrIdx(*Def); 241 const unsigned UseLoc = getInstrIdx(*UseInst); 242 const unsigned Delta = (UseLoc - DefLoc); 243 244 if (UseInst->getParent() != Def->getParent()) 245 continue; 246 if (DefLoc >= UseLoc) 247 continue; 248 249 if (Delta < Distance) { 250 Distance = Delta; 251 UseToBringDefCloserTo = UseInst; 252 } 253 } 254 255 const auto BBE = MBB->instr_end(); 256 MachineBasicBlock::iterator DefI = BBE; 257 MachineBasicBlock::iterator UseI = BBE; 258 259 for (auto BBI = MBB->instr_begin(); BBI != BBE; ++BBI) { 260 261 if (DefI != BBE && UseI != BBE) 262 break; 263 264 if (&*BBI == Def) { 265 DefI = BBI; 266 continue; 267 } 268 269 if (&*BBI == UseToBringDefCloserTo) { 270 UseI = BBI; 271 continue; 272 } 273 } 274 275 if (DefI == BBE || UseI == BBE) 276 continue; 277 278 DEBUG({ 279 dbgs() << "Splicing "; 280 DefI->dump(); 281 dbgs() << " right before: "; 282 UseI->dump(); 283 }); 284 285 MultiUsers[UseToBringDefCloserTo].push_back(Def); 286 Changed = true; 287 MBB->splice(UseI, MBB, DefI); 288 } 289 290 // Sort the defs for users of multiple defs lexographically. 291 for (const auto &E : MultiUsers) { 292 293 auto UseI = 294 std::find_if(MBB->instr_begin(), MBB->instr_end(), 295 [&](MachineInstr &MI) -> bool { return &MI == E.first; }); 296 297 if (UseI == MBB->instr_end()) 298 continue; 299 300 DEBUG(dbgs() << "Rescheduling Multi-Use Instructions Lexographically.";); 301 Changed |= rescheduleLexographically( 302 E.second, MBB, [&]() -> MachineBasicBlock::iterator { return UseI; }); 303 } 304 305 PseudoIdempotentInstCount = PseudoIdempotentInstructions.size(); 306 DEBUG(dbgs() << "Rescheduling Idempotent Instructions Lexographically.";); 307 Changed |= rescheduleLexographically( 308 PseudoIdempotentInstructions, MBB, 309 [&]() -> MachineBasicBlock::iterator { return MBB->begin(); }); 310 311 return Changed; 312 } 313 314 /// Here we find our candidates. What makes an interesting candidate? 315 /// An candidate for a canonicalization tree root is normally any kind of 316 /// instruction that causes side effects such as a store to memory or a copy to 317 /// a physical register or a return instruction. We use these as an expression 318 /// tree root that we walk inorder to build a canonical walk which should result 319 /// in canoncal vreg renaming. 320 static std::vector<MachineInstr *> populateCandidates(MachineBasicBlock *MBB) { 321 std::vector<MachineInstr *> Candidates; 322 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 323 324 for (auto II = MBB->begin(), IE = MBB->end(); II != IE; ++II) { 325 MachineInstr *MI = &*II; 326 327 bool DoesMISideEffect = false; 328 329 if (MI->getNumOperands() > 0 && MI->getOperand(0).isReg()) { 330 const unsigned Dst = MI->getOperand(0).getReg(); 331 DoesMISideEffect |= !TargetRegisterInfo::isVirtualRegister(Dst); 332 333 for (auto UI = MRI.use_begin(Dst); UI != MRI.use_end(); ++UI) { 334 if (DoesMISideEffect) break; 335 DoesMISideEffect |= (UI->getParent()->getParent() != MI->getParent()); 336 } 337 } 338 339 if (!MI->mayStore() && !MI->isBranch() && !DoesMISideEffect) 340 continue; 341 342 DEBUG(dbgs() << "Found Candidate: "; MI->dump();); 343 Candidates.push_back(MI); 344 } 345 346 return Candidates; 347 } 348 349 static void doCandidateWalk(std::vector<TypedVReg> &VRegs, 350 std::queue<TypedVReg> &RegQueue, 351 std::vector<MachineInstr *> &VisitedMIs, 352 const MachineBasicBlock *MBB) { 353 354 const MachineFunction &MF = *MBB->getParent(); 355 const MachineRegisterInfo &MRI = MF.getRegInfo(); 356 357 while (!RegQueue.empty()) { 358 359 auto TReg = RegQueue.front(); 360 RegQueue.pop(); 361 362 if (TReg.isFrameIndex()) { 363 DEBUG(dbgs() << "Popping frame index.\n";); 364 VRegs.push_back(TypedVReg(RSE_FrameIndex)); 365 continue; 366 } 367 368 assert(TReg.isReg() && "Expected vreg or physreg."); 369 unsigned Reg = TReg.getReg(); 370 371 if (TargetRegisterInfo::isVirtualRegister(Reg)) { 372 DEBUG({ 373 dbgs() << "Popping vreg "; 374 MRI.def_begin(Reg)->dump(); 375 dbgs() << "\n"; 376 }); 377 378 if (!llvm::any_of(VRegs, [&](const TypedVReg &TR) { 379 return TR.isReg() && TR.getReg() == Reg; 380 })) { 381 VRegs.push_back(TypedVReg(Reg)); 382 } 383 } else { 384 DEBUG(dbgs() << "Popping physreg.\n";); 385 VRegs.push_back(TypedVReg(Reg)); 386 continue; 387 } 388 389 for (auto RI = MRI.def_begin(Reg), RE = MRI.def_end(); RI != RE; ++RI) { 390 MachineInstr *Def = RI->getParent(); 391 392 if (Def->getParent() != MBB) 393 continue; 394 395 if (llvm::any_of(VisitedMIs, 396 [&](const MachineInstr *VMI) { return Def == VMI; })) { 397 break; 398 } 399 400 DEBUG({ 401 dbgs() << "\n========================\n"; 402 dbgs() << "Visited MI: "; 403 Def->dump(); 404 dbgs() << "BB Name: " << Def->getParent()->getName() << "\n"; 405 dbgs() << "\n========================\n"; 406 }); 407 VisitedMIs.push_back(Def); 408 for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) { 409 410 MachineOperand &MO = Def->getOperand(I); 411 if (MO.isFI()) { 412 DEBUG(dbgs() << "Pushing frame index.\n";); 413 RegQueue.push(TypedVReg(RSE_FrameIndex)); 414 } 415 416 if (!MO.isReg()) 417 continue; 418 RegQueue.push(TypedVReg(MO.getReg())); 419 } 420 } 421 } 422 } 423 424 class NamedVRegCursor { 425 426 private: 427 428 MachineRegisterInfo &MRI; 429 unsigned virtualVRegNumber; 430 431 public: 432 433 NamedVRegCursor(MachineRegisterInfo &MRI): MRI(MRI) { 434 unsigned VRegGapIndex = 0; 435 const unsigned VR_GAP = (++VRegGapIndex * 1000); 436 437 unsigned I = MRI.createIncompleteVirtualRegister(); 438 const unsigned E = (((I + VR_GAP) / VR_GAP) + 1) * VR_GAP; 439 440 virtualVRegNumber = E; 441 } 442 443 void SkipVRegs() { 444 unsigned VRegGapIndex = 1; 445 const unsigned VR_GAP = (++VRegGapIndex * 1000); 446 447 unsigned I = virtualVRegNumber; 448 const unsigned E = (((I + VR_GAP) / VR_GAP) + 1) * VR_GAP; 449 450 virtualVRegNumber = E; 451 } 452 453 unsigned getVirtualVReg() const { 454 return virtualVRegNumber; 455 } 456 457 unsigned incrementVirtualVReg(unsigned incr = 1) { 458 virtualVRegNumber += incr; 459 return virtualVRegNumber; 460 } 461 462 unsigned createVirtualRegister(const TargetRegisterClass *RC) { 463 std::string S; 464 raw_string_ostream OS(S); 465 OS << "namedVReg" << (virtualVRegNumber & ~0x80000000); 466 OS.flush(); 467 virtualVRegNumber++; 468 469 return MRI.createVirtualRegister(RC, OS.str()); 470 } 471 }; 472 473 static std::map<unsigned, unsigned> 474 GetVRegRenameMap(const std::vector<TypedVReg> &VRegs, 475 const std::vector<unsigned> &renamedInOtherBB, 476 MachineRegisterInfo &MRI, 477 NamedVRegCursor &NVC) { 478 std::map<unsigned, unsigned> VRegRenameMap; 479 bool FirstCandidate = true; 480 481 for (auto &vreg : VRegs) { 482 if (vreg.isFrameIndex()) { 483 // We skip one vreg for any frame index because there is a good chance 484 // (especially when comparing SelectionDAG to GlobalISel generated MIR) 485 // that in the other file we are just getting an incoming vreg that comes 486 // from a copy from a frame index. So it's safe to skip by one. 487 unsigned LastRenameReg = NVC.incrementVirtualVReg(); (void)LastRenameReg; 488 DEBUG(dbgs() << "Skipping rename for FI " << LastRenameReg << "\n";); 489 continue; 490 } else if (vreg.isCandidate()) { 491 492 // After the first candidate, for every subsequent candidate, we skip mod 493 // 10 registers so that the candidates are more likely to start at the 494 // same vreg number making it more likely that the canonical walk from the 495 // candidate insruction. We don't need to skip from the first candidate of 496 // the BasicBlock because we already skip ahead several vregs for each BB. 497 unsigned LastRenameReg = NVC.getVirtualVReg(); 498 if (FirstCandidate) 499 NVC.incrementVirtualVReg(LastRenameReg % 10); 500 FirstCandidate = false; 501 continue; 502 } else if (!TargetRegisterInfo::isVirtualRegister(vreg.getReg())) { 503 unsigned LastRenameReg = NVC.incrementVirtualVReg(); (void)LastRenameReg; 504 DEBUG({ 505 dbgs() << "Skipping rename for Phys Reg " << LastRenameReg << "\n"; 506 }); 507 continue; 508 } 509 510 auto Reg = vreg.getReg(); 511 if (llvm::find(renamedInOtherBB, Reg) != renamedInOtherBB.end()) { 512 DEBUG(dbgs() << "Vreg " << Reg << " already renamed in other BB.\n";); 513 continue; 514 } 515 516 auto Rename = NVC.createVirtualRegister(MRI.getRegClass(Reg)); 517 518 if (VRegRenameMap.find(Reg) == VRegRenameMap.end()) { 519 DEBUG(dbgs() << "Mapping vreg ";); 520 if (MRI.reg_begin(Reg) != MRI.reg_end()) { 521 DEBUG(auto foo = &*MRI.reg_begin(Reg); foo->dump();); 522 } else { 523 DEBUG(dbgs() << Reg;); 524 } 525 DEBUG(dbgs() << " to ";); 526 if (MRI.reg_begin(Rename) != MRI.reg_end()) { 527 DEBUG(auto foo = &*MRI.reg_begin(Rename); foo->dump();); 528 } else { 529 DEBUG(dbgs() << Rename;); 530 } 531 DEBUG(dbgs() << "\n";); 532 533 VRegRenameMap.insert(std::pair<unsigned, unsigned>(Reg, Rename)); 534 } 535 } 536 537 return VRegRenameMap; 538 } 539 540 static bool doVRegRenaming(std::vector<unsigned> &RenamedInOtherBB, 541 const std::map<unsigned, unsigned> &VRegRenameMap, 542 MachineRegisterInfo &MRI) { 543 bool Changed = false; 544 for (auto I = VRegRenameMap.begin(), E = VRegRenameMap.end(); I != E; ++I) { 545 546 auto VReg = I->first; 547 auto Rename = I->second; 548 549 RenamedInOtherBB.push_back(Rename); 550 551 std::vector<MachineOperand *> RenameMOs; 552 for (auto &MO : MRI.reg_operands(VReg)) { 553 RenameMOs.push_back(&MO); 554 } 555 556 for (auto *MO : RenameMOs) { 557 Changed = true; 558 MO->setReg(Rename); 559 560 if (!MO->isDef()) 561 MO->setIsKill(false); 562 } 563 } 564 565 return Changed; 566 } 567 568 static bool doDefKillClear(MachineBasicBlock *MBB) { 569 bool Changed = false; 570 571 for (auto &MI : *MBB) { 572 for (auto &MO : MI.operands()) { 573 if (!MO.isReg()) 574 continue; 575 if (!MO.isDef() && MO.isKill()) { 576 Changed = true; 577 MO.setIsKill(false); 578 } 579 580 if (MO.isDef() && MO.isDead()) { 581 Changed = true; 582 MO.setIsDead(false); 583 } 584 } 585 } 586 587 return Changed; 588 } 589 590 static bool runOnBasicBlock(MachineBasicBlock *MBB, 591 std::vector<StringRef> &bbNames, 592 std::vector<unsigned> &renamedInOtherBB, 593 unsigned &basicBlockNum, unsigned &VRegGapIndex, 594 NamedVRegCursor &NVC) { 595 596 if (CanonicalizeBasicBlockNumber != ~0U) { 597 if (CanonicalizeBasicBlockNumber != basicBlockNum++) 598 return false; 599 DEBUG(dbgs() << "\n Canonicalizing BasicBlock " << MBB->getName() << "\n";); 600 } 601 602 if (llvm::find(bbNames, MBB->getName()) != bbNames.end()) { 603 DEBUG({ 604 dbgs() << "Found potentially duplicate BasicBlocks: " << MBB->getName() 605 << "\n"; 606 }); 607 return false; 608 } 609 610 DEBUG({ 611 dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << " \n\n"; 612 dbgs() << "\n\n================================================\n\n"; 613 }); 614 615 bool Changed = false; 616 MachineFunction &MF = *MBB->getParent(); 617 MachineRegisterInfo &MRI = MF.getRegInfo(); 618 619 bbNames.push_back(MBB->getName()); 620 DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n";); 621 622 DEBUG(dbgs() << "MBB Before Scheduling:\n"; MBB->dump();); 623 unsigned IdempotentInstCount = 0; 624 Changed |= rescheduleCanonically(IdempotentInstCount, MBB); 625 DEBUG(dbgs() << "MBB After Scheduling:\n"; MBB->dump();); 626 627 std::vector<MachineInstr *> Candidates = populateCandidates(MBB); 628 std::vector<MachineInstr *> VisitedMIs; 629 std::copy(Candidates.begin(), Candidates.end(), 630 std::back_inserter(VisitedMIs)); 631 632 std::vector<TypedVReg> VRegs; 633 for (auto candidate : Candidates) { 634 VRegs.push_back(TypedVReg(RSE_NewCandidate)); 635 636 std::queue<TypedVReg> RegQueue; 637 638 // Here we walk the vreg operands of a non-root node along our walk. 639 // The root nodes are the original candidates (stores normally). 640 // These are normally not the root nodes (except for the case of copies to 641 // physical registers). 642 for (unsigned i = 1; i < candidate->getNumOperands(); i++) { 643 if (candidate->mayStore() || candidate->isBranch()) 644 break; 645 646 MachineOperand &MO = candidate->getOperand(i); 647 if (!(MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))) 648 continue; 649 650 DEBUG(dbgs() << "Enqueue register"; MO.dump(); dbgs() << "\n";); 651 RegQueue.push(TypedVReg(MO.getReg())); 652 } 653 654 // Here we walk the root candidates. We start from the 0th operand because 655 // the root is normally a store to a vreg. 656 for (unsigned i = 0; i < candidate->getNumOperands(); i++) { 657 658 if (!candidate->mayStore() && !candidate->isBranch()) 659 break; 660 661 MachineOperand &MO = candidate->getOperand(i); 662 663 // TODO: Do we want to only add vregs here? 664 if (!MO.isReg() && !MO.isFI()) 665 continue; 666 667 DEBUG(dbgs() << "Enqueue Reg/FI"; MO.dump(); dbgs() << "\n";); 668 669 RegQueue.push(MO.isReg() ? TypedVReg(MO.getReg()) : 670 TypedVReg(RSE_FrameIndex)); 671 } 672 673 doCandidateWalk(VRegs, RegQueue, VisitedMIs, MBB); 674 } 675 676 // If we have populated no vregs to rename then bail. 677 // The rest of this function does the vreg remaping. 678 if (VRegs.size() == 0) 679 return Changed; 680 681 auto VRegRenameMap = GetVRegRenameMap(VRegs, renamedInOtherBB, MRI, NVC); 682 Changed |= doVRegRenaming(renamedInOtherBB, VRegRenameMap, MRI); 683 684 // Here we renumber the def vregs for the idempotent instructions from the top 685 // of the MachineBasicBlock so that they are named in the order that we sorted 686 // them alphabetically. Eventually we wont need SkipVRegs because we will use 687 // named vregs instead. 688 NVC.SkipVRegs(); 689 690 auto MII = MBB->begin(); 691 for (unsigned i = 0; i < IdempotentInstCount && MII != MBB->end(); ++i) { 692 MachineInstr &MI = *MII++; 693 Changed = true; 694 unsigned vRegToRename = MI.getOperand(0).getReg(); 695 auto Rename = NVC.createVirtualRegister(MRI.getRegClass(vRegToRename)); 696 697 std::vector<MachineOperand *> RenameMOs; 698 for (auto &MO : MRI.reg_operands(vRegToRename)) { 699 RenameMOs.push_back(&MO); 700 } 701 702 for (auto *MO : RenameMOs) { 703 MO->setReg(Rename); 704 } 705 } 706 707 Changed |= doDefKillClear(MBB); 708 709 DEBUG(dbgs() << "Updated MachineBasicBlock:\n"; MBB->dump(); dbgs() << "\n";); 710 DEBUG(dbgs() << "\n\n================================================\n\n"); 711 return Changed; 712 } 713 714 bool MIRCanonicalizer::runOnMachineFunction(MachineFunction &MF) { 715 716 static unsigned functionNum = 0; 717 if (CanonicalizeFunctionNumber != ~0U) { 718 if (CanonicalizeFunctionNumber != functionNum++) 719 return false; 720 DEBUG(dbgs() << "\n Canonicalizing Function " << MF.getName() << "\n";); 721 } 722 723 // we need a valid vreg to create a vreg type for skipping all those 724 // stray vreg numbers so reach alignment/canonical vreg values. 725 std::vector<MachineBasicBlock*> RPOList = GetRPOList(MF); 726 727 DEBUG( 728 dbgs() << "\n\n NEW MACHINE FUNCTION: " << MF.getName() << " \n\n"; 729 dbgs() << "\n\n================================================\n\n"; 730 dbgs() << "Total Basic Blocks: " << RPOList.size() << "\n"; 731 for (auto MBB : RPOList) { 732 dbgs() << MBB->getName() << "\n"; 733 } 734 dbgs() << "\n\n================================================\n\n"; 735 ); 736 737 std::vector<StringRef> BBNames; 738 std::vector<unsigned> RenamedInOtherBB; 739 740 unsigned GapIdx = 0; 741 unsigned BBNum = 0; 742 743 bool Changed = false; 744 745 MachineRegisterInfo &MRI = MF.getRegInfo(); 746 NamedVRegCursor NVC(MRI); 747 for (auto MBB : RPOList) 748 Changed |= runOnBasicBlock(MBB, BBNames, RenamedInOtherBB, BBNum, GapIdx, NVC); 749 750 return Changed; 751 } 752 753