summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-12 22:06:11 +0000
committerChris Lattner <sabre@nondot.org>2005-08-12 22:06:11 +0000
commit4fec86d3489057482c160608d3cb9bb6df96500c (patch)
treed7737522db2d7e77ed1cb7eed0f782de3ba569dc /llvm/lib/Transforms
parentb7ebe65c561630310d580d1df7692fddff10b9c8 (diff)
downloadbcm5719-llvm-4fec86d3489057482c160608d3cb9bb6df96500c.tar.gz
bcm5719-llvm-4fec86d3489057482c160608d3cb9bb6df96500c.zip
Fix a FIXME: if we are inserting code for a PHI argument, split the critical
edge so that the code is not always executed for both operands. This prevents LSR from inserting code into loops whose exit blocks contain PHI uses of IV expressions (which are outside of loops). On gzip, for example, we turn this ugly code: .LBB_test_1: ; loopentry add r27, r3, r28 lhz r27, 3(r27) add r26, r4, r28 lhz r26, 3(r26) add r25, r30, r28 ;; Only live if exiting the loop add r24, r29, r28 ;; Only live if exiting the loop cmpw cr0, r27, r26 bne .LBB_test_5 ; loopexit into this: .LBB_test_1: ; loopentry or r27, r28, r28 add r28, r3, r27 lhz r28, 3(r28) add r26, r4, r27 lhz r26, 3(r26) cmpw cr0, r28, r26 beq .LBB_test_3 ; shortcirc_next.0 .LBB_test_2: ; loopentry.loopexit_crit_edge add r2, r30, r27 add r8, r29, r27 b .LBB_test_9 ; loopexit .LBB_test_2: ; shortcirc_next.0 ... blt .LBB_test_1 into this: .LBB_test_1: ; loopentry or r27, r28, r28 add r28, r3, r27 lhz r28, 3(r28) add r26, r4, r27 lhz r26, 3(r26) cmpw cr0, r28, r26 beq .LBB_test_3 ; shortcirc_next.0 .LBB_test_2: ; loopentry.loopexit_crit_edge add r2, r30, r27 add r8, r29, r27 b .LBB_t_3: ; shortcirc_next.0 .LBB_test_3: ; shortcirc_next.0 ... blt .LBB_test_1 Next step: get the block out of the loop so that the loop is all fall-throughs again. llvm-svn: 22766
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index dc1dc18b899..75a681d98ec 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -26,6 +26,7 @@
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/Statistic.h"
@@ -391,7 +392,7 @@ namespace {
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
// to it.
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
- SCEVExpander &Rewriter);
+ SCEVExpander &Rewriter, Pass *P);
// Sort by the Base field.
bool operator<(const BasedUser &BU) const { return Base < BU.Base; }
@@ -413,12 +414,12 @@ void BasedUser::dump() const {
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
// to it.
void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
- SCEVExpander &Rewriter) {
+ SCEVExpander &Rewriter,
+ Pass *P) {
if (!isa<PHINode>(Inst)) {
SCEVHandle NewValSCEV = SCEVAddExpr::get(NewBase, Imm);
Value *NewVal = Rewriter.expandCodeFor(NewValSCEV, Inst,
OperandValToReplace->getType());
-
// Replace the use of the operand Value with the new Phi we just created.
Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
DEBUG(std::cerr << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst);
@@ -434,7 +435,19 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
PHINode *PN = cast<PHINode>(Inst);
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
if (PN->getIncomingValue(i) == OperandValToReplace) {
- // FIXME: this should split any critical edges.
+ // If this is a critical edge, split the edge so that we do not insert the
+ // code on all predecessor/successor paths.
+ if (e != 1 &&
+ PN->getIncomingBlock(i)->getTerminator()->getNumSuccessors() > 1) {
+ TerminatorInst *PredTI = PN->getIncomingBlock(i)->getTerminator();
+ for (unsigned Succ = 0; ; ++Succ) {
+ assert(Succ != PredTI->getNumSuccessors() &&"Didn't find successor?");
+ if (PredTI->getSuccessor(Succ) == PN->getParent()) {
+ SplitCriticalEdge(PredTI, Succ, P);
+ break;
+ }
+ }
+ }
Value *&Code = InsertedCode[PN->getIncomingBlock(i)];
if (!Code) {
@@ -623,7 +636,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses) {
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
if (!SubExpressionUseCounts.count(AE->getOperand(j)))
NewOps.push_back(AE->getOperand(j));
- if (NewOps.size() == 0)
+ if (NewOps.empty())
Uses[i].Base = Zero;
else
Uses[i].Base = SCEVAddExpr::get(NewOps);
@@ -783,7 +796,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
// Add BaseV to the PHI value if needed.
RewriteExpr = SCEVAddExpr::get(RewriteExpr, SCEVUnknown::get(BaseV));
- User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter);
+ User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, this);
// Mark old value we replaced as possibly dead, so that it is elminated
// if we just replaced the last use of that value.
OpenPOWER on IntegriCloud