- // If this spill slot is available, turn it into a copy (or nothing)
- // instead of leaving it as a load!
- unsigned InReg;
- if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) {
- DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
- MachineFunction &MF = *MBB.getParent();
- if (DestReg != InReg) {
- MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
- MF.getSSARegMap()->getRegClass(VirtReg));
- // Revisit the copy so we make sure to notice the effects of the
- // operation on the destreg (either needing to RA it if it's
- // virtual or needing to clobber any values if it's physical).
- NextMII = &MI;
- --NextMII; // backtrack to the copy.
+ if (FrameIdx == SS) {
+ // If this spill slot is available, turn it into a copy (or nothing)
+ // instead of leaving it as a load!
+ MachineInstr *SSMI = NULL;
+ if (unsigned InReg = Spills.getSpillSlotPhysReg(SS, SSMI)) {
+ DOUT << "Promoted Load To Copy: " << MI;
+ MachineFunction &MF = *MBB.getParent();
+ if (DestReg != InReg) {
+ MRI->copyRegToReg(MBB, &MI, DestReg, InReg,
+ MF.getSSARegMap()->getRegClass(VirtReg));
+ // Revisit the copy so we make sure to notice the effects of the
+ // operation on the destreg (either needing to RA it if it's
+ // virtual or needing to clobber any values if it's physical).
+ NextMII = &MI;
+ --NextMII; // backtrack to the copy.
+ } else
+ DOUT << "Removing now-noop copy: " << MI;
+
+ // Either way, the live range of the last kill of InReg has been
+ // extended. Remove its kill.
+ bool WasKill = false;
+ if (SSMI) {
+ int UIdx = SSMI->findRegisterUseOperand(InReg, true);
+ if (UIdx != -1) {
+ MachineOperand &MOK = SSMI->getOperand(UIdx);
+ WasKill = MOK.isKill();
+ MOK.unsetIsKill();
+ }
+ }
+ if (NextMII != MBB.end()) {
+ // If NextMII uses InReg and the use is not a two address
+ // operand, mark it killed.
+ int UIdx = NextMII->findRegisterUseOperand(InReg);
+ if (UIdx != -1) {
+ MachineOperand &MOU = NextMII->getOperand(UIdx);
+ if (WasKill) {
+ const TargetInstrDescriptor *NTID =
+ NextMII->getInstrDescriptor();
+ if (UIdx >= NTID->numOperands ||
+ NTID->getOperandConstraint(UIdx, TOI::TIED_TO) == -1)
+ MOU.setIsKill();
+ }
+ Spills.addLastUse(InReg, &(*NextMII));
+ }
+ }
+
+ VRM.RemoveFromFoldedVirtMap(&MI);
+ MBB.erase(&MI);
+ goto ProcessNextInst;