diff options
author | Evan Cheng <evan.cheng@apple.com> | 2010-05-14 23:21:14 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2010-05-14 23:21:14 +0000 |
commit | b990a2f249196ad3e0cc451d40a45fc2f9278eaf (patch) | |
tree | d734296d75a3d1a53af705283c116447cc699f23 /lib/CodeGen/TwoAddressInstructionPass.cpp | |
parent | fd726176886b946ff4eaaf85bd254c5fbbacabfd (diff) |
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
Diffstat (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp')
-rw-r--r-- | lib/CodeGen/TwoAddressInstructionPass.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 9f00311fb4..80bb1a9e9d 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -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(); |