2009-04-16 03:18:22 +00:00
|
|
|
//===- LoopStrengthReduce.cpp - Strength Reduce IVs in Loops --------------===//
|
2005-04-21 23:48:37 +00:00
|
|
|
//
|
2004-10-18 21:08:22 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:36:04 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-21 23:48:37 +00:00
|
|
|
//
|
2004-10-18 21:08:22 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This pass performs a strength reduction on array references inside loops that
|
2009-04-16 03:18:22 +00:00
|
|
|
// have as one or more of their components the loop induction variable.
|
2004-10-18 21:08:22 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2005-08-03 23:30:08 +00:00
|
|
|
#define DEBUG_TYPE "loop-reduce"
|
2004-10-18 21:08:22 +00:00
|
|
|
#include "llvm/Transforms/Scalar.h"
|
|
|
|
#include "llvm/Constants.h"
|
|
|
|
#include "llvm/Instructions.h"
|
2007-05-04 14:59:09 +00:00
|
|
|
#include "llvm/IntrinsicInst.h"
|
2004-10-18 21:08:22 +00:00
|
|
|
#include "llvm/Type.h"
|
2005-03-04 04:04:26 +00:00
|
|
|
#include "llvm/DerivedTypes.h"
|
2004-10-18 21:08:22 +00:00
|
|
|
#include "llvm/Analysis/Dominators.h"
|
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
2007-03-06 21:14:09 +00:00
|
|
|
#include "llvm/Analysis/LoopPass.h"
|
2005-07-30 00:15:07 +00:00
|
|
|
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
2009-02-21 02:06:47 +00:00
|
|
|
#include "llvm/Transforms/Utils/AddrModeMatcher.h"
|
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22766 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-12 22:06:11 +00:00
|
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
2004-10-18 21:08:22 +00:00
|
|
|
#include "llvm/Transforms/Utils/Local.h"
|
2007-10-26 23:08:19 +00:00
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
2004-10-18 21:08:22 +00:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
2009-02-21 02:06:47 +00:00
|
|
|
#include "llvm/Support/CFG.h"
|
2005-07-30 00:15:07 +00:00
|
|
|
#include "llvm/Support/Debug.h"
|
2006-08-27 12:54:02 +00:00
|
|
|
#include "llvm/Support/Compiler.h"
|
2009-02-20 04:17:46 +00:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2009-05-02 18:29:22 +00:00
|
|
|
#include "llvm/Support/ValueHandle.h"
|
2006-03-13 23:14:23 +00:00
|
|
|
#include "llvm/Target/TargetLowering.h"
|
2005-07-30 18:22:27 +00:00
|
|
|
#include <algorithm>
|
2004-10-18 21:08:22 +00:00
|
|
|
using namespace llvm;
|
|
|
|
|
2009-04-16 16:46:01 +00:00
|
|
|
STATISTIC(NumReduced , "Number of IV uses strength reduced");
|
2007-10-25 09:11:16 +00:00
|
|
|
STATISTIC(NumInserted, "Number of PHIs inserted");
|
|
|
|
STATISTIC(NumVariable, "Number of PHIs with variable strides");
|
2008-08-27 17:50:18 +00:00
|
|
|
STATISTIC(NumEliminated, "Number of strides eliminated");
|
|
|
|
STATISTIC(NumShadow, "Number of Shadow IVs optimized");
|
2009-02-21 02:06:47 +00:00
|
|
|
STATISTIC(NumImmSunk, "Number of common expr immediates sunk into uses");
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
static cl::opt<bool> EnableFullLSRMode("enable-full-lsr",
|
|
|
|
cl::init(false),
|
|
|
|
cl::Hidden);
|
|
|
|
|
2006-12-19 21:40:18 +00:00
|
|
|
namespace {
|
2007-03-20 00:47:50 +00:00
|
|
|
|
2007-03-20 20:43:18 +00:00
|
|
|
struct BasedUser;
|
2007-03-20 00:47:50 +00:00
|
|
|
|
2005-08-03 22:21:05 +00:00
|
|
|
/// IVStrideUse - Keep track of one use of a strided induction variable, where
|
|
|
|
/// the stride is stored externally. The Offset member keeps track of the
|
2007-10-29 19:32:39 +00:00
|
|
|
/// offset from the IV, User is the actual user of the operand, and
|
|
|
|
/// 'OperandValToReplace' is the operand of the User that is the use.
|
2007-02-05 23:32:05 +00:00
|
|
|
struct VISIBILITY_HIDDEN IVStrideUse {
|
2005-08-03 22:21:05 +00:00
|
|
|
SCEVHandle Offset;
|
|
|
|
Instruction *User;
|
|
|
|
Value *OperandValToReplace;
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
|
|
|
|
// isUseOfPostIncrementedValue - True if this should use the
|
|
|
|
// post-incremented version of this IV, not the preincremented version.
|
|
|
|
// This can only be set in special cases, such as the terminating setcc
|
_test:
li r2, 0
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r2, 1
stw r2, 0(r4)
blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version. This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):
_test:
li r2, 0 **** IV starts at 0
LBB_test_1: ; no_exit.2
or r5, r2, r2 **** Copy for loop exit
li r2, 0
stw r2, 0(r3)
addi r3, r3, 4
addi r2, r5, 1
addi r6, r5, 2 **** IV+2
cmpwi cr0, r6, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r5, 2 **** IV+2
stw r2, 0(r4)
blr
And now generated code like this:
_test:
li r2, 1 *** IV starts at 1
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701 *** IV.postinc + 0
blt cr0, LBB_test_1
LBB_test_2: ; loopexit.2.loopexit
stw r2, 0(r4) *** IV.postinc + 0
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8
2005-09-12 06:04:47 +00:00
|
|
|
// instruction for a loop or uses dominated by the loop.
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
bool isUseOfPostIncrementedValue;
|
2005-08-03 22:21:05 +00:00
|
|
|
|
|
|
|
IVStrideUse(const SCEVHandle &Offs, Instruction *U, Value *O)
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
: Offset(Offs), User(U), OperandValToReplace(O),
|
|
|
|
isUseOfPostIncrementedValue(false) {}
|
2005-08-03 22:21:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// IVUsersOfOneStride - This structure keeps track of all instructions that
|
|
|
|
/// have an operand that is based on the trip count multiplied by some stride.
|
|
|
|
/// The stride for all of these users is common and kept external to this
|
|
|
|
/// structure.
|
2007-02-05 23:32:05 +00:00
|
|
|
struct VISIBILITY_HIDDEN IVUsersOfOneStride {
|
2005-07-30 00:15:07 +00:00
|
|
|
/// Users - Keep track of all of the users of this stride as well as the
|
2005-08-03 22:21:05 +00:00
|
|
|
/// initial value and the operand that uses the IV.
|
|
|
|
std::vector<IVStrideUse> Users;
|
|
|
|
|
|
|
|
void addUser(const SCEVHandle &Offset,Instruction *User, Value *Operand) {
|
|
|
|
Users.push_back(IVStrideUse(Offset, User, Operand));
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2006-03-16 21:53:05 +00:00
|
|
|
/// IVInfo - This structure keeps track of one IV expression inserted during
|
2006-03-18 08:03:12 +00:00
|
|
|
/// StrengthReduceStridedIVUsers. It contains the stride, the common base, as
|
|
|
|
/// well as the PHI node and increment value created for rewrite.
|
2007-02-05 23:32:05 +00:00
|
|
|
struct VISIBILITY_HIDDEN IVExpr {
|
2006-03-18 08:03:12 +00:00
|
|
|
SCEVHandle Stride;
|
2006-03-16 21:53:05 +00:00
|
|
|
SCEVHandle Base;
|
|
|
|
PHINode *PHI;
|
|
|
|
|
2009-03-09 22:04:01 +00:00
|
|
|
IVExpr(const SCEVHandle &stride, const SCEVHandle &base, PHINode *phi)
|
|
|
|
: Stride(stride), Base(base), PHI(phi) {}
|
2006-03-16 21:53:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// IVsOfOneStride - This structure keeps track of all IV expression inserted
|
|
|
|
/// during StrengthReduceStridedIVUsers for a particular stride of the IV.
|
2007-02-05 23:32:05 +00:00
|
|
|
struct VISIBILITY_HIDDEN IVsOfOneStride {
|
2006-03-16 21:53:05 +00:00
|
|
|
std::vector<IVExpr> IVs;
|
|
|
|
|
2009-03-09 22:04:01 +00:00
|
|
|
void addIV(const SCEVHandle &Stride, const SCEVHandle &Base, PHINode *PHI) {
|
|
|
|
IVs.push_back(IVExpr(Stride, Base, PHI));
|
2006-03-16 21:53:05 +00:00
|
|
|
}
|
|
|
|
};
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2007-03-06 21:14:09 +00:00
|
|
|
class VISIBILITY_HIDDEN LoopStrengthReduce : public LoopPass {
|
2004-10-18 21:08:22 +00:00
|
|
|
LoopInfo *LI;
|
2007-06-07 21:42:15 +00:00
|
|
|
DominatorTree *DT;
|
2005-07-30 00:15:07 +00:00
|
|
|
ScalarEvolution *SE;
|
2004-10-18 21:08:22 +00:00
|
|
|
bool Changed;
|
2005-08-02 02:52:02 +00:00
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
/// IVUsesByStride - Keep track of all uses of induction variables that we
|
|
|
|
/// are interested in. The key of the map is the stride of the access.
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
std::map<SCEVHandle, IVUsersOfOneStride> IVUsesByStride;
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2006-03-16 21:53:05 +00:00
|
|
|
/// IVsByStride - Keep track of all IVs that have been inserted for a
|
|
|
|
/// particular stride.
|
|
|
|
std::map<SCEVHandle, IVsOfOneStride> IVsByStride;
|
|
|
|
|
2005-10-09 06:20:55 +00:00
|
|
|
/// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
|
|
|
|
/// We use this to iterate over the IVUsesByStride collection without being
|
|
|
|
/// dependent on random ordering of pointers in the process.
|
2007-10-30 22:27:26 +00:00
|
|
|
SmallVector<SCEVHandle, 16> StrideOrder;
|
2005-10-09 06:20:55 +00:00
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
/// DeadInsts - Keep track of instructions we may have made dead, so that
|
|
|
|
/// we can remove them after we are done working.
|
2008-12-01 06:27:41 +00:00
|
|
|
SmallVector<Instruction*, 16> DeadInsts;
|
2006-03-13 23:14:23 +00:00
|
|
|
|
|
|
|
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
|
|
|
/// transformation profitability.
|
|
|
|
const TargetLowering *TLI;
|
|
|
|
|
2004-10-18 21:08:22 +00:00
|
|
|
public:
|
2007-05-03 01:11:54 +00:00
|
|
|
static char ID; // Pass ID, replacement for typeid
|
2007-08-01 15:32:29 +00:00
|
|
|
explicit LoopStrengthReduce(const TargetLowering *tli = NULL) :
|
2008-09-04 17:05:41 +00:00
|
|
|
LoopPass(&ID), TLI(tli) {
|
2005-03-04 04:04:26 +00:00
|
|
|
}
|
|
|
|
|
2007-03-06 21:14:09 +00:00
|
|
|
bool runOnLoop(Loop *L, LPPassManager &LPM);
|
2004-10-18 21:08:22 +00:00
|
|
|
|
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
2005-08-17 06:35:16 +00:00
|
|
|
// We split critical edges, so we change the CFG. However, we do update
|
|
|
|
// many analyses if they are around.
|
|
|
|
AU.addPreservedID(LoopSimplifyID);
|
|
|
|
AU.addPreserved<LoopInfo>();
|
|
|
|
AU.addPreserved<DominanceFrontier>();
|
|
|
|
AU.addPreserved<DominatorTree>();
|
|
|
|
|
2005-02-27 19:37:07 +00:00
|
|
|
AU.addRequiredID(LoopSimplifyID);
|
2004-10-18 21:08:22 +00:00
|
|
|
AU.addRequired<LoopInfo>();
|
2007-06-07 21:42:15 +00:00
|
|
|
AU.addRequired<DominatorTree>();
|
2005-07-30 00:15:07 +00:00
|
|
|
AU.addRequired<ScalarEvolution>();
|
2008-08-26 17:57:54 +00:00
|
|
|
AU.addPreserved<ScalarEvolution>();
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|
2009-04-16 03:18:22 +00:00
|
|
|
|
2009-05-01 16:56:32 +00:00
|
|
|
private:
|
2005-08-04 17:40:30 +00:00
|
|
|
bool AddUsersIfInteresting(Instruction *I, Loop *L,
|
2007-10-26 23:08:19 +00:00
|
|
|
SmallPtrSet<Instruction*,16> &Processed);
|
2007-10-25 09:11:16 +00:00
|
|
|
ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|
|
|
IVStrideUse* &CondUse,
|
|
|
|
const SCEVHandle* &CondStride);
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
void OptimizeIndvars(Loop *L);
|
2008-08-26 17:57:54 +00:00
|
|
|
|
|
|
|
/// OptimizeShadowIV - If IV is used in a int-to-float cast
|
|
|
|
/// inside the loop then try to eliminate the cast opeation.
|
|
|
|
void OptimizeShadowIV(Loop *L);
|
|
|
|
|
2008-09-15 21:22:06 +00:00
|
|
|
/// OptimizeSMax - Rewrite the loop's terminating condition
|
|
|
|
/// if it uses an smax computation.
|
|
|
|
ICmpInst *OptimizeSMax(Loop *L, ICmpInst *Cond,
|
|
|
|
IVStrideUse* &CondUse);
|
|
|
|
|
2008-08-13 20:31:11 +00:00
|
|
|
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
2008-08-26 17:57:54 +00:00
|
|
|
const SCEVHandle *&CondStride);
|
2007-10-25 22:45:20 +00:00
|
|
|
bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
SCEVHandle CheckForIVReuse(bool, bool, bool, const SCEVHandle&,
|
2007-10-22 20:40:42 +00:00
|
|
|
IVExpr&, const Type*,
|
2007-03-20 00:47:50 +00:00
|
|
|
const std::vector<BasedUser>& UsersToProcess);
|
2007-10-22 20:40:42 +00:00
|
|
|
bool ValidStride(bool, int64_t,
|
|
|
|
const std::vector<BasedUser>& UsersToProcess);
|
2007-10-25 22:45:20 +00:00
|
|
|
SCEVHandle CollectIVUsers(const SCEVHandle &Stride,
|
|
|
|
IVUsersOfOneStride &Uses,
|
|
|
|
Loop *L,
|
|
|
|
bool &AllUsesAreAddresses,
|
2008-12-16 22:16:28 +00:00
|
|
|
bool &AllUsesAreOutsideLoop,
|
2007-10-25 22:45:20 +00:00
|
|
|
std::vector<BasedUser> &UsersToProcess);
|
2009-02-20 04:17:46 +00:00
|
|
|
bool ShouldUseFullStrengthReductionMode(
|
|
|
|
const std::vector<BasedUser> &UsersToProcess,
|
|
|
|
const Loop *L,
|
|
|
|
bool AllUsesAreAddresses,
|
|
|
|
SCEVHandle Stride);
|
|
|
|
void PrepareToStrengthReduceFully(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
SCEVHandle Stride,
|
|
|
|
SCEVHandle CommonExprs,
|
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter);
|
|
|
|
void PrepareToStrengthReduceFromSmallerStride(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
Value *CommonBaseV,
|
|
|
|
const IVExpr &ReuseIV,
|
|
|
|
Instruction *PreInsertPt);
|
|
|
|
void PrepareToStrengthReduceWithNewPhi(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
SCEVHandle Stride,
|
|
|
|
SCEVHandle CommonExprs,
|
|
|
|
Value *CommonBaseV,
|
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter);
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
void StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|
|
|
IVUsersOfOneStride &Uses,
|
2009-03-09 20:41:15 +00:00
|
|
|
Loop *L);
|
2008-12-01 06:14:28 +00:00
|
|
|
void DeleteTriviallyDeadInstructions();
|
2004-10-18 21:08:22 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2008-05-13 00:00:25 +00:00
|
|
|
char LoopStrengthReduce::ID = 0;
|
|
|
|
static RegisterPass<LoopStrengthReduce>
|
|
|
|
X("loop-reduce", "Loop Strength Reduction");
|
|
|
|
|
2008-10-22 23:32:42 +00:00
|
|
|
Pass *llvm::createLoopStrengthReducePass(const TargetLowering *TLI) {
|
2006-03-16 21:53:05 +00:00
|
|
|
return new LoopStrengthReduce(TLI);
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// DeleteTriviallyDeadInstructions - If any of the instructions is the
|
|
|
|
/// specified set are trivially dead, delete them and see if this makes any of
|
|
|
|
/// their operands subsequently dead.
|
2008-12-01 06:14:28 +00:00
|
|
|
void LoopStrengthReduce::DeleteTriviallyDeadInstructions() {
|
2008-12-01 06:27:41 +00:00
|
|
|
if (DeadInsts.empty()) return;
|
|
|
|
|
|
|
|
// Sort the deadinsts list so that we can trivially eliminate duplicates as we
|
|
|
|
// go. The code below never adds a non-dead instruction to the worklist, but
|
|
|
|
// callers may not be so careful.
|
2008-12-01 06:49:59 +00:00
|
|
|
array_pod_sort(DeadInsts.begin(), DeadInsts.end());
|
2008-12-01 06:27:41 +00:00
|
|
|
|
|
|
|
// Drop duplicate instructions and those with uses.
|
|
|
|
for (unsigned i = 0, e = DeadInsts.size()-1; i < e; ++i) {
|
|
|
|
Instruction *I = DeadInsts[i];
|
|
|
|
if (!I->use_empty()) DeadInsts[i] = 0;
|
2008-12-09 04:47:21 +00:00
|
|
|
while (i != e && DeadInsts[i+1] == I)
|
2008-12-01 06:27:41 +00:00
|
|
|
DeadInsts[++i] = 0;
|
|
|
|
}
|
|
|
|
|
2008-12-01 06:14:28 +00:00
|
|
|
while (!DeadInsts.empty()) {
|
|
|
|
Instruction *I = DeadInsts.back();
|
|
|
|
DeadInsts.pop_back();
|
2008-12-01 06:27:41 +00:00
|
|
|
|
|
|
|
if (I == 0 || !isInstructionTriviallyDead(I))
|
2008-12-01 06:11:32 +00:00
|
|
|
continue;
|
|
|
|
|
2008-12-01 06:27:41 +00:00
|
|
|
for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) {
|
|
|
|
if (Instruction *U = dyn_cast<Instruction>(*OI)) {
|
|
|
|
*OI = 0;
|
2008-12-01 06:11:32 +00:00
|
|
|
if (U->use_empty())
|
2008-12-01 06:27:41 +00:00
|
|
|
DeadInsts.push_back(U);
|
2008-12-01 06:11:32 +00:00
|
|
|
}
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|
2008-12-01 06:11:32 +00:00
|
|
|
|
|
|
|
I->eraseFromParent();
|
|
|
|
Changed = true;
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
|
|
|
|
/// subexpression that is an AddRec from a loop other than L. An outer loop
|
|
|
|
/// of L is OK, but not an inner loop nor a disjoint loop.
|
|
|
|
static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
|
|
|
|
// This is very common, put it first.
|
|
|
|
if (isa<SCEVConstant>(S))
|
|
|
|
return false;
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVCommutativeExpr *AE = dyn_cast<SCEVCommutativeExpr>(S)) {
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
for (unsigned int i=0; i< AE->getNumOperands(); i++)
|
|
|
|
if (containsAddRecFromDifferentLoop(AE->getOperand(i), L))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVAddRecExpr *AE = dyn_cast<SCEVAddRecExpr>(S)) {
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
if (const Loop *newLoop = AE->getLoop()) {
|
|
|
|
if (newLoop == L)
|
|
|
|
return false;
|
|
|
|
// if newLoop is an outer loop of L, this is OK.
|
|
|
|
if (!LoopInfoBase<BasicBlock>::isNotAlreadyContainedIn(L, newLoop))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVUDivExpr *DE = dyn_cast<SCEVUDivExpr>(S))
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
return containsAddRecFromDifferentLoop(DE->getLHS(), L) ||
|
|
|
|
containsAddRecFromDifferentLoop(DE->getRHS(), L);
|
|
|
|
#if 0
|
|
|
|
// SCEVSDivExpr has been backed out temporarily, but will be back; we'll
|
|
|
|
// need this when it is.
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVSDivExpr *DE = dyn_cast<SCEVSDivExpr>(S))
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
return containsAddRecFromDifferentLoop(DE->getLHS(), L) ||
|
|
|
|
containsAddRecFromDifferentLoop(DE->getRHS(), L);
|
|
|
|
#endif
|
2009-04-21 01:25:57 +00:00
|
|
|
if (const SCEVCastExpr *CE = dyn_cast<SCEVCastExpr>(S))
|
|
|
|
return containsAddRecFromDifferentLoop(CE->getOperand(), L);
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-08-04 19:08:16 +00:00
|
|
|
/// getSCEVStartAndStride - Compute the start and stride of this expression,
|
|
|
|
/// returning false if the expression is not a start/stride pair, or true if it
|
|
|
|
/// is. The stride must be a loop invariant expression, but the start may be
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
/// a mix of loop invariant and loop variant expressions. The start cannot,
|
|
|
|
/// however, contain an AddRec from a different loop, unless that loop is an
|
|
|
|
/// outer loop of the current loop.
|
2005-08-04 19:08:16 +00:00
|
|
|
static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L,
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle &Start, SCEVHandle &Stride,
|
2009-02-15 06:06:15 +00:00
|
|
|
ScalarEvolution *SE, DominatorTree *DT) {
|
2005-08-04 19:08:16 +00:00
|
|
|
SCEVHandle TheAddRec = Start; // Initialize to zero.
|
|
|
|
|
|
|
|
// If the outer level is an AddExpr, the operands are all start values except
|
|
|
|
// for a nested AddRecExpr.
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(SH)) {
|
2005-08-04 19:08:16 +00:00
|
|
|
for (unsigned i = 0, e = AE->getNumOperands(); i != e; ++i)
|
2009-05-04 22:02:23 +00:00
|
|
|
if (const SCEVAddRecExpr *AddRec =
|
2005-08-04 19:08:16 +00:00
|
|
|
dyn_cast<SCEVAddRecExpr>(AE->getOperand(i))) {
|
|
|
|
if (AddRec->getLoop() == L)
|
2007-10-22 18:31:58 +00:00
|
|
|
TheAddRec = SE->getAddExpr(AddRec, TheAddRec);
|
2005-08-04 19:08:16 +00:00
|
|
|
else
|
|
|
|
return false; // Nested IV of some sort?
|
|
|
|
} else {
|
2007-10-22 18:31:58 +00:00
|
|
|
Start = SE->getAddExpr(Start, AE->getOperand(i));
|
2005-08-04 19:08:16 +00:00
|
|
|
}
|
|
|
|
|
2006-11-02 20:25:50 +00:00
|
|
|
} else if (isa<SCEVAddRecExpr>(SH)) {
|
2005-08-04 19:08:16 +00:00
|
|
|
TheAddRec = SH;
|
|
|
|
} else {
|
|
|
|
return false; // not analyzable.
|
|
|
|
}
|
|
|
|
|
2009-04-18 17:56:28 +00:00
|
|
|
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(TheAddRec);
|
2005-08-04 19:08:16 +00:00
|
|
|
if (!AddRec || AddRec->getLoop() != L) return false;
|
|
|
|
|
|
|
|
// FIXME: Generalize to non-affine IV's.
|
|
|
|
if (!AddRec->isAffine()) return false;
|
|
|
|
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
// If Start contains an SCEVAddRecExpr from a different loop, other than an
|
2009-02-09 22:14:15 +00:00
|
|
|
// outer loop of the current loop, reject it. SCEV has no concept of
|
2009-03-04 20:50:23 +00:00
|
|
|
// operating on more than one loop at a time so don't confuse it with such
|
|
|
|
// expressions.
|
2009-02-13 03:58:31 +00:00
|
|
|
if (containsAddRecFromDifferentLoop(AddRec->getOperand(0), L))
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
return false;
|
|
|
|
|
2007-10-22 18:31:58 +00:00
|
|
|
Start = SE->getAddExpr(Start, AddRec->getOperand(0));
|
2005-08-04 19:08:16 +00:00
|
|
|
|
2009-02-15 06:06:15 +00:00
|
|
|
if (!isa<SCEVConstant>(AddRec->getOperand(1))) {
|
2009-02-17 00:13:06 +00:00
|
|
|
// If stride is an instruction, make sure it dominates the loop preheader.
|
2009-02-15 06:06:15 +00:00
|
|
|
// Otherwise we could end up with a use before def situation.
|
2009-02-17 00:13:06 +00:00
|
|
|
BasicBlock *Preheader = L->getLoopPreheader();
|
|
|
|
if (!AddRec->getOperand(1)->dominates(Preheader, DT))
|
|
|
|
return false;
|
2009-02-15 06:06:15 +00:00
|
|
|
|
2006-11-26 09:46:52 +00:00
|
|
|
DOUT << "[" << L->getHeader()->getName()
|
|
|
|
<< "] Variable stride: " << *AddRec << "\n";
|
2009-02-15 06:06:15 +00:00
|
|
|
}
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
|
|
|
|
Stride = AddRec->getOperand(1);
|
2005-08-04 19:08:16 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2005-10-03 01:04:44 +00:00
|
|
|
/// IVUseShouldUsePostIncValue - We have discovered a "User" of an IV expression
|
|
|
|
/// and now we need to decide whether the user should use the preinc or post-inc
|
|
|
|
/// value. If this user should use the post-inc version of the IV, return true.
|
|
|
|
///
|
|
|
|
/// Choosing wrong here can break dominance properties (if we choose to use the
|
|
|
|
/// post-inc value when we cannot) or it can end up adding extra live-ranges to
|
|
|
|
/// 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,
|
2007-10-30 23:45:15 +00:00
|
|
|
Loop *L, DominatorTree *DT, Pass *P,
|
2008-12-01 06:27:41 +00:00
|
|
|
SmallVectorImpl<Instruction*> &DeadInsts){
|
2005-10-03 01:04:44 +00:00
|
|
|
// If the user is in the loop, use the preinc value.
|
|
|
|
if (L->contains(User->getParent())) return false;
|
|
|
|
|
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
2005-10-03 02:50:05 +00:00
|
|
|
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.
|
2007-06-07 21:42:15 +00:00
|
|
|
if (DT->dominates(LatchBlock, User->getParent()))
|
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
2005-10-03 02:50:05 +00:00
|
|
|
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;
|
2007-06-07 21:42:15 +00:00
|
|
|
if (!DT->dominates(LatchBlock, PN->getIncomingBlock(i)))
|
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
2005-10-03 02:50:05 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay, all uses of IV by PN are in predecessor blocks that really are
|
2009-05-02 05:36:01 +00:00
|
|
|
// dominated by the latch block. Use the post-incremented value.
|
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
2005-10-03 02:50:05 +00:00
|
|
|
return true;
|
2005-10-03 01:04:44 +00:00
|
|
|
}
|
|
|
|
|
2009-02-18 00:08:39 +00:00
|
|
|
/// isAddressUse - Returns true if the specified instruction is using the
|
2008-12-05 21:47:27 +00:00
|
|
|
/// specified value as an address.
|
|
|
|
static bool isAddressUse(Instruction *Inst, Value *OperandVal) {
|
|
|
|
bool isAddress = isa<LoadInst>(Inst);
|
|
|
|
if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
|
|
|
|
if (SI->getOperand(1) == OperandVal)
|
|
|
|
isAddress = true;
|
|
|
|
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
|
|
|
|
// Addressing modes can also be folded into prefetches and a variety
|
|
|
|
// of intrinsics.
|
|
|
|
switch (II->getIntrinsicID()) {
|
|
|
|
default: break;
|
|
|
|
case Intrinsic::prefetch:
|
|
|
|
case Intrinsic::x86_sse2_loadu_dq:
|
|
|
|
case Intrinsic::x86_sse2_loadu_pd:
|
|
|
|
case Intrinsic::x86_sse_loadu_ps:
|
|
|
|
case Intrinsic::x86_sse_storeu_ps:
|
|
|
|
case Intrinsic::x86_sse2_storeu_pd:
|
|
|
|
case Intrinsic::x86_sse2_storeu_dq:
|
|
|
|
case Intrinsic::x86_sse2_storel_dq:
|
|
|
|
if (II->getOperand(1) == OperandVal)
|
|
|
|
isAddress = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return isAddress;
|
|
|
|
}
|
2005-10-03 01:04:44 +00:00
|
|
|
|
2009-03-09 21:01:17 +00:00
|
|
|
/// getAccessType - Return the type of the memory being accessed.
|
|
|
|
static const Type *getAccessType(const Instruction *Inst) {
|
|
|
|
const Type *UseTy = Inst->getType();
|
|
|
|
if (const StoreInst *SI = dyn_cast<StoreInst>(Inst))
|
|
|
|
UseTy = SI->getOperand(0)->getType();
|
|
|
|
else if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
|
|
|
|
// Addressing modes can also be folded into prefetches and a variety
|
|
|
|
// of intrinsics.
|
|
|
|
switch (II->getIntrinsicID()) {
|
|
|
|
default: break;
|
|
|
|
case Intrinsic::x86_sse_storeu_ps:
|
|
|
|
case Intrinsic::x86_sse2_storeu_pd:
|
|
|
|
case Intrinsic::x86_sse2_storeu_dq:
|
|
|
|
case Intrinsic::x86_sse2_storel_dq:
|
|
|
|
UseTy = II->getOperand(1)->getType();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return UseTy;
|
|
|
|
}
|
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
/// AddUsersIfInteresting - Inspect the specified instruction. If it is a
|
|
|
|
/// reducible SCEV, recursively add its users to the IVUsesByStride set and
|
|
|
|
/// return true. Otherwise, return false.
|
2005-08-04 17:40:30 +00:00
|
|
|
bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
|
2007-10-26 23:08:19 +00:00
|
|
|
SmallPtrSet<Instruction*,16> &Processed) {
|
2009-04-21 01:07:12 +00:00
|
|
|
if (!SE->isSCEVable(I->getType()))
|
2008-04-14 18:26:16 +00:00
|
|
|
return false; // Void and FP expressions cannot be reduced.
|
2009-03-17 23:58:30 +00:00
|
|
|
|
|
|
|
// LSR is not APInt clean, do not touch integers bigger than 64-bits.
|
2009-04-21 01:07:12 +00:00
|
|
|
if (SE->getTypeSizeInBits(I->getType()) > 64)
|
2009-03-17 23:58:30 +00:00
|
|
|
return false;
|
|
|
|
|
2007-10-26 23:08:19 +00:00
|
|
|
if (!Processed.insert(I))
|
2005-08-04 17:40:30 +00:00
|
|
|
return true; // Instruction already handled.
|
|
|
|
|
2005-08-04 19:08:16 +00:00
|
|
|
// Get the symbolic expression for this instruction.
|
2009-04-16 03:18:22 +00:00
|
|
|
SCEVHandle ISE = SE->getSCEV(I);
|
2005-08-04 19:08:16 +00:00
|
|
|
if (isa<SCEVCouldNotCompute>(ISE)) return false;
|
|
|
|
|
|
|
|
// Get the start and stride for this expression.
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType());
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
SCEVHandle Stride = Start;
|
2009-02-15 06:06:15 +00:00
|
|
|
if (!getSCEVStartAndStride(ISE, L, Start, Stride, SE, DT))
|
2005-08-04 19:08:16 +00:00
|
|
|
return false; // Non-reducible symbolic expression, bail out.
|
2007-03-09 21:19:53 +00:00
|
|
|
|
2007-04-23 22:42:03 +00:00
|
|
|
std::vector<Instruction *> IUsers;
|
|
|
|
// Collect all I uses now because IVUseShouldUsePostIncValue may
|
|
|
|
// invalidate use_iterator.
|
|
|
|
for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI)
|
|
|
|
IUsers.push_back(cast<Instruction>(*UI));
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2007-04-23 22:42:03 +00:00
|
|
|
for (unsigned iused_index = 0, iused_size = IUsers.size();
|
|
|
|
iused_index != iused_size; ++iused_index) {
|
|
|
|
|
|
|
|
Instruction *User = IUsers[iused_index];
|
2007-03-09 21:19:53 +00:00
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
// Do not infinitely recurse on PHI nodes.
|
2005-09-13 02:09:55 +00:00
|
|
|
if (isa<PHINode>(User) && Processed.count(User))
|
2005-07-30 00:15:07 +00:00
|
|
|
continue;
|
|
|
|
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
// Descend recursively, but not into PHI nodes outside the current loop.
|
|
|
|
// It's important to see the entire expression outside the loop to get
|
|
|
|
// choices that depend on addressing mode use right, although we won't
|
|
|
|
// consider references ouside the loop in all cases.
|
|
|
|
// If User is already in Processed, we don't want to recurse into it again,
|
|
|
|
// but do want to record a second reference in the same instruction.
|
2005-08-04 19:08:16 +00:00
|
|
|
bool AddUserToIVUsers = false;
|
When processing outer loops and we find uses of an IV in inner loops, make
sure to handle the use, just don't recurse into it.
This permits us to generate this code for a simple nested loop case:
.LBB_foo_0: ; entry
stwu r1, -48(r1)
stw r29, 44(r1)
stw r30, 40(r1)
mflr r11
stw r11, 56(r1)
lis r2, ha16(L_A$non_lazy_ptr)
lwz r30, lo16(L_A$non_lazy_ptr)(r2)
li r29, 1
.LBB_foo_1: ; no_exit.0
bl L_bar$stub
li r2, 1
or r3, r30, r30
.LBB_foo_2: ; no_exit.1
lfd f0, 8(r3)
stfd f0, 0(r3)
addi r4, r2, 1
addi r3, r3, 8
cmpwi cr0, r2, 100
or r2, r4, r4
bne .LBB_foo_2 ; no_exit.1
.LBB_foo_3: ; loopexit.1
addi r30, r30, 800
addi r2, r29, 1
cmpwi cr0, r29, 100
or r29, r2, r2
bne .LBB_foo_1 ; no_exit.0
.LBB_foo_4: ; return
lwz r11, 56(r1)
mtlr r11
lwz r30, 40(r1)
lwz r29, 44(r1)
lwz r1, 0(r1)
blr
instead of this:
_foo:
.LBB_foo_0: ; entry
stwu r1, -48(r1)
stw r28, 44(r1) ;; uses an extra register.
stw r29, 40(r1)
stw r30, 36(r1)
mflr r11
stw r11, 56(r1)
li r30, 1
li r29, 0
or r28, r29, r29
.LBB_foo_1: ; no_exit.0
bl L_bar$stub
mulli r2, r28, 800 ;; unstrength-reduced multiply
lis r3, ha16(L_A$non_lazy_ptr) ;; loop invariant address computation
lwz r3, lo16(L_A$non_lazy_ptr)(r3)
add r2, r2, r3
mulli r4, r29, 800 ;; unstrength-reduced multiply
addi r3, r3, 8
add r3, r4, r3
li r4, 1
.LBB_foo_2: ; no_exit.1
lfd f0, 0(r3)
stfd f0, 0(r2)
addi r5, r4, 1
addi r2, r2, 8 ;; multiple stride 8 IV's
addi r3, r3, 8
cmpwi cr0, r4, 100
or r4, r5, r5
bne .LBB_foo_2 ; no_exit.1
.LBB_foo_3: ; loopexit.1
addi r28, r28, 1 ;;; Many IV's with stride 1
addi r29, r29, 1
addi r2, r30, 1
cmpwi cr0, r30, 100
or r30, r2, r2
bne .LBB_foo_1 ; no_exit.0
.LBB_foo_4: ; return
lwz r11, 56(r1)
mtlr r11
lwz r30, 36(r1)
lwz r29, 40(r1)
lwz r28, 44(r1)
lwz r1, 0(r1)
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22640 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-04 00:14:11 +00:00
|
|
|
if (LI->getLoopFor(User->getParent()) != L) {
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
if (isa<PHINode>(User) || Processed.count(User) ||
|
|
|
|
!AddUsersIfInteresting(User, L, Processed)) {
|
|
|
|
DOUT << "FOUND USER in other loop: " << *User
|
|
|
|
<< " OF SCEV: " << *ISE << "\n";
|
|
|
|
AddUserToIVUsers = true;
|
|
|
|
}
|
|
|
|
} else if (Processed.count(User) ||
|
|
|
|
!AddUsersIfInteresting(User, L, Processed)) {
|
2006-11-26 09:46:52 +00:00
|
|
|
DOUT << "FOUND USER: " << *User
|
|
|
|
<< " OF SCEV: " << *ISE << "\n";
|
2005-08-04 19:08:16 +00:00
|
|
|
AddUserToIVUsers = true;
|
|
|
|
}
|
2005-04-21 23:48:37 +00:00
|
|
|
|
2005-08-04 19:08:16 +00:00
|
|
|
if (AddUserToIVUsers) {
|
2005-10-09 06:20:55 +00:00
|
|
|
IVUsersOfOneStride &StrideUses = IVUsesByStride[Stride];
|
2008-12-16 22:16:28 +00:00
|
|
|
if (StrideUses.Users.empty()) // First occurrence of this stride?
|
2005-10-09 06:20:55 +00:00
|
|
|
StrideOrder.push_back(Stride);
|
|
|
|
|
2005-08-04 00:40:47 +00:00
|
|
|
// Okay, we found a user that we cannot reduce. Analyze the instruction
|
_test:
li r2, 0
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r2, 1
stw r2, 0(r4)
blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version. This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):
_test:
li r2, 0 **** IV starts at 0
LBB_test_1: ; no_exit.2
or r5, r2, r2 **** Copy for loop exit
li r2, 0
stw r2, 0(r3)
addi r3, r3, 4
addi r2, r5, 1
addi r6, r5, 2 **** IV+2
cmpwi cr0, r6, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r5, 2 **** IV+2
stw r2, 0(r4)
blr
And now generated code like this:
_test:
li r2, 1 *** IV starts at 1
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701 *** IV.postinc + 0
blt cr0, LBB_test_1
LBB_test_2: ; loopexit.2.loopexit
stw r2, 0(r4) *** IV.postinc + 0
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8
2005-09-12 06:04:47 +00:00
|
|
|
// 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.
|
2007-10-30 23:45:15 +00:00
|
|
|
if (IVUseShouldUsePostIncValue(User, I, L, DT, this, DeadInsts)) {
|
_test:
li r2, 0
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r2, 1
stw r2, 0(r4)
blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version. This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):
_test:
li r2, 0 **** IV starts at 0
LBB_test_1: ; no_exit.2
or r5, r2, r2 **** Copy for loop exit
li r2, 0
stw r2, 0(r3)
addi r3, r3, 4
addi r2, r5, 1
addi r6, r5, 2 **** IV+2
cmpwi cr0, r6, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r5, 2 **** IV+2
stw r2, 0(r4)
blr
And now generated code like this:
_test:
li r2, 1 *** IV starts at 1
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701 *** IV.postinc + 0
blt cr0, LBB_test_1
LBB_test_2: ; loopexit.2.loopexit
stw r2, 0(r4) *** IV.postinc + 0
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8
2005-09-12 06:04:47 +00:00
|
|
|
// The value used will be incremented by the stride more than we are
|
|
|
|
// expecting, so subtract this off.
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
|
2005-10-09 06:20:55 +00:00
|
|
|
StrideUses.addUser(NewStart, User, I);
|
|
|
|
StrideUses.Users.back().isUseOfPostIncrementedValue = true;
|
2006-11-26 09:46:52 +00:00
|
|
|
DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n";
|
2005-10-03 01:04:44 +00:00
|
|
|
} else {
|
2005-10-09 06:20:55 +00:00
|
|
|
StrideUses.addUser(Start, User, I);
|
_test:
li r2, 0
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r2, 1
stw r2, 0(r4)
blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version. This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):
_test:
li r2, 0 **** IV starts at 0
LBB_test_1: ; no_exit.2
or r5, r2, r2 **** Copy for loop exit
li r2, 0
stw r2, 0(r3)
addi r3, r3, 4
addi r2, r5, 1
addi r6, r5, 2 **** IV+2
cmpwi cr0, r6, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r5, 2 **** IV+2
stw r2, 0(r4)
blr
And now generated code like this:
_test:
li r2, 1 *** IV starts at 1
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701 *** IV.postinc + 0
blt cr0, LBB_test_1
LBB_test_2: ; loopexit.2.loopexit
stw r2, 0(r4) *** IV.postinc + 0
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8
2005-09-12 06:04:47 +00:00
|
|
|
}
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
/// BasedUser - For a particular base value, keep information about how we've
|
|
|
|
/// partitioned the expression so far.
|
|
|
|
struct BasedUser {
|
2007-10-22 18:31:58 +00:00
|
|
|
/// SE - The current ScalarEvolution object.
|
|
|
|
ScalarEvolution *SE;
|
|
|
|
|
2005-08-08 22:56:21 +00:00
|
|
|
/// Base - The Base value for the PHI node that needs to be inserted for
|
|
|
|
/// this use. As the use is processed, information gets moved from this
|
|
|
|
/// field to the Imm field (below). BasedUser values are sorted by this
|
|
|
|
/// field.
|
|
|
|
SCEVHandle Base;
|
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
/// Inst - The instruction using the induction variable.
|
|
|
|
Instruction *Inst;
|
|
|
|
|
2005-08-03 22:21:05 +00:00
|
|
|
/// OperandValToReplace - The operand value of Inst to replace with the
|
|
|
|
/// EmittedBase.
|
|
|
|
Value *OperandValToReplace;
|
2005-07-30 00:15:07 +00:00
|
|
|
|
|
|
|
/// Imm - The immediate value that should be added to the base immediately
|
|
|
|
/// before Inst, because it will be folded into the imm field of the
|
2009-02-20 20:29:04 +00:00
|
|
|
/// instruction. This is also sometimes used for loop-variant values that
|
|
|
|
/// must be added inside the loop.
|
2005-07-30 00:15:07 +00:00
|
|
|
SCEVHandle Imm;
|
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
/// Phi - The induction variable that performs the striding that
|
|
|
|
/// should be used for this user.
|
2009-03-09 22:04:01 +00:00
|
|
|
PHINode *Phi;
|
2009-02-20 04:17:46 +00:00
|
|
|
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
// isUseOfPostIncrementedValue - True if this should use the
|
|
|
|
// post-incremented version of this IV, not the preincremented version.
|
|
|
|
// This can only be set in special cases, such as the terminating setcc
|
_test:
li r2, 0
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r2, 1
stw r2, 0(r4)
blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version. This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):
_test:
li r2, 0 **** IV starts at 0
LBB_test_1: ; no_exit.2
or r5, r2, r2 **** Copy for loop exit
li r2, 0
stw r2, 0(r3)
addi r3, r3, 4
addi r2, r5, 1
addi r6, r5, 2 **** IV+2
cmpwi cr0, r6, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r5, 2 **** IV+2
stw r2, 0(r4)
blr
And now generated code like this:
_test:
li r2, 1 *** IV starts at 1
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701 *** IV.postinc + 0
blt cr0, LBB_test_1
LBB_test_2: ; loopexit.2.loopexit
stw r2, 0(r4) *** IV.postinc + 0
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8
2005-09-12 06:04:47 +00:00
|
|
|
// instruction for a loop and uses outside the loop that are dominated by
|
|
|
|
// the loop.
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
bool isUseOfPostIncrementedValue;
|
2005-08-08 22:56:21 +00:00
|
|
|
|
2007-10-22 18:31:58 +00:00
|
|
|
BasedUser(IVStrideUse &IVSU, ScalarEvolution *se)
|
|
|
|
: SE(se), Base(IVSU.Offset), Inst(IVSU.User),
|
2005-08-08 22:56:21 +00:00
|
|
|
OperandValToReplace(IVSU.OperandValToReplace),
|
2008-12-03 22:43:56 +00:00
|
|
|
Imm(SE->getIntegerSCEV(0, Base->getType())),
|
2005-08-08 22:56:21 +00:00
|
|
|
isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue) {}
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2005-08-04 20:03:32 +00:00
|
|
|
// Once we rewrite the code to insert the new IVs we want, update the
|
|
|
|
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
|
|
|
// to it.
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
2008-05-15 23:26:57 +00:00
|
|
|
Instruction *InsertPt,
|
2007-10-30 23:45:15 +00:00
|
|
|
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
2008-12-01 06:27:41 +00:00
|
|
|
SmallVectorImpl<Instruction*> &DeadInsts);
|
2006-02-04 07:36:50 +00:00
|
|
|
|
|
|
|
Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
2009-04-16 03:18:22 +00:00
|
|
|
const Type *Ty,
|
2006-02-04 07:36:50 +00:00
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
Instruction *IP, Loop *L);
|
2005-07-30 00:15:07 +00:00
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void BasedUser::dump() const {
|
2006-12-07 01:30:32 +00:00
|
|
|
cerr << " Base=" << *Base;
|
|
|
|
cerr << " Imm=" << *Imm;
|
|
|
|
cerr << " Inst: " << *Inst;
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
|
2006-02-04 07:36:50 +00:00
|
|
|
Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
2009-04-16 03:18:22 +00:00
|
|
|
const Type *Ty,
|
2006-02-04 07:36:50 +00:00
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
Instruction *IP, Loop *L) {
|
|
|
|
// Figure out where we *really* want to insert this code. In particular, if
|
|
|
|
// the user is inside of a loop that is nested inside of L, we really don't
|
|
|
|
// want to insert this expression before the user, we'd rather pull it out as
|
|
|
|
// many loops as possible.
|
|
|
|
LoopInfo &LI = Rewriter.getLoopInfo();
|
|
|
|
Instruction *BaseInsertPt = IP;
|
|
|
|
|
|
|
|
// Figure out the most-nested loop that IP is in.
|
|
|
|
Loop *InsertLoop = LI.getLoopFor(IP->getParent());
|
|
|
|
|
|
|
|
// If InsertLoop is not L, and InsertLoop is nested inside of L, figure out
|
|
|
|
// the preheader of the outer-most loop where NewBase is not loop invariant.
|
2008-12-02 18:40:09 +00:00
|
|
|
if (L->contains(IP->getParent()))
|
|
|
|
while (InsertLoop && NewBase->isLoopInvariant(InsertLoop)) {
|
|
|
|
BaseInsertPt = InsertLoop->getLoopPreheader()->getTerminator();
|
|
|
|
InsertLoop = InsertLoop->getParentLoop();
|
|
|
|
}
|
2006-02-04 07:36:50 +00:00
|
|
|
|
2009-04-16 03:18:22 +00:00
|
|
|
Value *Base = Rewriter.expandCodeFor(NewBase, Ty, BaseInsertPt);
|
2009-02-19 19:23:27 +00:00
|
|
|
|
2006-02-04 07:36:50 +00:00
|
|
|
// If there is no immediate value, skip the next part.
|
2008-06-18 16:23:07 +00:00
|
|
|
if (Imm->isZero())
|
2009-02-19 19:23:27 +00:00
|
|
|
return Base;
|
2007-06-06 01:23:55 +00:00
|
|
|
|
|
|
|
// If we are inserting the base and imm values in the same block, make sure to
|
|
|
|
// adjust the IP position if insertion reused a result.
|
|
|
|
if (IP == BaseInsertPt)
|
|
|
|
IP = Rewriter.getInsertionPoint();
|
2006-02-04 07:36:50 +00:00
|
|
|
|
|
|
|
// Always emit the immediate (if non-zero) into the same block as the user.
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle NewValSCEV = SE->getAddExpr(SE->getUnknown(Base), Imm);
|
2009-04-16 03:18:22 +00:00
|
|
|
return Rewriter.expandCodeFor(NewValSCEV, Ty, IP);
|
2006-02-04 07:36:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-04 20:03:32 +00:00
|
|
|
// Once we rewrite the code to insert the new IVs we want, update the
|
|
|
|
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
2008-05-15 23:26:57 +00:00
|
|
|
// to it. NewBasePt is the last instruction which contributes to the
|
|
|
|
// value of NewBase in the case that it's a diffferent instruction from
|
|
|
|
// the PHI that NewBase is computed from, or null otherwise.
|
|
|
|
//
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
2008-05-15 23:26:57 +00:00
|
|
|
Instruction *NewBasePt,
|
2007-10-30 23:45:15 +00:00
|
|
|
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
2008-12-01 06:27:41 +00:00
|
|
|
SmallVectorImpl<Instruction*> &DeadInsts){
|
2005-08-04 20:03:32 +00:00
|
|
|
if (!isa<PHINode>(Inst)) {
|
Now that codegen prepare isn't defeating me, I can finally fix what I set
out to do! :)
This fixes a problem where LSR would insert a bunch of code into each MBB
that uses a particular subexpression (e.g. IV+base+C). The problem is that
this code cannot be CSE'd back together if inserted into different blocks.
This patch changes LSR to attempt to insert a single copy of this code and
share it, allowing codegenprepare to duplicate the code if it can be sunk
into various addressing modes. On CodeGen/ARM/lsr-code-insertion.ll,
for example, this gives us code like:
add r8, r0, r5
str r6, [r8, #+4]
..
ble LBB1_4 @cond_next
LBB1_3: @cond_true
str r10, [r8, #+4]
LBB1_4: @cond_next
...
LBB1_5: @cond_true55
ldr r6, LCPI1_1
str r6, [r8, #+4]
instead of:
add r10, r0, r6
str r8, [r10, #+4]
...
ble LBB1_4 @cond_next
LBB1_3: @cond_true
add r8, r0, r6
str r10, [r8, #+4]
LBB1_4: @cond_next
...
LBB1_5: @cond_true55
add r8, r0, r6
ldr r10, LCPI1_1
str r10, [r8, #+4]
Besides being smaller and more efficient, this makes it immediately
obvious that it is profitable to predicate LBB1_3 now :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35972 91177308-0d34-0410-b5e6-96231b3b80d8
2007-04-13 20:42:26 +00:00
|
|
|
// By default, insert code at the user instruction.
|
|
|
|
BasicBlock::iterator InsertPt = Inst;
|
|
|
|
|
|
|
|
// However, if the Operand is itself an instruction, the (potentially
|
|
|
|
// complex) inserted code may be shared by many users. Because of this, we
|
|
|
|
// want to emit code for the computation of the operand right before its old
|
|
|
|
// computation. This is usually safe, because we obviously used to use the
|
|
|
|
// computation when it was computed in its current block. However, in some
|
|
|
|
// cases (e.g. use of a post-incremented induction variable) the NewBase
|
|
|
|
// value will be pinned to live somewhere after the original computation.
|
|
|
|
// In this case, we have to back off.
|
2008-12-02 04:52:26 +00:00
|
|
|
//
|
|
|
|
// If this is a use outside the loop (which means after, since it is based
|
|
|
|
// on a loop indvar) we use the post-incremented value, so that we don't
|
|
|
|
// artificially make the preinc value live out the bottom of the loop.
|
2008-12-01 22:00:01 +00:00
|
|
|
if (!isUseOfPostIncrementedValue && L->contains(Inst->getParent())) {
|
2008-05-20 03:01:48 +00:00
|
|
|
if (NewBasePt && isa<PHINode>(OperandValToReplace)) {
|
2008-05-15 23:26:57 +00:00
|
|
|
InsertPt = NewBasePt;
|
|
|
|
++InsertPt;
|
2008-06-11 21:38:51 +00:00
|
|
|
} else if (Instruction *OpInst
|
|
|
|
= dyn_cast<Instruction>(OperandValToReplace)) {
|
Now that codegen prepare isn't defeating me, I can finally fix what I set
out to do! :)
This fixes a problem where LSR would insert a bunch of code into each MBB
that uses a particular subexpression (e.g. IV+base+C). The problem is that
this code cannot be CSE'd back together if inserted into different blocks.
This patch changes LSR to attempt to insert a single copy of this code and
share it, allowing codegenprepare to duplicate the code if it can be sunk
into various addressing modes. On CodeGen/ARM/lsr-code-insertion.ll,
for example, this gives us code like:
add r8, r0, r5
str r6, [r8, #+4]
..
ble LBB1_4 @cond_next
LBB1_3: @cond_true
str r10, [r8, #+4]
LBB1_4: @cond_next
...
LBB1_5: @cond_true55
ldr r6, LCPI1_1
str r6, [r8, #+4]
instead of:
add r10, r0, r6
str r8, [r10, #+4]
...
ble LBB1_4 @cond_next
LBB1_3: @cond_true
add r8, r0, r6
str r10, [r8, #+4]
LBB1_4: @cond_next
...
LBB1_5: @cond_true55
add r8, r0, r6
ldr r10, LCPI1_1
str r10, [r8, #+4]
Besides being smaller and more efficient, this makes it immediately
obvious that it is profitable to predicate LBB1_3 now :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35972 91177308-0d34-0410-b5e6-96231b3b80d8
2007-04-13 20:42:26 +00:00
|
|
|
InsertPt = OpInst;
|
|
|
|
while (isa<PHINode>(InsertPt)) ++InsertPt;
|
|
|
|
}
|
|
|
|
}
|
2009-04-16 03:18:22 +00:00
|
|
|
Value *NewVal = InsertCodeForBaseAtPosition(NewBase,
|
|
|
|
OperandValToReplace->getType(),
|
|
|
|
Rewriter, InsertPt, L);
|
2005-08-04 20:03:32 +00:00
|
|
|
// Replace the use of the operand Value with the new Phi we just created.
|
|
|
|
Inst->replaceUsesOfWith(OperandValToReplace, NewVal);
|
2009-02-19 19:23:27 +00:00
|
|
|
|
|
|
|
DOUT << " Replacing with ";
|
2009-02-19 19:32:06 +00:00
|
|
|
DEBUG(WriteAsOperand(*DOUT, NewVal, /*PrintType=*/false));
|
2009-02-19 19:23:27 +00:00
|
|
|
DOUT << ", which has value " << *NewBase << " plus IMM " << *Imm << "\n";
|
2005-08-04 20:03:32 +00:00
|
|
|
return;
|
|
|
|
}
|
2009-02-19 19:23:27 +00:00
|
|
|
|
2005-08-04 20:03:32 +00:00
|
|
|
// PHI nodes are more complex. We have to insert one copy of the NewBase+Imm
|
2005-08-10 00:35:32 +00:00
|
|
|
// expression into each operand block that uses it. Note that PHI nodes can
|
|
|
|
// have multiple entries for the same predecessor. We use a map to make sure
|
|
|
|
// that a PHI node only has a single Value* for each predecessor (which also
|
|
|
|
// prevents us from inserting duplicate code in some blocks).
|
2007-10-30 22:27:26 +00:00
|
|
|
DenseMap<BasicBlock*, Value*> InsertedCode;
|
2005-08-04 20:03:32 +00:00
|
|
|
PHINode *PN = cast<PHINode>(Inst);
|
|
|
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
|
|
|
if (PN->getIncomingValue(i) == OperandValToReplace) {
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
// If the original expression is outside the loop, put the replacement
|
|
|
|
// code in the same place as the original expression,
|
|
|
|
// which need not be an immediate predecessor of this PHI. This way we
|
|
|
|
// need only one copy of it even if it is referenced multiple times in
|
|
|
|
// the PHI. We don't do this when the original expression is inside the
|
2009-02-09 22:14:15 +00:00
|
|
|
// loop because multiple copies sometimes do useful sinking of code in
|
|
|
|
// that case(?).
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace);
|
|
|
|
if (L->contains(OldLoc->getParent())) {
|
2009-02-09 22:14:15 +00:00
|
|
|
// If this is a critical edge, split the edge so that we do not insert
|
|
|
|
// the code on all predecessor/successor paths. We do this unless this
|
|
|
|
// is the canonical backedge for this loop, as this can make some
|
|
|
|
// inserted code be in an illegal position.
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
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, false);
|
|
|
|
|
|
|
|
// Next step: move the basic block. In particular, if the PHI node
|
|
|
|
// is outside of the loop, and PredTI is in the loop, we want to
|
|
|
|
// move the block to be immediately before the PHI block, not
|
|
|
|
// immediately after PredTI.
|
|
|
|
if (L->contains(PHIPred) && !L->contains(PN->getParent())) {
|
|
|
|
BasicBlock *NewBB = PN->getIncomingBlock(i);
|
|
|
|
NewBB->moveBefore(PN->getParent());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Splitting the edge can reduce the number of PHI entries we have.
|
|
|
|
e = PN->getNumIncomingValues();
|
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22766 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-12 22:06:11 +00:00
|
|
|
}
|
|
|
|
}
|
2005-08-10 00:35:32 +00:00
|
|
|
Value *&Code = InsertedCode[PN->getIncomingBlock(i)];
|
|
|
|
if (!Code) {
|
|
|
|
// Insert the code into the end of the predecessor block.
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
Instruction *InsertPt = (L->contains(OldLoc->getParent())) ?
|
|
|
|
PN->getIncomingBlock(i)->getTerminator() :
|
|
|
|
OldLoc->getParent()->getTerminator();
|
2009-04-16 03:18:22 +00:00
|
|
|
Code = InsertCodeForBaseAtPosition(NewBase, PN->getType(),
|
|
|
|
Rewriter, InsertPt, L);
|
2009-02-19 19:23:27 +00:00
|
|
|
|
|
|
|
DOUT << " Changing PHI use to ";
|
2009-02-19 19:32:06 +00:00
|
|
|
DEBUG(WriteAsOperand(*DOUT, Code, /*PrintType=*/false));
|
2009-02-19 19:23:27 +00:00
|
|
|
DOUT << ", which has value " << *NewBase << " plus IMM " << *Imm << "\n";
|
2005-08-10 00:35:32 +00:00
|
|
|
}
|
2009-02-19 19:23:27 +00:00
|
|
|
|
2005-08-04 20:03:32 +00:00
|
|
|
// Replace the use of the operand Value with the new Phi we just created.
|
2005-08-10 00:35:32 +00:00
|
|
|
PN->setIncomingValue(i, Code);
|
2005-08-04 20:03:32 +00:00
|
|
|
Rewriter.clear();
|
|
|
|
}
|
|
|
|
}
|
2007-10-30 23:45:15 +00:00
|
|
|
|
|
|
|
// PHI node might have become a constant value after SplitCriticalEdge.
|
2008-12-01 06:27:41 +00:00
|
|
|
DeadInsts.push_back(Inst);
|
2005-08-04 20:03:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-05 21:47:27 +00:00
|
|
|
/// fitsInAddressMode - Return true if V can be subsumed within an addressing
|
|
|
|
/// mode, and does not need to be put in a register first.
|
|
|
|
static bool fitsInAddressMode(const SCEVHandle &V, const Type *UseTy,
|
|
|
|
const TargetLowering *TLI, bool HasBaseReg) {
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
|
2007-03-12 23:27:37 +00:00
|
|
|
int64_t VC = SC->getValue()->getSExtValue();
|
2007-04-09 22:20:14 +00:00
|
|
|
if (TLI) {
|
|
|
|
TargetLowering::AddrMode AM;
|
|
|
|
AM.BaseOffs = VC;
|
2008-12-05 21:47:27 +00:00
|
|
|
AM.HasBaseReg = HasBaseReg;
|
2007-04-09 22:20:14 +00:00
|
|
|
return TLI->isLegalAddressingMode(AM, UseTy);
|
|
|
|
} else {
|
2006-03-13 23:14:23 +00:00
|
|
|
// Defaults to PPC. PPC allows a sign-extended 16-bit immediate field.
|
2007-03-12 23:27:37 +00:00
|
|
|
return (VC > -(1 << 16) && VC < (1 << 16)-1);
|
2007-04-09 22:20:14 +00:00
|
|
|
}
|
2005-08-08 06:25:50 +00:00
|
|
|
}
|
2005-07-30 18:33:25 +00:00
|
|
|
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V))
|
2009-04-16 03:18:22 +00:00
|
|
|
if (GlobalValue *GV = dyn_cast<GlobalValue>(SU->getValue())) {
|
2009-05-01 16:29:14 +00:00
|
|
|
if (TLI) {
|
|
|
|
TargetLowering::AddrMode AM;
|
|
|
|
AM.BaseGV = GV;
|
|
|
|
AM.HasBaseReg = HasBaseReg;
|
|
|
|
return TLI->isLegalAddressingMode(AM, UseTy);
|
|
|
|
} else {
|
|
|
|
// Default: assume global addresses are not legal.
|
|
|
|
}
|
2009-04-16 03:18:22 +00:00
|
|
|
}
|
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-12-03 20:56:12 +00:00
|
|
|
/// MoveLoopVariantsToImmediateField - Move any subexpressions from Val that are
|
2005-08-08 22:32:34 +00:00
|
|
|
/// loop varying to the Imm operand.
|
2008-12-03 20:56:12 +00:00
|
|
|
static void MoveLoopVariantsToImmediateField(SCEVHandle &Val, SCEVHandle &Imm,
|
2007-10-22 18:31:58 +00:00
|
|
|
Loop *L, ScalarEvolution *SE) {
|
2005-08-08 22:32:34 +00:00
|
|
|
if (Val->isLoopInvariant(L)) return; // Nothing to do.
|
|
|
|
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
|
2005-08-08 22:32:34 +00:00
|
|
|
std::vector<SCEVHandle> NewOps;
|
|
|
|
NewOps.reserve(SAE->getNumOperands());
|
|
|
|
|
|
|
|
for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
|
|
|
|
if (!SAE->getOperand(i)->isLoopInvariant(L)) {
|
|
|
|
// If this is a loop-variant expression, it must stay in the immediate
|
|
|
|
// field of the expression.
|
2007-10-22 18:31:58 +00:00
|
|
|
Imm = SE->getAddExpr(Imm, SAE->getOperand(i));
|
2005-08-08 22:32:34 +00:00
|
|
|
} else {
|
|
|
|
NewOps.push_back(SAE->getOperand(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NewOps.empty())
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getIntegerSCEV(0, Val->getType());
|
2005-08-08 22:32:34 +00:00
|
|
|
else
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getAddExpr(NewOps);
|
2009-04-18 17:56:28 +00:00
|
|
|
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
|
2005-08-08 22:32:34 +00:00
|
|
|
// Try to pull immediates out of the start value of nested addrec's.
|
|
|
|
SCEVHandle Start = SARE->getStart();
|
2008-12-03 20:56:12 +00:00
|
|
|
MoveLoopVariantsToImmediateField(Start, Imm, L, SE);
|
2005-08-08 22:32:34 +00:00
|
|
|
|
|
|
|
std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
|
|
|
|
Ops[0] = Start;
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getAddRecExpr(Ops, SARE->getLoop());
|
2005-08-08 22:32:34 +00:00
|
|
|
} else {
|
|
|
|
// Otherwise, all of Val is variant, move the whole thing over.
|
2007-10-22 18:31:58 +00:00
|
|
|
Imm = SE->getAddExpr(Imm, Val);
|
|
|
|
Val = SE->getIntegerSCEV(0, Val->getType());
|
2005-08-08 22:32:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-04 22:34:05 +00:00
|
|
|
/// MoveImmediateValues - Look at Val, and pull out any additions of constants
|
2005-07-30 00:15:07 +00:00
|
|
|
/// that can fit into the immediate field of instructions in the target.
|
2005-08-04 22:34:05 +00:00
|
|
|
/// Accumulate these immediate values into the Imm value.
|
2006-03-13 23:14:23 +00:00
|
|
|
static void MoveImmediateValues(const TargetLowering *TLI,
|
2009-02-21 02:06:47 +00:00
|
|
|
const Type *UseTy,
|
2006-03-13 23:14:23 +00:00
|
|
|
SCEVHandle &Val, SCEVHandle &Imm,
|
2007-10-22 18:31:58 +00:00
|
|
|
bool isAddress, Loop *L,
|
|
|
|
ScalarEvolution *SE) {
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
|
2005-08-04 22:34:05 +00:00
|
|
|
std::vector<SCEVHandle> NewOps;
|
|
|
|
NewOps.reserve(SAE->getNumOperands());
|
|
|
|
|
2006-02-04 07:36:50 +00:00
|
|
|
for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
|
|
|
|
SCEVHandle NewOp = SAE->getOperand(i);
|
2009-02-21 02:06:47 +00:00
|
|
|
MoveImmediateValues(TLI, UseTy, NewOp, Imm, isAddress, L, SE);
|
2006-02-04 07:36:50 +00:00
|
|
|
|
|
|
|
if (!NewOp->isLoopInvariant(L)) {
|
2005-08-04 19:08:16 +00:00
|
|
|
// If this is a loop-variant expression, it must stay in the immediate
|
|
|
|
// field of the expression.
|
2007-10-22 18:31:58 +00:00
|
|
|
Imm = SE->getAddExpr(Imm, NewOp);
|
2005-08-04 22:34:05 +00:00
|
|
|
} else {
|
2006-02-04 07:36:50 +00:00
|
|
|
NewOps.push_back(NewOp);
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
2006-02-04 07:36:50 +00:00
|
|
|
}
|
2005-08-04 22:34:05 +00:00
|
|
|
|
|
|
|
if (NewOps.empty())
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getIntegerSCEV(0, Val->getType());
|
2005-08-04 22:34:05 +00:00
|
|
|
else
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getAddExpr(NewOps);
|
2005-08-04 22:34:05 +00:00
|
|
|
return;
|
2009-04-18 17:56:28 +00:00
|
|
|
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
|
Teach loop-reduce to see into nested loops, to pull out immediate values
pushed down by SCEV.
In a nested loop case, this allows us to emit this:
lis r3, ha16(L_A$non_lazy_ptr)
lwz r3, lo16(L_A$non_lazy_ptr)(r3)
add r2, r2, r3
li r3, 1
.LBB_foo_2: ; no_exit.1
lfd f0, 8(r2) ;; Uses offset of 8 instead of 0
stfd f0, 0(r2)
addi r4, r3, 1
addi r2, r2, 8
cmpwi cr0, r3, 100
or r3, r4, r4
bne .LBB_foo_2 ; no_exit.1
instead of this:
lis r3, ha16(L_A$non_lazy_ptr)
lwz r3, lo16(L_A$non_lazy_ptr)(r3)
add r2, r2, r3
addi r3, r3, 8
li r4, 1
.LBB_foo_2: ; no_exit.1
lfd f0, 0(r3)
stfd f0, 0(r2)
addi r5, r4, 1
addi r2, r2, 8
addi r3, r3, 8
cmpwi cr0, r4, 100
or r4, r5, r5
bne .LBB_foo_2 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22639 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 23:44:42 +00:00
|
|
|
// Try to pull immediates out of the start value of nested addrec's.
|
2005-08-04 22:34:05 +00:00
|
|
|
SCEVHandle Start = SARE->getStart();
|
2009-02-21 02:06:47 +00:00
|
|
|
MoveImmediateValues(TLI, UseTy, Start, Imm, isAddress, L, SE);
|
2005-08-04 22:34:05 +00:00
|
|
|
|
|
|
|
if (Start != SARE->getStart()) {
|
|
|
|
std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
|
|
|
|
Ops[0] = Start;
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getAddRecExpr(Ops, SARE->getLoop());
|
2005-08-04 22:34:05 +00:00
|
|
|
}
|
|
|
|
return;
|
2009-04-18 17:56:28 +00:00
|
|
|
} else if (const SCEVMulExpr *SME = dyn_cast<SCEVMulExpr>(Val)) {
|
2006-02-04 07:36:50 +00:00
|
|
|
// Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the immed field.
|
2008-12-05 21:47:27 +00:00
|
|
|
if (isAddress && fitsInAddressMode(SME->getOperand(0), UseTy, TLI, false) &&
|
2006-02-04 07:36:50 +00:00
|
|
|
SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
|
|
|
|
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle SubImm = SE->getIntegerSCEV(0, Val->getType());
|
2006-02-04 07:36:50 +00:00
|
|
|
SCEVHandle NewOp = SME->getOperand(1);
|
2009-02-21 02:06:47 +00:00
|
|
|
MoveImmediateValues(TLI, UseTy, NewOp, SubImm, isAddress, L, SE);
|
2006-02-04 07:36:50 +00:00
|
|
|
|
|
|
|
// If we extracted something out of the subexpressions, see if we can
|
|
|
|
// simplify this!
|
|
|
|
if (NewOp != SME->getOperand(1)) {
|
|
|
|
// Scale SubImm up by "8". If the result is a target constant, we are
|
|
|
|
// good.
|
2007-10-22 18:31:58 +00:00
|
|
|
SubImm = SE->getMulExpr(SubImm, SME->getOperand(0));
|
2008-12-05 21:47:27 +00:00
|
|
|
if (fitsInAddressMode(SubImm, UseTy, TLI, false)) {
|
2006-02-04 07:36:50 +00:00
|
|
|
// Accumulate the immediate.
|
2007-10-22 18:31:58 +00:00
|
|
|
Imm = SE->getAddExpr(Imm, SubImm);
|
2006-02-04 07:36:50 +00:00
|
|
|
|
|
|
|
// Update what is left of 'Val'.
|
2007-10-22 18:31:58 +00:00
|
|
|
Val = SE->getMulExpr(SME->getOperand(0), NewOp);
|
2006-02-04 07:36:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
|
2005-08-04 22:34:05 +00:00
|
|
|
// Loop-variant expressions must stay in the immediate field of the
|
|
|
|
// expression.
|
2008-12-05 21:47:27 +00:00
|
|
|
if ((isAddress && fitsInAddressMode(Val, UseTy, TLI, false)) ||
|
2005-08-04 22:34:05 +00:00
|
|
|
!Val->isLoopInvariant(L)) {
|
2007-10-22 18:31:58 +00:00
|
|
|
Imm = SE->getAddExpr(Imm, Val);
|
|
|
|
Val = SE->getIntegerSCEV(0, Val->getType());
|
2005-08-04 22:34:05 +00:00
|
|
|
return;
|
2005-08-04 19:26:19 +00:00
|
|
|
}
|
2005-08-04 22:34:05 +00:00
|
|
|
|
|
|
|
// Otherwise, no immediates to move.
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
|
2009-02-21 02:06:47 +00:00
|
|
|
static void MoveImmediateValues(const TargetLowering *TLI,
|
|
|
|
Instruction *User,
|
|
|
|
SCEVHandle &Val, SCEVHandle &Imm,
|
|
|
|
bool isAddress, Loop *L,
|
|
|
|
ScalarEvolution *SE) {
|
2009-03-09 21:01:17 +00:00
|
|
|
const Type *UseTy = getAccessType(User);
|
2009-02-21 02:06:47 +00:00
|
|
|
MoveImmediateValues(TLI, UseTy, Val, Imm, isAddress, L, SE);
|
|
|
|
}
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
|
2006-08-03 06:34:50 +00:00
|
|
|
/// SeparateSubExprs - Decompose Expr into all of the subexpressions that are
|
|
|
|
/// added together. This is used to reassociate common addition subexprs
|
|
|
|
/// together for maximal sharing when rewriting bases.
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
static void SeparateSubExprs(std::vector<SCEVHandle> &SubExprs,
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle Expr,
|
|
|
|
ScalarEvolution *SE) {
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
|
2007-10-22 18:31:58 +00:00
|
|
|
SeparateSubExprs(SubExprs, AE->getOperand(j), SE);
|
2009-04-18 17:56:28 +00:00
|
|
|
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle Zero = SE->getIntegerSCEV(0, Expr->getType());
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
if (SARE->getOperand(0) == Zero) {
|
|
|
|
SubExprs.push_back(Expr);
|
|
|
|
} else {
|
|
|
|
// Compute the addrec with zero as its base.
|
|
|
|
std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
|
|
|
|
Ops[0] = Zero; // Start with zero base.
|
2007-10-22 18:31:58 +00:00
|
|
|
SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop()));
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
|
|
|
|
|
2007-10-22 18:31:58 +00:00
|
|
|
SeparateSubExprs(SubExprs, SARE->getOperand(0), SE);
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
}
|
2008-06-18 16:23:07 +00:00
|
|
|
} else if (!Expr->isZero()) {
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
// Do not add zero.
|
|
|
|
SubExprs.push_back(Expr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-05 21:47:27 +00:00
|
|
|
// This is logically local to the following function, but C++ says we have
|
|
|
|
// to make it file scope.
|
|
|
|
struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
|
2008-12-05 21:47:27 +00:00
|
|
|
/// RemoveCommonExpressionsFromUseBases - Look through all of the Bases of all
|
|
|
|
/// the Uses, removing any common subexpressions, except that if all such
|
|
|
|
/// subexpressions can be folded into an addressing mode for all uses inside
|
|
|
|
/// the loop (this case is referred to as "free" in comments herein) we do
|
|
|
|
/// not remove anything. This looks for things like (a+b+c) and
|
2008-12-02 04:52:26 +00:00
|
|
|
/// (a+c+d) and computes the common (a+c) subexpression. The common expression
|
|
|
|
/// is *removed* from the Bases and returned.
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
static SCEVHandle
|
2007-10-22 18:31:58 +00:00
|
|
|
RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
2008-12-05 21:47:27 +00:00
|
|
|
ScalarEvolution *SE, Loop *L,
|
|
|
|
const TargetLowering *TLI) {
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
unsigned NumUses = Uses.size();
|
|
|
|
|
2008-12-02 04:52:26 +00:00
|
|
|
// Only one use? This is a very common case, so we handle it specially and
|
|
|
|
// cheaply.
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
SCEVHandle Result = Zero;
|
2008-12-05 21:47:27 +00:00
|
|
|
SCEVHandle FreeResult = Zero;
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
if (NumUses == 1) {
|
2008-12-02 04:52:26 +00:00
|
|
|
// If the use is inside the loop, use its base, regardless of what it is:
|
|
|
|
// it is clearly shared across all the IV's. If the use is outside the loop
|
|
|
|
// (which means after it) we don't want to factor anything *into* the loop,
|
|
|
|
// so just use 0 as the base.
|
2008-12-01 22:00:01 +00:00
|
|
|
if (L->contains(Uses[0].Inst->getParent()))
|
|
|
|
std::swap(Result, Uses[0].Base);
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// To find common subexpressions, count how many of Uses use each expression.
|
|
|
|
// If any subexpressions are used Uses.size() times, they are common.
|
2008-12-05 21:47:27 +00:00
|
|
|
// Also track whether all uses of each expression can be moved into an
|
|
|
|
// an addressing mode "for free"; such expressions are left within the loop.
|
|
|
|
// struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
|
|
|
|
std::map<SCEVHandle, SubExprUseData> SubExpressionUseData;
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
|
2005-10-11 18:41:04 +00:00
|
|
|
// UniqueSubExprs - Keep track of all of the subexpressions we see in the
|
|
|
|
// order we see them.
|
|
|
|
std::vector<SCEVHandle> UniqueSubExprs;
|
|
|
|
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
std::vector<SCEVHandle> SubExprs;
|
2008-12-02 04:52:26 +00:00
|
|
|
unsigned NumUsesInsideLoop = 0;
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
for (unsigned i = 0; i != NumUses; ++i) {
|
2008-12-02 04:52:26 +00:00
|
|
|
// If the user is outside the loop, just ignore it for base computation.
|
|
|
|
// Since the user is outside the loop, it must be *after* the loop (if it
|
|
|
|
// were before, it could not be based on the loop IV). We don't want users
|
|
|
|
// after the loop to affect base computation of values *inside* the loop,
|
|
|
|
// because we can always add their offsets to the result IV after the loop
|
|
|
|
// is done, ensuring we get good code inside the loop.
|
2008-12-01 22:00:01 +00:00
|
|
|
if (!L->contains(Uses[i].Inst->getParent()))
|
|
|
|
continue;
|
|
|
|
NumUsesInsideLoop++;
|
|
|
|
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
// If the base is zero (which is common), return zero now, there are no
|
|
|
|
// CSEs we can find.
|
|
|
|
if (Uses[i].Base == Zero) return Zero;
|
|
|
|
|
2008-12-05 21:47:27 +00:00
|
|
|
// If this use is as an address we may be able to put CSEs in the addressing
|
|
|
|
// mode rather than hoisting them.
|
|
|
|
bool isAddrUse = isAddressUse(Uses[i].Inst, Uses[i].OperandValToReplace);
|
|
|
|
// We may need the UseTy below, but only when isAddrUse, so compute it
|
|
|
|
// only in that case.
|
|
|
|
const Type *UseTy = 0;
|
2009-03-09 21:01:17 +00:00
|
|
|
if (isAddrUse)
|
|
|
|
UseTy = getAccessType(Uses[i].Inst);
|
2008-12-05 21:47:27 +00:00
|
|
|
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
// Split the expression into subexprs.
|
2007-10-22 18:31:58 +00:00
|
|
|
SeparateSubExprs(SubExprs, Uses[i].Base, SE);
|
2008-12-05 21:47:27 +00:00
|
|
|
// Add one to SubExpressionUseData.Count for each subexpr present, and
|
|
|
|
// if the subexpr is not a valid immediate within an addressing mode use,
|
|
|
|
// set SubExpressionUseData.notAllUsesAreFree. We definitely want to
|
|
|
|
// hoist these out of the loop (if they are common to all uses).
|
|
|
|
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
|
|
|
|
if (++SubExpressionUseData[SubExprs[j]].Count == 1)
|
2005-10-11 18:41:04 +00:00
|
|
|
UniqueSubExprs.push_back(SubExprs[j]);
|
2008-12-05 21:47:27 +00:00
|
|
|
if (!isAddrUse || !fitsInAddressMode(SubExprs[j], UseTy, TLI, false))
|
|
|
|
SubExpressionUseData[SubExprs[j]].notAllUsesAreFree = true;
|
|
|
|
}
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
SubExprs.clear();
|
|
|
|
}
|
|
|
|
|
2005-10-11 18:41:04 +00:00
|
|
|
// Now that we know how many times each is used, build Result. Iterate over
|
|
|
|
// UniqueSubexprs so that we have a stable ordering.
|
|
|
|
for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) {
|
2008-12-05 21:47:27 +00:00
|
|
|
std::map<SCEVHandle, SubExprUseData>::iterator I =
|
|
|
|
SubExpressionUseData.find(UniqueSubExprs[i]);
|
|
|
|
assert(I != SubExpressionUseData.end() && "Entry not found?");
|
|
|
|
if (I->second.Count == NumUsesInsideLoop) { // Found CSE!
|
|
|
|
if (I->second.notAllUsesAreFree)
|
|
|
|
Result = SE->getAddExpr(Result, I->first);
|
|
|
|
else
|
|
|
|
FreeResult = SE->getAddExpr(FreeResult, I->first);
|
|
|
|
} else
|
|
|
|
// Remove non-cse's from SubExpressionUseData.
|
|
|
|
SubExpressionUseData.erase(I);
|
2005-10-11 18:41:04 +00:00
|
|
|
}
|
2008-12-05 21:47:27 +00:00
|
|
|
|
|
|
|
if (FreeResult != Zero) {
|
|
|
|
// We have some subexpressions that can be subsumed into addressing
|
|
|
|
// modes in every use inside the loop. However, it's possible that
|
|
|
|
// there are so many of them that the combined FreeResult cannot
|
|
|
|
// be subsumed, or that the target cannot handle both a FreeResult
|
|
|
|
// and a Result in the same instruction (for example because it would
|
|
|
|
// require too many registers). Check this.
|
|
|
|
for (unsigned i=0; i<NumUses; ++i) {
|
|
|
|
if (!L->contains(Uses[i].Inst->getParent()))
|
|
|
|
continue;
|
|
|
|
// We know this is an addressing mode use; if there are any uses that
|
|
|
|
// are not, FreeResult would be Zero.
|
2009-03-09 21:01:17 +00:00
|
|
|
const Type *UseTy = getAccessType(Uses[i].Inst);
|
2008-12-05 21:47:27 +00:00
|
|
|
if (!fitsInAddressMode(FreeResult, UseTy, TLI, Result!=Zero)) {
|
|
|
|
// FIXME: could split up FreeResult into pieces here, some hoisted
|
2008-12-16 22:16:28 +00:00
|
|
|
// and some not. There is no obvious advantage to this.
|
2008-12-05 21:47:27 +00:00
|
|
|
Result = SE->getAddExpr(Result, FreeResult);
|
|
|
|
FreeResult = Zero;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// If we found no CSE's, return now.
|
|
|
|
if (Result == Zero) return Result;
|
|
|
|
|
2008-12-05 21:47:27 +00:00
|
|
|
// If we still have a FreeResult, remove its subexpressions from
|
|
|
|
// SubExpressionUseData. This means they will remain in the use Bases.
|
|
|
|
if (FreeResult != Zero) {
|
|
|
|
SeparateSubExprs(SubExprs, FreeResult, SE);
|
|
|
|
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
|
|
|
|
std::map<SCEVHandle, SubExprUseData>::iterator I =
|
|
|
|
SubExpressionUseData.find(SubExprs[j]);
|
|
|
|
SubExpressionUseData.erase(I);
|
|
|
|
}
|
|
|
|
SubExprs.clear();
|
|
|
|
}
|
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// Otherwise, remove all of the CSE's we found from each of the base values.
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
for (unsigned i = 0; i != NumUses; ++i) {
|
2008-12-02 21:17:11 +00:00
|
|
|
// Uses outside the loop don't necessarily include the common base, but
|
|
|
|
// the final IV value coming into those uses does. Instead of trying to
|
|
|
|
// remove the pieces of the common base, which might not be there,
|
|
|
|
// subtract off the base to compensate for this.
|
|
|
|
if (!L->contains(Uses[i].Inst->getParent())) {
|
|
|
|
Uses[i].Base = SE->getMinusSCEV(Uses[i].Base, Result);
|
2008-12-01 22:00:01 +00:00
|
|
|
continue;
|
2008-12-02 21:17:11 +00:00
|
|
|
}
|
2008-12-01 22:00:01 +00:00
|
|
|
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
// Split the expression into subexprs.
|
2007-10-22 18:31:58 +00:00
|
|
|
SeparateSubExprs(SubExprs, Uses[i].Base, SE);
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
|
|
|
|
// Remove any common subexpressions.
|
|
|
|
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
|
2008-12-05 21:47:27 +00:00
|
|
|
if (SubExpressionUseData.count(SubExprs[j])) {
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
SubExprs.erase(SubExprs.begin()+j);
|
|
|
|
--j; --e;
|
|
|
|
}
|
|
|
|
|
2008-12-02 04:52:26 +00:00
|
|
|
// Finally, add the non-shared expressions together.
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
if (SubExprs.empty())
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
Uses[i].Base = Zero;
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
else
|
2007-10-22 18:31:58 +00:00
|
|
|
Uses[i].Base = SE->getAddExpr(SubExprs);
|
Ooops, don't forget to clear this. The real inner loop is now:
.LBB_foo_3: ; no_exit.1
lfd f2, 0(r9)
lfd f3, 8(r9)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r9)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfd f2, 0(r9)
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22782 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:42:01 +00:00
|
|
|
SubExprs.clear();
|
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that
these two expressions:
{( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1>
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
Have the following common part that can be shared:
{(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1>
This allows us to codegen an important inner loop in 168.wupwise as:
.LBB_foo_4: ; no_exit.1
lfd f2, 16(r9)
fmul f3, f0, f2
fmul f2, f1, f2
fadd f4, f3, f2
stfd f4, 8(r9)
fsub f2, f3, f2
stfd f2, 16(r9)
addi r8, r8, 1
addi r9, r9, 16
cmpw cr0, r8, r4
ble .LBB_foo_4 ; no_exit.1
instead of:
.LBB_foo_3: ; no_exit.1
lfdx f2, r6, r9
add r10, r6, r9
lfd f3, 8(r10)
fmul f4, f1, f2
fmadd f4, f0, f3, f4
stfd f4, 8(r10)
fmul f3, f1, f3
fmsub f2, f0, f2, f3
stfdx f2, r6, r9
addi r9, r9, 16
addi r8, r8, 1
cmpw cr0, r8, r4
ble .LBB_foo_3 ; no_exit.1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22781 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-13 07:27:18 +00:00
|
|
|
}
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2007-03-20 00:47:50 +00:00
|
|
|
/// ValidStride - Check whether the given Scale is valid for all loads and
|
2007-04-09 22:20:14 +00:00
|
|
|
/// stores in UsersToProcess.
|
2007-03-20 00:47:50 +00:00
|
|
|
///
|
2007-10-22 20:40:42 +00:00
|
|
|
bool LoopStrengthReduce::ValidStride(bool HasBaseReg,
|
|
|
|
int64_t Scale,
|
2007-03-20 00:47:50 +00:00
|
|
|
const std::vector<BasedUser>& UsersToProcess) {
|
2007-12-19 23:33:23 +00:00
|
|
|
if (!TLI)
|
|
|
|
return true;
|
|
|
|
|
2007-03-20 21:54:54 +00:00
|
|
|
for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) {
|
Pass the type of the store access, not the type of the store, into the
target hook. This allows us to codegen a loop as:
LBB1_1: @cond_next
mov r2, #0
str r2, [r0, +r3, lsl #2]
add r3, r3, #1
cmn r3, #1
bne LBB1_1 @cond_next
instead of:
LBB1_1: @cond_next
mov r2, #0
str r2, [r0], #+4
add r3, r3, #1
cmn r3, #1
bne LBB1_1 @cond_next
This looks the same, but has one fewer induction variable (and therefore,
one fewer register) live in the loop.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35592 91177308-0d34-0410-b5e6-96231b3b80d8
2007-04-02 06:34:44 +00:00
|
|
|
// If this is a load or other access, pass the type of the access in.
|
|
|
|
const Type *AccessTy = Type::VoidTy;
|
2009-03-09 21:01:17 +00:00
|
|
|
if (isAddressUse(UsersToProcess[i].Inst,
|
|
|
|
UsersToProcess[i].OperandValToReplace))
|
|
|
|
AccessTy = getAccessType(UsersToProcess[i].Inst);
|
2008-03-19 22:02:26 +00:00
|
|
|
else if (isa<PHINode>(UsersToProcess[i].Inst))
|
|
|
|
continue;
|
Pass the type of the store access, not the type of the store, into the
target hook. This allows us to codegen a loop as:
LBB1_1: @cond_next
mov r2, #0
str r2, [r0, +r3, lsl #2]
add r3, r3, #1
cmn r3, #1
bne LBB1_1 @cond_next
instead of:
LBB1_1: @cond_next
mov r2, #0
str r2, [r0], #+4
add r3, r3, #1
cmn r3, #1
bne LBB1_1 @cond_next
This looks the same, but has one fewer induction variable (and therefore,
one fewer register) live in the loop.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35592 91177308-0d34-0410-b5e6-96231b3b80d8
2007-04-02 06:34:44 +00:00
|
|
|
|
2007-04-09 22:20:14 +00:00
|
|
|
TargetLowering::AddrMode AM;
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
|
2007-04-09 22:20:14 +00:00
|
|
|
AM.BaseOffs = SC->getValue()->getSExtValue();
|
2008-06-18 16:23:07 +00:00
|
|
|
AM.HasBaseReg = HasBaseReg || !UsersToProcess[i].Base->isZero();
|
2007-04-09 22:20:14 +00:00
|
|
|
AM.Scale = Scale;
|
|
|
|
|
|
|
|
// If load[imm+r*scale] is illegal, bail out.
|
2007-12-19 23:33:23 +00:00
|
|
|
if (!TLI->isLegalAddressingMode(AM, AccessTy))
|
2007-03-20 00:47:50 +00:00
|
|
|
return false;
|
2007-03-20 21:54:54 +00:00
|
|
|
}
|
2007-03-20 00:47:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
|
2009-02-09 22:14:15 +00:00
|
|
|
/// RequiresTypeConversion - Returns true if converting Ty1 to Ty2 is not
|
2007-10-25 22:45:20 +00:00
|
|
|
/// a nop.
|
Loosen up iv reuse to allow reuse of the same stride but a larger type when truncating from the larger type to smaller type is free.
e.g.
Turns this loop:
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
movw %dx, %si
LBB1_2: # bb
movl L_X$non_lazy_ptr, %edi
movw %si, (%edi)
movl L_Y$non_lazy_ptr, %edi
movw %dx, (%edi)
addw $4, %dx
incw %si
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
into
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
LBB1_2: # bb
movl L_X$non_lazy_ptr, %esi
movw %cx, (%esi)
movl L_Y$non_lazy_ptr, %esi
movw %dx, (%esi)
addw $4, %dx
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43375 91177308-0d34-0410-b5e6-96231b3b80d8
2007-10-26 01:56:11 +00:00
|
|
|
bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1,
|
|
|
|
const Type *Ty2) {
|
|
|
|
if (Ty1 == Ty2)
|
2007-10-25 22:45:20 +00:00
|
|
|
return false;
|
2009-05-01 17:07:43 +00:00
|
|
|
Ty1 = SE->getEffectiveSCEVType(Ty1);
|
|
|
|
Ty2 = SE->getEffectiveSCEVType(Ty2);
|
|
|
|
if (Ty1 == Ty2)
|
2009-04-21 01:07:12 +00:00
|
|
|
return false;
|
2009-02-09 22:14:15 +00:00
|
|
|
if (Ty1->canLosslesslyBitCastTo(Ty2))
|
|
|
|
return false;
|
Loosen up iv reuse to allow reuse of the same stride but a larger type when truncating from the larger type to smaller type is free.
e.g.
Turns this loop:
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
movw %dx, %si
LBB1_2: # bb
movl L_X$non_lazy_ptr, %edi
movw %si, (%edi)
movl L_Y$non_lazy_ptr, %edi
movw %dx, (%edi)
addw $4, %dx
incw %si
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
into
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
LBB1_2: # bb
movl L_X$non_lazy_ptr, %esi
movw %cx, (%esi)
movl L_Y$non_lazy_ptr, %esi
movw %dx, (%esi)
addw $4, %dx
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43375 91177308-0d34-0410-b5e6-96231b3b80d8
2007-10-26 01:56:11 +00:00
|
|
|
if (TLI && TLI->isTruncateFree(Ty1, Ty2))
|
|
|
|
return false;
|
2009-02-09 22:14:15 +00:00
|
|
|
return true;
|
2007-10-25 22:45:20 +00:00
|
|
|
}
|
|
|
|
|
2006-03-17 19:52:23 +00:00
|
|
|
/// CheckForIVReuse - Returns the multiple if the stride is the multiple
|
|
|
|
/// of a previous stride and it is a legal value for the target addressing
|
2007-10-22 20:40:42 +00:00
|
|
|
/// mode scale component and optional base reg. This allows the users of
|
|
|
|
/// this stride to be rewritten as prev iv * factor. It returns 0 if no
|
2008-12-16 22:16:28 +00:00
|
|
|
/// reuse is possible. Factors can be negative on same targets, e.g. ARM.
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
///
|
|
|
|
/// If all uses are outside the loop, we don't require that all multiplies
|
|
|
|
/// be folded into the addressing mode, nor even that the factor be constant;
|
|
|
|
/// a multiply (executed once) outside the loop is better than another IV
|
|
|
|
/// within. Well, usually.
|
|
|
|
SCEVHandle LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
Loosen up iv reuse to allow reuse of the same stride but a larger type when truncating from the larger type to smaller type is free.
e.g.
Turns this loop:
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
movw %dx, %si
LBB1_2: # bb
movl L_X$non_lazy_ptr, %edi
movw %si, (%edi)
movl L_Y$non_lazy_ptr, %edi
movw %dx, (%edi)
addw $4, %dx
incw %si
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
into
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
LBB1_2: # bb
movl L_X$non_lazy_ptr, %esi
movw %cx, (%esi)
movl L_Y$non_lazy_ptr, %esi
movw %dx, (%esi)
addw $4, %dx
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43375 91177308-0d34-0410-b5e6-96231b3b80d8
2007-10-26 01:56:11 +00:00
|
|
|
bool AllUsesAreAddresses,
|
2008-12-16 22:16:28 +00:00
|
|
|
bool AllUsesAreOutsideLoop,
|
2007-10-22 20:40:42 +00:00
|
|
|
const SCEVHandle &Stride,
|
2007-03-20 00:47:50 +00:00
|
|
|
IVExpr &IV, const Type *Ty,
|
|
|
|
const std::vector<BasedUser>& UsersToProcess) {
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Stride)) {
|
2007-03-02 23:37:53 +00:00
|
|
|
int64_t SInt = SC->getValue()->getSExtValue();
|
2007-11-17 02:48:01 +00:00
|
|
|
for (unsigned NewStride = 0, e = StrideOrder.size(); NewStride != e;
|
|
|
|
++NewStride) {
|
|
|
|
std::map<SCEVHandle, IVsOfOneStride>::iterator SI =
|
|
|
|
IVsByStride.find(StrideOrder[NewStride]);
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
|
2007-11-17 02:48:01 +00:00
|
|
|
continue;
|
2007-03-12 23:27:37 +00:00
|
|
|
int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
|
Loosen up iv reuse to allow reuse of the same stride but a larger type when truncating from the larger type to smaller type is free.
e.g.
Turns this loop:
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
movw %dx, %si
LBB1_2: # bb
movl L_X$non_lazy_ptr, %edi
movw %si, (%edi)
movl L_Y$non_lazy_ptr, %edi
movw %dx, (%edi)
addw $4, %dx
incw %si
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
into
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
LBB1_2: # bb
movl L_X$non_lazy_ptr, %esi
movw %cx, (%esi)
movl L_Y$non_lazy_ptr, %esi
movw %dx, (%esi)
addw $4, %dx
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43375 91177308-0d34-0410-b5e6-96231b3b80d8
2007-10-26 01:56:11 +00:00
|
|
|
if (SI->first != Stride &&
|
2007-04-02 22:51:58 +00:00
|
|
|
(unsigned(abs(SInt)) < SSInt || (SInt % SSInt) != 0))
|
2006-03-17 19:52:23 +00:00
|
|
|
continue;
|
2007-03-12 23:27:37 +00:00
|
|
|
int64_t Scale = SInt / SSInt;
|
2007-03-20 00:47:50 +00:00
|
|
|
// Check that this stride is valid for all the types used for loads and
|
|
|
|
// stores; if it can be used for some and not others, we might as well use
|
|
|
|
// the original stride everywhere, since we have to create the IV for it
|
2007-10-29 19:23:53 +00:00
|
|
|
// anyway. If the scale is 1, then we don't need to worry about folding
|
|
|
|
// multiplications.
|
|
|
|
if (Scale == 1 ||
|
|
|
|
(AllUsesAreAddresses &&
|
|
|
|
ValidStride(HasBaseReg, Scale, UsersToProcess)))
|
2007-03-12 23:27:37 +00:00
|
|
|
for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
|
|
|
|
IE = SI->second.IVs.end(); II != IE; ++II)
|
|
|
|
// FIXME: Only handle base == 0 for now.
|
|
|
|
// Only reuse previous IV if it would not require a type conversion.
|
2008-06-18 16:23:07 +00:00
|
|
|
if (II->Base->isZero() &&
|
Loosen up iv reuse to allow reuse of the same stride but a larger type when truncating from the larger type to smaller type is free.
e.g.
Turns this loop:
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
movw %dx, %si
LBB1_2: # bb
movl L_X$non_lazy_ptr, %edi
movw %si, (%edi)
movl L_Y$non_lazy_ptr, %edi
movw %dx, (%edi)
addw $4, %dx
incw %si
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
into
LBB1_1: # entry.bb_crit_edge
xorl %ecx, %ecx
xorw %dx, %dx
LBB1_2: # bb
movl L_X$non_lazy_ptr, %esi
movw %cx, (%esi)
movl L_Y$non_lazy_ptr, %esi
movw %dx, (%esi)
addw $4, %dx
incl %ecx
cmpl %eax, %ecx
jne LBB1_2 # bb
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43375 91177308-0d34-0410-b5e6-96231b3b80d8
2007-10-26 01:56:11 +00:00
|
|
|
!RequiresTypeConversion(II->Base->getType(), Ty)) {
|
2007-03-12 23:27:37 +00:00
|
|
|
IV = *II;
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
return SE->getIntegerSCEV(Scale, Stride->getType());
|
2007-03-12 23:27:37 +00:00
|
|
|
}
|
2006-03-17 19:52:23 +00:00
|
|
|
}
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
} else if (AllUsesAreOutsideLoop) {
|
|
|
|
// Accept nonconstant strides here; it is really really right to substitute
|
|
|
|
// an existing IV if we can.
|
|
|
|
for (unsigned NewStride = 0, e = StrideOrder.size(); NewStride != e;
|
|
|
|
++NewStride) {
|
|
|
|
std::map<SCEVHandle, IVsOfOneStride>::iterator SI =
|
|
|
|
IVsByStride.find(StrideOrder[NewStride]);
|
|
|
|
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
|
|
|
|
continue;
|
|
|
|
int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
|
|
|
|
if (SI->first != Stride && SSInt != 1)
|
|
|
|
continue;
|
|
|
|
for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
|
|
|
|
IE = SI->second.IVs.end(); II != IE; ++II)
|
|
|
|
// Accept nonzero base here.
|
|
|
|
// Only reuse previous IV if it would not require a type conversion.
|
|
|
|
if (!RequiresTypeConversion(II->Base->getType(), Ty)) {
|
|
|
|
IV = *II;
|
|
|
|
return Stride;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Special case, old IV is -1*x and this one is x. Can treat this one as
|
|
|
|
// -1*old.
|
|
|
|
for (unsigned NewStride = 0, e = StrideOrder.size(); NewStride != e;
|
|
|
|
++NewStride) {
|
|
|
|
std::map<SCEVHandle, IVsOfOneStride>::iterator SI =
|
|
|
|
IVsByStride.find(StrideOrder[NewStride]);
|
|
|
|
if (SI == IVsByStride.end())
|
|
|
|
continue;
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVMulExpr *ME = dyn_cast<SCEVMulExpr>(SI->first))
|
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(ME->getOperand(0)))
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
if (Stride == ME->getOperand(1) &&
|
|
|
|
SC->getValue()->getSExtValue() == -1LL)
|
|
|
|
for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
|
|
|
|
IE = SI->second.IVs.end(); II != IE; ++II)
|
|
|
|
// Accept nonzero base here.
|
|
|
|
// Only reuse previous IV if it would not require type conversion.
|
|
|
|
if (!RequiresTypeConversion(II->Base->getType(), Ty)) {
|
|
|
|
IV = *II;
|
|
|
|
return SE->getIntegerSCEV(-1LL, Stride->getType());
|
|
|
|
}
|
|
|
|
}
|
2006-03-17 19:52:23 +00:00
|
|
|
}
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
return SE->getIntegerSCEV(0, Stride->getType());
|
2006-03-17 19:52:23 +00:00
|
|
|
}
|
|
|
|
|
2006-08-03 06:34:50 +00:00
|
|
|
/// PartitionByIsUseOfPostIncrementedValue - Simple boolean predicate that
|
|
|
|
/// returns true if Val's isUseOfPostIncrementedValue is true.
|
|
|
|
static bool PartitionByIsUseOfPostIncrementedValue(const BasedUser &Val) {
|
|
|
|
return Val.isUseOfPostIncrementedValue;
|
|
|
|
}
|
2006-03-17 19:52:23 +00:00
|
|
|
|
2008-04-14 18:26:16 +00:00
|
|
|
/// isNonConstantNegative - Return true if the specified scev is negated, but
|
Handle negative strides much more optimally. This compiles X86/lsr-negative-stride.ll
into:
_t:
movl 8(%esp), %ecx
movl 4(%esp), %eax
cmpl %ecx, %eax
je LBB1_3 #bb17
LBB1_1: #bb
cmpl %ecx, %eax
jg LBB1_4 #cond_true
LBB1_2: #cond_false
subl %eax, %ecx
cmpl %ecx, %eax
jne LBB1_1 #bb
LBB1_3: #bb17
ret
LBB1_4: #cond_true
subl %ecx, %eax
cmpl %ecx, %eax
jne LBB1_1 #bb
jmp LBB1_3 #bb17
instead of:
_t:
subl $4, %esp
movl %esi, (%esp)
movl 12(%esp), %ecx
movl 8(%esp), %eax
cmpl %ecx, %eax
je LBB1_4 #bb17
LBB1_1: #bb.outer
movl %ecx, %edx
negl %edx
LBB1_2: #bb
cmpl %ecx, %eax
jle LBB1_5 #cond_false
LBB1_3: #cond_true
addl %edx, %eax
cmpl %ecx, %eax
jne LBB1_2 #bb
LBB1_4: #bb17
movl (%esp), %esi
addl $4, %esp
ret
LBB1_5: #cond_false
movl %ecx, %edx
subl %eax, %edx
movl %eax, %esi
addl %esi, %esi
cmpl %ecx, %esi
je LBB1_4 #bb17
LBB1_6: #cond_false.bb.outer_crit_edge
movl %edx, %ecx
jmp LBB1_1 #bb.outer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37252 91177308-0d34-0410-b5e6-96231b3b80d8
2007-05-19 01:22:21 +00:00
|
|
|
/// not a constant.
|
|
|
|
static bool isNonConstantNegative(const SCEVHandle &Expr) {
|
2009-04-18 17:56:28 +00:00
|
|
|
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Expr);
|
Handle negative strides much more optimally. This compiles X86/lsr-negative-stride.ll
into:
_t:
movl 8(%esp), %ecx
movl 4(%esp), %eax
cmpl %ecx, %eax
je LBB1_3 #bb17
LBB1_1: #bb
cmpl %ecx, %eax
jg LBB1_4 #cond_true
LBB1_2: #cond_false
subl %eax, %ecx
cmpl %ecx, %eax
jne LBB1_1 #bb
LBB1_3: #bb17
ret
LBB1_4: #cond_true
subl %ecx, %eax
cmpl %ecx, %eax
jne LBB1_1 #bb
jmp LBB1_3 #bb17
instead of:
_t:
subl $4, %esp
movl %esi, (%esp)
movl 12(%esp), %ecx
movl 8(%esp), %eax
cmpl %ecx, %eax
je LBB1_4 #bb17
LBB1_1: #bb.outer
movl %ecx, %edx
negl %edx
LBB1_2: #bb
cmpl %ecx, %eax
jle LBB1_5 #cond_false
LBB1_3: #cond_true
addl %edx, %eax
cmpl %ecx, %eax
jne LBB1_2 #bb
LBB1_4: #bb17
movl (%esp), %esi
addl $4, %esp
ret
LBB1_5: #cond_false
movl %ecx, %edx
subl %eax, %edx
movl %eax, %esi
addl %esi, %esi
cmpl %ecx, %esi
je LBB1_4 #bb17
LBB1_6: #cond_false.bb.outer_crit_edge
movl %edx, %ecx
jmp LBB1_1 #bb.outer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37252 91177308-0d34-0410-b5e6-96231b3b80d8
2007-05-19 01:22:21 +00:00
|
|
|
if (!Mul) return false;
|
|
|
|
|
|
|
|
// If there is a constant factor, it will be first.
|
2009-04-18 17:56:28 +00:00
|
|
|
const SCEVConstant *SC = dyn_cast<SCEVConstant>(Mul->getOperand(0));
|
Handle negative strides much more optimally. This compiles X86/lsr-negative-stride.ll
into:
_t:
movl 8(%esp), %ecx
movl 4(%esp), %eax
cmpl %ecx, %eax
je LBB1_3 #bb17
LBB1_1: #bb
cmpl %ecx, %eax
jg LBB1_4 #cond_true
LBB1_2: #cond_false
subl %eax, %ecx
cmpl %ecx, %eax
jne LBB1_1 #bb
LBB1_3: #bb17
ret
LBB1_4: #cond_true
subl %ecx, %eax
cmpl %ecx, %eax
jne LBB1_1 #bb
jmp LBB1_3 #bb17
instead of:
_t:
subl $4, %esp
movl %esi, (%esp)
movl 12(%esp), %ecx
movl 8(%esp), %eax
cmpl %ecx, %eax
je LBB1_4 #bb17
LBB1_1: #bb.outer
movl %ecx, %edx
negl %edx
LBB1_2: #bb
cmpl %ecx, %eax
jle LBB1_5 #cond_false
LBB1_3: #cond_true
addl %edx, %eax
cmpl %ecx, %eax
jne LBB1_2 #bb
LBB1_4: #bb17
movl (%esp), %esi
addl $4, %esp
ret
LBB1_5: #cond_false
movl %ecx, %edx
subl %eax, %edx
movl %eax, %esi
addl %esi, %esi
cmpl %ecx, %esi
je LBB1_4 #bb17
LBB1_6: #cond_false.bb.outer_crit_edge
movl %edx, %ecx
jmp LBB1_1 #bb.outer
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37252 91177308-0d34-0410-b5e6-96231b3b80d8
2007-05-19 01:22:21 +00:00
|
|
|
if (!SC) return false;
|
|
|
|
|
|
|
|
// Return true if the value is negative, this matches things like (-42 * V).
|
|
|
|
return SC->getValue()->getValue().isNegative();
|
|
|
|
}
|
|
|
|
|
2007-10-25 22:45:20 +00:00
|
|
|
// CollectIVUsers - Transform our list of users and offsets to a bit more
|
2008-06-23 22:11:52 +00:00
|
|
|
// complex table. In this new vector, each 'BasedUser' contains 'Base', the base
|
|
|
|
// of the strided accesses, as well as the old information from Uses. We
|
2007-10-25 22:45:20 +00:00
|
|
|
// progressively move information from the Base field to the Imm field, until
|
|
|
|
// we eventually have the full access expression to rewrite the use.
|
|
|
|
SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
|
|
|
IVUsersOfOneStride &Uses,
|
|
|
|
Loop *L,
|
|
|
|
bool &AllUsesAreAddresses,
|
2008-12-16 22:16:28 +00:00
|
|
|
bool &AllUsesAreOutsideLoop,
|
2007-10-25 22:45:20 +00:00
|
|
|
std::vector<BasedUser> &UsersToProcess) {
|
2005-07-30 00:15:07 +00:00
|
|
|
UsersToProcess.reserve(Uses.Users.size());
|
2005-08-08 22:56:21 +00:00
|
|
|
for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) {
|
2007-10-22 18:31:58 +00:00
|
|
|
UsersToProcess.push_back(BasedUser(Uses.Users[i], SE));
|
2005-08-08 22:56:21 +00:00
|
|
|
|
2008-12-03 19:25:46 +00:00
|
|
|
// Move any loop variant operands from the offset field to the immediate
|
2005-08-08 22:56:21 +00:00
|
|
|
// field of the use, so that we don't try to use something before it is
|
|
|
|
// computed.
|
2008-12-03 20:56:12 +00:00
|
|
|
MoveLoopVariantsToImmediateField(UsersToProcess.back().Base,
|
2007-10-22 18:31:58 +00:00
|
|
|
UsersToProcess.back().Imm, L, SE);
|
2005-08-08 22:56:21 +00:00
|
|
|
assert(UsersToProcess.back().Base->isLoopInvariant(L) &&
|
2005-08-04 22:34:05 +00:00
|
|
|
"Base value is not loop invariant!");
|
2005-03-06 21:58:22 +00:00
|
|
|
}
|
2006-03-17 19:52:23 +00:00
|
|
|
|
2006-07-18 19:07:58 +00:00
|
|
|
// We now have a whole bunch of uses of like-strided induction variables, but
|
|
|
|
// they might all have different bases. We want to emit one PHI node for this
|
|
|
|
// stride which we fold as many common expressions (between the IVs) into as
|
|
|
|
// possible. Start by identifying the common expressions in the base values
|
|
|
|
// for the strides (e.g. if we have "A+C+B" and "A+B+D" as our bases, find
|
|
|
|
// "A+B"), emit it to the preheader, then remove the expression from the
|
|
|
|
// UsersToProcess base values.
|
|
|
|
SCEVHandle CommonExprs =
|
2008-12-05 21:47:27 +00:00
|
|
|
RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI);
|
2007-10-22 20:40:42 +00:00
|
|
|
|
2005-08-08 22:32:34 +00:00
|
|
|
// Next, figure out what we can represent in the immediate fields of
|
|
|
|
// instructions. If we can represent anything there, move it to the imm
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// fields of the BasedUsers. We do this so that it increases the commonality
|
|
|
|
// of the remaining uses.
|
2007-12-20 02:20:53 +00:00
|
|
|
unsigned NumPHI = 0;
|
2009-02-20 22:16:49 +00:00
|
|
|
bool HasAddress = false;
|
2005-08-08 22:32:34 +00:00
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
|
2005-08-16 00:38:11 +00:00
|
|
|
// If the user is not in the current loop, this means it is using the exit
|
|
|
|
// value of the IV. Do not put anything in the base, make sure it's all in
|
|
|
|
// the immediate field to allow as much factoring as possible.
|
|
|
|
if (!L->contains(UsersToProcess[i].Inst->getParent())) {
|
2007-10-22 18:31:58 +00:00
|
|
|
UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm,
|
|
|
|
UsersToProcess[i].Base);
|
2005-08-17 21:22:41 +00:00
|
|
|
UsersToProcess[i].Base =
|
2007-10-22 18:31:58 +00:00
|
|
|
SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType());
|
2005-08-16 00:38:11 +00:00
|
|
|
} else {
|
2009-02-21 02:06:47 +00:00
|
|
|
// Not all uses are outside the loop.
|
|
|
|
AllUsesAreOutsideLoop = false;
|
|
|
|
|
2005-08-16 00:38:11 +00:00
|
|
|
// Addressing modes can be folded into loads and stores. Be careful that
|
|
|
|
// the store is through the expression, not of the expression though.
|
2007-12-20 02:20:53 +00:00
|
|
|
bool isPHI = false;
|
2007-12-19 23:33:23 +00:00
|
|
|
bool isAddress = isAddressUse(UsersToProcess[i].Inst,
|
|
|
|
UsersToProcess[i].OperandValToReplace);
|
|
|
|
if (isa<PHINode>(UsersToProcess[i].Inst)) {
|
2007-12-20 02:20:53 +00:00
|
|
|
isPHI = true;
|
|
|
|
++NumPHI;
|
2007-05-03 23:20:33 +00:00
|
|
|
}
|
2007-10-22 20:40:42 +00:00
|
|
|
|
2009-02-20 22:16:49 +00:00
|
|
|
if (isAddress)
|
|
|
|
HasAddress = true;
|
2008-12-16 22:16:28 +00:00
|
|
|
|
2007-10-22 20:40:42 +00:00
|
|
|
// If this use isn't an address, then not all uses are addresses.
|
2008-03-19 22:02:26 +00:00
|
|
|
if (!isAddress && !isPHI)
|
2007-10-22 20:40:42 +00:00
|
|
|
AllUsesAreAddresses = false;
|
2005-08-16 00:38:11 +00:00
|
|
|
|
2007-03-13 20:34:37 +00:00
|
|
|
MoveImmediateValues(TLI, UsersToProcess[i].Inst, UsersToProcess[i].Base,
|
2007-10-22 18:31:58 +00:00
|
|
|
UsersToProcess[i].Imm, isAddress, L, SE);
|
2005-08-16 00:38:11 +00:00
|
|
|
}
|
2005-08-08 22:32:34 +00:00
|
|
|
}
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2009-02-21 02:06:47 +00:00
|
|
|
// If one of the use is a PHI node and all other uses are addresses, still
|
2007-12-20 02:20:53 +00:00
|
|
|
// allow iv reuse. Essentially we are trading one constant multiplication
|
|
|
|
// for one fewer iv.
|
|
|
|
if (NumPHI > 1)
|
|
|
|
AllUsesAreAddresses = false;
|
2009-02-21 02:06:47 +00:00
|
|
|
|
2009-02-20 22:16:49 +00:00
|
|
|
// There are no in-loop address uses.
|
|
|
|
if (AllUsesAreAddresses && (!HasAddress && !AllUsesAreOutsideLoop))
|
|
|
|
AllUsesAreAddresses = false;
|
2007-12-20 02:20:53 +00:00
|
|
|
|
2007-10-25 22:45:20 +00:00
|
|
|
return CommonExprs;
|
|
|
|
}
|
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
/// ShouldUseFullStrengthReductionMode - Test whether full strength-reduction
|
|
|
|
/// is valid and profitable for the given set of users of a stride. In
|
|
|
|
/// full strength-reduction mode, all addresses at the current stride are
|
|
|
|
/// strength-reduced all the way down to pointer arithmetic.
|
|
|
|
///
|
|
|
|
bool LoopStrengthReduce::ShouldUseFullStrengthReductionMode(
|
|
|
|
const std::vector<BasedUser> &UsersToProcess,
|
|
|
|
const Loop *L,
|
|
|
|
bool AllUsesAreAddresses,
|
|
|
|
SCEVHandle Stride) {
|
|
|
|
if (!EnableFullLSRMode)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// The heuristics below aim to avoid increasing register pressure, but
|
|
|
|
// fully strength-reducing all the addresses increases the number of
|
|
|
|
// add instructions, so don't do this when optimizing for size.
|
|
|
|
// TODO: If the loop is large, the savings due to simpler addresses
|
|
|
|
// may oughtweight the costs of the extra increment instructions.
|
|
|
|
if (L->getHeader()->getParent()->hasFnAttr(Attribute::OptimizeForSize))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// TODO: For now, don't do full strength reduction if there could
|
|
|
|
// potentially be greater-stride multiples of the current stride
|
|
|
|
// which could reuse the current stride IV.
|
|
|
|
if (StrideOrder.back() != Stride)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Iterate through the uses to find conditions that automatically rule out
|
|
|
|
// full-lsr mode.
|
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) {
|
2009-05-04 22:02:23 +00:00
|
|
|
const SCEV *Base = UsersToProcess[i].Base;
|
|
|
|
const SCEV *Imm = UsersToProcess[i].Imm;
|
2009-02-20 04:17:46 +00:00
|
|
|
// If any users have a loop-variant component, they can't be fully
|
|
|
|
// strength-reduced.
|
|
|
|
if (Imm && !Imm->isLoopInvariant(L))
|
|
|
|
return false;
|
|
|
|
// If there are to users with the same base and the difference between
|
|
|
|
// the two Imm values can't be folded into the address, full
|
|
|
|
// strength reduction would increase register pressure.
|
|
|
|
do {
|
2009-05-04 22:02:23 +00:00
|
|
|
const SCEV *CurImm = UsersToProcess[i].Imm;
|
2009-02-22 16:40:52 +00:00
|
|
|
if ((CurImm || Imm) && CurImm != Imm) {
|
2009-02-20 04:17:46 +00:00
|
|
|
if (!CurImm) CurImm = SE->getIntegerSCEV(0, Stride->getType());
|
|
|
|
if (!Imm) Imm = SE->getIntegerSCEV(0, Stride->getType());
|
|
|
|
const Instruction *Inst = UsersToProcess[i].Inst;
|
2009-03-09 21:01:17 +00:00
|
|
|
const Type *UseTy = getAccessType(Inst);
|
2009-02-20 04:17:46 +00:00
|
|
|
SCEVHandle Diff = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
|
|
|
|
if (!Diff->isZero() &&
|
|
|
|
(!AllUsesAreAddresses ||
|
|
|
|
!fitsInAddressMode(Diff, UseTy, TLI, /*HasBaseReg=*/true)))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} while (++i != e && Base == UsersToProcess[i].Base);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there's exactly one user in this stride, fully strength-reducing it
|
|
|
|
// won't increase register pressure. If it's starting from a non-zero base,
|
|
|
|
// it'll be simpler this way.
|
|
|
|
if (UsersToProcess.size() == 1 && !UsersToProcess[0].Base->isZero())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Otherwise, if there are any users in this stride that don't require
|
|
|
|
// a register for their base, full strength-reduction will increase
|
|
|
|
// register pressure.
|
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
|
2009-02-20 21:05:23 +00:00
|
|
|
if (UsersToProcess[i].Base->isZero())
|
2009-02-20 04:17:46 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Otherwise, go for it.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// InsertAffinePhi Create and insert a PHI node for an induction variable
|
|
|
|
/// with the specified start and step values in the specified loop.
|
|
|
|
///
|
|
|
|
/// If NegateStride is true, the stride should be negated by using a
|
|
|
|
/// subtract instead of an add.
|
|
|
|
///
|
2009-03-09 22:04:01 +00:00
|
|
|
/// Return the created phi node.
|
2009-02-20 04:17:46 +00:00
|
|
|
///
|
|
|
|
static PHINode *InsertAffinePhi(SCEVHandle Start, SCEVHandle Step,
|
|
|
|
const Loop *L,
|
2009-03-09 22:04:01 +00:00
|
|
|
SCEVExpander &Rewriter) {
|
2009-02-20 04:17:46 +00:00
|
|
|
assert(Start->isLoopInvariant(L) && "New PHI start is not loop invariant!");
|
|
|
|
assert(Step->isLoopInvariant(L) && "New PHI stride is not loop invariant!");
|
|
|
|
|
|
|
|
BasicBlock *Header = L->getHeader();
|
|
|
|
BasicBlock *Preheader = L->getLoopPreheader();
|
2009-03-09 21:14:16 +00:00
|
|
|
BasicBlock *LatchBlock = L->getLoopLatch();
|
2009-04-16 03:18:22 +00:00
|
|
|
const Type *Ty = Start->getType();
|
2009-04-21 01:07:12 +00:00
|
|
|
Ty = Rewriter.SE.getEffectiveSCEVType(Ty);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2009-04-16 03:18:22 +00:00
|
|
|
PHINode *PN = PHINode::Create(Ty, "lsr.iv", Header->begin());
|
|
|
|
PN->addIncoming(Rewriter.expandCodeFor(Start, Ty, Preheader->getTerminator()),
|
2009-02-20 04:17:46 +00:00
|
|
|
Preheader);
|
|
|
|
|
|
|
|
// If the stride is negative, insert a sub instead of an add for the
|
|
|
|
// increment.
|
|
|
|
bool isNegative = isNonConstantNegative(Step);
|
|
|
|
SCEVHandle IncAmount = Step;
|
|
|
|
if (isNegative)
|
|
|
|
IncAmount = Rewriter.SE.getNegativeSCEV(Step);
|
|
|
|
|
|
|
|
// Insert an add instruction right before the terminator corresponding
|
|
|
|
// to the back-edge.
|
2009-04-16 03:18:22 +00:00
|
|
|
Value *StepV = Rewriter.expandCodeFor(IncAmount, Ty,
|
|
|
|
Preheader->getTerminator());
|
2009-03-09 22:04:01 +00:00
|
|
|
Instruction *IncV;
|
2009-02-20 04:17:46 +00:00
|
|
|
if (isNegative) {
|
|
|
|
IncV = BinaryOperator::CreateSub(PN, StepV, "lsr.iv.next",
|
2009-03-09 21:14:16 +00:00
|
|
|
LatchBlock->getTerminator());
|
2009-02-20 04:17:46 +00:00
|
|
|
} else {
|
|
|
|
IncV = BinaryOperator::CreateAdd(PN, StepV, "lsr.iv.next",
|
2009-03-09 21:14:16 +00:00
|
|
|
LatchBlock->getTerminator());
|
2009-02-20 04:17:46 +00:00
|
|
|
}
|
|
|
|
if (!isa<ConstantInt>(StepV)) ++NumVariable;
|
|
|
|
|
2009-03-09 21:14:16 +00:00
|
|
|
PN->addIncoming(IncV, LatchBlock);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
|
|
|
++NumInserted;
|
|
|
|
return PN;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SortUsersToProcess(std::vector<BasedUser> &UsersToProcess) {
|
|
|
|
// We want to emit code for users inside the loop first. To do this, we
|
|
|
|
// rearrange BasedUser so that the entries at the end have
|
|
|
|
// isUseOfPostIncrementedValue = false, because we pop off the end of the
|
|
|
|
// vector (so we handle them first).
|
|
|
|
std::partition(UsersToProcess.begin(), UsersToProcess.end(),
|
|
|
|
PartitionByIsUseOfPostIncrementedValue);
|
|
|
|
|
|
|
|
// Sort this by base, so that things with the same base are handled
|
|
|
|
// together. By partitioning first and stable-sorting later, we are
|
|
|
|
// guaranteed that within each base we will pop off users from within the
|
|
|
|
// loop before users outside of the loop with a particular base.
|
|
|
|
//
|
|
|
|
// We would like to use stable_sort here, but we can't. The problem is that
|
|
|
|
// SCEVHandle's don't have a deterministic ordering w.r.t to each other, so
|
|
|
|
// we don't have anything to do a '<' comparison on. Because we think the
|
|
|
|
// number of uses is small, do a horrible bubble sort which just relies on
|
|
|
|
// ==.
|
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
|
|
|
|
// Get a base value.
|
|
|
|
SCEVHandle Base = UsersToProcess[i].Base;
|
|
|
|
|
|
|
|
// Compact everything with this base to be consecutive with this one.
|
|
|
|
for (unsigned j = i+1; j != e; ++j) {
|
|
|
|
if (UsersToProcess[j].Base == Base) {
|
|
|
|
std::swap(UsersToProcess[i+1], UsersToProcess[j]);
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-20 21:06:57 +00:00
|
|
|
/// PrepareToStrengthReduceFully - Prepare to fully strength-reduce
|
|
|
|
/// UsersToProcess, meaning lowering addresses all the way down to direct
|
|
|
|
/// pointer arithmetic.
|
2009-02-20 04:17:46 +00:00
|
|
|
///
|
|
|
|
void
|
|
|
|
LoopStrengthReduce::PrepareToStrengthReduceFully(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
SCEVHandle Stride,
|
|
|
|
SCEVHandle CommonExprs,
|
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter) {
|
|
|
|
DOUT << " Fully reducing all users\n";
|
|
|
|
|
|
|
|
// Rewrite the UsersToProcess records, creating a separate PHI for each
|
|
|
|
// unique Base value.
|
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ) {
|
|
|
|
// TODO: The uses are grouped by base, but not sorted. We arbitrarily
|
|
|
|
// pick the first Imm value here to start with, and adjust it for the
|
|
|
|
// other uses.
|
|
|
|
SCEVHandle Imm = UsersToProcess[i].Imm;
|
|
|
|
SCEVHandle Base = UsersToProcess[i].Base;
|
|
|
|
SCEVHandle Start = SE->getAddExpr(CommonExprs, Base, Imm);
|
2009-04-21 01:07:12 +00:00
|
|
|
PHINode *Phi = InsertAffinePhi(Start, Stride, L,
|
2009-03-09 22:04:01 +00:00
|
|
|
PreheaderRewriter);
|
2009-02-20 04:17:46 +00:00
|
|
|
// Loop over all the users with the same base.
|
|
|
|
do {
|
|
|
|
UsersToProcess[i].Base = SE->getIntegerSCEV(0, Stride->getType());
|
|
|
|
UsersToProcess[i].Imm = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
|
|
|
|
UsersToProcess[i].Phi = Phi;
|
|
|
|
assert(UsersToProcess[i].Imm->isLoopInvariant(L) &&
|
|
|
|
"ShouldUseFullStrengthReductionMode should reject this!");
|
|
|
|
} while (++i != e && Base == UsersToProcess[i].Base);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// PrepareToStrengthReduceWithNewPhi - Insert a new induction variable for the
|
|
|
|
/// given users to share.
|
|
|
|
///
|
|
|
|
void
|
|
|
|
LoopStrengthReduce::PrepareToStrengthReduceWithNewPhi(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
SCEVHandle Stride,
|
|
|
|
SCEVHandle CommonExprs,
|
|
|
|
Value *CommonBaseV,
|
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter) {
|
|
|
|
DOUT << " Inserting new PHI:\n";
|
|
|
|
|
|
|
|
PHINode *Phi = InsertAffinePhi(SE->getUnknown(CommonBaseV),
|
2009-04-21 01:07:12 +00:00
|
|
|
Stride, L,
|
2009-03-09 22:04:01 +00:00
|
|
|
PreheaderRewriter);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
|
|
|
// Remember this in case a later stride is multiple of this.
|
2009-03-09 22:04:01 +00:00
|
|
|
IVsByStride[Stride].addIV(Stride, CommonExprs, Phi);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
|
|
|
// All the users will share this new IV.
|
2009-03-09 22:04:01 +00:00
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
|
2009-02-20 04:17:46 +00:00
|
|
|
UsersToProcess[i].Phi = Phi;
|
|
|
|
|
|
|
|
DOUT << " IV=";
|
|
|
|
DEBUG(WriteAsOperand(*DOUT, Phi, /*PrintType=*/false));
|
|
|
|
DOUT << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
/// PrepareToStrengthReduceWithNewPhi - Prepare for the given users to reuse
|
|
|
|
/// an induction variable with a stride that is a factor of the current
|
|
|
|
/// induction variable.
|
|
|
|
///
|
|
|
|
void
|
|
|
|
LoopStrengthReduce::PrepareToStrengthReduceFromSmallerStride(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
Value *CommonBaseV,
|
|
|
|
const IVExpr &ReuseIV,
|
|
|
|
Instruction *PreInsertPt) {
|
|
|
|
DOUT << " Rewriting in terms of existing IV of STRIDE " << *ReuseIV.Stride
|
|
|
|
<< " and BASE " << *ReuseIV.Base << "\n";
|
|
|
|
|
|
|
|
// All the users will share the reused IV.
|
2009-03-09 22:04:01 +00:00
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
|
2009-02-20 04:17:46 +00:00
|
|
|
UsersToProcess[i].Phi = ReuseIV.PHI;
|
|
|
|
|
|
|
|
Constant *C = dyn_cast<Constant>(CommonBaseV);
|
|
|
|
if (C &&
|
|
|
|
(!C->isNullValue() &&
|
|
|
|
!fitsInAddressMode(SE->getUnknown(CommonBaseV), CommonBaseV->getType(),
|
|
|
|
TLI, false)))
|
|
|
|
// We want the common base emitted into the preheader! This is just
|
|
|
|
// using cast as a copy so BitCast (no-op cast) is appropriate
|
|
|
|
CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(),
|
|
|
|
"commonbase", PreInsertPt);
|
|
|
|
}
|
|
|
|
|
2009-02-21 02:06:47 +00:00
|
|
|
static bool IsImmFoldedIntoAddrMode(GlobalValue *GV, int64_t Offset,
|
2009-03-09 21:04:19 +00:00
|
|
|
const Type *AccessTy,
|
2009-02-21 02:06:47 +00:00
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
const TargetLowering *TLI) {
|
|
|
|
SmallVector<Instruction*, 16> AddrModeInsts;
|
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
|
|
|
|
if (UsersToProcess[i].isUseOfPostIncrementedValue)
|
|
|
|
continue;
|
|
|
|
ExtAddrMode AddrMode =
|
|
|
|
AddressingModeMatcher::Match(UsersToProcess[i].OperandValToReplace,
|
2009-03-09 21:04:19 +00:00
|
|
|
AccessTy, UsersToProcess[i].Inst,
|
2009-02-21 02:06:47 +00:00
|
|
|
AddrModeInsts, *TLI);
|
|
|
|
if (GV && GV != AddrMode.BaseGV)
|
|
|
|
return false;
|
|
|
|
if (Offset && !AddrMode.BaseOffs)
|
|
|
|
// FIXME: How to accurate check it's immediate offset is folded.
|
|
|
|
return false;
|
|
|
|
AddrModeInsts.clear();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-10-25 22:45:20 +00:00
|
|
|
/// StrengthReduceStridedIVUsers - Strength reduce all of the users of a single
|
|
|
|
/// stride of IV. All of the users may have different starting values, and this
|
2009-03-09 20:41:15 +00:00
|
|
|
/// may not be the only stride.
|
2007-10-25 22:45:20 +00:00
|
|
|
void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|
|
|
IVUsersOfOneStride &Uses,
|
2009-03-09 20:41:15 +00:00
|
|
|
Loop *L) {
|
2007-10-25 22:45:20 +00:00
|
|
|
// If all the users are moved to another stride, then there is nothing to do.
|
2008-01-29 13:02:09 +00:00
|
|
|
if (Uses.Users.empty())
|
2007-10-25 22:45:20 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Keep track if every use in UsersToProcess is an address. If they all are,
|
|
|
|
// we may be able to rewrite the entire collection of them in terms of a
|
|
|
|
// smaller-stride IV.
|
|
|
|
bool AllUsesAreAddresses = true;
|
|
|
|
|
2008-12-16 22:16:28 +00:00
|
|
|
// Keep track if every use of a single stride is outside the loop. If so,
|
|
|
|
// we want to be more aggressive about reusing a smaller-stride IV; a
|
|
|
|
// multiply outside the loop is better than another IV inside. Well, usually.
|
|
|
|
bool AllUsesAreOutsideLoop = true;
|
|
|
|
|
2007-10-25 22:45:20 +00:00
|
|
|
// Transform our list of users and offsets to a bit more complex table. In
|
|
|
|
// this new vector, each 'BasedUser' contains 'Base' the base of the
|
|
|
|
// strided accessas well as the old information from Uses. We progressively
|
|
|
|
// move information from the Base field to the Imm field, until we eventually
|
|
|
|
// have the full access expression to rewrite the use.
|
|
|
|
std::vector<BasedUser> UsersToProcess;
|
|
|
|
SCEVHandle CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
|
2008-12-16 22:16:28 +00:00
|
|
|
AllUsesAreOutsideLoop,
|
2007-10-25 22:45:20 +00:00
|
|
|
UsersToProcess);
|
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
// Sort the UsersToProcess array so that users with common bases are
|
|
|
|
// next to each other.
|
|
|
|
SortUsersToProcess(UsersToProcess);
|
|
|
|
|
2007-10-25 22:45:20 +00:00
|
|
|
// If we managed to find some expressions in common, we'll need to carry
|
|
|
|
// their value in a register and add it in for each use. This will take up
|
|
|
|
// a register operand, which potentially restricts what stride values are
|
|
|
|
// valid.
|
2008-06-18 16:23:07 +00:00
|
|
|
bool HaveCommonExprs = !CommonExprs->isZero();
|
2007-04-01 22:21:39 +00:00
|
|
|
const Type *ReplacedTy = CommonExprs->getType();
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2009-02-21 02:06:47 +00:00
|
|
|
// If all uses are addresses, consider sinking the immediate part of the
|
|
|
|
// common expression back into uses if they can fit in the immediate fields.
|
2009-02-22 07:31:19 +00:00
|
|
|
if (TLI && HaveCommonExprs && AllUsesAreAddresses) {
|
2009-02-21 02:06:47 +00:00
|
|
|
SCEVHandle NewCommon = CommonExprs;
|
|
|
|
SCEVHandle Imm = SE->getIntegerSCEV(0, ReplacedTy);
|
2009-03-09 21:22:12 +00:00
|
|
|
MoveImmediateValues(TLI, Type::VoidTy, NewCommon, Imm, true, L, SE);
|
2009-02-21 02:06:47 +00:00
|
|
|
if (!Imm->isZero()) {
|
|
|
|
bool DoSink = true;
|
|
|
|
|
|
|
|
// If the immediate part of the common expression is a GV, check if it's
|
|
|
|
// possible to fold it into the target addressing mode.
|
|
|
|
GlobalValue *GV = 0;
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(Imm))
|
2009-04-16 03:18:22 +00:00
|
|
|
GV = dyn_cast<GlobalValue>(SU->getValue());
|
2009-02-21 02:06:47 +00:00
|
|
|
int64_t Offset = 0;
|
2009-04-18 17:56:28 +00:00
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(Imm))
|
2009-02-21 02:06:47 +00:00
|
|
|
Offset = SC->getValue()->getSExtValue();
|
|
|
|
if (GV || Offset)
|
2009-03-09 21:04:19 +00:00
|
|
|
// Pass VoidTy as the AccessTy to be conservative, because
|
|
|
|
// there could be multiple access types among all the uses.
|
|
|
|
DoSink = IsImmFoldedIntoAddrMode(GV, Offset, Type::VoidTy,
|
2009-02-21 02:06:47 +00:00
|
|
|
UsersToProcess, TLI);
|
|
|
|
|
|
|
|
if (DoSink) {
|
|
|
|
DOUT << " Sinking " << *Imm << " back down into uses\n";
|
|
|
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i)
|
|
|
|
UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm, Imm);
|
|
|
|
CommonExprs = NewCommon;
|
|
|
|
HaveCommonExprs = !CommonExprs->isZero();
|
|
|
|
++NumImmSunk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// Now that we know what we need to do, insert the PHI node itself.
|
|
|
|
//
|
2009-02-19 19:23:27 +00:00
|
|
|
DOUT << "LSR: Examining IVs of TYPE " << *ReplacedTy << " of STRIDE "
|
|
|
|
<< *Stride << ":\n"
|
|
|
|
<< " Common base: " << *CommonExprs << "\n";
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2009-04-21 01:07:12 +00:00
|
|
|
SCEVExpander Rewriter(*SE, *LI);
|
|
|
|
SCEVExpander PreheaderRewriter(*SE, *LI);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
BasicBlock *Preheader = L->getLoopPreheader();
|
|
|
|
Instruction *PreInsertPt = Preheader->getTerminator();
|
2005-09-12 17:11:27 +00:00
|
|
|
BasicBlock *LatchBlock = L->getLoopLatch();
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2009-04-21 01:07:12 +00:00
|
|
|
Value *CommonBaseV = Constant::getNullValue(ReplacedTy);
|
2006-03-17 19:52:23 +00:00
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
SCEVHandle RewriteFactor = SE->getIntegerSCEV(0, ReplacedTy);
|
|
|
|
IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty),
|
|
|
|
SE->getIntegerSCEV(0, Type::Int32Ty),
|
2009-03-09 22:04:01 +00:00
|
|
|
0);
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
/// Choose a strength-reduction strategy and prepare for it by creating
|
|
|
|
/// the necessary PHIs and adjusting the bookkeeping.
|
|
|
|
if (ShouldUseFullStrengthReductionMode(UsersToProcess, L,
|
|
|
|
AllUsesAreAddresses, Stride)) {
|
|
|
|
PrepareToStrengthReduceFully(UsersToProcess, Stride, CommonExprs, L,
|
|
|
|
PreheaderRewriter);
|
|
|
|
} else {
|
|
|
|
// Emit the initial base value into the loop preheader.
|
2009-04-16 03:18:22 +00:00
|
|
|
CommonBaseV = PreheaderRewriter.expandCodeFor(CommonExprs, ReplacedTy,
|
|
|
|
PreInsertPt);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
|
|
|
// If all uses are addresses, check if it is possible to reuse an IV with a
|
|
|
|
// stride that is a factor of this stride. And that the multiple is a number
|
|
|
|
// that can be encoded in the scale field of the target addressing mode. And
|
2009-02-20 21:06:57 +00:00
|
|
|
// that we will have a valid instruction after this substition, including
|
|
|
|
// the immediate field, if any.
|
2009-02-20 04:17:46 +00:00
|
|
|
RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses,
|
|
|
|
AllUsesAreOutsideLoop,
|
2009-03-09 21:19:58 +00:00
|
|
|
Stride, ReuseIV, ReplacedTy,
|
2009-02-20 04:17:46 +00:00
|
|
|
UsersToProcess);
|
|
|
|
if (isa<SCEVConstant>(RewriteFactor) &&
|
|
|
|
cast<SCEVConstant>(RewriteFactor)->isZero())
|
|
|
|
PrepareToStrengthReduceWithNewPhi(UsersToProcess, Stride, CommonExprs,
|
|
|
|
CommonBaseV, L, PreheaderRewriter);
|
|
|
|
else
|
|
|
|
PrepareToStrengthReduceFromSmallerStride(UsersToProcess, CommonBaseV,
|
|
|
|
ReuseIV, PreInsertPt);
|
2006-08-03 06:34:50 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
// Process all the users now, replacing their strided uses with
|
|
|
|
// strength-reduced forms. This outer loop handles all bases, the inner
|
2006-08-03 06:34:50 +00:00
|
|
|
// loop handles all users of a particular base.
|
2005-07-30 00:15:07 +00:00
|
|
|
while (!UsersToProcess.empty()) {
|
2005-10-11 18:30:57 +00:00
|
|
|
SCEVHandle Base = UsersToProcess.back().Base;
|
2009-02-19 19:23:27 +00:00
|
|
|
Instruction *Inst = UsersToProcess.back().Inst;
|
2005-08-03 23:30:08 +00:00
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// Emit the code for Base into the preheader.
|
2009-04-16 03:18:22 +00:00
|
|
|
Value *BaseV = 0;
|
|
|
|
if (!Base->isZero()) {
|
|
|
|
BaseV = PreheaderRewriter.expandCodeFor(Base, Base->getType(),
|
|
|
|
PreInsertPt);
|
|
|
|
|
|
|
|
DOUT << " INSERTING code for BASE = " << *Base << ":";
|
|
|
|
if (BaseV->hasName())
|
|
|
|
DOUT << " Result value name = %" << BaseV->getNameStr();
|
|
|
|
DOUT << "\n";
|
|
|
|
|
|
|
|
// If BaseV is a non-zero constant, make sure that it gets inserted into
|
|
|
|
// the preheader, instead of being forward substituted into the uses. We
|
|
|
|
// do this by forcing a BitCast (noop cast) to be inserted into the
|
|
|
|
// preheader in this case.
|
|
|
|
if (!fitsInAddressMode(Base, getAccessType(Inst), TLI, false)) {
|
2006-11-27 01:05:10 +00:00
|
|
|
// We want this constant emitted into the preheader! This is just
|
|
|
|
// using cast as a copy so BitCast (no-op cast) is appropriate
|
|
|
|
BaseV = new BitCastInst(BaseV, BaseV->getType(), "preheaderinsert",
|
2008-04-14 18:26:16 +00:00
|
|
|
PreInsertPt);
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
}
|
2006-08-03 06:34:50 +00:00
|
|
|
}
|
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
// Emit the code to add the immediate offset to the Phi value, just before
|
Move from Stage 0 to Stage 1.
Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).
This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:
or r30, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r30)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
instead of this code:
or r30, r3, r3
or r29, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r29)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8 ;; Two iv's with step of 8
addi r29, r29, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22635 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 22:51:21 +00:00
|
|
|
// the instructions that we identified as using this stride and base.
|
2005-10-11 18:30:57 +00:00
|
|
|
do {
|
2006-08-03 06:34:50 +00:00
|
|
|
// FIXME: Use emitted users to emit other users.
|
2005-10-11 18:30:57 +00:00
|
|
|
BasedUser &User = UsersToProcess.back();
|
Move from Stage 0 to Stage 1.
Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).
This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:
or r30, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r30)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
instead of this code:
or r30, r3, r3
or r29, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r29)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8 ;; Two iv's with step of 8
addi r29, r29, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22635 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 22:51:21 +00:00
|
|
|
|
2009-02-19 19:23:27 +00:00
|
|
|
DOUT << " Examining use ";
|
2009-02-19 19:32:06 +00:00
|
|
|
DEBUG(WriteAsOperand(*DOUT, UsersToProcess.back().OperandValToReplace,
|
|
|
|
/*PrintType=*/false));
|
2009-04-29 22:57:20 +00:00
|
|
|
DOUT << " in Inst: " << *(User.Inst);
|
2009-02-19 19:23:27 +00:00
|
|
|
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
// If this instruction wants to use the post-incremented value, move it
|
|
|
|
// after the post-inc and use its value instead of the PHI.
|
2009-02-20 04:17:46 +00:00
|
|
|
Value *RewriteOp = User.Phi;
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
if (User.isUseOfPostIncrementedValue) {
|
2009-03-09 22:04:01 +00:00
|
|
|
RewriteOp = User.Phi->getIncomingValueForBlock(LatchBlock);
|
_test:
li r2, 0
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r2, 1
stw r2, 0(r4)
blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version. This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):
_test:
li r2, 0 **** IV starts at 0
LBB_test_1: ; no_exit.2
or r5, r2, r2 **** Copy for loop exit
li r2, 0
stw r2, 0(r3)
addi r3, r3, 4
addi r2, r5, 1
addi r6, r5, 2 **** IV+2
cmpwi cr0, r6, 701
blt cr0, LBB_test_1 ; no_exit.2
LBB_test_2: ; loopexit.2.loopexit
addi r2, r5, 2 **** IV+2
stw r2, 0(r4)
blr
And now generated code like this:
_test:
li r2, 1 *** IV starts at 1
LBB_test_1: ; no_exit.2
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
addi r3, r3, 4
cmpwi cr0, r2, 701 *** IV.postinc + 0
blt cr0, LBB_test_1
LBB_test_2: ; loopexit.2.loopexit
stw r2, 0(r4) *** IV.postinc + 0
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8
2005-09-12 06:04:47 +00:00
|
|
|
|
|
|
|
// If this user is in the loop, make sure it is the last thing in the
|
|
|
|
// loop to ensure it is dominated by the increment.
|
|
|
|
if (L->contains(User.Inst->getParent()))
|
|
|
|
User.Inst->moveBefore(LatchBlock->getTerminator());
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
}
|
2006-06-09 00:12:42 +00:00
|
|
|
|
2007-10-22 18:31:58 +00:00
|
|
|
SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp);
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
|
2009-04-21 01:07:12 +00:00
|
|
|
if (SE->getTypeSizeInBits(RewriteOp->getType()) !=
|
|
|
|
SE->getTypeSizeInBits(ReplacedTy)) {
|
|
|
|
assert(SE->getTypeSizeInBits(RewriteOp->getType()) >
|
|
|
|
SE->getTypeSizeInBits(ReplacedTy) &&
|
2009-04-16 15:47:35 +00:00
|
|
|
"Unexpected widening cast!");
|
|
|
|
RewriteExpr = SE->getTruncateExpr(RewriteExpr, ReplacedTy);
|
|
|
|
}
|
|
|
|
|
2008-12-16 22:16:28 +00:00
|
|
|
// If we had to insert new instructions for RewriteOp, we have to
|
2008-05-15 23:26:57 +00:00
|
|
|
// consider that they may not have been able to end up immediately
|
|
|
|
// next to RewriteOp, because non-PHI instructions may never precede
|
|
|
|
// PHI instructions in a block. In this case, remember where the last
|
2008-05-20 03:01:48 +00:00
|
|
|
// instruction was inserted so that if we're replacing a different
|
|
|
|
// PHI node, we can use the later point to expand the final
|
|
|
|
// RewriteExpr.
|
2008-05-15 23:26:57 +00:00
|
|
|
Instruction *NewBasePt = dyn_cast<Instruction>(RewriteOp);
|
2009-02-20 04:17:46 +00:00
|
|
|
if (RewriteOp == User.Phi) NewBasePt = 0;
|
2008-05-15 23:26:57 +00:00
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// Clear the SCEVExpander's expression map so that we are guaranteed
|
|
|
|
// to have the code emitted where we expect it.
|
|
|
|
Rewriter.clear();
|
2006-03-16 21:53:05 +00:00
|
|
|
|
|
|
|
// If we are reusing the iv, then it must be multiplied by a constant
|
2009-02-09 22:14:15 +00:00
|
|
|
// factor to take advantage of the addressing mode scale component.
|
2009-04-16 03:18:22 +00:00
|
|
|
if (!RewriteFactor->isZero()) {
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
// If we're reusing an IV with a nonzero base (currently this happens
|
|
|
|
// only when all reuses are outside the loop) subtract that base here.
|
|
|
|
// The base has been used to initialize the PHI node but we don't want
|
|
|
|
// it here.
|
2009-02-09 22:14:15 +00:00
|
|
|
if (!ReuseIV.Base->isZero()) {
|
|
|
|
SCEVHandle typedBase = ReuseIV.Base;
|
2009-04-21 01:07:12 +00:00
|
|
|
if (SE->getTypeSizeInBits(RewriteExpr->getType()) !=
|
|
|
|
SE->getTypeSizeInBits(ReuseIV.Base->getType())) {
|
2009-02-09 22:14:15 +00:00
|
|
|
// It's possible the original IV is a larger type than the new IV,
|
|
|
|
// in which case we have to truncate the Base. We checked in
|
|
|
|
// RequiresTypeConversion that this is valid.
|
2009-04-21 01:07:12 +00:00
|
|
|
assert(SE->getTypeSizeInBits(RewriteExpr->getType()) <
|
|
|
|
SE->getTypeSizeInBits(ReuseIV.Base->getType()) &&
|
2009-04-16 22:35:57 +00:00
|
|
|
"Unexpected lengthening conversion!");
|
2009-02-09 22:14:15 +00:00
|
|
|
typedBase = SE->getTruncateExpr(ReuseIV.Base,
|
|
|
|
RewriteExpr->getType());
|
|
|
|
}
|
|
|
|
RewriteExpr = SE->getMinusSCEV(RewriteExpr, typedBase);
|
|
|
|
}
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
|
|
|
|
// Multiply old variable, with base removed, by new scale factor.
|
|
|
|
RewriteExpr = SE->getMulExpr(RewriteFactor,
|
2007-10-30 22:27:26 +00:00
|
|
|
RewriteExpr);
|
2006-03-17 19:52:23 +00:00
|
|
|
|
|
|
|
// The common base is emitted in the loop preheader. But since we
|
|
|
|
// are reusing an IV, it has not been used to initialize the PHI node.
|
|
|
|
// Add it to the expression used to rewrite the uses.
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
// When this use is outside the loop, we earlier subtracted the
|
|
|
|
// common base, and are adding it back here. Use the same expression
|
|
|
|
// as before, rather than CommonBaseV, so DAGCombiner will zap it.
|
2009-04-16 03:18:22 +00:00
|
|
|
if (!CommonExprs->isZero()) {
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
if (L->contains(User.Inst->getParent()))
|
|
|
|
RewriteExpr = SE->getAddExpr(RewriteExpr,
|
2008-12-16 22:16:28 +00:00
|
|
|
SE->getUnknown(CommonBaseV));
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
else
|
|
|
|
RewriteExpr = SE->getAddExpr(RewriteExpr, CommonExprs);
|
|
|
|
}
|
2006-03-17 19:52:23 +00:00
|
|
|
}
|
2006-03-16 21:53:05 +00:00
|
|
|
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// Now that we know what we need to do, insert code before User for the
|
|
|
|
// immediate and any loop-variant expressions.
|
2009-04-16 03:18:22 +00:00
|
|
|
if (BaseV)
|
Implement: LoopStrengthReduce/share_ivs.ll
Two changes:
* Only insert one PHI node for each stride. Other values are live in
values. This cannot introduce higher register pressure than the
previous approach, and can take advantage of reg+reg addressing modes.
* Factor common base values out of uses before moving values from the
base to the immediate fields. This improves codegen by starting the
stride-specific PHI node out at a common place for each IV use.
As an example, we used to generate this for a loop in swim:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfd f0, 0(r8)
stfd f0, 0(r3)
lfd f0, 0(r6)
stfd f0, 0(r7)
lfd f0, 0(r2)
stfd f0, 0(r5)
addi r9, r9, 1
addi r2, r2, 8
addi r5, r5, 8
addi r6, r6, 8
addi r7, r7, 8
addi r8, r8, 8
addi r3, r3, 8
cmpw cr0, r9, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
now we emit:
.LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_2: ; no_exit.7.i
lfdx f0, r8, r2
stfdx f0, r9, r2
lfdx f0, r5, r2
stfdx f0, r7, r2
lfdx f0, r3, r2
stfdx f0, r6, r2
addi r10, r10, 1
addi r2, r2, 8
cmpw cr0, r10, r4
bgt .LBB_main_no_exit_2E_6_2E_i_no_exit_2E_7_2E_i_1
As another more dramatic example, we used to emit this:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfd f0, 8(r21)
lfd f4, 8(r3)
lfd f5, 8(r27)
lfd f6, 8(r22)
lfd f7, 8(r5)
lfd f8, 8(r6)
lfd f9, 8(r30)
lfd f10, 8(r11)
lfd f11, 8(r12)
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfd f0, 8(r4)
lfd f0, 8(r25)
lfd f5, 8(r26)
lfd f6, 8(r23)
lfd f9, 8(r28)
lfd f10, 8(r10)
lfd f12, 8(r9)
lfd f13, 8(r29)
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfd f0, 8(r24)
lfd f0, 8(r8)
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfd f0, 8(r2)
addi r20, r20, 1
addi r2, r2, 8
addi r8, r8, 8
addi r10, r10, 8
addi r12, r12, 8
addi r6, r6, 8
addi r29, r29, 8
addi r28, r28, 8
addi r26, r26, 8
addi r25, r25, 8
addi r24, r24, 8
addi r5, r5, 8
addi r23, r23, 8
addi r22, r22, 8
addi r3, r3, 8
addi r9, r9, 8
addi r11, r11, 8
addi r30, r30, 8
addi r27, r27, 8
addi r21, r21, 8
addi r4, r4, 8
cmpw cr0, r20, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
we now emit:
.LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_2: ; no_exit.1.i19
lfdx f0, r21, r20
lfdx f4, r3, r20
lfdx f5, r27, r20
lfdx f6, r22, r20
lfdx f7, r5, r20
lfdx f8, r6, r20
lfdx f9, r30, r20
lfdx f10, r11, r20
lfdx f11, r12, r20
fsub f10, f10, f11
fadd f5, f4, f5
fmul f5, f5, f1
fadd f6, f6, f7
fadd f6, f6, f8
fadd f6, f6, f9
fmadd f0, f5, f6, f0
fnmsub f0, f10, f2, f0
stfdx f0, r4, r20
lfdx f0, r25, r20
lfdx f5, r26, r20
lfdx f6, r23, r20
lfdx f9, r28, r20
lfdx f10, r10, r20
lfdx f12, r9, r20
lfdx f13, r29, r20
fsub f11, f13, f11
fadd f4, f4, f5
fmul f4, f4, f1
fadd f5, f6, f9
fadd f5, f5, f10
fadd f5, f5, f12
fnmsub f0, f4, f5, f0
fnmsub f0, f11, f3, f0
stfdx f0, r24, r20
lfdx f0, r8, r20
fsub f4, f7, f8
fsub f5, f12, f10
fnmsub f0, f5, f2, f0
fnmsub f0, f4, f3, f0
stfdx f0, r2, r20
addi r19, r19, 1
addi r20, r20, 8
cmpw cr0, r19, r7
bgt .LBB_main_L_90_no_exit_2E_0_2E_i16_no_exit_2E_1_2E_i19_1
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22722 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-09 00:18:09 +00:00
|
|
|
// Add BaseV to the PHI value if needed.
|
2007-10-22 18:31:58 +00:00
|
|
|
RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2008-05-15 23:26:57 +00:00
|
|
|
User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt,
|
|
|
|
Rewriter, L, this,
|
2007-10-30 23:45:15 +00:00
|
|
|
DeadInsts);
|
Move from Stage 0 to Stage 1.
Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).
This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:
or r30, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r30)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
instead of this code:
or r30, r3, r3
or r29, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r29)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8 ;; Two iv's with step of 8
addi r29, r29, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22635 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 22:51:21 +00:00
|
|
|
|
2008-12-01 06:14:28 +00:00
|
|
|
// Mark old value we replaced as possibly dead, so that it is eliminated
|
Move from Stage 0 to Stage 1.
Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).
This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:
or r30, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r30)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
instead of this code:
or r30, r3, r3
or r29, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r29)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8 ;; Two iv's with step of 8
addi r29, r29, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22635 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 22:51:21 +00:00
|
|
|
// if we just replaced the last use of that value.
|
2008-12-01 06:27:41 +00:00
|
|
|
DeadInsts.push_back(cast<Instruction>(User.OperandValToReplace));
|
Move from Stage 0 to Stage 1.
Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).
This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:
or r30, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r30)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
instead of this code:
or r30, r3, r3
or r29, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r29)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8 ;; Two iv's with step of 8
addi r29, r29, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22635 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 22:51:21 +00:00
|
|
|
|
2005-10-11 18:30:57 +00:00
|
|
|
UsersToProcess.pop_back();
|
Move from Stage 0 to Stage 1.
Only emit one PHI node for IV uses with identical bases and strides (after
moving foldable immediates to the load/store instruction).
This implements LoopStrengthReduce/dont_insert_redundant_ops.ll, allowing
us to generate this PPC code for test1:
or r30, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r30)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
instead of this code:
or r30, r3, r3
or r29, r3, r3
.LBB_test1_1: ; Loop
li r2, 0
stw r2, 0(r29)
stw r2, 4(r30)
bl L_pred$stub
addi r30, r30, 8 ;; Two iv's with step of 8
addi r29, r29, 8
cmplwi cr0, r3, 0
bne .LBB_test1_1 ; Loop
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22635 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-03 22:51:21 +00:00
|
|
|
++NumReduced;
|
2005-10-11 18:30:57 +00:00
|
|
|
|
2006-08-03 06:34:50 +00:00
|
|
|
// If there are any more users to process with the same base, process them
|
|
|
|
// now. We sorted by base above, so we just have to check the last elt.
|
2005-10-11 18:30:57 +00:00
|
|
|
} while (!UsersToProcess.empty() && UsersToProcess.back().Base == Base);
|
2005-07-30 00:15:07 +00:00
|
|
|
// TODO: Next, find out which base index is the most common, pull it out.
|
|
|
|
}
|
|
|
|
|
|
|
|
// IMPORTANT TODO: Figure out how to partition the IV's with this stride, but
|
|
|
|
// different starting values, into different PHIs.
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|
|
|
|
|
2008-08-13 20:31:11 +00:00
|
|
|
/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
|
2007-04-03 05:11:24 +00:00
|
|
|
/// set the IV user and stride information and return true, otherwise return
|
|
|
|
/// false.
|
2008-08-13 20:31:11 +00:00
|
|
|
bool LoopStrengthReduce::FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
2007-04-03 05:11:24 +00:00
|
|
|
const SCEVHandle *&CondStride) {
|
|
|
|
for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e && !CondUse;
|
|
|
|
++Stride) {
|
|
|
|
std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI =
|
|
|
|
IVUsesByStride.find(StrideOrder[Stride]);
|
|
|
|
assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
|
|
|
|
|
|
|
|
for (std::vector<IVStrideUse>::iterator UI = SI->second.Users.begin(),
|
|
|
|
E = SI->second.Users.end(); UI != E; ++UI)
|
|
|
|
if (UI->User == Cond) {
|
|
|
|
// NOTE: we could handle setcc instructions with multiple uses here, but
|
|
|
|
// InstCombine does it as well for simple uses, it's not clear that it
|
|
|
|
// occurs enough in real life to handle.
|
|
|
|
CondUse = &*UI;
|
|
|
|
CondStride = &SI->first;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2007-10-25 09:11:16 +00:00
|
|
|
namespace {
|
|
|
|
// Constant strides come first which in turns are sorted by their absolute
|
|
|
|
// values. If absolute values are the same, then positive strides comes first.
|
|
|
|
// e.g.
|
|
|
|
// 4, -1, X, 1, 2 ==> 1, -1, 2, 4, X
|
|
|
|
struct StrideCompare {
|
2009-04-21 01:07:12 +00:00
|
|
|
const ScalarEvolution *SE;
|
|
|
|
explicit StrideCompare(const ScalarEvolution *se) : SE(se) {}
|
2009-04-16 03:18:22 +00:00
|
|
|
|
2007-10-25 09:11:16 +00:00
|
|
|
bool operator()(const SCEVHandle &LHS, const SCEVHandle &RHS) {
|
2009-04-18 17:56:28 +00:00
|
|
|
const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS);
|
|
|
|
const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS);
|
2007-10-25 09:11:16 +00:00
|
|
|
if (LHSC && RHSC) {
|
|
|
|
int64_t LV = LHSC->getValue()->getSExtValue();
|
|
|
|
int64_t RV = RHSC->getValue()->getSExtValue();
|
|
|
|
uint64_t ALV = (LV < 0) ? -LV : LV;
|
|
|
|
uint64_t ARV = (RV < 0) ? -RV : RV;
|
2009-02-13 00:26:43 +00:00
|
|
|
if (ALV == ARV) {
|
|
|
|
if (LV != RV)
|
|
|
|
return LV > RV;
|
|
|
|
} else {
|
2007-10-25 09:11:16 +00:00
|
|
|
return ALV < ARV;
|
2009-02-13 00:26:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If it's the same value but different type, sort by bit width so
|
|
|
|
// that we emit larger induction variables before smaller
|
|
|
|
// ones, letting the smaller be re-written in terms of larger ones.
|
2009-04-21 01:07:12 +00:00
|
|
|
return SE->getTypeSizeInBits(RHS->getType()) <
|
|
|
|
SE->getTypeSizeInBits(LHS->getType());
|
2007-10-25 09:11:16 +00:00
|
|
|
}
|
2009-02-13 00:26:43 +00:00
|
|
|
return LHSC && !RHSC;
|
2007-10-25 09:11:16 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ChangeCompareStride - If a loop termination compare instruction is the
|
|
|
|
/// only use of its stride, and the compaison is against a constant value,
|
|
|
|
/// try eliminate the stride by moving the compare instruction to another
|
|
|
|
/// stride and change its constant operand accordingly. e.g.
|
|
|
|
///
|
|
|
|
/// loop:
|
|
|
|
/// ...
|
|
|
|
/// v1 = v1 + 3
|
|
|
|
/// v2 = v2 + 1
|
|
|
|
/// if (v2 < 10) goto loop
|
|
|
|
/// =>
|
|
|
|
/// loop:
|
|
|
|
/// ...
|
|
|
|
/// v1 = v1 + 3
|
|
|
|
/// if (v1 < 30) goto loop
|
|
|
|
ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
2007-10-30 23:45:15 +00:00
|
|
|
IVStrideUse* &CondUse,
|
2007-10-25 09:11:16 +00:00
|
|
|
const SCEVHandle* &CondStride) {
|
|
|
|
if (StrideOrder.size() < 2 ||
|
|
|
|
IVUsesByStride[*CondStride].Users.size() != 1)
|
|
|
|
return Cond;
|
|
|
|
const SCEVConstant *SC = dyn_cast<SCEVConstant>(*CondStride);
|
|
|
|
if (!SC) return Cond;
|
|
|
|
|
|
|
|
ICmpInst::Predicate Predicate = Cond->getPredicate();
|
|
|
|
int64_t CmpSSInt = SC->getValue()->getSExtValue();
|
2009-04-21 01:07:12 +00:00
|
|
|
unsigned BitWidth = SE->getTypeSizeInBits((*CondStride)->getType());
|
2007-10-26 23:08:19 +00:00
|
|
|
uint64_t SignBit = 1ULL << (BitWidth-1);
|
2009-02-24 01:58:00 +00:00
|
|
|
const Type *CmpTy = Cond->getOperand(0)->getType();
|
2007-10-26 23:08:19 +00:00
|
|
|
const Type *NewCmpTy = NULL;
|
2009-04-21 01:07:12 +00:00
|
|
|
unsigned TyBits = SE->getTypeSizeInBits(CmpTy);
|
2007-10-29 22:07:18 +00:00
|
|
|
unsigned NewTyBits = 0;
|
2007-10-25 09:11:16 +00:00
|
|
|
SCEVHandle *NewStride = NULL;
|
2009-02-20 21:27:23 +00:00
|
|
|
Value *NewCmpLHS = NULL;
|
|
|
|
Value *NewCmpRHS = NULL;
|
2007-10-25 09:11:16 +00:00
|
|
|
int64_t Scale = 1;
|
2009-04-21 01:07:12 +00:00
|
|
|
SCEVHandle NewOffset = SE->getIntegerSCEV(0, CmpTy);
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
if (ConstantInt *C = dyn_cast<ConstantInt>(Cond->getOperand(1))) {
|
|
|
|
int64_t CmpVal = C->getValue().getSExtValue();
|
2008-08-13 02:05:14 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
// Check stride constant and the comparision constant signs to detect
|
|
|
|
// overflow.
|
|
|
|
if ((CmpVal & SignBit) != (CmpSSInt & SignBit))
|
|
|
|
return Cond;
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
// Look for a suitable stride / iv as replacement.
|
|
|
|
for (unsigned i = 0, e = StrideOrder.size(); i != e; ++i) {
|
|
|
|
std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI =
|
|
|
|
IVUsesByStride.find(StrideOrder[i]);
|
|
|
|
if (!isa<SCEVConstant>(SI->first))
|
|
|
|
continue;
|
|
|
|
int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
|
2009-04-27 20:35:32 +00:00
|
|
|
if (SSInt == CmpSSInt ||
|
|
|
|
abs(SSInt) < abs(CmpSSInt) ||
|
|
|
|
(SSInt % CmpSSInt) != 0)
|
2009-02-24 01:58:00 +00:00
|
|
|
continue;
|
2007-10-26 23:08:19 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
Scale = SSInt / CmpSSInt;
|
|
|
|
int64_t NewCmpVal = CmpVal * Scale;
|
2009-05-05 20:49:46 +00:00
|
|
|
APInt Mul = APInt(BitWidth, NewCmpVal);
|
2009-02-24 01:58:00 +00:00
|
|
|
// Check for overflow.
|
2009-05-05 20:49:46 +00:00
|
|
|
if (Mul.getSExtValue() != NewCmpVal)
|
2009-02-24 01:58:00 +00:00
|
|
|
continue;
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
// Watch out for overflow.
|
|
|
|
if (ICmpInst::isSignedPredicate(Predicate) &&
|
|
|
|
(CmpVal & SignBit) != (NewCmpVal & SignBit))
|
|
|
|
continue;
|
2007-10-29 22:07:18 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
if (NewCmpVal == CmpVal)
|
|
|
|
continue;
|
|
|
|
// Pick the best iv to use trying to avoid a cast.
|
|
|
|
NewCmpLHS = NULL;
|
|
|
|
for (std::vector<IVStrideUse>::iterator UI = SI->second.Users.begin(),
|
|
|
|
E = SI->second.Users.end(); UI != E; ++UI) {
|
|
|
|
NewCmpLHS = UI->OperandValToReplace;
|
|
|
|
if (NewCmpLHS->getType() == CmpTy)
|
|
|
|
break;
|
2007-10-25 22:45:20 +00:00
|
|
|
}
|
2009-02-24 01:58:00 +00:00
|
|
|
if (!NewCmpLHS)
|
2007-10-25 09:11:16 +00:00
|
|
|
continue;
|
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
NewCmpTy = NewCmpLHS->getType();
|
2009-04-21 01:07:12 +00:00
|
|
|
NewTyBits = SE->getTypeSizeInBits(NewCmpTy);
|
|
|
|
const Type *NewCmpIntTy = IntegerType::get(NewTyBits);
|
2009-02-24 01:58:00 +00:00
|
|
|
if (RequiresTypeConversion(NewCmpTy, CmpTy)) {
|
|
|
|
// Check if it is possible to rewrite it using
|
|
|
|
// an iv / stride of a smaller integer type.
|
2009-04-16 16:49:48 +00:00
|
|
|
unsigned Bits = NewTyBits;
|
|
|
|
if (ICmpInst::isSignedPredicate(Predicate))
|
|
|
|
--Bits;
|
|
|
|
uint64_t Mask = (1ULL << Bits) - 1;
|
|
|
|
if (((uint64_t)NewCmpVal & Mask) != (uint64_t)NewCmpVal)
|
2009-02-24 01:58:00 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-02-20 21:27:23 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
// Don't rewrite if use offset is non-constant and the new type is
|
|
|
|
// of a different type.
|
|
|
|
// FIXME: too conservative?
|
|
|
|
if (NewTyBits != TyBits && !isa<SCEVConstant>(CondUse->Offset))
|
|
|
|
continue;
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
bool AllUsesAreAddresses = true;
|
|
|
|
bool AllUsesAreOutsideLoop = true;
|
|
|
|
std::vector<BasedUser> UsersToProcess;
|
|
|
|
SCEVHandle CommonExprs = CollectIVUsers(SI->first, SI->second, L,
|
|
|
|
AllUsesAreAddresses,
|
|
|
|
AllUsesAreOutsideLoop,
|
|
|
|
UsersToProcess);
|
|
|
|
// Avoid rewriting the compare instruction with an iv of new stride
|
|
|
|
// if it's likely the new stride uses will be rewritten using the
|
|
|
|
// stride of the compare instruction.
|
|
|
|
if (AllUsesAreAddresses &&
|
|
|
|
ValidStride(!CommonExprs->isZero(), Scale, UsersToProcess))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// If scale is negative, use swapped predicate unless it's testing
|
|
|
|
// for equality.
|
|
|
|
if (Scale < 0 && !Cond->isEquality())
|
|
|
|
Predicate = ICmpInst::getSwappedPredicate(Predicate);
|
|
|
|
|
|
|
|
NewStride = &StrideOrder[i];
|
|
|
|
if (!isa<PointerType>(NewCmpTy))
|
|
|
|
NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal);
|
|
|
|
else {
|
2009-04-21 01:07:12 +00:00
|
|
|
ConstantInt *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal);
|
2009-04-16 15:48:38 +00:00
|
|
|
NewCmpRHS = ConstantExpr::getIntToPtr(CI, NewCmpTy);
|
2009-02-24 01:58:00 +00:00
|
|
|
}
|
|
|
|
NewOffset = TyBits == NewTyBits
|
|
|
|
? SE->getMulExpr(CondUse->Offset,
|
|
|
|
SE->getConstant(ConstantInt::get(CmpTy, Scale)))
|
2009-04-21 01:07:12 +00:00
|
|
|
: SE->getConstant(ConstantInt::get(NewCmpIntTy,
|
2009-02-24 01:58:00 +00:00
|
|
|
cast<SCEVConstant>(CondUse->Offset)->getValue()->getSExtValue()*Scale));
|
|
|
|
break;
|
2007-10-25 09:11:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-16 22:34:15 +00:00
|
|
|
// Forgo this transformation if it the increment happens to be
|
|
|
|
// unfortunately positioned after the condition, and the condition
|
|
|
|
// has multiple uses which prevent it from being moved immediately
|
|
|
|
// before the branch. See
|
|
|
|
// test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-*.ll
|
|
|
|
// for an example of this situation.
|
2008-08-13 02:05:14 +00:00
|
|
|
if (!Cond->hasOneUse()) {
|
2008-06-16 22:34:15 +00:00
|
|
|
for (BasicBlock::iterator I = Cond, E = Cond->getParent()->end();
|
|
|
|
I != E; ++I)
|
2009-02-20 21:27:23 +00:00
|
|
|
if (I == NewCmpLHS)
|
2008-06-16 22:34:15 +00:00
|
|
|
return Cond;
|
2008-08-13 02:05:14 +00:00
|
|
|
}
|
2008-06-16 22:34:15 +00:00
|
|
|
|
2009-02-20 21:27:23 +00:00
|
|
|
if (NewCmpRHS) {
|
2007-10-25 09:11:16 +00:00
|
|
|
// Create a new compare instruction using new stride / iv.
|
|
|
|
ICmpInst *OldCond = Cond;
|
2007-10-26 23:08:19 +00:00
|
|
|
// Insert new compare instruction.
|
2009-02-20 21:27:23 +00:00
|
|
|
Cond = new ICmpInst(Predicate, NewCmpLHS, NewCmpRHS,
|
2008-06-13 21:43:41 +00:00
|
|
|
L->getHeader()->getName() + ".termcond",
|
|
|
|
OldCond);
|
2007-10-26 23:08:19 +00:00
|
|
|
|
|
|
|
// Remove the old compare instruction. The old indvar is probably dead too.
|
2008-12-01 06:27:41 +00:00
|
|
|
DeadInsts.push_back(cast<Instruction>(CondUse->OperandValToReplace));
|
2008-05-21 00:54:12 +00:00
|
|
|
OldCond->replaceAllUsesWith(Cond);
|
2007-10-25 09:11:16 +00:00
|
|
|
OldCond->eraseFromParent();
|
2007-10-26 23:08:19 +00:00
|
|
|
|
2007-10-25 09:11:16 +00:00
|
|
|
IVUsesByStride[*CondStride].Users.pop_back();
|
2009-02-20 21:27:23 +00:00
|
|
|
IVUsesByStride[*NewStride].addUser(NewOffset, Cond, NewCmpLHS);
|
2007-10-25 09:11:16 +00:00
|
|
|
CondUse = &IVUsesByStride[*NewStride].Users.back();
|
|
|
|
CondStride = NewStride;
|
|
|
|
++NumEliminated;
|
2009-05-02 18:29:22 +00:00
|
|
|
Changed = true;
|
2007-10-25 09:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Cond;
|
|
|
|
}
|
|
|
|
|
2008-09-15 21:22:06 +00:00
|
|
|
/// OptimizeSMax - Rewrite the loop's terminating condition if it uses
|
|
|
|
/// an smax computation.
|
|
|
|
///
|
|
|
|
/// This is a narrow solution to a specific, but acute, problem. For loops
|
|
|
|
/// like this:
|
|
|
|
///
|
|
|
|
/// i = 0;
|
|
|
|
/// do {
|
|
|
|
/// p[i] = 0.0;
|
|
|
|
/// } while (++i < n);
|
|
|
|
///
|
|
|
|
/// where the comparison is signed, the trip count isn't just 'n', because
|
|
|
|
/// 'n' could be negative. And unfortunately this can come up even for loops
|
|
|
|
/// where the user didn't use a C do-while loop. For example, seemingly
|
|
|
|
/// well-behaved top-test loops will commonly be lowered like this:
|
|
|
|
//
|
|
|
|
/// if (n > 0) {
|
|
|
|
/// i = 0;
|
|
|
|
/// do {
|
|
|
|
/// p[i] = 0.0;
|
|
|
|
/// } while (++i < n);
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// and then it's possible for subsequent optimization to obscure the if
|
|
|
|
/// test in such a way that indvars can't find it.
|
|
|
|
///
|
|
|
|
/// When indvars can't find the if test in loops like this, it creates a
|
|
|
|
/// signed-max expression, which allows it to give the loop a canonical
|
|
|
|
/// induction variable:
|
|
|
|
///
|
|
|
|
/// i = 0;
|
|
|
|
/// smax = n < 1 ? 1 : n;
|
|
|
|
/// do {
|
|
|
|
/// p[i] = 0.0;
|
|
|
|
/// } while (++i != smax);
|
|
|
|
///
|
|
|
|
/// Canonical induction variables are necessary because the loop passes
|
|
|
|
/// are designed around them. The most obvious example of this is the
|
|
|
|
/// LoopInfo analysis, which doesn't remember trip count values. It
|
|
|
|
/// expects to be able to rediscover the trip count each time it is
|
|
|
|
/// needed, and it does this using a simple analyis that only succeeds if
|
|
|
|
/// the loop has a canonical induction variable.
|
|
|
|
///
|
|
|
|
/// However, when it comes time to generate code, the maximum operation
|
|
|
|
/// can be quite costly, especially if it's inside of an outer loop.
|
|
|
|
///
|
|
|
|
/// This function solves this problem by detecting this type of loop and
|
|
|
|
/// rewriting their conditions from ICMP_NE back to ICMP_SLT, and deleting
|
|
|
|
/// the instructions for the maximum computation.
|
|
|
|
///
|
|
|
|
ICmpInst *LoopStrengthReduce::OptimizeSMax(Loop *L, ICmpInst *Cond,
|
|
|
|
IVStrideUse* &CondUse) {
|
|
|
|
// Check that the loop matches the pattern we're looking for.
|
|
|
|
if (Cond->getPredicate() != CmpInst::ICMP_EQ &&
|
|
|
|
Cond->getPredicate() != CmpInst::ICMP_NE)
|
|
|
|
return Cond;
|
|
|
|
|
|
|
|
SelectInst *Sel = dyn_cast<SelectInst>(Cond->getOperand(1));
|
|
|
|
if (!Sel || !Sel->hasOneUse()) return Cond;
|
|
|
|
|
2009-02-24 18:55:53 +00:00
|
|
|
SCEVHandle BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
2008-09-15 21:22:06 +00:00
|
|
|
return Cond;
|
2009-02-24 18:55:53 +00:00
|
|
|
SCEVHandle One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2009-02-24 18:55:53 +00:00
|
|
|
// Add one to the backedge-taken count to get the trip count.
|
|
|
|
SCEVHandle IterationCount = SE->getAddExpr(BackedgeTakenCount, One);
|
2008-09-15 21:22:06 +00:00
|
|
|
|
|
|
|
// Check for a max calculation that matches the pattern.
|
2009-05-04 22:30:44 +00:00
|
|
|
const SCEVSMaxExpr *SMax = dyn_cast<SCEVSMaxExpr>(IterationCount);
|
2008-09-15 21:22:06 +00:00
|
|
|
if (!SMax || SMax != SE->getSCEV(Sel)) return Cond;
|
|
|
|
|
|
|
|
SCEVHandle SMaxLHS = SMax->getOperand(0);
|
|
|
|
SCEVHandle SMaxRHS = SMax->getOperand(1);
|
|
|
|
if (!SMaxLHS || SMaxLHS != One) return Cond;
|
|
|
|
|
|
|
|
// Check the relevant induction variable for conformance to
|
|
|
|
// the pattern.
|
|
|
|
SCEVHandle IV = SE->getSCEV(Cond->getOperand(0));
|
2009-04-18 17:56:28 +00:00
|
|
|
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
2008-09-15 21:22:06 +00:00
|
|
|
if (!AR || !AR->isAffine() ||
|
|
|
|
AR->getStart() != One ||
|
|
|
|
AR->getStepRecurrence(*SE) != One)
|
|
|
|
return Cond;
|
|
|
|
|
2009-03-04 20:49:01 +00:00
|
|
|
assert(AR->getLoop() == L &&
|
|
|
|
"Loop condition operand is an addrec in a different loop!");
|
|
|
|
|
2008-09-15 21:22:06 +00:00
|
|
|
// Check the right operand of the select, and remember it, as it will
|
|
|
|
// be used in the new comparison instruction.
|
|
|
|
Value *NewRHS = 0;
|
|
|
|
if (SE->getSCEV(Sel->getOperand(1)) == SMaxRHS)
|
|
|
|
NewRHS = Sel->getOperand(1);
|
|
|
|
else if (SE->getSCEV(Sel->getOperand(2)) == SMaxRHS)
|
|
|
|
NewRHS = Sel->getOperand(2);
|
|
|
|
if (!NewRHS) return Cond;
|
|
|
|
|
|
|
|
// Ok, everything looks ok to change the condition into an SLT or SGE and
|
|
|
|
// delete the max calculation.
|
|
|
|
ICmpInst *NewCond =
|
|
|
|
new ICmpInst(Cond->getPredicate() == CmpInst::ICMP_NE ?
|
|
|
|
CmpInst::ICMP_SLT :
|
|
|
|
CmpInst::ICMP_SGE,
|
|
|
|
Cond->getOperand(0), NewRHS, "scmp", Cond);
|
|
|
|
|
|
|
|
// Delete the max calculation instructions.
|
|
|
|
Cond->replaceAllUsesWith(NewCond);
|
|
|
|
Cond->eraseFromParent();
|
|
|
|
Instruction *Cmp = cast<Instruction>(Sel->getOperand(0));
|
2008-10-01 02:02:03 +00:00
|
|
|
Sel->eraseFromParent();
|
2009-05-04 22:30:44 +00:00
|
|
|
if (Cmp->use_empty())
|
2008-10-01 02:02:03 +00:00
|
|
|
Cmp->eraseFromParent();
|
2008-09-15 21:22:06 +00:00
|
|
|
CondUse->User = NewCond;
|
|
|
|
return NewCond;
|
|
|
|
}
|
|
|
|
|
2008-08-26 17:57:54 +00:00
|
|
|
/// OptimizeShadowIV - If IV is used in a int-to-float cast
|
|
|
|
/// inside the loop then try to eliminate the cast opeation.
|
|
|
|
void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
|
|
|
|
|
2009-02-24 18:55:53 +00:00
|
|
|
SCEVHandle BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
2008-08-26 17:57:54 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e;
|
|
|
|
++Stride) {
|
|
|
|
std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI =
|
|
|
|
IVUsesByStride.find(StrideOrder[Stride]);
|
|
|
|
assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
|
|
|
|
if (!isa<SCEVConstant>(SI->first))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (std::vector<IVStrideUse>::iterator UI = SI->second.Users.begin(),
|
|
|
|
E = SI->second.Users.end(); UI != E; /* empty */) {
|
|
|
|
std::vector<IVStrideUse>::iterator CandidateUI = UI;
|
2008-08-27 17:50:18 +00:00
|
|
|
++UI;
|
2008-08-26 17:57:54 +00:00
|
|
|
Instruction *ShadowUse = CandidateUI->User;
|
|
|
|
const Type *DestTy = NULL;
|
|
|
|
|
|
|
|
/* If shadow use is a int->float cast then insert a second IV
|
2008-08-27 17:50:18 +00:00
|
|
|
to eliminate this cast.
|
2008-08-26 17:57:54 +00:00
|
|
|
|
|
|
|
for (unsigned i = 0; i < n; ++i)
|
|
|
|
foo((double)i);
|
|
|
|
|
2008-08-27 17:50:18 +00:00
|
|
|
is transformed into
|
2008-08-26 17:57:54 +00:00
|
|
|
|
|
|
|
double d = 0.0;
|
|
|
|
for (unsigned i = 0; i < n; ++i, ++d)
|
|
|
|
foo(d);
|
|
|
|
*/
|
2008-08-27 17:50:18 +00:00
|
|
|
if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->User))
|
2008-08-26 17:57:54 +00:00
|
|
|
DestTy = UCast->getDestTy();
|
2008-08-27 17:50:18 +00:00
|
|
|
else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->User))
|
2008-08-26 17:57:54 +00:00
|
|
|
DestTy = SCast->getDestTy();
|
2008-08-27 20:55:23 +00:00
|
|
|
if (!DestTy) continue;
|
|
|
|
|
|
|
|
if (TLI) {
|
|
|
|
/* If target does not support DestTy natively then do not apply
|
|
|
|
this transformation. */
|
|
|
|
MVT DVT = TLI->getValueType(DestTy);
|
|
|
|
if (!TLI->isTypeLegal(DVT)) continue;
|
|
|
|
}
|
|
|
|
|
2008-08-26 17:57:54 +00:00
|
|
|
PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
|
|
|
|
if (!PH) continue;
|
|
|
|
if (PH->getNumIncomingValues() != 2) continue;
|
|
|
|
|
|
|
|
const Type *SrcTy = PH->getType();
|
|
|
|
int Mantissa = DestTy->getFPMantissaWidth();
|
|
|
|
if (Mantissa == -1) continue;
|
2009-04-21 01:07:12 +00:00
|
|
|
if ((int)SE->getTypeSizeInBits(SrcTy) > Mantissa)
|
2008-08-26 17:57:54 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
unsigned Entry, Latch;
|
|
|
|
if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
|
|
|
|
Entry = 0;
|
|
|
|
Latch = 1;
|
|
|
|
} else {
|
|
|
|
Entry = 1;
|
|
|
|
Latch = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
|
|
|
|
if (!Init) continue;
|
|
|
|
ConstantFP *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
|
|
|
|
|
|
|
|
BinaryOperator *Incr =
|
|
|
|
dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
|
|
|
|
if (!Incr) continue;
|
|
|
|
if (Incr->getOpcode() != Instruction::Add
|
|
|
|
&& Incr->getOpcode() != Instruction::Sub)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Initialize new IV, double d = 0.0 in above example. */
|
|
|
|
ConstantInt *C = NULL;
|
|
|
|
if (Incr->getOperand(0) == PH)
|
|
|
|
C = dyn_cast<ConstantInt>(Incr->getOperand(1));
|
|
|
|
else if (Incr->getOperand(1) == PH)
|
|
|
|
C = dyn_cast<ConstantInt>(Incr->getOperand(0));
|
|
|
|
else
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!C) continue;
|
|
|
|
|
|
|
|
/* Add new PHINode. */
|
|
|
|
PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
|
|
|
|
|
2008-08-27 17:50:18 +00:00
|
|
|
/* create new increment. '++d' in above example. */
|
2008-08-26 17:57:54 +00:00
|
|
|
ConstantFP *CFP = ConstantFP::get(DestTy, C->getZExtValue());
|
|
|
|
BinaryOperator *NewIncr =
|
|
|
|
BinaryOperator::Create(Incr->getOpcode(),
|
|
|
|
NewPH, CFP, "IV.S.next.", Incr);
|
|
|
|
|
|
|
|
NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
|
|
|
|
NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
|
|
|
|
|
|
|
|
/* Remove cast operation */
|
|
|
|
ShadowUse->replaceAllUsesWith(NewPH);
|
|
|
|
ShadowUse->eraseFromParent();
|
|
|
|
SI->second.Users.erase(CandidateUI);
|
|
|
|
NumShadow++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
// OptimizeIndvars - Now that IVUsesByStride is set up with all of the indvar
|
|
|
|
// uses in the loop, look to see if we can eliminate some, in favor of using
|
|
|
|
// common indvars for the different uses.
|
|
|
|
void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
|
|
|
|
// TODO: implement optzns here.
|
|
|
|
|
2008-08-26 17:57:54 +00:00
|
|
|
OptimizeShadowIV(L);
|
|
|
|
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
// Finally, get the terminating condition for the loop if possible. If we
|
|
|
|
// can, we want to change it to use a post-incremented version of its
|
2006-03-24 07:14:34 +00:00
|
|
|
// induction variable, to allow coalescing the live ranges for the IV into
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
// one register value.
|
|
|
|
PHINode *SomePHI = cast<PHINode>(L->getHeader()->begin());
|
|
|
|
BasicBlock *Preheader = L->getLoopPreheader();
|
|
|
|
BasicBlock *LatchBlock =
|
|
|
|
SomePHI->getIncomingBlock(SomePHI->getIncomingBlock(0) == Preheader);
|
|
|
|
BranchInst *TermBr = dyn_cast<BranchInst>(LatchBlock->getTerminator());
|
2006-12-23 06:05:41 +00:00
|
|
|
if (!TermBr || TermBr->isUnconditional() ||
|
|
|
|
!isa<ICmpInst>(TermBr->getCondition()))
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
return;
|
2006-12-23 06:05:41 +00:00
|
|
|
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
|
|
|
|
// Search IVUsesByStride to find Cond's IVUse if there is one.
|
|
|
|
IVStrideUse *CondUse = 0;
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
const SCEVHandle *CondStride = 0;
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
|
2008-08-13 20:31:11 +00:00
|
|
|
if (!FindIVUserForCond(Cond, CondUse, CondStride))
|
2007-04-03 05:11:24 +00:00
|
|
|
return; // setcc doesn't use the IV.
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2008-09-15 21:22:06 +00:00
|
|
|
// If the trip count is computed in terms of an smax (due to ScalarEvolution
|
|
|
|
// being unable to find a sufficient guard, for example), change the loop
|
|
|
|
// comparison to use SLT instead of NE.
|
|
|
|
Cond = OptimizeSMax(L, Cond, CondUse);
|
|
|
|
|
2007-10-25 09:11:16 +00:00
|
|
|
// If possible, change stride and operands of the compare instruction to
|
|
|
|
// eliminate one stride.
|
|
|
|
Cond = ChangeCompareStride(L, Cond, CondUse, CondStride);
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
|
|
|
|
// It's possible for the setcc instruction to be anywhere in the loop, and
|
|
|
|
// possible for it to have multiple users. If it is not immediately before
|
|
|
|
// the latch block branch, move it.
|
|
|
|
if (&*++BasicBlock::iterator(Cond) != (Instruction*)TermBr) {
|
|
|
|
if (Cond->hasOneUse()) { // Condition has a single use, just move it.
|
|
|
|
Cond->moveBefore(TermBr);
|
|
|
|
} else {
|
|
|
|
// Otherwise, clone the terminating condition and insert into the loopend.
|
2006-12-23 06:05:41 +00:00
|
|
|
Cond = cast<ICmpInst>(Cond->clone());
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
Cond->setName(L->getHeader()->getName() + ".termcond");
|
|
|
|
LatchBlock->getInstList().insert(TermBr, Cond);
|
|
|
|
|
|
|
|
// Clone the IVUse, as the old use still exists!
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
IVUsesByStride[*CondStride].addUser(CondUse->Offset, Cond,
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
CondUse->OperandValToReplace);
|
Teach LSR to strength reduce IVs that have a loop-invariant but non-constant stride.
For code like this:
void foo(float *a, float *b, int n, int stride_a, int stride_b) {
int i;
for (i=0; i<n; i++)
a[i*stride_a] = b[i*stride_b];
}
we now emit:
.LBB_foo2_2: ; no_exit
lfs f0, 0(r4)
stfs f0, 0(r3)
addi r7, r7, 1
add r4, r2, r4
add r3, r6, r3
cmpw cr0, r7, r5
blt .LBB_foo2_2 ; no_exit
instead of:
.LBB_foo_2: ; no_exit
mullw r8, r2, r7 ;; multiply!
slwi r8, r8, 2
lfsx f0, r4, r8
mullw r8, r2, r6 ;; multiply!
slwi r8, r8, 2
stfsx f0, r3, r8
addi r2, r2, 1
cmpw cr0, r2, r5
blt .LBB_foo_2 ; no_exit
loops with variable strides occur pretty often. For example, in SPECFP2K
there are 317 variable strides in 177.mesa, 3 in 179.art, 14 in 188.ammp,
56 in 168.wupwise, 36 in 172.mgrid.
Now we can allow indvars to turn functions written like this:
void foo2(float *a, float *b, int n, int stride_a, int stride_b) {
int i, ai = 0, bi = 0;
for (i=0; i<n; i++)
{
a[ai] = b[bi];
ai += stride_a;
bi += stride_b;
}
}
into code like the above for better analysis. With this patch, they generate
identical code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22740 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-10 00:45:21 +00:00
|
|
|
CondUse = &IVUsesByStride[*CondStride].Users.back();
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we get to here, we know that we can transform the setcc instruction to
|
2006-03-24 07:14:34 +00:00
|
|
|
// use the post-incremented version of the IV, allowing us to coalesce the
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
// live ranges for the IV correctly.
|
2007-10-22 18:31:58 +00:00
|
|
|
CondUse->Offset = SE->getMinusSCEV(CondUse->Offset, *CondStride);
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
CondUse->isUseOfPostIncrementedValue = true;
|
2008-07-07 19:51:32 +00:00
|
|
|
Changed = true;
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
}
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2007-03-06 21:14:09 +00:00
|
|
|
bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2007-03-06 21:14:09 +00:00
|
|
|
LI = &getAnalysis<LoopInfo>();
|
2007-06-07 21:42:15 +00:00
|
|
|
DT = &getAnalysis<DominatorTree>();
|
2007-03-06 21:14:09 +00:00
|
|
|
SE = &getAnalysis<ScalarEvolution>();
|
2008-07-14 17:55:01 +00:00
|
|
|
Changed = false;
|
2007-03-06 21:14:09 +00:00
|
|
|
|
2008-12-16 22:16:28 +00:00
|
|
|
// Find all uses of induction variables in this loop, and categorize
|
2005-07-30 00:15:07 +00:00
|
|
|
// them by stride. Start by finding all of the PHI nodes in the header for
|
|
|
|
// this loop. If they are induction variables, inspect their uses.
|
2007-10-26 23:08:19 +00:00
|
|
|
SmallPtrSet<Instruction*,16> Processed; // Don't reprocess instructions.
|
2005-07-30 00:15:07 +00:00
|
|
|
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I)
|
2005-08-04 17:40:30 +00:00
|
|
|
AddUsersIfInteresting(I, L, Processed);
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2008-07-07 19:51:32 +00:00
|
|
|
if (!IVUsesByStride.empty()) {
|
2009-03-09 20:34:59 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
DOUT << "\nLSR on \"" << L->getHeader()->getParent()->getNameStart()
|
|
|
|
<< "\" ";
|
|
|
|
DEBUG(L->dump());
|
|
|
|
#endif
|
|
|
|
|
2009-03-09 20:46:50 +00:00
|
|
|
// Sort the StrideOrder so we process larger strides first.
|
2009-04-21 01:07:12 +00:00
|
|
|
std::stable_sort(StrideOrder.begin(), StrideOrder.end(), StrideCompare(SE));
|
2009-03-09 20:46:50 +00:00
|
|
|
|
2008-07-07 19:51:32 +00:00
|
|
|
// Optimize induction variables. Some indvar uses can be transformed to use
|
|
|
|
// strides that will be needed for other purposes. A common example of this
|
|
|
|
// is the exit test for the loop, which can often be rewritten to use the
|
|
|
|
// computation of some other indvar to decide when to terminate the loop.
|
|
|
|
OptimizeIndvars(L);
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
|
2009-05-05 23:02:38 +00:00
|
|
|
// FIXME: We can shrink overlarge IV's here. e.g. if the code has
|
2009-05-05 22:59:55 +00:00
|
|
|
// computation in i64 values and the target doesn't support i64, demote
|
|
|
|
// the computation to 32-bit if safe.
|
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value
of the loop, not a new indvar with an unusual base.
On PPC, for example, this allows us to compile
LoopStrengthReduce/exit_compare_live_range.ll to:
_foo:
li r2, 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r2, r2, 1
cmpw cr0, r2, r4
bne .LBB_foo_1 ; no_exit
blr
instead of:
_foo:
li r2, 1 ;; IV starts at 1, not 0
.LBB_foo_1: ; no_exit
li r5, 0
stw r5, 0(r3)
addi r5, r2, 1
cmpw cr0, r2, r4
or r2, r5, r5 ;; Reg-reg copy, extra live range
bne .LBB_foo_1 ; no_exit
blr
This implements LoopStrengthReduce/exit_compare_live_range.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22699 91177308-0d34-0410-b5e6-96231b3b80d8
2005-08-08 05:28:22 +00:00
|
|
|
|
2008-07-07 19:51:32 +00:00
|
|
|
// FIXME: Attempt to reuse values across multiple IV's. In particular, we
|
|
|
|
// could have something like "for(i) { foo(i*8); bar(i*16) }", which should
|
|
|
|
// be codegened as "for (j = 0;; j+=8) { foo(j); bar(j+j); }" on X86/PPC.
|
|
|
|
// Need to be careful that IV's are all the same type. Only works for
|
|
|
|
// intptr_t indvars.
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2008-07-07 19:51:32 +00:00
|
|
|
// IVsByStride keeps IVs for one particular loop.
|
|
|
|
assert(IVsByStride.empty() && "Stale entries in IVsByStride?");
|
|
|
|
|
|
|
|
// Note: this processes each stride/type pair individually. All users
|
|
|
|
// passed into StrengthReduceStridedIVUsers have the same type AND stride.
|
|
|
|
// Also, note that we iterate over IVUsesByStride indirectly by using
|
|
|
|
// StrideOrder. This extra layer of indirection makes the ordering of
|
|
|
|
// strides deterministic - not dependent on map order.
|
|
|
|
for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e; ++Stride) {
|
|
|
|
std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI =
|
|
|
|
IVUsesByStride.find(StrideOrder[Stride]);
|
|
|
|
assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
|
2009-03-09 20:41:15 +00:00
|
|
|
StrengthReduceStridedIVUsers(SI->first, SI->second, L);
|
2008-07-07 19:51:32 +00:00
|
|
|
}
|
2005-10-09 06:20:55 +00:00
|
|
|
}
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2008-05-21 00:54:12 +00:00
|
|
|
// We're done analyzing this loop; release all the state we built up for it.
|
|
|
|
IVUsesByStride.clear();
|
|
|
|
IVsByStride.clear();
|
|
|
|
StrideOrder.clear();
|
|
|
|
|
2004-10-18 21:08:22 +00:00
|
|
|
// Clean up after ourselves
|
2009-05-02 18:29:22 +00:00
|
|
|
if (!DeadInsts.empty())
|
2008-12-01 06:14:28 +00:00
|
|
|
DeleteTriviallyDeadInstructions();
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2009-05-02 18:29:22 +00:00
|
|
|
// At this point, it is worth checking to see if any recurrence PHIs are also
|
2009-05-04 22:30:44 +00:00
|
|
|
// dead, so that we can remove them as well.
|
|
|
|
DeleteDeadPHIs(L->getHeader());
|
2009-05-02 18:29:22 +00:00
|
|
|
|
2008-07-07 19:51:32 +00:00
|
|
|
return Changed;
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|