Detect and handle COPY in many places.

This code is transitional, it will soon be possible to eliminate
isExtractSubreg, isInsertSubreg, and isMoveInstr in most places.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107547 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen
2010-07-03 00:04:37 +00:00
parent 43b8fd728b
commit 273f7e4299
10 changed files with 73 additions and 40 deletions

View File

@ -231,6 +231,12 @@ public:
return getOpcode() == TargetOpcode::COPY; return getOpcode() == TargetOpcode::COPY;
} }
/// isCopyLike - Return true if the instruction behaves like a copy.
/// This does not include native copy instructions.
bool isCopyLike() const {
return isCopy() || isSubregToReg() || isExtractSubreg() || isInsertSubreg();
}
/// readsRegister - Return true if the MachineInstr reads the specified /// readsRegister - Return true if the MachineInstr reads the specified
/// register. If TargetRegisterInfo is passed, then it also checks if there /// register. If TargetRegisterInfo is passed, then it also checks if there
/// is a read of a super-register. /// is a read of a super-register.

View File

@ -321,7 +321,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
MachineInstr *CopyMI = NULL; MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg() || if (mi->isCopyLike() ||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg)) { tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg)) {
CopyMI = mi; CopyMI = mi;
@ -457,8 +457,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
// A re-def may be a copy. e.g. %reg1030:6<def> = VMOVD %reg1026, ... // A re-def may be a copy. e.g. %reg1030:6<def> = VMOVD %reg1026, ...
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (PartReDef && if (PartReDef && (mi->isCopyLike() ||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg)) tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg)))
OldValNo->setCopy(&*mi); OldValNo->setCopy(&*mi);
// Add the new live interval which replaces the range for the input copy. // Add the new live interval which replaces the range for the input copy.
@ -488,7 +488,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
VNInfo *ValNo; VNInfo *ValNo;
MachineInstr *CopyMI = NULL; MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (mi->isExtractSubreg() || mi->isInsertSubreg() || mi->isSubregToReg()|| if (mi->isCopyLike() ||
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg)) tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi; CopyMI = mi;
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator); ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
@ -605,7 +605,7 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
else if (allocatableRegs_[MO.getReg()]) { else if (allocatableRegs_[MO.getReg()]) {
MachineInstr *CopyMI = NULL; MachineInstr *CopyMI = NULL;
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg() || if (MI->isCopyLike() ||
tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = MI; CopyMI = MI;
handlePhysicalRegisterDef(MBB, MI, MIIdx, MO, handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,

View File

@ -241,8 +241,8 @@ bool MachineCSE::PhysRegDefReaches(MachineInstr *CSMI, MachineInstr *MI,
static bool isCopy(const MachineInstr *MI, const TargetInstrInfo *TII) { static bool isCopy(const MachineInstr *MI, const TargetInstrInfo *TII) {
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
return TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) || return MI->isCopyLike() ||
MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg(); TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
} }
bool MachineCSE::isCSECandidate(MachineInstr *MI) { bool MachineCSE::isCSECandidate(MachineInstr *MI) {

View File

@ -107,6 +107,11 @@ bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI,
SrcSubIdx == 0 && DstSubIdx == 0 && SrcSubIdx == 0 && DstSubIdx == 0 &&
TargetRegisterInfo::isVirtualRegister(MvSrcReg)) TargetRegisterInfo::isVirtualRegister(MvSrcReg))
SrcMI = MRI->getVRegDef(MvSrcReg); SrcMI = MRI->getVRegDef(MvSrcReg);
else if (SrcMI && SrcMI->isCopy() &&
!SrcMI->getOperand(0).getSubReg() &&
!SrcMI->getOperand(1).getSubReg() &&
TargetRegisterInfo::isVirtualRegister(SrcMI->getOperand(1).getReg()))
SrcMI = MRI->getVRegDef(SrcMI->getOperand(1).getReg());
if (!SrcMI) if (!SrcMI)
return false; return false;

View File

@ -677,10 +677,12 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
// If the def is a move, set the copy field. // If the def is a move, set the copy field.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (TII->isMoveInstr(*DI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) if (TII->isMoveInstr(*DI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
if (DstReg == LI->reg) if (DstReg == LI->reg)
NewVN->setCopy(&*DI); NewVN->setCopy(&*DI);
} else if (DI->isCopyLike() && DI->getOperand(0).getReg() == LI->reg)
NewVN->setCopy(&*DI);
NewVNs[&*DI] = NewVN; NewVNs[&*DI] = NewVN;
} }

View File

@ -46,14 +46,15 @@ bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI,
const TargetInstrInfo *tii_) { const TargetInstrInfo *tii_) {
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) && if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
Reg == SrcReg && SrcSubReg == 0 && DstSubReg == 0) Reg == SrcReg && DstSubReg == 0)
return true; return true;
if (OpIdx == 2 && MI->isSubregToReg()) switch(OpIdx) {
return true; case 1: return (MI->isExtractSubreg() || MI->isCopy()) &&
if (OpIdx == 1 && MI->isExtractSubreg()) MI->getOperand(0).getSubReg() == 0;
return true; case 2: return MI->isSubregToReg() && MI->getOperand(0).getSubReg() == 0;
return false; default: return false;
}
} }
/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure /// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure
@ -219,8 +220,10 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
// Turn a copy use into an implicit_def. // Turn a copy use into an implicit_def.
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) && if ((RMI->isCopy() && RMI->getOperand(1).getReg() == Reg &&
Reg == SrcReg && SrcSubReg == 0 && DstSubReg == 0) { RMI->getOperand(0).getSubReg() == 0) ||
(tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
Reg == SrcReg && DstSubReg == 0)) {
RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF)); RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF));
bool isKill = false; bool isKill = false;

View File

@ -519,10 +519,12 @@ RAFast::defineVirtReg(MachineInstr *MI, unsigned OpNum,
// If there is no hint, peek at the only use of this register. // If there is no hint, peek at the only use of this register.
if ((!Hint || !TargetRegisterInfo::isPhysicalRegister(Hint)) && if ((!Hint || !TargetRegisterInfo::isPhysicalRegister(Hint)) &&
MRI->hasOneNonDBGUse(VirtReg)) { MRI->hasOneNonDBGUse(VirtReg)) {
const MachineInstr &UseMI = *MRI->use_nodbg_begin(VirtReg);
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
// It's a copy, use the destination register as a hint. // It's a copy, use the destination register as a hint.
if (TII->isMoveInstr(*MRI->use_nodbg_begin(VirtReg), if (UseMI.isCopyLike())
SrcReg, DstReg, SrcSubReg, DstSubReg)) Hint = UseMI.getOperand(0).getReg();
else if (TII->isMoveInstr(UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
Hint = DstReg; Hint = DstReg;
} }
allocVirtReg(MI, *LRI, Hint); allocVirtReg(MI, *LRI, Hint);
@ -771,7 +773,12 @@ void RAFast::AllocateBasicBlock() {
// If this is a copy, we may be able to coalesce. // If this is a copy, we may be able to coalesce.
unsigned CopySrc, CopyDst, CopySrcSub, CopyDstSub; unsigned CopySrc, CopyDst, CopySrcSub, CopyDstSub;
if (!TII->isMoveInstr(*MI, CopySrc, CopyDst, CopySrcSub, CopyDstSub)) if (MI->isCopy()) {
CopyDst = MI->getOperand(0).getReg();
CopySrc = MI->getOperand(1).getReg();
CopyDstSub = MI->getOperand(0).getSubReg();
CopySrcSub = MI->getOperand(1).getSubReg();
} else if (!TII->isMoveInstr(*MI, CopySrc, CopyDst, CopySrcSub, CopyDstSub))
CopySrc = CopyDst = 0; CopySrc = CopyDst = 0;
// Track registers used by instruction. // Track registers used by instruction.

View File

@ -44,7 +44,12 @@ unsigned CoalescerPair::compose(unsigned a, unsigned b) const {
bool CoalescerPair::isMoveInstr(const MachineInstr *MI, bool CoalescerPair::isMoveInstr(const MachineInstr *MI,
unsigned &Src, unsigned &Dst, unsigned &Src, unsigned &Dst,
unsigned &SrcSub, unsigned &DstSub) const { unsigned &SrcSub, unsigned &DstSub) const {
if (MI->isExtractSubreg()) { if (MI->isCopy()) {
Dst = MI->getOperand(0).getReg();
DstSub = MI->getOperand(0).getSubReg();
Src = MI->getOperand(1).getReg();
SrcSub = MI->getOperand(1).getSubReg();
} else if (MI->isExtractSubreg()) {
Dst = MI->getOperand(0).getReg(); Dst = MI->getOperand(0).getReg();
DstSub = MI->getOperand(0).getSubReg(); DstSub = MI->getOperand(0).getSubReg();
Src = MI->getOperand(1).getReg(); Src = MI->getOperand(1).getReg();

View File

@ -450,20 +450,25 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
UseMO.setIsKill(false); UseMO.setIsKill(false);
} }
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) if (UseMI->isCopy()) {
if (UseMI->getOperand(0).getReg() != IntB.reg ||
UseMI->getOperand(0).getSubReg())
continue;
} else if (tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)){
if (DstReg != IntB.reg || DstSubIdx)
continue;
} else
continue; continue;
if (DstReg == IntB.reg && DstSubIdx == 0) { // This copy will become a noop. If it's defining a new val#,
// This copy will become a noop. If it's defining a new val#, // remove that val# as well. However this live range is being
// remove that val# as well. However this live range is being // extended to the end of the existing live range defined by the copy.
// extended to the end of the existing live range defined by the copy. SlotIndex DefIdx = UseIdx.getDefIndex();
SlotIndex DefIdx = UseIdx.getDefIndex(); const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx);
const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx); BHasPHIKill |= DLR->valno->hasPHIKill();
BHasPHIKill |= DLR->valno->hasPHIKill(); assert(DLR->valno->def == DefIdx);
assert(DLR->valno->def == DefIdx); BDeadValNos.push_back(DLR->valno);
BDeadValNos.push_back(DLR->valno); BExtend[DLR->start] = DLR->end;
BExtend[DLR->start] = DLR->end; JoinedCopies.insert(UseMI);
JoinedCopies.insert(UseMI);
}
} }
// We need to insert a new liverange: [ALR.start, LastUse). It may be we can // We need to insert a new liverange: [ALR.start, LastUse). It may be we can
@ -604,8 +609,9 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(SlotIndex CopyIdx,
LastUse->setIsKill(); LastUse->setIsKill();
removeRange(li, LastUseIdx.getDefIndex(), LR->end, li_, tri_); removeRange(li, LastUseIdx.getDefIndex(), LR->end, li_, tri_);
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && if ((LastUseMI->isCopy() && !LastUseMI->getOperand(0).getSubReg()) ||
DstReg == li.reg && DstSubIdx == 0) { (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
DstReg == li.reg && DstSubIdx == 0)) {
// Last use is itself an identity code. // Last use is itself an identity code.
int DeadIdx = LastUseMI->findRegisterDefOperandIdx(li.reg, int DeadIdx = LastUseMI->findRegisterDefOperandIdx(li.reg,
false, false, tri_); false, false, tri_);
@ -1556,7 +1562,7 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
// If this isn't a copy nor a extract_subreg, we can't join intervals. // If this isn't a copy nor a extract_subreg, we can't join intervals.
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
bool isInsUndef = false; bool isInsUndef = false;
if (Inst->isExtractSubreg()) { if (Inst->isCopy() || Inst->isExtractSubreg()) {
DstReg = Inst->getOperand(0).getReg(); DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(1).getReg(); SrcReg = Inst->getOperand(1).getReg();
} else if (Inst->isInsertSubreg()) { } else if (Inst->isInsertSubreg()) {
@ -1793,8 +1799,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
// Delete all coalesced copies. // Delete all coalesced copies.
bool DoDelete = true; bool DoDelete = true;
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) { if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
assert((MI->isExtractSubreg() || MI->isInsertSubreg() || assert(MI->isCopyLike() && "Unrecognized copy instruction");
MI->isSubregToReg()) && "Unrecognized copy instruction");
SrcReg = MI->getOperand(MI->isSubregToReg() ? 2 : 1).getReg(); SrcReg = MI->getOperand(MI->isSubregToReg() ? 2 : 1).getReg();
if (TargetRegisterInfo::isPhysicalRegister(SrcReg)) if (TargetRegisterInfo::isPhysicalRegister(SrcReg))
// Do not delete extract_subreg, insert_subreg of physical // Do not delete extract_subreg, insert_subreg of physical

View File

@ -382,7 +382,7 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII,
DstReg = 0; DstReg = 0;
unsigned SrcSubIdx, DstSubIdx; unsigned SrcSubIdx, DstSubIdx;
if (!TII->isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) { if (!TII->isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
if (MI.isExtractSubreg()) { if (MI.isCopy() || MI.isExtractSubreg()) {
DstReg = MI.getOperand(0).getReg(); DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(1).getReg(); SrcReg = MI.getOperand(1).getReg();
} else if (MI.isInsertSubreg()) { } else if (MI.isInsertSubreg()) {