Index: lib/CodeGen/MIRCanonicalizerPass.cpp =================================================================== --- lib/CodeGen/MIRCanonicalizerPass.cpp +++ lib/CodeGen/MIRCanonicalizerPass.cpp @@ -311,6 +311,47 @@ return Changed; } +bool propagateLocalCopies(MachineBasicBlock *MBB) { + bool Changed = false; + MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); + + std::vector copies; + for (auto II = MBB->begin(), IE = MBB->end(); II != IE; ++II) { + if (II->isCopy()) + copies.push_back(&*II); + } + + for (auto MI : copies) { + + if (!MI->getOperand(0).isReg()) + continue; + if (!MI->getOperand(1).isReg()) + continue; + + const unsigned Dst = MI->getOperand(0).getReg(); + const unsigned Src = MI->getOperand(1).getReg(); + + if (!TargetRegisterInfo::isVirtualRegister(Dst)) + continue; + if (!TargetRegisterInfo::isVirtualRegister(Src)) + continue; + + std::vector RenameMOs; + for (auto UI = MRI.use_begin(Dst); UI != MRI.use_end(); ++UI) { + RenameMOs.push_back(&*UI); + } + + for (auto *MO : RenameMOs) { + Changed = true; + MO->setReg(Src); + } + + MI->eraseFromParent(); + } + + return Changed; +} + /// Here we find our candidates. What makes an interesting candidate? /// An candidate for a canonicalization tree root is normally any kind of /// instruction that causes side effects such as a store to memory or a copy to @@ -619,6 +660,10 @@ bbNames.push_back(MBB->getName()); DEBUG(dbgs() << "\n\n NEW BASIC BLOCK: " << MBB->getName() << "\n\n";); + DEBUG(dbgs() << "MBB Before Canonical Copy Propagation:\n"; MBB->dump();); + Changed |= propagateLocalCopies(MBB); + DEBUG(dbgs() << "MBB After Canonical Copy Propagation:\n"; MBB->dump();); + DEBUG(dbgs() << "MBB Before Scheduling:\n"; MBB->dump();); unsigned IdempotentInstCount = 0; Changed |= rescheduleCanonically(IdempotentInstCount, MBB);