mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-24 23:28:41 +00:00
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:
@@ -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();
|
||||
|
Reference in New Issue
Block a user