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
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2009-05-19 20:37:36 +00:00
|
|
|
// This transformation analyzes and transforms the induction variables (and
|
|
|
|
// computations derived from them) into forms suitable for efficient execution
|
|
|
|
// on the target.
|
|
|
|
//
|
2004-10-18 21:08:22 +00:00
|
|
|
// This pass performs a strength reduction on array references inside loops that
|
2009-05-19 20:37:36 +00:00
|
|
|
// have as one or more of their components the loop induction variable, it
|
|
|
|
// rewrites expressions to take advantage of scaled-index addressing modes
|
|
|
|
// available on the target, and it performs a variety of other optimizations
|
|
|
|
// related to loop induction variables.
|
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"
|
2009-05-12 02:17:14 +00:00
|
|
|
#include "llvm/Analysis/IVUsers.h"
|
2004-10-18 21:08:22 +00:00
|
|
|
#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"
|
|
|
|
#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");
|
2009-05-11 22:33:01 +00:00
|
|
|
STATISTIC(NumLoopCond, "Number of loop terminating conds optimized");
|
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
|
|
|
|
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 {
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride;
|
|
|
|
const SCEV* Base;
|
2006-03-16 21:53:05 +00:00
|
|
|
PHINode *PHI;
|
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
IVExpr(const SCEV* const stride, const SCEV* const base, PHINode *phi)
|
2009-03-09 22:04:01 +00:00
|
|
|
: 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-06-22 21:39:50 +00:00
|
|
|
void addIV(const SCEV* const Stride, const SCEV* const Base, PHINode *PHI) {
|
2009-03-09 22:04:01 +00:00
|
|
|
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 {
|
2009-05-12 02:17:14 +00:00
|
|
|
IVUsers *IU;
|
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
|
|
|
|
2006-03-16 21:53:05 +00:00
|
|
|
/// IVsByStride - Keep track of all IVs that have been inserted for a
|
|
|
|
/// particular stride.
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVsOfOneStride> IVsByStride;
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2009-05-11 22:33:01 +00:00
|
|
|
/// StrideNoReuse - Keep track of all the strides whose ivs cannot be
|
|
|
|
/// reused (nor should they be rewritten to reuse other strides).
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallSet<const SCEV*, 4> StrideNoReuse;
|
2009-05-11 22:33:01 +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.
|
2009-05-12 02:17:14 +00:00
|
|
|
SmallVector<WeakVH, 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>();
|
2009-05-12 02:17:14 +00:00
|
|
|
AU.addRequired<IVUsers>();
|
|
|
|
AU.addPreserved<IVUsers>();
|
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:
|
2007-10-25 09:11:16 +00:00
|
|
|
ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|
|
|
IVStrideUse* &CondUse,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* const * &CondStride);
|
2009-05-09 01:08:24 +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
|
|
|
void OptimizeIndvars(Loop *L);
|
2009-05-11 17:15:42 +00:00
|
|
|
void OptimizeLoopCountIV(Loop *L);
|
2009-05-09 01:08:24 +00:00
|
|
|
void OptimizeLoopTermCond(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);
|
|
|
|
|
2009-06-19 23:23:27 +00:00
|
|
|
/// OptimizeMax - Rewrite the loop's terminating condition
|
|
|
|
/// if it uses a max computation.
|
|
|
|
ICmpInst *OptimizeMax(Loop *L, ICmpInst *Cond,
|
|
|
|
IVStrideUse* &CondUse);
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2008-08-13 20:31:11 +00:00
|
|
|
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* const * &CondStride);
|
2007-10-25 22:45:20 +00:00
|
|
|
bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* CheckForIVReuse(bool, bool, bool, const SCEV* const&,
|
2007-10-22 20:40:42 +00:00
|
|
|
IVExpr&, const Type*,
|
2007-03-20 00:47:50 +00:00
|
|
|
const std::vector<BasedUser>& UsersToProcess);
|
2009-05-11 22:33:01 +00:00
|
|
|
bool ValidScale(bool, int64_t,
|
|
|
|
const std::vector<BasedUser>& UsersToProcess);
|
2009-05-12 02:17:14 +00:00
|
|
|
bool ValidOffset(bool, int64_t, int64_t,
|
|
|
|
const std::vector<BasedUser>& UsersToProcess);
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* CollectIVUsers(const SCEV* const &Stride,
|
2007-10-25 22:45:20 +00:00
|
|
|
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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride);
|
2009-02-20 04:17:46 +00:00
|
|
|
void PrepareToStrengthReduceFully(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride,
|
|
|
|
const SCEV* CommonExprs,
|
2009-02-20 04:17:46 +00:00
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter);
|
|
|
|
void PrepareToStrengthReduceFromSmallerStride(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
|
|
|
Value *CommonBaseV,
|
|
|
|
const IVExpr &ReuseIV,
|
|
|
|
Instruction *PreInsertPt);
|
|
|
|
void PrepareToStrengthReduceWithNewPhi(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride,
|
|
|
|
const SCEV* CommonExprs,
|
2009-02-20 04:17:46 +00:00
|
|
|
Value *CommonBaseV,
|
2009-05-11 22:33:01 +00:00
|
|
|
Instruction *IVIncInsertPt,
|
2009-02-20 04:17:46 +00:00
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter);
|
2009-06-22 21:39:50 +00:00
|
|
|
void StrengthReduceStridedIVUsers(const SCEV* const &Stride,
|
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
|
|
|
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;
|
|
|
|
|
2008-12-01 06:14:28 +00:00
|
|
|
while (!DeadInsts.empty()) {
|
2009-05-12 02:17:14 +00:00
|
|
|
Instruction *I = dyn_cast_or_null<Instruction>(DeadInsts.back());
|
2008-12-01 06:14:28 +00:00
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
static bool containsAddRecFromDifferentLoop(const SCEV* S, Loop *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
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
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) {
|
2009-05-18 16:45:28 +00:00
|
|
|
const Type *AccessTy = Inst->getType();
|
2009-03-09 21:01:17 +00:00
|
|
|
if (const StoreInst *SI = dyn_cast<StoreInst>(Inst))
|
2009-05-18 16:45:28 +00:00
|
|
|
AccessTy = SI->getOperand(0)->getType();
|
2009-03-09 21:01:17 +00:00
|
|
|
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:
|
2009-05-18 16:45:28 +00:00
|
|
|
AccessTy = II->getOperand(1)->getType();
|
2009-03-09 21:01:17 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-05-18 16:45:28 +00:00
|
|
|
return AccessTy;
|
2009-03-09 21:01:17 +00:00
|
|
|
}
|
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Base;
|
2005-08-08 22:56:21 +00:00
|
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Imm;
|
2005-07-30 00:15:07 +00:00
|
|
|
|
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)
|
2009-05-12 02:17:14 +00:00
|
|
|
: SE(se), Base(IVSU.getOffset()), Inst(IVSU.getUser()),
|
|
|
|
OperandValToReplace(IVSU.getOperandValToReplace()),
|
2008-12-03 22:43:56 +00:00
|
|
|
Imm(SE->getIntegerSCEV(0, Base->getType())),
|
2009-05-12 02:17:14 +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.
|
2009-06-22 21:39:50 +00:00
|
|
|
void RewriteInstructionToUseNewBase(const SCEV* const &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,
|
2009-05-19 02:15:55 +00:00
|
|
|
LoopInfo &LI,
|
2009-05-12 02:17:14 +00:00
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts);
|
2006-02-04 07:36:50 +00:00
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
Value *InsertCodeForBaseAtPosition(const SCEV* const &NewBase,
|
2009-04-16 03:18:22 +00:00
|
|
|
const Type *Ty,
|
2006-02-04 07:36:50 +00:00
|
|
|
SCEVExpander &Rewriter,
|
2009-05-19 02:15:55 +00:00
|
|
|
Instruction *IP, Loop *L,
|
|
|
|
LoopInfo &LI);
|
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
|
|
|
}
|
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
Value *BasedUser::InsertCodeForBaseAtPosition(const SCEV* const &NewBase,
|
2009-04-16 03:18:22 +00:00
|
|
|
const Type *Ty,
|
2006-02-04 07:36:50 +00:00
|
|
|
SCEVExpander &Rewriter,
|
2009-05-19 02:15:55 +00:00
|
|
|
Instruction *IP, Loop *L,
|
|
|
|
LoopInfo &LI) {
|
2006-02-04 07:36:50 +00:00
|
|
|
// 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.
|
|
|
|
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-05-19 02:15:55 +00:00
|
|
|
Value *Base = Rewriter.expandCodeFor(NewBase, 0, BaseInsertPt);
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* NewValSCEV = SE->getUnknown(Base);
|
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.
|
2009-05-12 02:17:14 +00:00
|
|
|
if (!Imm->isZero()) {
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
// Always emit the immediate (if non-zero) into the same block as the user.
|
|
|
|
NewValSCEV = SE->getAddExpr(NewValSCEV, 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.
|
|
|
|
//
|
2009-06-22 21:39:50 +00:00
|
|
|
void BasedUser::RewriteInstructionToUseNewBase(const SCEV* const &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,
|
2009-05-19 02:15:55 +00:00
|
|
|
LoopInfo &LI,
|
2009-05-12 02:17:14 +00:00
|
|
|
SmallVectorImpl<WeakVH> &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(),
|
2009-05-19 02:15:55 +00:00
|
|
|
Rewriter, InsertPt, L, LI);
|
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(),
|
2009-05-19 02:15:55 +00:00
|
|
|
Rewriter, InsertPt, L, LI);
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
static bool fitsInAddressMode(const SCEV* const &V, const Type *AccessTy,
|
2008-12-05 21:47:27 +00:00
|
|
|
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;
|
2009-05-18 16:45:28 +00:00
|
|
|
return TLI->isLegalAddressingMode(AM, AccessTy);
|
2007-04-09 22:20:14 +00:00
|
|
|
} 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;
|
2009-05-18 16:45:28 +00:00
|
|
|
return TLI->isLegalAddressingMode(AM, AccessTy);
|
2009-05-01 16:29:14 +00:00
|
|
|
} 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
static void MoveLoopVariantsToImmediateField(const SCEV* &Val, const SCEV* &Imm,
|
2009-05-11 22:33:01 +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)) {
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 4> NewOps;
|
2005-08-08 22:32:34 +00:00
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Start = SARE->getStart();
|
2008-12-03 20:56:12 +00:00
|
|
|
MoveLoopVariantsToImmediateField(Start, Imm, L, SE);
|
2005-08-08 22:32:34 +00:00
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 4> Ops(SARE->op_begin(), SARE->op_end());
|
2005-08-08 22:32:34 +00:00
|
|
|
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-05-18 16:45:28 +00:00
|
|
|
const Type *AccessTy,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* &Val, const SCEV* &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)) {
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 4> NewOps;
|
2005-08-04 22:34:05 +00:00
|
|
|
NewOps.reserve(SAE->getNumOperands());
|
|
|
|
|
2006-02-04 07:36:50 +00:00
|
|
|
for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* NewOp = SAE->getOperand(i);
|
2009-05-18 16:45:28 +00:00
|
|
|
MoveImmediateValues(TLI, AccessTy, 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Start = SARE->getStart();
|
2009-05-18 16:45:28 +00:00
|
|
|
MoveImmediateValues(TLI, AccessTy, Start, Imm, isAddress, L, SE);
|
2005-08-04 22:34:05 +00:00
|
|
|
|
|
|
|
if (Start != SARE->getStart()) {
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 4> Ops(SARE->op_begin(), SARE->op_end());
|
2005-08-04 22:34:05 +00:00
|
|
|
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.
|
2009-05-18 16:45:28 +00:00
|
|
|
if (isAddress &&
|
|
|
|
fitsInAddressMode(SME->getOperand(0), AccessTy, TLI, false) &&
|
2006-02-04 07:36:50 +00:00
|
|
|
SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
|
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* SubImm = SE->getIntegerSCEV(0, Val->getType());
|
|
|
|
const SCEV* NewOp = SME->getOperand(1);
|
2009-05-18 16:45:28 +00:00
|
|
|
MoveImmediateValues(TLI, AccessTy, 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));
|
2009-05-18 16:45:28 +00:00
|
|
|
if (fitsInAddressMode(SubImm, AccessTy, 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.
|
2009-05-18 16:45:28 +00:00
|
|
|
if ((isAddress && fitsInAddressMode(Val, AccessTy, 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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* &Val, const SCEV* &Imm,
|
2009-02-21 02:06:47 +00:00
|
|
|
bool isAddress, Loop *L,
|
|
|
|
ScalarEvolution *SE) {
|
2009-05-18 16:45:28 +00:00
|
|
|
const Type *AccessTy = getAccessType(User);
|
|
|
|
MoveImmediateValues(TLI, AccessTy, Val, Imm, isAddress, L, SE);
|
2009-02-21 02:06:47 +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
|
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
static void SeparateSubExprs(SmallVector<const SCEV*, 16> &SubExprs,
|
|
|
|
const SCEV* Expr,
|
2007-10-22 18:31:58 +00:00
|
|
|
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)) {
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 4> Ops(SARE->op_begin(), SARE->op_end());
|
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
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
static const SCEV*
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
|
|
|
|
const SCEV* Result = Zero;
|
|
|
|
const SCEV* 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; };
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 16> UniqueSubExprs;
|
2005-10-11 18:41:04 +00:00
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
SmallVector<const SCEV*, 16> 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);
|
2009-05-18 16:45:28 +00:00
|
|
|
// We may need the AccessTy below, but only when isAddrUse, so compute it
|
2008-12-05 21:47:27 +00:00
|
|
|
// only in that case.
|
2009-05-18 16:45:28 +00:00
|
|
|
const Type *AccessTy = 0;
|
2009-03-09 21:01:17 +00:00
|
|
|
if (isAddrUse)
|
2009-05-18 16:45:28 +00:00
|
|
|
AccessTy = 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]);
|
2009-05-18 16:45:28 +00:00
|
|
|
if (!isAddrUse || !fitsInAddressMode(SubExprs[j], AccessTy, TLI, false))
|
2008-12-05 21:47:27 +00:00
|
|
|
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) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, SubExprUseData>::iterator I =
|
2008-12-05 21:47:27 +00:00
|
|
|
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-05-18 16:45:28 +00:00
|
|
|
const Type *AccessTy = getAccessType(Uses[i].Inst);
|
|
|
|
if (!fitsInAddressMode(FreeResult, AccessTy, TLI, Result!=Zero)) {
|
2008-12-05 21:47:27 +00:00
|
|
|
// 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) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, SubExprUseData>::iterator I =
|
2008-12-05 21:47:27 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-05-11 22:33:01 +00:00
|
|
|
/// ValidScale - 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
|
|
|
///
|
2009-05-11 22:33:01 +00:00
|
|
|
bool LoopStrengthReduce::ValidScale(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;
|
|
|
|
|
2009-05-11 22:33:01 +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-05-12 02:17:14 +00:00
|
|
|
/// ValidOffset - Check whether the given Offset is valid for all loads and
|
|
|
|
/// stores in UsersToProcess.
|
|
|
|
///
|
|
|
|
bool LoopStrengthReduce::ValidOffset(bool HasBaseReg,
|
|
|
|
int64_t Offset,
|
|
|
|
int64_t Scale,
|
|
|
|
const std::vector<BasedUser>& UsersToProcess) {
|
|
|
|
if (!TLI)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) {
|
|
|
|
// If this is a load or other access, pass the type of the access in.
|
|
|
|
const Type *AccessTy = Type::VoidTy;
|
|
|
|
if (isAddressUse(UsersToProcess[i].Inst,
|
|
|
|
UsersToProcess[i].OperandValToReplace))
|
|
|
|
AccessTy = getAccessType(UsersToProcess[i].Inst);
|
|
|
|
else if (isa<PHINode>(UsersToProcess[i].Inst))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
TargetLowering::AddrMode AM;
|
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(UsersToProcess[i].Imm))
|
|
|
|
AM.BaseOffs = SC->getValue()->getSExtValue();
|
|
|
|
AM.BaseOffs = (uint64_t)AM.BaseOffs + (uint64_t)Offset;
|
|
|
|
AM.HasBaseReg = HasBaseReg || !UsersToProcess[i].Base->isZero();
|
|
|
|
AM.Scale = Scale;
|
|
|
|
|
|
|
|
// If load[imm+r*scale] is illegal, bail out.
|
|
|
|
if (!TLI->isLegalAddressingMode(AM, AccessTy))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* const &Stride,
|
2007-03-20 00:47:50 +00:00
|
|
|
IVExpr &IV, const Type *Ty,
|
|
|
|
const std::vector<BasedUser>& UsersToProcess) {
|
2009-05-11 22:33:01 +00:00
|
|
|
if (StrideNoReuse.count(Stride))
|
|
|
|
return SE->getIntegerSCEV(0, Stride->getType());
|
|
|
|
|
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();
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
|
|
|
NewStride != e; ++NewStride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVsOfOneStride>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IVsByStride.find(IU->StrideOrder[NewStride]);
|
2009-05-11 22:33:01 +00:00
|
|
|
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first) ||
|
|
|
|
StrideNoReuse.count(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 &&
|
2009-05-13 00:24:22 +00:00
|
|
|
(unsigned(abs64(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 &&
|
2009-05-12 02:17:14 +00:00
|
|
|
ValidScale(HasBaseReg, Scale, UsersToProcess))) {
|
|
|
|
// Prefer to reuse an IV with a base of zero.
|
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)
|
2009-05-12 02:17:14 +00:00
|
|
|
// Only reuse previous IV if it would not require a type conversion
|
|
|
|
// and if the base difference can be folded.
|
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
|
|
|
}
|
2009-05-12 02:17:14 +00:00
|
|
|
// Otherwise, settle for an IV with a foldable base.
|
|
|
|
if (AllUsesAreAddresses)
|
|
|
|
for (std::vector<IVExpr>::iterator II = SI->second.IVs.begin(),
|
|
|
|
IE = SI->second.IVs.end(); II != IE; ++II)
|
|
|
|
// Only reuse previous IV if it would not require a type conversion
|
|
|
|
// and if the base difference can be folded.
|
|
|
|
if (SE->getEffectiveSCEVType(II->Base->getType()) ==
|
|
|
|
SE->getEffectiveSCEVType(Ty) &&
|
|
|
|
isa<SCEVConstant>(II->Base)) {
|
|
|
|
int64_t Base =
|
|
|
|
cast<SCEVConstant>(II->Base)->getValue()->getSExtValue();
|
|
|
|
if (Base > INT32_MIN && Base <= INT32_MAX &&
|
|
|
|
ValidOffset(HasBaseReg, -Base * Scale,
|
|
|
|
Scale, UsersToProcess)) {
|
|
|
|
IV = *II;
|
|
|
|
return SE->getIntegerSCEV(Scale, 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
|
|
|
} else if (AllUsesAreOutsideLoop) {
|
|
|
|
// Accept nonconstant strides here; it is really really right to substitute
|
|
|
|
// an existing IV if we can.
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
|
|
|
NewStride != e; ++NewStride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVsOfOneStride>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IVsByStride.find(IU->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))
|
|
|
|
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.
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
|
|
|
NewStride != e; ++NewStride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVsOfOneStride>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IVsByStride.find(IU->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())
|
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
static bool isNonConstantNegative(const SCEV* const &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();
|
|
|
|
}
|
|
|
|
|
2009-06-17 17:51:33 +00:00
|
|
|
/// CollectIVUsers - 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 accesses, as 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* LoopStrengthReduce::CollectIVUsers(const SCEV* const &Stride,
|
2007-10-25 22:45:20 +00:00
|
|
|
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-05-12 02:17:14 +00:00
|
|
|
// FIXME: Generalize to non-affine IV's.
|
|
|
|
if (!Stride->isLoopInvariant(L))
|
|
|
|
return SE->getIntegerSCEV(0, Stride->getType());
|
|
|
|
|
2005-07-30 00:15:07 +00:00
|
|
|
UsersToProcess.reserve(Uses.Users.size());
|
2009-05-12 02:17:14 +00:00
|
|
|
for (ilist<IVStrideUse>::iterator I = Uses.Users.begin(),
|
|
|
|
E = Uses.Users.end(); I != E; ++I) {
|
|
|
|
UsersToProcess.push_back(BasedUser(*I, SE));
|
|
|
|
|
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,
|
2009-05-11 22:33:01 +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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride) {
|
2009-02-20 04:17:46 +00:00
|
|
|
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.
|
2009-05-12 02:17:14 +00:00
|
|
|
if (IU->StrideOrder.back() != Stride)
|
2009-02-20 04:17:46 +00:00
|
|
|
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-05-18 16:45:28 +00:00
|
|
|
const Type *AccessTy = getAccessType(Inst);
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Diff = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
|
2009-02-20 04:17:46 +00:00
|
|
|
if (!Diff->isZero() &&
|
|
|
|
(!AllUsesAreAddresses ||
|
2009-05-18 16:45:28 +00:00
|
|
|
!fitsInAddressMode(Diff, AccessTy, TLI, /*HasBaseReg=*/true)))
|
2009-02-20 04:17:46 +00:00
|
|
|
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
|
|
|
///
|
2009-06-22 21:39:50 +00:00
|
|
|
static PHINode *InsertAffinePhi(const SCEV* Start, const SCEV* Step,
|
2009-05-11 22:33:01 +00:00
|
|
|
Instruction *IVIncInsertPt,
|
2009-02-20 04:17:46 +00:00
|
|
|
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);
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* IncAmount = Step;
|
2009-02-20 04:17:46 +00:00
|
|
|
if (isNegative)
|
|
|
|
IncAmount = Rewriter.SE.getNegativeSCEV(Step);
|
|
|
|
|
|
|
|
// Insert an add instruction right before the terminator corresponding
|
2009-05-11 22:33:01 +00:00
|
|
|
// to the back-edge or just before the only use. The location is determined
|
|
|
|
// by the caller and passed in as IVIncInsertPt.
|
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-05-11 22:33:01 +00:00
|
|
|
IVIncInsertPt);
|
2009-02-20 04:17:46 +00:00
|
|
|
} else {
|
|
|
|
IncV = BinaryOperator::CreateAdd(PN, StepV, "lsr.iv.next",
|
2009-05-11 22:33:01 +00:00
|
|
|
IVIncInsertPt);
|
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
|
2009-06-22 21:39:50 +00:00
|
|
|
// const SCEV*'s don't have a deterministic ordering w.r.t to each other, so
|
2009-02-20 04:17:46 +00:00
|
|
|
// 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Base = UsersToProcess[i].Base;
|
2009-02-20 04:17:46 +00:00
|
|
|
|
|
|
|
// 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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride,
|
|
|
|
const SCEV* CommonExprs,
|
2009-02-20 04:17:46 +00:00
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter) {
|
|
|
|
DOUT << " Fully reducing all users\n";
|
|
|
|
|
|
|
|
// Rewrite the UsersToProcess records, creating a separate PHI for each
|
|
|
|
// unique Base value.
|
2009-05-11 22:33:01 +00:00
|
|
|
Instruction *IVIncInsertPt = L->getLoopLatch()->getTerminator();
|
2009-02-20 04:17:46 +00:00
|
|
|
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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Imm = UsersToProcess[i].Imm;
|
|
|
|
const SCEV* Base = UsersToProcess[i].Base;
|
|
|
|
const SCEV* Start = SE->getAddExpr(CommonExprs, Base, Imm);
|
2009-05-11 22:33:01 +00:00
|
|
|
PHINode *Phi = InsertAffinePhi(Start, Stride, IVIncInsertPt, 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-11 22:33:01 +00:00
|
|
|
/// FindIVIncInsertPt - Return the location to insert the increment instruction.
|
|
|
|
/// If the only use if a use of postinc value, (must be the loop termination
|
|
|
|
/// condition), then insert it just before the use.
|
|
|
|
static Instruction *FindIVIncInsertPt(std::vector<BasedUser> &UsersToProcess,
|
|
|
|
const Loop *L) {
|
|
|
|
if (UsersToProcess.size() == 1 &&
|
|
|
|
UsersToProcess[0].isUseOfPostIncrementedValue &&
|
|
|
|
L->contains(UsersToProcess[0].Inst->getParent()))
|
|
|
|
return UsersToProcess[0].Inst;
|
|
|
|
return L->getLoopLatch()->getTerminator();
|
|
|
|
}
|
|
|
|
|
2009-02-20 04:17:46 +00:00
|
|
|
/// PrepareToStrengthReduceWithNewPhi - Insert a new induction variable for the
|
|
|
|
/// given users to share.
|
|
|
|
///
|
|
|
|
void
|
|
|
|
LoopStrengthReduce::PrepareToStrengthReduceWithNewPhi(
|
|
|
|
std::vector<BasedUser> &UsersToProcess,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* Stride,
|
|
|
|
const SCEV* CommonExprs,
|
2009-02-20 04:17:46 +00:00
|
|
|
Value *CommonBaseV,
|
2009-05-11 22:33:01 +00:00
|
|
|
Instruction *IVIncInsertPt,
|
2009-02-20 04:17:46 +00:00
|
|
|
const Loop *L,
|
|
|
|
SCEVExpander &PreheaderRewriter) {
|
|
|
|
DOUT << " Inserting new PHI:\n";
|
|
|
|
|
|
|
|
PHINode *Phi = InsertAffinePhi(SE->getUnknown(CommonBaseV),
|
2009-05-11 22:33:01 +00:00
|
|
|
Stride, IVIncInsertPt, 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";
|
|
|
|
}
|
|
|
|
|
2009-05-11 22:33:01 +00:00
|
|
|
/// PrepareToStrengthReduceFromSmallerStride - Prepare for the given users to
|
|
|
|
/// reuse an induction variable with a stride that is a factor of the current
|
2009-02-20 04:17:46 +00:00
|
|
|
/// 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEV* const &Stride,
|
2007-10-25 22:45:20 +00:00
|
|
|
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;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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-06-22 21:39:50 +00:00
|
|
|
const SCEV* NewCommon = CommonExprs;
|
|
|
|
const SCEV* 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-05-19 02:15:55 +00:00
|
|
|
SCEVExpander Rewriter(*SE);
|
|
|
|
SCEVExpander PreheaderRewriter(*SE);
|
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();
|
2009-05-11 22:33:01 +00:00
|
|
|
Instruction *IVIncInsertPt = LatchBlock->getTerminator();
|
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-06-22 21:39:50 +00:00
|
|
|
const SCEV* RewriteFactor = SE->getIntegerSCEV(0, ReplacedTy);
|
2009-02-20 04:17:46 +00:00
|
|
|
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
|
|
|
|
2009-05-11 17:15:42 +00:00
|
|
|
// If all uses are addresses, check if it is possible to reuse an IV. The
|
|
|
|
// new IV must have a stride that is a multiple of the old stride; the
|
|
|
|
// multiple must be a number that can be encoded in the scale field of the
|
|
|
|
// target addressing mode; and we must have a valid instruction after this
|
|
|
|
// substitution, 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);
|
2009-05-11 22:33:01 +00:00
|
|
|
if (!RewriteFactor->isZero())
|
2009-02-20 04:17:46 +00:00
|
|
|
PrepareToStrengthReduceFromSmallerStride(UsersToProcess, CommonBaseV,
|
|
|
|
ReuseIV, PreInsertPt);
|
2009-05-11 22:33:01 +00:00
|
|
|
else {
|
|
|
|
IVIncInsertPt = FindIVIncInsertPt(UsersToProcess, L);
|
|
|
|
PrepareToStrengthReduceWithNewPhi(UsersToProcess, Stride, CommonExprs,
|
|
|
|
CommonBaseV, IVIncInsertPt,
|
|
|
|
L, PreheaderRewriter);
|
|
|
|
}
|
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()) {
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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()) {
|
2009-05-19 02:15:55 +00:00
|
|
|
BaseV = PreheaderRewriter.expandCodeFor(Base, 0, PreInsertPt);
|
2009-04-16 03:18:22 +00:00
|
|
|
|
|
|
|
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-05-11 22:33:01 +00:00
|
|
|
DOUT << " Examining ";
|
|
|
|
if (User.isUseOfPostIncrementedValue)
|
|
|
|
DOUT << "postinc";
|
|
|
|
else
|
|
|
|
DOUT << "preinc";
|
|
|
|
DOUT << " 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
|
2009-05-11 22:33:01 +00:00
|
|
|
// loop to ensure it is dominated by the increment. In case it's the
|
|
|
|
// only use of the iv, the increment instruction is already before the
|
|
|
|
// use.
|
|
|
|
if (L->contains(User.Inst->getParent()) && User.Inst != IVIncInsertPt)
|
|
|
|
User.Inst->moveBefore(IVIncInsertPt);
|
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
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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-05-12 02:17:14 +00:00
|
|
|
if (SE->getEffectiveSCEVType(RewriteOp->getType()) !=
|
|
|
|
SE->getEffectiveSCEVType(ReplacedTy)) {
|
2009-04-21 01:07:12 +00:00
|
|
|
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()) {
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* typedBase = ReuseIV.Base;
|
2009-05-12 02:17:14 +00:00
|
|
|
if (SE->getEffectiveSCEVType(RewriteExpr->getType()) !=
|
|
|
|
SE->getEffectiveSCEVType(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,
|
2009-05-19 02:15:55 +00:00
|
|
|
Rewriter, L, this, *LI,
|
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.
|
2009-05-12 02:17:14 +00:00
|
|
|
DeadInsts.push_back(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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* const * &CondStride) {
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned Stride = 0, e = IU->StrideOrder.size();
|
|
|
|
Stride != e && !CondUse; ++Stride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
|
|
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
|
|
|
|
|
|
|
for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
|
|
|
|
E = SI->second->Users.end(); UI != E; ++UI)
|
|
|
|
if (UI->getUser() == Cond) {
|
2007-04-03 05:11:24 +00:00
|
|
|
// 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.
|
2009-05-12 02:17:14 +00:00
|
|
|
CondUse = UI;
|
2007-04-03 05:11:24 +00:00
|
|
|
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
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
bool operator()(const SCEV* const &LHS, const SCEV* const &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,
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* const* &CondStride) {
|
2009-05-12 02:17:14 +00:00
|
|
|
// If there's only one stride in the loop, there's nothing to do here.
|
|
|
|
if (IU->StrideOrder.size() < 2)
|
|
|
|
return Cond;
|
|
|
|
// If there are other users of the condition's stride, don't bother
|
|
|
|
// trying to change the condition because the stride will still
|
|
|
|
// remain.
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator I =
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride.find(*CondStride);
|
|
|
|
if (I == IU->IVUsesByStride.end() ||
|
|
|
|
I->second->Users.size() != 1)
|
2007-10-25 09:11:16 +00:00
|
|
|
return Cond;
|
2009-05-12 02:17:14 +00:00
|
|
|
// Only handle constant strides for now.
|
2007-10-25 09:11:16 +00:00
|
|
|
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;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* *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-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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.
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
2009-02-24 01:58:00 +00:00
|
|
|
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 ||
|
2009-05-13 00:24:22 +00:00
|
|
|
abs64(SSInt) < abs64(CmpSSInt) ||
|
2009-04-27 20:35:32 +00:00
|
|
|
(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-06 17:39:26 +00:00
|
|
|
APInt Mul = APInt(BitWidth*2, CmpVal, true);
|
|
|
|
Mul = Mul * APInt(BitWidth*2, Scale, true);
|
2009-02-24 01:58:00 +00:00
|
|
|
// Check for overflow.
|
2009-05-06 18:00:56 +00:00
|
|
|
if (!Mul.isSignedIntN(BitWidth))
|
2009-02-24 01:58:00 +00:00
|
|
|
continue;
|
2009-05-12 02:17:14 +00:00
|
|
|
// Check for overflow in the stride's type too.
|
|
|
|
if (!Mul.isSignedIntN(SE->getTypeSizeInBits(SI->first->getType())))
|
|
|
|
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;
|
2009-05-12 02:17:14 +00:00
|
|
|
for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
|
|
|
|
E = SI->second->Users.end(); UI != E; ++UI) {
|
|
|
|
Value *Op = UI->getOperandValToReplace();
|
|
|
|
|
|
|
|
// If the IVStrideUse implies a cast, check for an actual cast which
|
|
|
|
// can be used to find the original IV expression.
|
|
|
|
if (SE->getEffectiveSCEVType(Op->getType()) !=
|
|
|
|
SE->getEffectiveSCEVType(SI->first->getType())) {
|
|
|
|
CastInst *CI = dyn_cast<CastInst>(Op);
|
|
|
|
// If it's not a simple cast, it's complicated.
|
|
|
|
if (!CI)
|
|
|
|
continue;
|
|
|
|
// If it's a cast from a type other than the stride type,
|
|
|
|
// it's complicated.
|
|
|
|
if (CI->getOperand(0)->getType() != SI->first->getType())
|
|
|
|
continue;
|
|
|
|
// Ok, we found the IV expression in the stride's type.
|
|
|
|
Op = CI->getOperand(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
NewCmpLHS = Op;
|
2009-02-24 01:58:00 +00:00
|
|
|
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?
|
2009-05-12 02:17:14 +00:00
|
|
|
if (NewTyBits != TyBits && !isa<SCEVConstant>(CondUse->getOffset()))
|
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
|
|
|
bool AllUsesAreAddresses = true;
|
|
|
|
bool AllUsesAreOutsideLoop = true;
|
|
|
|
std::vector<BasedUser> UsersToProcess;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
|
2009-02-24 01:58:00 +00:00
|
|
|
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 &&
|
2009-05-11 22:33:01 +00:00
|
|
|
ValidScale(!CommonExprs->isZero(), Scale, UsersToProcess))
|
2009-02-24 01:58:00 +00:00
|
|
|
continue;
|
|
|
|
|
2009-05-27 21:10:47 +00:00
|
|
|
// Avoid rewriting the compare instruction with an iv which has
|
|
|
|
// implicit extension or truncation built into it.
|
|
|
|
// TODO: This is over-conservative.
|
|
|
|
if (SE->getTypeSizeInBits(CondUse->getOffset()->getType()) != TyBits)
|
|
|
|
continue;
|
|
|
|
|
2009-02-24 01:58:00 +00:00
|
|
|
// If scale is negative, use swapped predicate unless it's testing
|
|
|
|
// for equality.
|
|
|
|
if (Scale < 0 && !Cond->isEquality())
|
|
|
|
Predicate = ICmpInst::getSwappedPredicate(Predicate);
|
|
|
|
|
2009-05-12 02:17:14 +00:00
|
|
|
NewStride = &IU->StrideOrder[i];
|
2009-02-24 01:58:00 +00:00
|
|
|
if (!isa<PointerType>(NewCmpTy))
|
|
|
|
NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal);
|
|
|
|
else {
|
2009-06-15 22:12:54 +00:00
|
|
|
Constant *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
|
2009-05-27 21:10:47 +00:00
|
|
|
? SE->getMulExpr(CondUse->getOffset(),
|
2009-06-15 22:12:54 +00:00
|
|
|
SE->getConstant(CmpTy, Scale))
|
|
|
|
: SE->getConstant(NewCmpIntTy,
|
2009-05-27 21:10:47 +00:00
|
|
|
cast<SCEVConstant>(CondUse->getOffset())->getValue()
|
2009-06-15 22:12:54 +00:00
|
|
|
->getSExtValue()*Scale);
|
2009-02-24 01:58:00 +00:00
|
|
|
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.
|
2009-05-12 02:17:14 +00:00
|
|
|
DeadInsts.push_back(CondUse->getOperandValToReplace());
|
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
|
|
|
|
2009-06-18 16:54:06 +00:00
|
|
|
IU->IVUsesByStride[*NewStride]->addUser(NewOffset, Cond, NewCmpLHS);
|
2009-05-12 02:17:14 +00:00
|
|
|
CondUse = &IU->IVUsesByStride[*NewStride]->Users.back();
|
2007-10-25 09:11:16 +00:00
|
|
|
CondStride = NewStride;
|
|
|
|
++NumEliminated;
|
2009-05-02 18:29:22 +00:00
|
|
|
Changed = true;
|
2007-10-25 09:11:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Cond;
|
|
|
|
}
|
|
|
|
|
2009-06-19 23:23:27 +00:00
|
|
|
/// OptimizeMax - Rewrite the loop's terminating condition if it uses
|
|
|
|
/// a max computation.
|
2008-09-15 21:22:06 +00:00
|
|
|
///
|
|
|
|
/// 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);
|
|
|
|
///
|
2009-06-19 23:23:27 +00:00
|
|
|
/// the trip count isn't just 'n', because 'n' might not be positive. 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:
|
2008-09-15 21:22:06 +00:00
|
|
|
//
|
|
|
|
/// 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
|
2009-06-19 23:23:27 +00:00
|
|
|
/// max expression, which allows it to give the loop a canonical
|
2008-09-15 21:22:06 +00:00
|
|
|
/// induction variable:
|
|
|
|
///
|
|
|
|
/// i = 0;
|
2009-06-19 23:23:27 +00:00
|
|
|
/// max = n < 1 ? 1 : n;
|
2008-09-15 21:22:06 +00:00
|
|
|
/// do {
|
|
|
|
/// p[i] = 0.0;
|
2009-06-19 23:23:27 +00:00
|
|
|
/// } while (++i != max);
|
2008-09-15 21:22:06 +00:00
|
|
|
///
|
|
|
|
/// 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.
|
|
|
|
///
|
2009-06-19 23:23:27 +00:00
|
|
|
ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
|
|
|
|
IVStrideUse* &CondUse) {
|
2008-09-15 21:22:06 +00:00
|
|
|
// 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-06-22 21:39:50 +00:00
|
|
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
2009-02-24 18:55:53 +00:00
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
2008-09-15 21:22:06 +00:00
|
|
|
return Cond;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* IterationCount = SE->getAddExpr(BackedgeTakenCount, One);
|
2008-09-15 21:22:06 +00:00
|
|
|
|
|
|
|
// Check for a max calculation that matches the pattern.
|
2009-06-19 23:23:27 +00:00
|
|
|
if (!isa<SCEVSMaxExpr>(IterationCount) && !isa<SCEVUMaxExpr>(IterationCount))
|
|
|
|
return Cond;
|
|
|
|
const SCEVNAryExpr *Max = cast<SCEVNAryExpr>(IterationCount);
|
|
|
|
if (Max != SE->getSCEV(Sel)) return Cond;
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2009-06-19 23:41:37 +00:00
|
|
|
// To handle a max with more than two operands, this optimization would
|
2009-06-19 23:03:46 +00:00
|
|
|
// require additional checking and setup.
|
2009-06-19 23:23:27 +00:00
|
|
|
if (Max->getNumOperands() != 2)
|
2009-06-19 23:03:46 +00:00
|
|
|
return Cond;
|
|
|
|
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* MaxLHS = Max->getOperand(0);
|
|
|
|
const SCEV* MaxRHS = Max->getOperand(1);
|
2009-06-19 23:23:27 +00:00
|
|
|
if (!MaxLHS || MaxLHS != One) return Cond;
|
2008-09-15 21:22:06 +00:00
|
|
|
|
|
|
|
// Check the relevant induction variable for conformance to
|
|
|
|
// the pattern.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* 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;
|
2009-06-19 23:23:27 +00:00
|
|
|
if (SE->getSCEV(Sel->getOperand(1)) == MaxRHS)
|
2008-09-15 21:22:06 +00:00
|
|
|
NewRHS = Sel->getOperand(1);
|
2009-06-19 23:23:27 +00:00
|
|
|
else if (SE->getSCEV(Sel->getOperand(2)) == MaxRHS)
|
2008-09-15 21:22:06 +00:00
|
|
|
NewRHS = Sel->getOperand(2);
|
|
|
|
if (!NewRHS) return Cond;
|
|
|
|
|
2009-06-19 23:23:27 +00:00
|
|
|
// Determine the new comparison opcode. It may be signed or unsigned,
|
|
|
|
// and the original comparison may be either equality or inequality.
|
|
|
|
CmpInst::Predicate Pred =
|
|
|
|
isa<SCEVSMaxExpr>(Max) ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT;
|
|
|
|
if (Cond->getPredicate() == CmpInst::ICMP_EQ)
|
|
|
|
Pred = CmpInst::getInversePredicate(Pred);
|
|
|
|
|
2008-09-15 21:22:06 +00:00
|
|
|
// Ok, everything looks ok to change the condition into an SLT or SGE and
|
|
|
|
// delete the max calculation.
|
|
|
|
ICmpInst *NewCond =
|
2009-06-19 23:23:27 +00:00
|
|
|
new ICmpInst(Pred, Cond->getOperand(0), NewRHS, "scmp", Cond);
|
2008-09-15 21:22:06 +00:00
|
|
|
|
|
|
|
// Delete the max calculation instructions.
|
|
|
|
Cond->replaceAllUsesWith(NewCond);
|
2009-05-12 02:17:14 +00:00
|
|
|
CondUse->setUser(NewCond);
|
2008-09-15 21:22:06 +00:00
|
|
|
Instruction *Cmp = cast<Instruction>(Sel->getOperand(0));
|
2009-05-12 02:17:14 +00:00
|
|
|
Cond->eraseFromParent();
|
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
|
|
|
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-06-22 21:39:50 +00:00
|
|
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
2009-02-24 18:55:53 +00:00
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
2008-08-26 17:57:54 +00:00
|
|
|
return;
|
|
|
|
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e;
|
2008-08-26 17:57:54 +00:00
|
|
|
++Stride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
|
|
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
2008-08-26 17:57:54 +00:00
|
|
|
if (!isa<SCEVConstant>(SI->first))
|
|
|
|
continue;
|
|
|
|
|
2009-05-12 02:17:14 +00:00
|
|
|
for (ilist<IVStrideUse>::iterator UI = SI->second->Users.begin(),
|
|
|
|
E = SI->second->Users.end(); UI != E; /* empty */) {
|
|
|
|
ilist<IVStrideUse>::iterator CandidateUI = UI;
|
2008-08-27 17:50:18 +00:00
|
|
|
++UI;
|
2009-05-12 02:17:14 +00:00
|
|
|
Instruction *ShadowUse = CandidateUI->getUser();
|
2008-08-26 17:57:54 +00:00
|
|
|
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);
|
|
|
|
*/
|
2009-05-12 02:17:14 +00:00
|
|
|
if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser()))
|
2008-08-26 17:57:54 +00:00
|
|
|
DestTy = UCast->getDestTy();
|
2009-05-12 02:17:14 +00:00
|
|
|
else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser()))
|
2008-08-26 17:57:54 +00:00
|
|
|
DestTy = SCast->getDestTy();
|
2008-08-27 20:55:23 +00:00
|
|
|
if (!DestTy) continue;
|
|
|
|
|
|
|
|
if (TLI) {
|
2009-05-11 22:33:01 +00:00
|
|
|
// If target does not support DestTy natively then do not apply
|
|
|
|
// this transformation.
|
2008-08-27 20:55:23 +00:00
|
|
|
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;
|
2009-06-15 22:12:54 +00:00
|
|
|
Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
|
2008-08-26 17:57:54 +00:00
|
|
|
|
|
|
|
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. */
|
2009-06-15 22:12:54 +00:00
|
|
|
Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
|
2008-08-26 17:57:54 +00:00
|
|
|
BinaryOperator *NewIncr =
|
2009-06-04 22:49:04 +00:00
|
|
|
BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
|
|
|
|
Instruction::FAdd : Instruction::FSub,
|
2008-08-26 17:57:54 +00:00
|
|
|
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();
|
|
|
|
NumShadow++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-17 17:51:33 +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.
|
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 LoopStrengthReduce::OptimizeIndvars(Loop *L) {
|
|
|
|
// TODO: implement optzns here.
|
|
|
|
|
2008-08-26 17:57:54 +00:00
|
|
|
OptimizeShadowIV(L);
|
2009-05-09 01:08:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// OptimizeLoopTermCond - Change loop terminating condition to use the
|
|
|
|
/// postinc iv when possible.
|
|
|
|
void LoopStrengthReduce::OptimizeLoopTermCond(Loop *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.
|
2009-05-11 22:33:01 +00:00
|
|
|
BasicBlock *LatchBlock = L->getLoopLatch();
|
2009-06-21 23:48:38 +00:00
|
|
|
BasicBlock *ExitingBlock = L->getExitingBlock();
|
|
|
|
if (!ExitingBlock)
|
2009-05-11 22:33:01 +00:00
|
|
|
// Multiple exits, just look at the exit in the latch block if there is one.
|
2009-06-21 23:48:38 +00:00
|
|
|
ExitingBlock = LatchBlock;
|
|
|
|
BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
|
2009-05-11 22:33:01 +00:00
|
|
|
if (!TermBr)
|
|
|
|
return;
|
|
|
|
if (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;
|
|
|
|
|
|
|
|
// Search IVUsesByStride to find Cond's IVUse if there is one.
|
|
|
|
IVStrideUse *CondUse = 0;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* const *CondStride = 0;
|
2009-05-11 22:33:01 +00:00
|
|
|
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
|
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
|
|
|
|
2009-06-21 23:48:38 +00:00
|
|
|
if (ExitingBlock != LatchBlock) {
|
2009-05-11 22:33:01 +00:00
|
|
|
if (!Cond->hasOneUse())
|
|
|
|
// See below, we don't want the condition to be cloned.
|
|
|
|
return;
|
|
|
|
|
|
|
|
// If exiting block is the latch block, we know it's safe and profitable to
|
|
|
|
// transform the icmp to use post-inc iv. Otherwise do so only if it would
|
|
|
|
// not reuse another iv and its iv would be reused by other uses. We are
|
|
|
|
// optimizing for the case where the icmp is the only use of the iv.
|
2009-05-12 02:17:14 +00:00
|
|
|
IVUsersOfOneStride &StrideUses = *IU->IVUsesByStride[*CondStride];
|
|
|
|
for (ilist<IVStrideUse>::iterator I = StrideUses.Users.begin(),
|
|
|
|
E = StrideUses.Users.end(); I != E; ++I) {
|
|
|
|
if (I->getUser() == Cond)
|
2009-05-11 22:33:01 +00:00
|
|
|
continue;
|
2009-05-12 02:17:14 +00:00
|
|
|
if (!I->isUseOfPostIncrementedValue())
|
2009-05-11 22:33:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: This is expensive, and worse still ChangeCompareStride does a
|
|
|
|
// similar check. Can we perform all the icmp related transformations after
|
|
|
|
// StrengthReduceStridedIVUsers?
|
|
|
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(*CondStride)) {
|
|
|
|
int64_t SInt = SC->getValue()->getSExtValue();
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned NewStride = 0, ee = IU->StrideOrder.size(); NewStride != ee;
|
2009-05-11 22:33:01 +00:00
|
|
|
++NewStride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride.find(IU->StrideOrder[NewStride]);
|
2009-05-11 22:33:01 +00:00
|
|
|
if (!isa<SCEVConstant>(SI->first) || SI->first == *CondStride)
|
|
|
|
continue;
|
|
|
|
int64_t SSInt =
|
|
|
|
cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
|
|
|
|
if (SSInt == SInt)
|
|
|
|
return; // This can definitely be reused.
|
2009-05-13 00:24:22 +00:00
|
|
|
if (unsigned(abs64(SSInt)) < SInt || (SSInt % SInt) != 0)
|
2009-05-11 22:33:01 +00:00
|
|
|
continue;
|
|
|
|
int64_t Scale = SSInt / SInt;
|
|
|
|
bool AllUsesAreAddresses = true;
|
|
|
|
bool AllUsesAreOutsideLoop = true;
|
|
|
|
std::vector<BasedUser> UsersToProcess;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
|
2009-05-11 22:33:01 +00:00
|
|
|
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 &&
|
|
|
|
ValidScale(!CommonExprs->isZero(), Scale, UsersToProcess))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StrideNoReuse.insert(*CondStride);
|
|
|
|
}
|
|
|
|
|
2009-06-19 23:23:27 +00:00
|
|
|
// If the trip count is computed in terms of a max (due to ScalarEvolution
|
2008-09-15 21:22:06 +00:00
|
|
|
// being unable to find a sufficient guard, for example), change the loop
|
2009-06-19 23:23:27 +00:00
|
|
|
// comparison to use SLT or ULT instead of NE.
|
|
|
|
Cond = OptimizeMax(L, Cond, CondUse);
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2007-10-25 09:11:16 +00:00
|
|
|
// If possible, change stride and operands of the compare instruction to
|
|
|
|
// eliminate one stride.
|
2009-06-21 23:48:38 +00:00
|
|
|
if (ExitingBlock == LatchBlock)
|
2009-05-11 22:33:01 +00:00
|
|
|
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!
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride[*CondStride]->addUser(CondUse->getOffset(), Cond,
|
2009-06-18 16:54:06 +00:00
|
|
|
CondUse->getOperandValToReplace());
|
2009-05-12 02:17:14 +00:00
|
|
|
CondUse = &IU->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.
|
2009-05-12 02:17:14 +00:00
|
|
|
CondUse->setOffset(SE->getMinusSCEV(CondUse->getOffset(), *CondStride));
|
|
|
|
CondUse->setIsUseOfPostIncrementedValue(true);
|
2008-07-07 19:51:32 +00:00
|
|
|
Changed = true;
|
2009-05-11 22:33:01 +00:00
|
|
|
|
|
|
|
++NumLoopCond;
|
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
|
|
|
|
2009-06-17 17:51:33 +00:00
|
|
|
/// OptimizeLoopCountIV - If, after all sharing of IVs, the IV used for deciding
|
|
|
|
/// when to exit the loop is used only for that purpose, try to rearrange things
|
|
|
|
/// so it counts down to a test against zero.
|
2009-05-11 17:15:42 +00:00
|
|
|
void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
|
|
|
|
|
|
|
|
// If the number of times the loop is executed isn't computable, give up.
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
2009-05-11 17:15:42 +00:00
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Get the terminating condition for the loop if possible (this isn't
|
|
|
|
// necessarily in the latch, or a block that's a predecessor of the header).
|
2009-06-05 22:39:21 +00:00
|
|
|
if (!L->getExitBlock())
|
|
|
|
return; // More than one loop exit blocks.
|
2009-05-11 17:15:42 +00:00
|
|
|
|
|
|
|
// Okay, there is one exit block. Try to find the condition that causes the
|
|
|
|
// loop to be exited.
|
2009-06-05 22:39:21 +00:00
|
|
|
BasicBlock *ExitingBlock = L->getExitingBlock();
|
|
|
|
if (!ExitingBlock)
|
|
|
|
return; // More than one block exiting!
|
2009-05-11 17:15:42 +00:00
|
|
|
|
|
|
|
// Okay, we've computed the exiting block. See what condition causes us to
|
|
|
|
// exit.
|
|
|
|
//
|
|
|
|
// FIXME: we should be able to handle switch instructions (with a single exit)
|
|
|
|
BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
|
|
|
|
if (TermBr == 0) return;
|
|
|
|
assert(TermBr->isConditional() && "If unconditional, it can't be in loop!");
|
|
|
|
if (!isa<ICmpInst>(TermBr->getCondition()))
|
|
|
|
return;
|
|
|
|
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
|
|
|
|
|
|
|
|
// Handle only tests for equality for the moment, and only stride 1.
|
|
|
|
if (Cond->getPredicate() != CmpInst::ICMP_EQ)
|
|
|
|
return;
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* IV = SE->getSCEV(Cond->getOperand(0));
|
2009-05-11 17:15:42 +00:00
|
|
|
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
2009-06-22 21:39:50 +00:00
|
|
|
const SCEV* One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
|
2009-05-11 17:15:42 +00:00
|
|
|
if (!AR || !AR->isAffine() || AR->getStepRecurrence(*SE) != One)
|
|
|
|
return;
|
2009-05-20 00:34:08 +00:00
|
|
|
// If the RHS of the comparison is defined inside the loop, the rewrite
|
|
|
|
// cannot be done.
|
|
|
|
if (Instruction *CR = dyn_cast<Instruction>(Cond->getOperand(1)))
|
|
|
|
if (L->contains(CR->getParent()))
|
|
|
|
return;
|
2009-05-11 17:15:42 +00:00
|
|
|
|
|
|
|
// Make sure the IV is only used for counting. Value may be preinc or
|
|
|
|
// postinc; 2 uses in either case.
|
|
|
|
if (!Cond->getOperand(0)->hasNUses(2))
|
|
|
|
return;
|
|
|
|
PHINode *phi = dyn_cast<PHINode>(Cond->getOperand(0));
|
|
|
|
Instruction *incr;
|
|
|
|
if (phi && phi->getParent()==L->getHeader()) {
|
|
|
|
// value tested is preinc. Find the increment.
|
|
|
|
// A CmpInst is not a BinaryOperator; we depend on this.
|
|
|
|
Instruction::use_iterator UI = phi->use_begin();
|
|
|
|
incr = dyn_cast<BinaryOperator>(UI);
|
|
|
|
if (!incr)
|
|
|
|
incr = dyn_cast<BinaryOperator>(++UI);
|
|
|
|
// 1 use for postinc value, the phi. Unnecessarily conservative?
|
|
|
|
if (!incr || !incr->hasOneUse() || incr->getOpcode()!=Instruction::Add)
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
// Value tested is postinc. Find the phi node.
|
|
|
|
incr = dyn_cast<BinaryOperator>(Cond->getOperand(0));
|
|
|
|
if (!incr || incr->getOpcode()!=Instruction::Add)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Instruction::use_iterator UI = Cond->getOperand(0)->use_begin();
|
|
|
|
phi = dyn_cast<PHINode>(UI);
|
|
|
|
if (!phi)
|
|
|
|
phi = dyn_cast<PHINode>(++UI);
|
|
|
|
// 1 use for preinc value, the increment.
|
|
|
|
if (!phi || phi->getParent()!=L->getHeader() || !phi->hasOneUse())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace the increment with a decrement.
|
|
|
|
BinaryOperator *decr =
|
|
|
|
BinaryOperator::Create(Instruction::Sub, incr->getOperand(0),
|
|
|
|
incr->getOperand(1), "tmp", incr);
|
|
|
|
incr->replaceAllUsesWith(decr);
|
|
|
|
incr->eraseFromParent();
|
|
|
|
|
|
|
|
// Substitute endval-startval for the original startval, and 0 for the
|
|
|
|
// original endval. Since we're only testing for equality this is OK even
|
|
|
|
// if the computation wraps around.
|
|
|
|
BasicBlock *Preheader = L->getLoopPreheader();
|
|
|
|
Instruction *PreInsertPt = Preheader->getTerminator();
|
|
|
|
int inBlock = L->contains(phi->getIncomingBlock(0)) ? 1 : 0;
|
|
|
|
Value *startVal = phi->getIncomingValue(inBlock);
|
|
|
|
Value *endVal = Cond->getOperand(1);
|
|
|
|
// FIXME check for case where both are constant
|
2009-06-15 22:12:54 +00:00
|
|
|
Constant* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0);
|
2009-05-11 17:15:42 +00:00
|
|
|
BinaryOperator *NewStartVal =
|
|
|
|
BinaryOperator::Create(Instruction::Sub, endVal, startVal,
|
|
|
|
"tmp", PreInsertPt);
|
|
|
|
phi->setIncomingValue(inBlock, NewStartVal);
|
|
|
|
Cond->setOperand(1, Zero);
|
|
|
|
|
|
|
|
Changed = true;
|
|
|
|
}
|
|
|
|
|
2007-03-06 21:14:09 +00:00
|
|
|
bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2009-05-12 02:17:14 +00:00
|
|
|
IU = &getAnalysis<IVUsers>();
|
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
|
|
|
|
2009-05-12 02:17:14 +00:00
|
|
|
if (!IU->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-05-12 02:17:14 +00:00
|
|
|
std::stable_sort(IU->StrideOrder.begin(), IU->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-11 22:33:01 +00:00
|
|
|
// Change loop terminating condition to use the postinc iv when possible
|
|
|
|
// and optimize loop terminating compare. FIXME: Move this after
|
|
|
|
// StrengthReduceStridedIVUsers?
|
|
|
|
OptimizeLoopTermCond(L);
|
|
|
|
|
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.
|
2009-05-12 02:17:14 +00:00
|
|
|
for (unsigned Stride = 0, e = IU->StrideOrder.size();
|
|
|
|
Stride != e; ++Stride) {
|
2009-06-22 21:39:50 +00:00
|
|
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
2009-05-12 02:17:14 +00:00
|
|
|
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
|
|
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
|
|
|
// FIXME: Generalize to non-affine IV's.
|
|
|
|
if (!SI->first->isLoopInvariant(L))
|
|
|
|
continue;
|
|
|
|
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
|
|
|
|
2009-05-11 17:15:42 +00:00
|
|
|
// After all sharing is done, see if we can adjust the loop to test against
|
|
|
|
// zero instead of counting up to a maximum. This is usually faster.
|
|
|
|
OptimizeLoopCountIV(L);
|
|
|
|
|
2008-05-21 00:54:12 +00:00
|
|
|
// We're done analyzing this loop; release all the state we built up for it.
|
|
|
|
IVsByStride.clear();
|
2009-05-11 22:33:01 +00:00
|
|
|
StrideNoReuse.clear();
|
2008-05-21 00:54:12 +00:00
|
|
|
|
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
|
|
|
}
|