Teach two-address pass to do some coalescing while eliminating REG_SEQUENCE

instructions.

e.g.
%reg1026<def> = VLDMQ %reg1025<kill>, 260, pred:14, pred:%reg0
%reg1027<def> = EXTRACT_SUBREG %reg1026, 6
%reg1028<def> = EXTRACT_SUBREG %reg1026<kill>, 5
...
%reg1029<def> = REG_SEQUENCE %reg1028<kill>, 5, %reg1027<kill>, 6, %reg1028, 7, %reg1027, 8, %reg1028, 9, %reg1027, 10, %reg1030<kill>, 11, %reg1032<kill>, 12

After REG_SEQUENCE is eliminated, we are left with:

%reg1026<def> = VLDMQ %reg1025<kill>, 260, pred:14, pred:%reg0
%reg1029:6<def> = EXTRACT_SUBREG %reg1026, 6
%reg1029:5<def> = EXTRACT_SUBREG %reg1026<kill>, 5

The regular coalescer will not be able to coalesce reg1026 and reg1029 because it doesn't
know how to combine sub-register indices 5 and 6. Now 2-address pass will consult the
target whether sub-registers 5 and 6 of reg1026 can be combined to into a larger
sub-register (or combined to be reg1026 itself as is the case here). If it is possible, 
it will be able to replace references of reg1026 with reg1029 + the larger sub-register
index.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103835 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2010-05-14 23:21:14 +00:00
parent fd72617688
commit b990a2f249
7 changed files with 204 additions and 3 deletions

View File

@@ -1166,6 +1166,7 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
llvm_unreachable(0);
}
SmallVector<unsigned, 4> RealSrcs;
SmallSet<unsigned, 4> Seen;
for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) {
unsigned SrcReg = MI->getOperand(i).getReg();
@@ -1176,6 +1177,16 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
}
MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
if (DefMI->isImplicitDef()) {
DefMI->eraseFromParent();
continue;
}
// Remember EXTRACT_SUBREG sources. These might be candidate for
// coalescing.
if (DefMI->isExtractSubreg())
RealSrcs.push_back(DefMI->getOperand(1).getReg());
if (!Seen.insert(SrcReg) || MI->getParent() != DefMI->getParent()) {
// REG_SEQUENCE cannot have duplicated operands, add a copy.
// Also add an copy if the source if live-in the block. We don't want
@@ -1216,6 +1227,44 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
DEBUG(dbgs() << "Eliminated: " << *MI);
MI->eraseFromParent();
// Try coalescing some EXTRACT_SUBREG instructions.
Seen.clear();
for (unsigned i = 0, e = RealSrcs.size(); i != e; ++i) {
unsigned SrcReg = RealSrcs[i];
if (!Seen.insert(SrcReg))
continue;
// If there are no other uses than extract_subreg which feed into
// the reg_sequence, then we might be able to coalesce them.
bool CanCoalesce = true;
SmallVector<unsigned, 4> SubIndices;
for (MachineRegisterInfo::use_nodbg_iterator
UI = MRI->use_nodbg_begin(SrcReg),
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
if (!UseMI->isExtractSubreg() ||
UseMI->getOperand(0).getReg() != DstReg) {
CanCoalesce = false;
break;
}
SubIndices.push_back(UseMI->getOperand(2).getImm());
}
if (!CanCoalesce)
continue;
// %reg1026<def> = VLDMQ %reg1025<kill>, 260, pred:14, pred:%reg0
// %reg1029:6<def> = EXTRACT_SUBREG %reg1026, 6
// %reg1029:5<def> = EXTRACT_SUBREG %reg1026<kill>, 5
// Since D subregs 5, 6 can combine to a Q register, we can coalesce
// reg1026 to reg1029.
std::sort(SubIndices.begin(), SubIndices.end());
unsigned NewSubIdx = 0;
if (TRI->canCombinedSubRegIndex(MRI->getRegClass(SrcReg), SubIndices,
NewSubIdx))
UpdateRegSequenceSrcs(SrcReg, DstReg, NewSubIdx, MRI);
}
}
RegSequences.clear();