diff options
author | Quentin Colombet <qcolombet@apple.com> | 2014-08-21 00:19:16 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2014-08-21 00:19:16 +0000 |
commit | 689623009b8792bb09416686f2b1d21f4f0d6ddf (patch) | |
tree | 286fc003edb7403994c4878a8ea50561d2c987bd /llvm/lib/CodeGen/PeepholeOptimizer.cpp | |
parent | 84f15bd1b05387e506cf2b49d3d40df193edce79 (diff) | |
download | bcm5719-llvm-689623009b8792bb09416686f2b1d21f4f0d6ddf.tar.gz bcm5719-llvm-689623009b8792bb09416686f2b1d21f4f0d6ddf.zip |
[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>
llvm-svn: 216144
Diffstat (limited to 'llvm/lib/CodeGen/PeepholeOptimizer.cpp')
-rw-r--r-- | llvm/lib/CodeGen/PeepholeOptimizer.cpp | 47 |
1 files changed, 15 insertions, 32 deletions
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp index 495ed67397d..ae14331d663 100644 --- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp +++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp @@ -161,9 +161,10 @@ namespace { /// \brief Check whether \p MI is a copy like instruction that is /// not recognized by the register coalescer. bool isUncoalescableCopy(const MachineInstr &MI) { - return MI.isBitcast() || (!DisableAdvCopyOpt && - (MI.isRegSequenceLike() || - MI.isExtractSubregLike())); + return MI.isBitcast() || + (!DisableAdvCopyOpt && + (MI.isRegSequenceLike() || MI.isInsertSubregLike() || + MI.isExtractSubregLike())); } }; @@ -1271,44 +1272,26 @@ bool ValueTracker::getNextSourceFromRegSequence(unsigned &SrcReg, 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, unsigned &SrcSubReg) { - assert(Def->isInsertSubreg() && "Invalid definition"); + assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) && + "Invalid definition"); + if (Def->getOperand(DefIdx).getSubReg()) // If we are composing subreg, bails out. // Same remark as getNextSourceFromRegSequence. // I.e., this may be turned into an assert. 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::RegSubRegPairAndIdx InsertedReg; - assert(DefIdx == 0 && "Invalid definition"); - getInsertSubregInputs(*Def, BaseReg, InsertedReg); + if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg)) + return false; // We are looking at: // Def = INSERT_SUBREG v0, v1, sub1 @@ -1416,7 +1399,7 @@ bool ValueTracker::getNextSourceImpl(unsigned &SrcReg, unsigned &SrcSubReg) { return false; if (Def->isRegSequence() || Def->isRegSequenceLike()) return getNextSourceFromRegSequence(SrcReg, SrcSubReg); - if (Def->isInsertSubreg()) + if (Def->isInsertSubreg() || Def->isInsertSubregLike()) return getNextSourceFromInsertSubreg(SrcReg, SrcSubReg); if (Def->isExtractSubreg() || Def->isExtractSubregLike()) return getNextSourceFromExtractSubreg(SrcReg, SrcSubReg); |