mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 04:33:40 +00:00
[PeepholeOptimizer] Take advantage of the isInsertSubreg property in the
advanced copy optimization. This is the final step patch toward transforming: udiv r0, r0, r2 udiv r1, r1, r3 vmov.32 d16[0], r0 vmov.32 d16[1], r1 vmov r0, r1, d16 bx lr into: udiv r0, r0, r2 udiv r1, r1, r3 bx lr Indeed, thanks to this patch, this optimization is able to look through vmov.32 d16[0], r0 vmov.32 d16[1], r1 and is able to rewrite the following sequence: vmov.32 d16[0], r0 vmov.32 d16[1], r1 vmov r0, r1, d16 into simple generic GPR copies that the coalescer managed to remove. <rdar://problem/12702965> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216144 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7599acc2af
commit
e817bdd304
@ -161,9 +161,10 @@ namespace {
|
|||||||
/// \brief Check whether \p MI is a copy like instruction that is
|
/// \brief Check whether \p MI is a copy like instruction that is
|
||||||
/// not recognized by the register coalescer.
|
/// not recognized by the register coalescer.
|
||||||
bool isUncoalescableCopy(const MachineInstr &MI) {
|
bool isUncoalescableCopy(const MachineInstr &MI) {
|
||||||
return MI.isBitcast() || (!DisableAdvCopyOpt &&
|
return MI.isBitcast() ||
|
||||||
(MI.isRegSequenceLike() ||
|
(!DisableAdvCopyOpt &&
|
||||||
MI.isExtractSubregLike()));
|
(MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
|
||||||
|
MI.isExtractSubregLike()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1271,44 +1272,26 @@ bool ValueTracker::getNextSourceFromRegSequence(unsigned &SrcReg,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the inputs from INSERT_SUBREG.
|
|
||||||
/// INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
|
|
||||||
/// - BaseReg: vreg0:sub0
|
|
||||||
/// - InsertedReg: vreg1:sub1, sub3
|
|
||||||
static void
|
|
||||||
getInsertSubregInputs(const MachineInstr &MI,
|
|
||||||
TargetInstrInfo::RegSubRegPair &BaseReg,
|
|
||||||
TargetInstrInfo::RegSubRegPairAndIdx &InsertedReg) {
|
|
||||||
assert(MI.isInsertSubreg() && "Instruction do not have the proper type");
|
|
||||||
|
|
||||||
// We are looking at:
|
|
||||||
// Def = INSERT_SUBREG v0, v1, sub0.
|
|
||||||
const MachineOperand &MOBaseReg = MI.getOperand(1);
|
|
||||||
const MachineOperand &MOInsertedReg = MI.getOperand(2);
|
|
||||||
const MachineOperand &MOSubIdx = MI.getOperand(3);
|
|
||||||
assert(MOSubIdx.isImm() &&
|
|
||||||
"One of the subindex of the reg_sequence is not an immediate");
|
|
||||||
BaseReg.Reg = MOBaseReg.getReg();
|
|
||||||
BaseReg.SubReg = MOBaseReg.getSubReg();
|
|
||||||
|
|
||||||
InsertedReg.Reg = MOInsertedReg.getReg();
|
|
||||||
InsertedReg.SubReg = MOInsertedReg.getSubReg();
|
|
||||||
InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ValueTracker::getNextSourceFromInsertSubreg(unsigned &SrcReg,
|
bool ValueTracker::getNextSourceFromInsertSubreg(unsigned &SrcReg,
|
||||||
unsigned &SrcSubReg) {
|
unsigned &SrcSubReg) {
|
||||||
assert(Def->isInsertSubreg() && "Invalid definition");
|
assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) &&
|
||||||
|
"Invalid definition");
|
||||||
|
|
||||||
if (Def->getOperand(DefIdx).getSubReg())
|
if (Def->getOperand(DefIdx).getSubReg())
|
||||||
// If we are composing subreg, bails out.
|
// If we are composing subreg, bails out.
|
||||||
// Same remark as getNextSourceFromRegSequence.
|
// Same remark as getNextSourceFromRegSequence.
|
||||||
// I.e., this may be turned into an assert.
|
// I.e., this may be turned into an assert.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!TII)
|
||||||
|
// We could handle the REG_SEQUENCE here, but we do not want to
|
||||||
|
// duplicate the code from the generic TII.
|
||||||
|
return false;
|
||||||
|
|
||||||
TargetInstrInfo::RegSubRegPair BaseReg;
|
TargetInstrInfo::RegSubRegPair BaseReg;
|
||||||
TargetInstrInfo::RegSubRegPairAndIdx InsertedReg;
|
TargetInstrInfo::RegSubRegPairAndIdx InsertedReg;
|
||||||
assert(DefIdx == 0 && "Invalid definition");
|
if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg))
|
||||||
getInsertSubregInputs(*Def, BaseReg, InsertedReg);
|
return false;
|
||||||
|
|
||||||
// We are looking at:
|
// We are looking at:
|
||||||
// Def = INSERT_SUBREG v0, v1, sub1
|
// Def = INSERT_SUBREG v0, v1, sub1
|
||||||
@ -1416,7 +1399,7 @@ bool ValueTracker::getNextSourceImpl(unsigned &SrcReg, unsigned &SrcSubReg) {
|
|||||||
return false;
|
return false;
|
||||||
if (Def->isRegSequence() || Def->isRegSequenceLike())
|
if (Def->isRegSequence() || Def->isRegSequenceLike())
|
||||||
return getNextSourceFromRegSequence(SrcReg, SrcSubReg);
|
return getNextSourceFromRegSequence(SrcReg, SrcSubReg);
|
||||||
if (Def->isInsertSubreg())
|
if (Def->isInsertSubreg() || Def->isInsertSubregLike())
|
||||||
return getNextSourceFromInsertSubreg(SrcReg, SrcSubReg);
|
return getNextSourceFromInsertSubreg(SrcReg, SrcSubReg);
|
||||||
if (Def->isExtractSubreg() || Def->isExtractSubregLike())
|
if (Def->isExtractSubreg() || Def->isExtractSubregLike())
|
||||||
return getNextSourceFromExtractSubreg(SrcReg, SrcSubReg);
|
return getNextSourceFromExtractSubreg(SrcReg, SrcSubReg);
|
||||||
|
@ -26,11 +26,8 @@
|
|||||||
; NOOPT-NEXT: bx lr
|
; NOOPT-NEXT: bx lr
|
||||||
;
|
;
|
||||||
; OPT-NOT: vmov
|
; OPT-NOT: vmov
|
||||||
; OPT: udiv [[RES_LOW:r[0-9]+]], r0, r2
|
; OPT: udiv r0, r0, r2
|
||||||
; OPT-NEXT: udiv [[RES_HIGH:r[0-9]+]], r1, r3
|
; OPT-NEXT: udiv r1, r1, r3
|
||||||
; OPT-NEXT: vmov.32 [[RES:d[0-9]+]][0], [[RES_LOW]]
|
|
||||||
; OPT-NEXT: vmov.32 [[RES]][1], [[RES_HIGH]]
|
|
||||||
; OPT-NEXT: vmov r0, r1, [[RES]]
|
|
||||||
; OPT-NEXT: bx lr
|
; OPT-NEXT: bx lr
|
||||||
define <2 x i32> @simpleVectorDiv(<2 x i32> %A, <2 x i32> %B) nounwind {
|
define <2 x i32> @simpleVectorDiv(<2 x i32> %A, <2 x i32> %B) nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user