mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-24 21:14:56 +00:00
Make IVUseShouldUsePostIncValue more aggressive when the use is a PHI. In
particular, it should realize that phi's use their values in the pred block not the phi block itself. This change turns our em3d loop from this: _test: cmpwi cr0, r4, 0 bgt cr0, LBB_test_2 ; entry.no_exit_crit_edge LBB_test_1: ; entry.loopexit_crit_edge li r2, 0 b LBB_test_6 ; loopexit LBB_test_2: ; entry.no_exit_crit_edge li r6, 0 LBB_test_3: ; no_exit or r2, r6, r6 lwz r6, 0(r3) cmpw cr0, r6, r5 beq cr0, LBB_test_6 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r2, 1 cmpw cr0, r6, r4 blt cr0, LBB_test_3 ; no_exit LBB_test_5: ; endif.loopexit.loopexit_crit_edge addi r3, r2, 1 blr LBB_test_6: ; loopexit or r3, r2, r2 blr into: _test: cmpwi cr0, r4, 0 bgt cr0, LBB_test_2 ; entry.no_exit_crit_edge LBB_test_1: ; entry.loopexit_crit_edge li r2, 0 b LBB_test_5 ; loopexit LBB_test_2: ; entry.no_exit_crit_edge li r6, 0 LBB_test_3: ; no_exit lwz r2, 0(r3) cmpw cr0, r2, r5 or r2, r6, r6 beq cr0, LBB_test_5 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r6, 1 cmpw cr0, r6, r4 or r2, r6, r6 blt cr0, LBB_test_3 ; no_exit LBB_test_5: ; loopexit or r3, r2, r2 blr Unfortunately, this is actually worse code, because the register coallescer is getting confused somehow. If it were doing its job right, it could turn the code into this: _test: cmpwi cr0, r4, 0 bgt cr0, LBB_test_2 ; entry.no_exit_crit_edge LBB_test_1: ; entry.loopexit_crit_edge li r6, 0 b LBB_test_5 ; loopexit LBB_test_2: ; entry.no_exit_crit_edge li r6, 0 LBB_test_3: ; no_exit lwz r2, 0(r3) cmpw cr0, r2, r5 beq cr0, LBB_test_5 ; loopexit LBB_test_4: ; endif addi r3, r3, 4 addi r6, r6, 1 cmpw cr0, r6, r4 blt cr0, LBB_test_3 ; no_exit LBB_test_5: ; loopexit or r3, r6, r6 blr ... which I'll work on next. :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23604 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0ae33eb243
commit
5e8ca66914
@ -319,13 +319,45 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L,
|
||||
/// the loop, resulting in reg-reg copies (if we use the pre-inc value when we
|
||||
/// should use the post-inc value).
|
||||
static bool IVUseShouldUsePostIncValue(Instruction *User, Instruction *IV,
|
||||
Loop *L, DominatorSet *DS) {
|
||||
Loop *L, DominatorSet *DS, Pass *P) {
|
||||
// If the user is in the loop, use the preinc value.
|
||||
if (L->contains(User->getParent())) return false;
|
||||
|
||||
// Ok, the user is outside of the loop. If it is not dominated by the latch
|
||||
// block, we have to use the preincremented value.
|
||||
return DS->dominates(L->getLoopLatch(), User->getParent());
|
||||
BasicBlock *LatchBlock = L->getLoopLatch();
|
||||
|
||||
// Ok, the user is outside of the loop. If it is dominated by the latch
|
||||
// block, use the post-inc value.
|
||||
if (DS->dominates(LatchBlock, User->getParent()))
|
||||
return true;
|
||||
|
||||
// There is one case we have to be careful of: PHI nodes. These little guys
|
||||
// can live in blocks that do not dominate the latch block, but (since their
|
||||
// uses occur in the predecessor block, not the block the PHI lives in) should
|
||||
// still use the post-inc value. Check for this case now.
|
||||
PHINode *PN = dyn_cast<PHINode>(User);
|
||||
if (!PN) return false; // not a phi, not dominated by latch block.
|
||||
|
||||
// Look at all of the uses of IV by the PHI node. If any use corresponds to
|
||||
// a block that is not dominated by the latch block, give up and use the
|
||||
// preincremented value.
|
||||
unsigned NumUses = 0;
|
||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
||||
if (PN->getIncomingValue(i) == IV) {
|
||||
++NumUses;
|
||||
if (!DS->dominates(LatchBlock, PN->getIncomingBlock(i)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Okay, all uses of IV by PN are in predecessor blocks that really are
|
||||
// dominated by the latch block. Split the critical edges and use the
|
||||
// post-incremented value.
|
||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
||||
if (PN->getIncomingValue(i) == IV) {
|
||||
SplitCriticalEdge(PN->getIncomingBlock(i), PN->getParent(), P);
|
||||
if (--NumUses == 0) break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -373,12 +405,13 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
|
||||
// Okay, we found a user that we cannot reduce. Analyze the instruction
|
||||
// and decide what to do with it. If we are a use inside of the loop, use
|
||||
// the value before incrementation, otherwise use it after incrementation.
|
||||
if (IVUseShouldUsePostIncValue(User, I, L, DS)) {
|
||||
if (IVUseShouldUsePostIncValue(User, I, L, DS, this)) {
|
||||
// The value used will be incremented by the stride more than we are
|
||||
// expecting, so subtract this off.
|
||||
SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride);
|
||||
IVUsesByStride[Stride].addUser(NewStart, User, I);
|
||||
IVUsesByStride[Stride].Users.back().isUseOfPostIncrementedValue = true;
|
||||
DEBUG(std::cerr << " USING POSTINC SCEV, START=" << *NewStart<< "\n");
|
||||
} else {
|
||||
IVUsesByStride[Stride].addUser(Start, User, I);
|
||||
}
|
||||
@ -481,7 +514,6 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
||||
BasicBlock *PHIPred = PN->getIncomingBlock(i);
|
||||
if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 &&
|
||||
(PN->getParent() != L->getHeader() || !L->contains(PHIPred))) {
|
||||
|
||||
|
||||
// First step, split the critical edge.
|
||||
SplitCriticalEdge(PHIPred, PN->getParent(), P);
|
||||
|
Loading…
Reference in New Issue
Block a user