Remove the canCombineSubRegIndices() target hook.

The new coalescer can already do all of this, so there is no need to
duplicate the efforts.

llvm-svn: 166813
This commit is contained in:
Jakob Stoklund Olesen 2012-10-26 20:38:19 +00:00
parent 0f18b5e49c
commit 1875c109c5
4 changed files with 0 additions and 267 deletions

View File

@ -446,18 +446,6 @@ public:
return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC);
}
/// canCombineSubRegIndices - Given a register class and a list of
/// subregister indices, return true if it's possible to combine the
/// subregister indices into one that corresponds to a larger
/// subregister. Return the new subregister index by reference. Note the
/// new index may be zero if the given subregisters can be combined to
/// form the whole register.
virtual bool canCombineSubRegIndices(const TargetRegisterClass *RC,
SmallVectorImpl<unsigned> &SubIndices,
unsigned &NewSubIdx) const {
return 0;
}
/// getMatchingSuperRegClass - Return a subclass of the specified register
/// class A so that each register in it has a sub-register of the
/// specified sub-register index which is in the specified register class B.

View File

@ -142,8 +142,6 @@ namespace {
bool collectTiedOperands(MachineInstr *MI, TiedOperandMap&);
void processTiedPairs(MachineInstr *MI, TiedPairList&, unsigned &Dist);
void CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs, unsigned DstReg);
/// EliminateRegSequences - Eliminate REG_SEQUENCE instructions as part
/// of the de-ssa process. This replaces sources of REG_SEQUENCE as
/// sub-register references of the register defined by REG_SEQUENCE.
@ -1514,127 +1512,6 @@ static MachineInstr *findFirstDef(unsigned Reg, MachineRegisterInfo *MRI) {
return First;
}
/// CoalesceExtSubRegs - If a number of sources of the REG_SEQUENCE are
/// EXTRACT_SUBREG from the same register and to the same virtual register
/// with different sub-register indices, attempt to combine the
/// EXTRACT_SUBREGs and pre-coalesce them. e.g.
/// %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.
void
TwoAddressInstructionPass::CoalesceExtSubRegs(SmallVector<unsigned,4> &Srcs,
unsigned DstReg) {
SmallSet<unsigned, 4> Seen;
for (unsigned i = 0, e = Srcs.size(); i != e; ++i) {
unsigned SrcReg = Srcs[i];
if (!Seen.insert(SrcReg))
continue;
// Check that the instructions are all in the same basic block.
MachineInstr *SrcDefMI = MRI->getUniqueVRegDef(SrcReg);
MachineInstr *DstDefMI = MRI->getUniqueVRegDef(DstReg);
if (!SrcDefMI || !DstDefMI ||
SrcDefMI->getParent() != DstDefMI->getParent())
continue;
// If there are no other uses than copies which feed into
// the reg_sequence, then we might be able to coalesce them.
bool CanCoalesce = true;
SmallVector<unsigned, 4> SrcSubIndices, DstSubIndices;
for (MachineRegisterInfo::use_nodbg_iterator
UI = MRI->use_nodbg_begin(SrcReg),
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
if (!UseMI->isCopy() || UseMI->getOperand(0).getReg() != DstReg) {
CanCoalesce = false;
break;
}
SrcSubIndices.push_back(UseMI->getOperand(1).getSubReg());
DstSubIndices.push_back(UseMI->getOperand(0).getSubReg());
}
if (!CanCoalesce || SrcSubIndices.size() < 2)
continue;
// Check that the source subregisters can be combined.
std::sort(SrcSubIndices.begin(), SrcSubIndices.end());
unsigned NewSrcSubIdx = 0;
if (!TRI->canCombineSubRegIndices(MRI->getRegClass(SrcReg), SrcSubIndices,
NewSrcSubIdx))
continue;
// Check that the destination subregisters can also be combined.
std::sort(DstSubIndices.begin(), DstSubIndices.end());
unsigned NewDstSubIdx = 0;
if (!TRI->canCombineSubRegIndices(MRI->getRegClass(DstReg), DstSubIndices,
NewDstSubIdx))
continue;
// If neither source nor destination can be combined to the full register,
// just give up. This could be improved if it ever matters.
if (NewSrcSubIdx != 0 && NewDstSubIdx != 0)
continue;
// Now that we know that all the uses are extract_subregs and that those
// subregs can somehow be combined, scan all the extract_subregs again to
// make sure the subregs are in the right order and can be composed.
MachineInstr *SomeMI = 0;
CanCoalesce = true;
for (MachineRegisterInfo::use_nodbg_iterator
UI = MRI->use_nodbg_begin(SrcReg),
UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineInstr *UseMI = &*UI;
assert(UseMI->isCopy());
unsigned DstSubIdx = UseMI->getOperand(0).getSubReg();
unsigned SrcSubIdx = UseMI->getOperand(1).getSubReg();
assert(DstSubIdx != 0 && "missing subreg from RegSequence elimination");
if ((NewDstSubIdx == 0 &&
TRI->composeSubRegIndices(NewSrcSubIdx, DstSubIdx) != SrcSubIdx) ||
(NewSrcSubIdx == 0 &&
TRI->composeSubRegIndices(NewDstSubIdx, SrcSubIdx) != DstSubIdx)) {
CanCoalesce = false;
break;
}
// Keep track of one of the uses. Preferably the first one which has a
// <def,undef> flag.
if (!SomeMI || UseMI->getOperand(0).isUndef())
SomeMI = UseMI;
}
if (!CanCoalesce)
continue;
// Insert a copy to replace the original.
MachineInstr *CopyMI = BuildMI(*SomeMI->getParent(), SomeMI,
SomeMI->getDebugLoc(),
TII->get(TargetOpcode::COPY))
.addReg(DstReg, RegState::Define |
getUndefRegState(SomeMI->getOperand(0).isUndef()),
NewDstSubIdx)
.addReg(SrcReg, 0, NewSrcSubIdx);
// Remove all the old extract instructions.
for (MachineRegisterInfo::use_nodbg_iterator
UI = MRI->use_nodbg_begin(SrcReg),
UE = MRI->use_nodbg_end(); UI != UE; ) {
MachineInstr *UseMI = &*UI;
++UI;
if (UseMI == CopyMI)
continue;
assert(UseMI->isCopy());
// Move any kills to the new copy or extract instruction.
if (UseMI->getOperand(1).isKill()) {
CopyMI->getOperand(1).setIsKill();
if (LV)
// Update live variables
LV->replaceKillInstruction(SrcReg, UseMI, &*CopyMI);
}
UseMI->eraseFromParent();
}
}
}
static bool HasOtherRegSequenceUses(unsigned Reg, MachineInstr *RegSeq,
MachineRegisterInfo *MRI) {
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
@ -1770,12 +1647,6 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
DEBUG(dbgs() << "Eliminated: " << *MI);
MI->eraseFromParent();
}
// Try coalescing some EXTRACT_SUBREG instructions. This can create
// INSERT_SUBREG instructions that must have <undef> flags added by
// LiveIntervalAnalysis, so only run it when LiveVariables is available.
if (LV)
CoalesceExtSubRegs(RealSrcs, DstReg);
}
RegSequences.clear();

View File

@ -134,122 +134,6 @@ bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
return false;
}
bool
ARMBaseRegisterInfo::canCombineSubRegIndices(const TargetRegisterClass *RC,
SmallVectorImpl<unsigned> &SubIndices,
unsigned &NewSubIdx) const {
unsigned Size = RC->getSize() * 8;
if (Size < 6)
return 0;
NewSubIdx = 0; // Whole register.
unsigned NumRegs = SubIndices.size();
if (NumRegs == 8) {
// 8 D registers -> 1 QQQQ register.
return (Size == 512 &&
SubIndices[0] == ARM::dsub_0 &&
SubIndices[1] == ARM::dsub_1 &&
SubIndices[2] == ARM::dsub_2 &&
SubIndices[3] == ARM::dsub_3 &&
SubIndices[4] == ARM::dsub_4 &&
SubIndices[5] == ARM::dsub_5 &&
SubIndices[6] == ARM::dsub_6 &&
SubIndices[7] == ARM::dsub_7);
} else if (NumRegs == 4) {
if (SubIndices[0] == ARM::qsub_0) {
// 4 Q registers -> 1 QQQQ register.
return (Size == 512 &&
SubIndices[1] == ARM::qsub_1 &&
SubIndices[2] == ARM::qsub_2 &&
SubIndices[3] == ARM::qsub_3);
} else if (SubIndices[0] == ARM::dsub_0) {
// 4 D registers -> 1 QQ register.
if (Size >= 256 &&
SubIndices[1] == ARM::dsub_1 &&
SubIndices[2] == ARM::dsub_2 &&
SubIndices[3] == ARM::dsub_3) {
if (Size == 512)
NewSubIdx = ARM::qqsub_0;
return true;
}
} else if (SubIndices[0] == ARM::dsub_4) {
// 4 D registers -> 1 QQ register (2nd).
if (Size == 512 &&
SubIndices[1] == ARM::dsub_5 &&
SubIndices[2] == ARM::dsub_6 &&
SubIndices[3] == ARM::dsub_7) {
NewSubIdx = ARM::qqsub_1;
return true;
}
} else if (SubIndices[0] == ARM::ssub_0) {
// 4 S registers -> 1 Q register.
if (Size >= 128 &&
SubIndices[1] == ARM::ssub_1 &&
SubIndices[2] == ARM::ssub_2 &&
SubIndices[3] == ARM::ssub_3) {
if (Size >= 256)
NewSubIdx = ARM::qsub_0;
return true;
}
}
} else if (NumRegs == 2) {
if (SubIndices[0] == ARM::qsub_0) {
// 2 Q registers -> 1 QQ register.
if (Size >= 256 && SubIndices[1] == ARM::qsub_1) {
if (Size == 512)
NewSubIdx = ARM::qqsub_0;
return true;
}
} else if (SubIndices[0] == ARM::qsub_2) {
// 2 Q registers -> 1 QQ register (2nd).
if (Size == 512 && SubIndices[1] == ARM::qsub_3) {
NewSubIdx = ARM::qqsub_1;
return true;
}
} else if (SubIndices[0] == ARM::dsub_0) {
// 2 D registers -> 1 Q register.
if (Size >= 128 && SubIndices[1] == ARM::dsub_1) {
if (Size >= 256)
NewSubIdx = ARM::qsub_0;
return true;
}
} else if (SubIndices[0] == ARM::dsub_2) {
// 2 D registers -> 1 Q register (2nd).
if (Size >= 256 && SubIndices[1] == ARM::dsub_3) {
NewSubIdx = ARM::qsub_1;
return true;
}
} else if (SubIndices[0] == ARM::dsub_4) {
// 2 D registers -> 1 Q register (3rd).
if (Size == 512 && SubIndices[1] == ARM::dsub_5) {
NewSubIdx = ARM::qsub_2;
return true;
}
} else if (SubIndices[0] == ARM::dsub_6) {
// 2 D registers -> 1 Q register (3rd).
if (Size == 512 && SubIndices[1] == ARM::dsub_7) {
NewSubIdx = ARM::qsub_3;
return true;
}
} else if (SubIndices[0] == ARM::ssub_0) {
// 2 S registers -> 1 D register.
if (SubIndices[1] == ARM::ssub_1) {
if (Size >= 128)
NewSubIdx = ARM::dsub_0;
return true;
}
} else if (SubIndices[0] == ARM::ssub_2) {
// 2 S registers -> 1 D register (2nd).
if (Size >= 128 && SubIndices[1] == ARM::ssub_3) {
NewSubIdx = ARM::dsub_1;
return true;
}
}
}
return false;
}
const TargetRegisterClass*
ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC)
const {

View File

@ -99,16 +99,6 @@ public:
BitVector getReservedRegs(const MachineFunction &MF) const;
/// canCombineSubRegIndices - Given a register class and a list of
/// subregister indices, return true if it's possible to combine the
/// subregister indices into one that corresponds to a larger
/// subregister. Return the new subregister index by reference. Note the
/// new index may be zero if the given subregisters can be combined to
/// form the whole register.
virtual bool canCombineSubRegIndices(const TargetRegisterClass *RC,
SmallVectorImpl<unsigned> &SubIndices,
unsigned &NewSubIdx) const;
const TargetRegisterClass*
getPointerRegClass(const MachineFunction &MF, unsigned Kind = 0) const;
const TargetRegisterClass*