mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-16 08:08:01 +00:00
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:
parent
0f18b5e49c
commit
1875c109c5
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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*
|
||||
|
Loading…
Reference in New Issue
Block a user