Disable rematerialization in TwoAddressInstructionPass.

It is redundant; RegisterCoalescer will do the remat if it can't eliminate
the copy. Collected instruction counts before and after this. A few extra
instructions are generated due to spilling but it is normal to see these kinds
of changes with almost any small codegen change, according to Jakob.

This also fixed rdar://11830760 where xor is expected instead of movi0.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160749 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Manman Ren 2012-07-25 18:28:13 +00:00
parent 9f14ed1c60
commit d68e8cda24
4 changed files with 12 additions and 83 deletions

View File

@ -55,7 +55,6 @@ STATISTIC(NumCommuted , "Number of instructions commuted to coalesce");
STATISTIC(NumAggrCommuted , "Number of instructions aggressively commuted");
STATISTIC(NumConvertedTo3Addr, "Number of instructions promoted to 3-address");
STATISTIC(Num3AddrSunk, "Number of 3-address instructions sunk");
STATISTIC(NumReMats, "Number of instructions re-materialized");
STATISTIC(NumDeletes, "Number of dead instructions deleted");
STATISTIC(NumReSchedUps, "Number of instructions re-scheduled up");
STATISTIC(NumReSchedDowns, "Number of instructions re-scheduled down");
@ -92,10 +91,6 @@ namespace {
unsigned Reg,
MachineBasicBlock::iterator OldPos);
bool isProfitableToReMat(unsigned Reg, const TargetRegisterClass *RC,
MachineInstr *MI, MachineInstr *DefMI,
MachineBasicBlock *MBB, unsigned Loc);
bool NoUseAfterLastDef(unsigned Reg, MachineBasicBlock *MBB, unsigned Dist,
unsigned &LastDef);
@ -301,55 +296,6 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB,
return true;
}
/// isTwoAddrUse - Return true if the specified MI is using the specified
/// register as a two-address operand.
static bool isTwoAddrUse(MachineInstr *UseMI, unsigned Reg) {
const MCInstrDesc &MCID = UseMI->getDesc();
for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) {
MachineOperand &MO = UseMI->getOperand(i);
if (MO.isReg() && MO.getReg() == Reg &&
(MO.isDef() || UseMI->isRegTiedToDefOperand(i)))
// Earlier use is a two-address one.
return true;
}
return false;
}
/// isProfitableToReMat - Return true if the heuristics determines it is likely
/// to be profitable to re-materialize the definition of Reg rather than copy
/// the register.
bool
TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg,
const TargetRegisterClass *RC,
MachineInstr *MI, MachineInstr *DefMI,
MachineBasicBlock *MBB, unsigned Loc) {
bool OtherUse = false;
for (MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(Reg),
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineOperand &UseMO = UI.getOperand();
MachineInstr *UseMI = UseMO.getParent();
MachineBasicBlock *UseMBB = UseMI->getParent();
if (UseMBB == MBB) {
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UseMI);
if (DI != DistanceMap.end() && DI->second == Loc)
continue; // Current use.
OtherUse = true;
// There is at least one other use in the MBB that will clobber the
// register.
if (isTwoAddrUse(UseMI, Reg))
return true;
}
}
// If other uses in MBB are not two-address uses, then don't remat.
if (OtherUse)
return false;
// No other uses in the same block, remat if it's defined in the same
// block so it does not unnecessarily extend the live range.
return MBB == DefMI->getParent();
}
/// NoUseAfterLastDef - Return true if there are no intervening uses between the
/// last instruction in the MBB that defines the specified register and the
/// two-address instruction which is being processed. It also returns the last
@ -538,7 +484,7 @@ regsAreCompatible(unsigned RegA, unsigned RegB, const TargetRegisterInfo *TRI) {
}
/// isProfitableToReMat - Return true if it's potentially profitable to commute
/// isProfitableToCommute - Return true if it's potentially profitable to commute
/// the two-address instruction that's being processed.
bool
TwoAddressInstructionPass::isProfitableToCommute(unsigned regA, unsigned regB,
@ -1518,26 +1464,9 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
mi->getOperand(i).getReg() != regA);
#endif
// Emit a copy or rematerialize the definition.
bool isCopy = false;
const TargetRegisterClass *rc = MRI->getRegClass(regB);
MachineInstr *DefMI = MRI->getUniqueVRegDef(regB);
// If it's safe and profitable, remat the definition instead of
// copying it.
if (DefMI &&
DefMI->isAsCheapAsAMove() &&
DefMI->isSafeToReMat(TII, AA, regB) &&
isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){
DEBUG(dbgs() << "2addr: REMATTING : " << *DefMI << "\n");
unsigned regASubIdx = mi->getOperand(DstIdx).getSubReg();
TII->reMaterialize(*mbbi, mi, regA, regASubIdx, DefMI, *TRI);
ReMatRegs.set(TargetRegisterInfo::virtReg2Index(regB));
++NumReMats;
} else {
BuildMI(*mbbi, mi, mi->getDebugLoc(), TII->get(TargetOpcode::COPY),
regA).addReg(regB);
isCopy = true;
}
// Emit a copy.
BuildMI(*mbbi, mi, mi->getDebugLoc(), TII->get(TargetOpcode::COPY),
regA).addReg(regB);
// Update DistanceMap.
MachineBasicBlock::iterator prevMI = prior(mi);
@ -1561,9 +1490,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
MO.setReg(regA);
if (isCopy)
// Propagate SrcRegMap.
SrcRegMap[regA] = regB;
// Propagate SrcRegMap.
SrcRegMap[regA] = regB;
}
if (AllUsesCopied) {

View File

@ -4,8 +4,8 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
define i32 @test1(i32 %x, i32 %n, i32 %w, i32* %vp) nounwind readnone {
entry:
; CHECK: test1:
; CHECK: btl
; CHECK-NEXT: movl $12, %eax
; CHECK: movl $12, %eax
; CHECK-NEXT: btl
; CHECK-NEXT: cmovael (%rcx), %eax
; CHECK-NEXT: ret
@ -19,8 +19,8 @@ entry:
define i32 @test2(i32 %x, i32 %n, i32 %w, i32* %vp) nounwind readnone {
entry:
; CHECK: test2:
; CHECK: btl
; CHECK-NEXT: movl $12, %eax
; CHECK: movl $12, %eax
; CHECK-NEXT: btl
; CHECK-NEXT: cmovbl (%rcx), %eax
; CHECK-NEXT: ret

View File

@ -142,6 +142,7 @@ if.else:
define i32 @l4(i32 %a, i32 %b) nounwind {
entry:
; CHECK: l4:
; CHECK: xor
; CHECK: sub
; CHECK-NOT: cmp
%cmp = icmp sgt i32 %b, %a

View File

@ -189,8 +189,8 @@ entry:
%call = tail call noalias i8* @_Znam(i64 %D) nounwind noredzone
ret i8* %call
; CHECK: test12:
; CHECK: mulq
; CHECK: movq $-1, %rdi
; CHECK: mulq
; CHECK: cmovnoq %rax, %rdi
; CHECK: jmp __Znam
}