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
|
|
|
//
|
2010-02-12 10:34:29 +00:00
|
|
|
// Terminology note: this code has a lot of handling for "post-increment" or
|
|
|
|
// "post-inc" users. This is not talking about post-increment addressing modes;
|
|
|
|
// it is instead talking about code like this:
|
|
|
|
//
|
|
|
|
// %i = phi [ 0, %entry ], [ %i.next, %latch ]
|
|
|
|
// ...
|
|
|
|
// %i.next = add %i, 1
|
|
|
|
// %c = icmp eq %i.next, %n
|
|
|
|
//
|
|
|
|
// The SCEV for %i is {0,+,1}<%L>. The SCEV for %i.next is {1,+,1}<%L>, however
|
|
|
|
// it's useful to think about these as the same register, with some uses using
|
|
|
|
// the value of the register before the add and some using // it after. In this
|
|
|
|
// example, the icmp is a post-increment user, since it uses %i.next, which is
|
|
|
|
// the value of the induction variable after the increment. The other common
|
|
|
|
// case of post-increment users is users outside the loop.
|
|
|
|
//
|
|
|
|
// TODO: More sophistication in the way Formulae are generated and filtered.
|
|
|
|
//
|
|
|
|
// TODO: Handle multiple loops at a time.
|
|
|
|
//
|
|
|
|
// TODO: Should TargetLowering::AddrMode::BaseGV be changed to a ConstantExpr
|
|
|
|
// instead of a GlobalValue?
|
|
|
|
//
|
|
|
|
// TODO: When truncation is free, truncate ICmp users' operands to make it a
|
|
|
|
// smaller encoding (on x86 at least).
|
|
|
|
//
|
|
|
|
// TODO: When a negated register is used by an add (such as in a list of
|
|
|
|
// multiple base registers, or as the increment expression in an addrec),
|
|
|
|
// we may not actually need both reg and (-1 * reg) in registers; the
|
|
|
|
// negation can be implemented by using a sub instead of an add. The
|
|
|
|
// lack of support for taking this into consideration when making
|
|
|
|
// register pressure decisions is partly worked around by the "Special"
|
|
|
|
// use kind.
|
|
|
|
//
|
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"
|
2005-03-04 04:04:26 +00:00
|
|
|
#include "llvm/DerivedTypes.h"
|
2009-05-12 02:17:14 +00:00
|
|
|
#include "llvm/Analysis/IVUsers.h"
|
2010-02-12 10:34:29 +00:00
|
|
|
#include "llvm/Analysis/Dominators.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"
|
2011-01-02 22:09:33 +00:00
|
|
|
#include "llvm/Assembly/Writer.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"
|
2010-02-12 10:34:29 +00:00
|
|
|
#include "llvm/ADT/SmallBitVector.h"
|
|
|
|
#include "llvm/ADT/SetVector.h"
|
|
|
|
#include "llvm/ADT/DenseSet.h"
|
2005-07-30 00:15:07 +00:00
|
|
|
#include "llvm/Support/Debug.h"
|
2011-09-27 00:44:14 +00:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2009-05-02 18:29:22 +00:00
|
|
|
#include "llvm/Support/ValueHandle.h"
|
2009-07-26 09:48:23 +00:00
|
|
|
#include "llvm/Support/raw_ostream.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;
|
|
|
|
|
2011-11-26 23:01:57 +00:00
|
|
|
static cl::opt<bool> EnableNested(
|
2011-09-29 01:33:38 +00:00
|
|
|
"enable-lsr-nested", cl::Hidden, cl::desc("Enable LSR on nested loops"));
|
|
|
|
|
2011-11-26 23:01:57 +00:00
|
|
|
static cl::opt<bool> EnableRetry(
|
|
|
|
"enable-lsr-retry", cl::Hidden, cl::desc("Enable LSR retry"));
|
2011-10-11 02:30:45 +00:00
|
|
|
|
|
|
|
// Temporary flag to cleanup congruent phis after LSR phi expansion.
|
|
|
|
// It's currently disabled until we can determine whether it's truly useful or
|
|
|
|
// not. The flag should be removed after the v3.0 release.
|
2012-01-07 07:08:17 +00:00
|
|
|
// This is now needed for ivchains.
|
2011-11-26 23:01:57 +00:00
|
|
|
static cl::opt<bool> EnablePhiElim(
|
2012-01-07 07:08:17 +00:00
|
|
|
"enable-lsr-phielim", cl::Hidden, cl::init(true),
|
|
|
|
cl::desc("Enable LSR phi elimination"));
|
2011-09-27 00:44:14 +00:00
|
|
|
|
2012-01-09 21:18:52 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
// Stress test IV chain generation.
|
|
|
|
static cl::opt<bool> StressIVChain(
|
|
|
|
"stress-ivchain", cl::Hidden, cl::init(false),
|
|
|
|
cl::desc("Stress test LSR IV chains"));
|
|
|
|
#else
|
|
|
|
static bool StressIVChain = false;
|
|
|
|
#endif
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// RegSortData - This class holds data which is used to order reuse candidates.
|
|
|
|
class RegSortData {
|
|
|
|
public:
|
|
|
|
/// UsedByIndices - This represents the set of LSRUse indices which reference
|
|
|
|
/// a particular register.
|
|
|
|
SmallBitVector UsedByIndices;
|
|
|
|
|
|
|
|
RegSortData() {}
|
|
|
|
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void RegSortData::print(raw_ostream &OS) const {
|
|
|
|
OS << "[NumUses=" << UsedByIndices.count() << ']';
|
|
|
|
}
|
2007-03-20 00:47:50 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void RegSortData::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
|
|
|
}
|
2007-03-20 00:47:50 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
namespace {
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// RegUseTracker - Map register candidates to information about how they are
|
|
|
|
/// used.
|
|
|
|
class RegUseTracker {
|
|
|
|
typedef DenseMap<const SCEV *, RegSortData> RegUsesTy;
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2010-05-18 22:33:00 +00:00
|
|
|
RegUsesTy RegUsesMap;
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallVector<const SCEV *, 16> RegSequence;
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
public:
|
|
|
|
void CountRegister(const SCEV *Reg, size_t LUIdx);
|
2010-05-18 23:42:37 +00:00
|
|
|
void DropRegister(const SCEV *Reg, size_t LUIdx);
|
2010-10-07 23:33:43 +00:00
|
|
|
void SwapAndDropUse(size_t LUIdx, size_t LastLUIdx);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
bool isRegUsedByUsesOtherThan(const SCEV *Reg, size_t LUIdx) const;
|
|
|
|
|
|
|
|
const SmallBitVector &getUsedByIndices(const SCEV *Reg) const;
|
|
|
|
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
typedef SmallVectorImpl<const SCEV *>::iterator iterator;
|
|
|
|
typedef SmallVectorImpl<const SCEV *>::const_iterator const_iterator;
|
|
|
|
iterator begin() { return RegSequence.begin(); }
|
|
|
|
iterator end() { return RegSequence.end(); }
|
|
|
|
const_iterator begin() const { return RegSequence.begin(); }
|
|
|
|
const_iterator end() const { return RegSequence.end(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RegUseTracker::CountRegister(const SCEV *Reg, size_t LUIdx) {
|
|
|
|
std::pair<RegUsesTy::iterator, bool> Pair =
|
2010-05-18 22:33:00 +00:00
|
|
|
RegUsesMap.insert(std::make_pair(Reg, RegSortData()));
|
2010-02-12 10:34:29 +00:00
|
|
|
RegSortData &RSD = Pair.first->second;
|
|
|
|
if (Pair.second)
|
|
|
|
RegSequence.push_back(Reg);
|
|
|
|
RSD.UsedByIndices.resize(std::max(RSD.UsedByIndices.size(), LUIdx + 1));
|
|
|
|
RSD.UsedByIndices.set(LUIdx);
|
|
|
|
}
|
|
|
|
|
2010-05-18 23:42:37 +00:00
|
|
|
void
|
|
|
|
RegUseTracker::DropRegister(const SCEV *Reg, size_t LUIdx) {
|
|
|
|
RegUsesTy::iterator It = RegUsesMap.find(Reg);
|
|
|
|
assert(It != RegUsesMap.end());
|
|
|
|
RegSortData &RSD = It->second;
|
|
|
|
assert(RSD.UsedByIndices.size() > LUIdx);
|
|
|
|
RSD.UsedByIndices.reset(LUIdx);
|
|
|
|
}
|
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
void
|
2010-10-07 23:33:43 +00:00
|
|
|
RegUseTracker::SwapAndDropUse(size_t LUIdx, size_t LastLUIdx) {
|
|
|
|
assert(LUIdx <= LastLUIdx);
|
|
|
|
|
|
|
|
// Update RegUses. The data structure is not optimized for this purpose;
|
|
|
|
// we must iterate through it and update each of the bit vectors.
|
2010-05-19 23:43:12 +00:00
|
|
|
for (RegUsesTy::iterator I = RegUsesMap.begin(), E = RegUsesMap.end();
|
2010-10-07 23:33:43 +00:00
|
|
|
I != E; ++I) {
|
|
|
|
SmallBitVector &UsedByIndices = I->second.UsedByIndices;
|
|
|
|
if (LUIdx < UsedByIndices.size())
|
|
|
|
UsedByIndices[LUIdx] =
|
|
|
|
LastLUIdx < UsedByIndices.size() ? UsedByIndices[LastLUIdx] : 0;
|
|
|
|
UsedByIndices.resize(std::min(UsedByIndices.size(), LastLUIdx));
|
|
|
|
}
|
2010-05-19 23:43:12 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
bool
|
|
|
|
RegUseTracker::isRegUsedByUsesOtherThan(const SCEV *Reg, size_t LUIdx) const {
|
2010-08-29 15:18:49 +00:00
|
|
|
RegUsesTy::const_iterator I = RegUsesMap.find(Reg);
|
|
|
|
if (I == RegUsesMap.end())
|
|
|
|
return false;
|
|
|
|
const SmallBitVector &UsedByIndices = I->second.UsedByIndices;
|
2010-02-12 10:34:29 +00:00
|
|
|
int i = UsedByIndices.find_first();
|
|
|
|
if (i == -1) return false;
|
|
|
|
if ((size_t)i != LUIdx) return true;
|
|
|
|
return UsedByIndices.find_next(i) != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SmallBitVector &RegUseTracker::getUsedByIndices(const SCEV *Reg) const {
|
2010-05-18 22:33:00 +00:00
|
|
|
RegUsesTy::const_iterator I = RegUsesMap.find(Reg);
|
|
|
|
assert(I != RegUsesMap.end() && "Unknown register!");
|
2010-02-12 10:34:29 +00:00
|
|
|
return I->second.UsedByIndices;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RegUseTracker::clear() {
|
2010-05-18 22:33:00 +00:00
|
|
|
RegUsesMap.clear();
|
2010-02-12 10:34:29 +00:00
|
|
|
RegSequence.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// Formula - This class holds information that describes a formula for
|
|
|
|
/// computing satisfying a use. It may include broken-out immediates and scaled
|
|
|
|
/// registers.
|
|
|
|
struct Formula {
|
|
|
|
/// AM - This is used to represent complex addressing, as well as other kinds
|
|
|
|
/// of interesting uses.
|
|
|
|
TargetLowering::AddrMode AM;
|
|
|
|
|
|
|
|
/// BaseRegs - The list of "base" registers for this use. When this is
|
|
|
|
/// non-empty, AM.HasBaseReg should be set to true.
|
|
|
|
SmallVector<const SCEV *, 2> BaseRegs;
|
|
|
|
|
|
|
|
/// ScaledReg - The 'scaled' register for this use. This should be non-null
|
|
|
|
/// when AM.Scale is not zero.
|
|
|
|
const SCEV *ScaledReg;
|
|
|
|
|
2011-05-03 00:46:49 +00:00
|
|
|
/// UnfoldedOffset - An additional constant offset which added near the
|
|
|
|
/// use. This requires a temporary register, but the offset itself can
|
|
|
|
/// live in an add immediate field rather than a register.
|
|
|
|
int64_t UnfoldedOffset;
|
|
|
|
|
|
|
|
Formula() : ScaledReg(0), UnfoldedOffset(0) {}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-11-17 21:41:58 +00:00
|
|
|
void InitialMatch(const SCEV *S, Loop *L, ScalarEvolution &SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
unsigned getNumRegs() const;
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *getType() const;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-05-20 15:17:54 +00:00
|
|
|
void DeleteBaseReg(const SCEV *&S);
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
bool referencesReg(const SCEV *S) const;
|
|
|
|
bool hasRegsUsedByUsesOtherThan(size_t LUIdx,
|
|
|
|
const RegUseTracker &RegUses) const;
|
|
|
|
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-03-01 17:49:51 +00:00
|
|
|
/// DoInitialMatch - Recursion helper for InitialMatch.
|
2010-02-12 10:34:29 +00:00
|
|
|
static void DoInitialMatch(const SCEV *S, Loop *L,
|
|
|
|
SmallVectorImpl<const SCEV *> &Good,
|
|
|
|
SmallVectorImpl<const SCEV *> &Bad,
|
2010-11-17 21:41:58 +00:00
|
|
|
ScalarEvolution &SE) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Collect expressions which properly dominate the loop header.
|
2010-11-17 21:41:58 +00:00
|
|
|
if (SE.properlyDominates(S, L->getHeader())) {
|
2010-02-12 10:34:29 +00:00
|
|
|
Good.push_back(S);
|
|
|
|
return;
|
|
|
|
}
|
2006-03-16 21:53:05 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Look at add operands.
|
|
|
|
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
|
|
|
for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
|
|
|
|
I != E; ++I)
|
2010-11-17 21:41:58 +00:00
|
|
|
DoInitialMatch(*I, L, Good, Bad, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
return;
|
|
|
|
}
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Look at addrec operands.
|
|
|
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
|
|
|
|
if (!AR->getStart()->isZero()) {
|
2010-11-17 21:41:58 +00:00
|
|
|
DoInitialMatch(AR->getStart(), L, Good, Bad, SE);
|
2010-05-03 22:09:21 +00:00
|
|
|
DoInitialMatch(SE.getAddRecExpr(SE.getConstant(AR->getType(), 0),
|
2010-02-12 10:34:29 +00:00
|
|
|
AR->getStepRecurrence(SE),
|
2011-03-14 16:50:06 +00:00
|
|
|
// FIXME: AR->getNoWrapFlags()
|
|
|
|
AR->getLoop(), SCEV::FlagAnyWrap),
|
2010-11-17 21:41:58 +00:00
|
|
|
L, Good, Bad, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
return;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2009-04-16 03:18:22 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Handle a multiplication by -1 (negation) if it didn't fold.
|
|
|
|
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S))
|
|
|
|
if (Mul->getOperand(0)->isAllOnesValue()) {
|
|
|
|
SmallVector<const SCEV *, 4> Ops(Mul->op_begin()+1, Mul->op_end());
|
|
|
|
const SCEV *NewMul = SE.getMulExpr(Ops);
|
|
|
|
|
|
|
|
SmallVector<const SCEV *, 4> MyGood;
|
|
|
|
SmallVector<const SCEV *, 4> MyBad;
|
2010-11-17 21:41:58 +00:00
|
|
|
DoInitialMatch(NewMul, L, MyGood, MyBad, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
const SCEV *NegOne = SE.getSCEV(ConstantInt::getAllOnesValue(
|
|
|
|
SE.getEffectiveSCEVType(NewMul->getType())));
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = MyGood.begin(),
|
|
|
|
E = MyGood.end(); I != E; ++I)
|
|
|
|
Good.push_back(SE.getMulExpr(NegOne, *I));
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = MyBad.begin(),
|
|
|
|
E = MyBad.end(); I != E; ++I)
|
|
|
|
Bad.push_back(SE.getMulExpr(NegOne, *I));
|
|
|
|
return;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Ok, we can't do anything interesting. Just stuff the whole thing into a
|
|
|
|
// register and hope for the best.
|
|
|
|
Bad.push_back(S);
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2008-05-13 00:00:25 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// InitialMatch - Incorporate loop-variant parts of S into this Formula,
|
|
|
|
/// attempting to keep all loop-invariant and loop-computable values in a
|
|
|
|
/// single base register.
|
2010-11-17 21:41:58 +00:00
|
|
|
void Formula::InitialMatch(const SCEV *S, Loop *L, ScalarEvolution &SE) {
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallVector<const SCEV *, 4> Good;
|
|
|
|
SmallVector<const SCEV *, 4> Bad;
|
2010-11-17 21:41:58 +00:00
|
|
|
DoInitialMatch(S, L, Good, Bad, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!Good.empty()) {
|
2010-04-08 23:36:27 +00:00
|
|
|
const SCEV *Sum = SE.getAddExpr(Good);
|
|
|
|
if (!Sum->isZero())
|
|
|
|
BaseRegs.push_back(Sum);
|
2010-02-12 10:34:29 +00:00
|
|
|
AM.HasBaseReg = true;
|
|
|
|
}
|
|
|
|
if (!Bad.empty()) {
|
2010-04-08 23:36:27 +00:00
|
|
|
const SCEV *Sum = SE.getAddExpr(Bad);
|
|
|
|
if (!Sum->isZero())
|
|
|
|
BaseRegs.push_back(Sum);
|
2010-02-12 10:34:29 +00:00
|
|
|
AM.HasBaseReg = true;
|
|
|
|
}
|
|
|
|
}
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// getNumRegs - Return the total number of register operands used by this
|
|
|
|
/// formula. This does not include register uses implied by non-constant
|
|
|
|
/// addrec strides.
|
|
|
|
unsigned Formula::getNumRegs() const {
|
|
|
|
return !!ScaledReg + BaseRegs.size();
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// getType - Return the type of this formula, if it has one, or null
|
|
|
|
/// otherwise. This type is meaningless except for the bit size.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *Formula::getType() const {
|
2010-02-12 10:34:29 +00:00
|
|
|
return !BaseRegs.empty() ? BaseRegs.front()->getType() :
|
|
|
|
ScaledReg ? ScaledReg->getType() :
|
|
|
|
AM.BaseGV ? AM.BaseGV->getType() :
|
|
|
|
0;
|
|
|
|
}
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-05-20 15:17:54 +00:00
|
|
|
/// DeleteBaseReg - Delete the given base reg from the BaseRegs list.
|
|
|
|
void Formula::DeleteBaseReg(const SCEV *&S) {
|
|
|
|
if (&S != &BaseRegs.back())
|
|
|
|
std::swap(S, BaseRegs.back());
|
|
|
|
BaseRegs.pop_back();
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// referencesReg - Test if this formula references the given register.
|
|
|
|
bool Formula::referencesReg(const SCEV *S) const {
|
|
|
|
return S == ScaledReg ||
|
|
|
|
std::find(BaseRegs.begin(), BaseRegs.end(), S) != BaseRegs.end();
|
|
|
|
}
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// hasRegsUsedByUsesOtherThan - Test whether this formula uses registers
|
|
|
|
/// which are used by uses other than the use with the given index.
|
|
|
|
bool Formula::hasRegsUsedByUsesOtherThan(size_t LUIdx,
|
|
|
|
const RegUseTracker &RegUses) const {
|
|
|
|
if (ScaledReg)
|
|
|
|
if (RegUses.isRegUsedByUsesOtherThan(ScaledReg, LUIdx))
|
|
|
|
return true;
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
|
|
|
|
E = BaseRegs.end(); I != E; ++I)
|
|
|
|
if (RegUses.isRegUsedByUsesOtherThan(*I, LUIdx))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Formula::print(raw_ostream &OS) const {
|
|
|
|
bool First = true;
|
|
|
|
if (AM.BaseGV) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
WriteAsOperand(OS, AM.BaseGV, /*PrintType=*/false);
|
|
|
|
}
|
|
|
|
if (AM.BaseOffs != 0) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
OS << AM.BaseOffs;
|
|
|
|
}
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
|
|
|
|
E = BaseRegs.end(); I != E; ++I) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
OS << "reg(" << **I << ')';
|
|
|
|
}
|
2010-05-18 22:35:55 +00:00
|
|
|
if (AM.HasBaseReg && BaseRegs.empty()) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
OS << "**error: HasBaseReg**";
|
|
|
|
} else if (!AM.HasBaseReg && !BaseRegs.empty()) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
OS << "**error: !HasBaseReg**";
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
if (AM.Scale != 0) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
OS << AM.Scale << "*reg(";
|
|
|
|
if (ScaledReg)
|
|
|
|
OS << *ScaledReg;
|
|
|
|
else
|
|
|
|
OS << "<unknown>";
|
|
|
|
OS << ')';
|
|
|
|
}
|
2011-05-03 00:46:49 +00:00
|
|
|
if (UnfoldedOffset != 0) {
|
|
|
|
if (!First) OS << " + "; else First = false;
|
|
|
|
OS << "imm(" << UnfoldedOffset << ')';
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Formula::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
|
|
|
}
|
|
|
|
|
2010-02-19 19:32:49 +00:00
|
|
|
/// isAddRecSExtable - Return true if the given addrec can be sign-extended
|
|
|
|
/// without changing its value.
|
|
|
|
static bool isAddRecSExtable(const SCEVAddRecExpr *AR, ScalarEvolution &SE) {
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *WideTy =
|
2010-05-20 19:44:23 +00:00
|
|
|
IntegerType::get(SE.getContext(), SE.getTypeSizeInBits(AR->getType()) + 1);
|
2010-02-19 19:32:49 +00:00
|
|
|
return isa<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isAddSExtable - Return true if the given add can be sign-extended
|
|
|
|
/// without changing its value.
|
|
|
|
static bool isAddSExtable(const SCEVAddExpr *A, ScalarEvolution &SE) {
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *WideTy =
|
2010-05-20 19:44:23 +00:00
|
|
|
IntegerType::get(SE.getContext(), SE.getTypeSizeInBits(A->getType()) + 1);
|
2010-02-19 19:32:49 +00:00
|
|
|
return isa<SCEVAddExpr>(SE.getSignExtendExpr(A, WideTy));
|
|
|
|
}
|
|
|
|
|
2010-06-24 16:45:11 +00:00
|
|
|
/// isMulSExtable - Return true if the given mul can be sign-extended
|
2010-02-19 19:32:49 +00:00
|
|
|
/// without changing its value.
|
2010-06-24 16:45:11 +00:00
|
|
|
static bool isMulSExtable(const SCEVMulExpr *M, ScalarEvolution &SE) {
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *WideTy =
|
2010-06-24 16:45:11 +00:00
|
|
|
IntegerType::get(SE.getContext(),
|
|
|
|
SE.getTypeSizeInBits(M->getType()) * M->getNumOperands());
|
|
|
|
return isa<SCEVMulExpr>(SE.getSignExtendExpr(M, WideTy));
|
2010-02-19 19:32:49 +00:00
|
|
|
}
|
|
|
|
|
2010-02-19 19:35:48 +00:00
|
|
|
/// getExactSDiv - Return an expression for LHS /s RHS, if it can be determined
|
|
|
|
/// and if the remainder is known to be zero, or null otherwise. If
|
|
|
|
/// IgnoreSignificantBits is true, expressions like (X * Y) /s Y are simplified
|
|
|
|
/// to Y, ignoring that the multiplication may overflow, which is useful when
|
|
|
|
/// the result will be used in a context where the most significant bits are
|
|
|
|
/// ignored.
|
|
|
|
static const SCEV *getExactSDiv(const SCEV *LHS, const SCEV *RHS,
|
|
|
|
ScalarEvolution &SE,
|
|
|
|
bool IgnoreSignificantBits = false) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Handle the trivial case, which works for any SCEV type.
|
|
|
|
if (LHS == RHS)
|
2010-05-03 22:09:21 +00:00
|
|
|
return SE.getConstant(LHS->getType(), 1);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-06-24 16:51:25 +00:00
|
|
|
// Handle a few RHS special cases.
|
|
|
|
const SCEVConstant *RC = dyn_cast<SCEVConstant>(RHS);
|
|
|
|
if (RC) {
|
|
|
|
const APInt &RA = RC->getValue()->getValue();
|
|
|
|
// Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do
|
|
|
|
// some folding.
|
|
|
|
if (RA.isAllOnesValue())
|
|
|
|
return SE.getMulExpr(LHS, RC);
|
|
|
|
// Handle x /s 1 as x.
|
|
|
|
if (RA == 1)
|
|
|
|
return LHS;
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Check for a division of a constant by a constant.
|
|
|
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(LHS)) {
|
|
|
|
if (!RC)
|
|
|
|
return 0;
|
2010-06-24 16:51:25 +00:00
|
|
|
const APInt &LA = C->getValue()->getValue();
|
|
|
|
const APInt &RA = RC->getValue()->getValue();
|
|
|
|
if (LA.srem(RA) != 0)
|
2010-02-12 10:34:29 +00:00
|
|
|
return 0;
|
2010-06-24 16:51:25 +00:00
|
|
|
return SE.getConstant(LA.sdiv(RA));
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
2010-02-19 19:32:49 +00:00
|
|
|
// Distribute the sdiv over addrec operands, if the addrec doesn't overflow.
|
2010-02-12 10:34:29 +00:00
|
|
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS)) {
|
2010-02-19 19:32:49 +00:00
|
|
|
if (IgnoreSignificantBits || isAddRecSExtable(AR, SE)) {
|
2010-02-19 19:35:48 +00:00
|
|
|
const SCEV *Step = getExactSDiv(AR->getStepRecurrence(SE), RHS, SE,
|
|
|
|
IgnoreSignificantBits);
|
2010-02-19 19:32:49 +00:00
|
|
|
if (!Step) return 0;
|
2010-08-19 01:02:31 +00:00
|
|
|
const SCEV *Start = getExactSDiv(AR->getStart(), RHS, SE,
|
|
|
|
IgnoreSignificantBits);
|
|
|
|
if (!Start) return 0;
|
2011-03-14 16:50:06 +00:00
|
|
|
// FlagNW is independent of the start value, step direction, and is
|
|
|
|
// preserved with smaller magnitude steps.
|
|
|
|
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
|
|
|
|
return SE.getAddRecExpr(Start, Step, AR->getLoop(), SCEV::FlagAnyWrap);
|
2010-02-19 19:32:49 +00:00
|
|
|
}
|
2010-06-24 16:57:52 +00:00
|
|
|
return 0;
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
2010-02-19 19:32:49 +00:00
|
|
|
// Distribute the sdiv over add operands, if the add doesn't overflow.
|
2010-02-12 10:34:29 +00:00
|
|
|
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(LHS)) {
|
2010-02-19 19:32:49 +00:00
|
|
|
if (IgnoreSignificantBits || isAddSExtable(Add, SE)) {
|
|
|
|
SmallVector<const SCEV *, 8> Ops;
|
|
|
|
for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
|
|
|
|
I != E; ++I) {
|
2010-02-19 19:35:48 +00:00
|
|
|
const SCEV *Op = getExactSDiv(*I, RHS, SE,
|
|
|
|
IgnoreSignificantBits);
|
2010-02-19 19:32:49 +00:00
|
|
|
if (!Op) return 0;
|
|
|
|
Ops.push_back(Op);
|
|
|
|
}
|
|
|
|
return SE.getAddExpr(Ops);
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
2010-06-24 16:57:52 +00:00
|
|
|
return 0;
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check for a multiply operand that we can pull RHS out of.
|
2010-06-24 16:57:52 +00:00
|
|
|
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(LHS)) {
|
2010-02-19 19:32:49 +00:00
|
|
|
if (IgnoreSignificantBits || isMulSExtable(Mul, SE)) {
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallVector<const SCEV *, 4> Ops;
|
|
|
|
bool Found = false;
|
|
|
|
for (SCEVMulExpr::op_iterator I = Mul->op_begin(), E = Mul->op_end();
|
|
|
|
I != E; ++I) {
|
2010-05-20 16:23:28 +00:00
|
|
|
const SCEV *S = *I;
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!Found)
|
2010-05-20 16:23:28 +00:00
|
|
|
if (const SCEV *Q = getExactSDiv(S, RHS, SE,
|
2010-02-19 19:35:48 +00:00
|
|
|
IgnoreSignificantBits)) {
|
2010-05-20 16:23:28 +00:00
|
|
|
S = Q;
|
2010-02-12 10:34:29 +00:00
|
|
|
Found = true;
|
|
|
|
}
|
2010-05-20 16:23:28 +00:00
|
|
|
Ops.push_back(S);
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
return Found ? SE.getMulExpr(Ops) : 0;
|
|
|
|
}
|
2010-06-24 16:57:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Otherwise we don't know.
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ExtractImmediate - If S involves the addition of a constant integer value,
|
|
|
|
/// return that integer value, and mutate S to point to a new SCEV with that
|
|
|
|
/// value excluded.
|
|
|
|
static int64_t ExtractImmediate(const SCEV *&S, ScalarEvolution &SE) {
|
|
|
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
|
|
|
|
if (C->getValue()->getValue().getMinSignedBits() <= 64) {
|
2010-05-03 22:09:21 +00:00
|
|
|
S = SE.getConstant(C->getType(), 0);
|
2010-02-12 10:34:29 +00:00
|
|
|
return C->getValue()->getSExtValue();
|
|
|
|
}
|
|
|
|
} else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
|
|
|
SmallVector<const SCEV *, 8> NewOps(Add->op_begin(), Add->op_end());
|
|
|
|
int64_t Result = ExtractImmediate(NewOps.front(), SE);
|
2010-08-13 21:17:19 +00:00
|
|
|
if (Result != 0)
|
|
|
|
S = SE.getAddExpr(NewOps);
|
2010-02-12 10:34:29 +00:00
|
|
|
return Result;
|
|
|
|
} else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
|
|
|
|
SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
|
|
|
|
int64_t Result = ExtractImmediate(NewOps.front(), SE);
|
2010-08-13 21:17:19 +00:00
|
|
|
if (Result != 0)
|
2011-03-14 16:50:06 +00:00
|
|
|
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
|
|
|
|
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
|
|
|
|
SCEV::FlagAnyWrap);
|
2010-02-12 10:34:29 +00:00
|
|
|
return Result;
|
2009-03-09 21:01:17 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ExtractSymbol - If S involves the addition of a GlobalValue address,
|
|
|
|
/// return that symbol, and mutate S to point to a new SCEV with that
|
|
|
|
/// value excluded.
|
|
|
|
static GlobalValue *ExtractSymbol(const SCEV *&S, ScalarEvolution &SE) {
|
|
|
|
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
|
|
|
|
if (GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue())) {
|
2010-05-03 22:09:21 +00:00
|
|
|
S = SE.getConstant(GV->getType(), 0);
|
2010-02-12 10:34:29 +00:00
|
|
|
return GV;
|
|
|
|
}
|
|
|
|
} else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
|
|
|
SmallVector<const SCEV *, 8> NewOps(Add->op_begin(), Add->op_end());
|
|
|
|
GlobalValue *Result = ExtractSymbol(NewOps.back(), SE);
|
2010-08-13 21:17:19 +00:00
|
|
|
if (Result)
|
|
|
|
S = SE.getAddExpr(NewOps);
|
2010-02-12 10:34:29 +00:00
|
|
|
return Result;
|
|
|
|
} else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
|
|
|
|
SmallVector<const SCEV *, 8> NewOps(AR->op_begin(), AR->op_end());
|
|
|
|
GlobalValue *Result = ExtractSymbol(NewOps.front(), SE);
|
2010-08-13 21:17:19 +00:00
|
|
|
if (Result)
|
2011-03-14 16:50:06 +00:00
|
|
|
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
|
|
|
|
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
|
|
|
|
SCEV::FlagAnyWrap);
|
2010-02-12 10:34:29 +00:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
return 0;
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
/// isAddressUse - Returns true if the specified instruction is using the
|
|
|
|
/// 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_sse_storeu_ps:
|
|
|
|
case Intrinsic::x86_sse2_storeu_pd:
|
|
|
|
case Intrinsic::x86_sse2_storeu_dq:
|
|
|
|
case Intrinsic::x86_sse2_storel_dq:
|
2010-06-30 09:15:28 +00:00
|
|
|
if (II->getArgOperand(0) == OperandVal)
|
2010-01-22 00:46:49 +00:00
|
|
|
isAddress = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return isAddress;
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
/// getAccessType - Return the type of the memory being accessed.
|
2011-07-18 04:54:35 +00:00
|
|
|
static Type *getAccessType(const Instruction *Inst) {
|
|
|
|
Type *AccessTy = Inst->getType();
|
2010-01-22 00:46:49 +00:00
|
|
|
if (const StoreInst *SI = dyn_cast<StoreInst>(Inst))
|
|
|
|
AccessTy = SI->getOperand(0)->getType();
|
|
|
|
else if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
|
|
|
|
// Addressing modes can also be folded into prefetches and a variety
|
|
|
|
// of intrinsics.
|
|
|
|
switch (II->getIntrinsicID()) {
|
|
|
|
default: break;
|
|
|
|
case Intrinsic::x86_sse_storeu_ps:
|
|
|
|
case Intrinsic::x86_sse2_storeu_pd:
|
|
|
|
case Intrinsic::x86_sse2_storeu_dq:
|
|
|
|
case Intrinsic::x86_sse2_storel_dq:
|
2010-06-30 09:15:28 +00:00
|
|
|
AccessTy = II->getArgOperand(0)->getType();
|
2010-01-22 00:46:49 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// All pointers have the same requirements, so canonicalize them to an
|
|
|
|
// arbitrary pointer type to minimize variation.
|
2011-07-18 04:54:35 +00:00
|
|
|
if (PointerType *PTy = dyn_cast<PointerType>(AccessTy))
|
2010-02-12 10:34:29 +00:00
|
|
|
AccessTy = PointerType::get(IntegerType::get(PTy->getContext(), 1),
|
|
|
|
PTy->getAddressSpace());
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
return AccessTy;
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2011-12-06 03:13:31 +00:00
|
|
|
/// isExistingPhi - Return true if this AddRec is already a phi in its loop.
|
|
|
|
static bool isExistingPhi(const SCEVAddRecExpr *AR, ScalarEvolution &SE) {
|
|
|
|
for (BasicBlock::iterator I = AR->getLoop()->getHeader()->begin();
|
|
|
|
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
|
|
|
|
if (SE.isSCEVable(PN->getType()) &&
|
|
|
|
(SE.getEffectiveSCEVType(PN->getType()) ==
|
|
|
|
SE.getEffectiveSCEVType(AR->getType())) &&
|
|
|
|
SE.getSCEV(PN) == AR)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-01-10 01:45:08 +00:00
|
|
|
/// Check if expanding this expression is likely to incur significant cost. This
|
|
|
|
/// is tricky because SCEV doesn't track which expressions are actually computed
|
|
|
|
/// by the current IR.
|
|
|
|
///
|
|
|
|
/// We currently allow expansion of IV increments that involve adds,
|
|
|
|
/// multiplication by constants, and AddRecs from existing phis.
|
|
|
|
///
|
|
|
|
/// TODO: Allow UDivExpr if we can find an existing IV increment that is an
|
|
|
|
/// obvious multiple of the UDivExpr.
|
|
|
|
static bool isHighCostExpansion(const SCEV *S,
|
|
|
|
SmallPtrSet<const SCEV*, 8> &Processed,
|
|
|
|
ScalarEvolution &SE) {
|
|
|
|
// Zero/One operand expressions
|
|
|
|
switch (S->getSCEVType()) {
|
|
|
|
case scUnknown:
|
|
|
|
case scConstant:
|
|
|
|
return false;
|
|
|
|
case scTruncate:
|
|
|
|
return isHighCostExpansion(cast<SCEVTruncateExpr>(S)->getOperand(),
|
|
|
|
Processed, SE);
|
|
|
|
case scZeroExtend:
|
|
|
|
return isHighCostExpansion(cast<SCEVZeroExtendExpr>(S)->getOperand(),
|
|
|
|
Processed, SE);
|
|
|
|
case scSignExtend:
|
|
|
|
return isHighCostExpansion(cast<SCEVSignExtendExpr>(S)->getOperand(),
|
|
|
|
Processed, SE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Processed.insert(S))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
|
|
|
for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
|
|
|
|
I != E; ++I) {
|
|
|
|
if (isHighCostExpansion(*I, Processed, SE))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
|
|
|
|
if (Mul->getNumOperands() == 2) {
|
|
|
|
// Multiplication by a constant is ok
|
|
|
|
if (isa<SCEVConstant>(Mul->getOperand(0)))
|
|
|
|
return isHighCostExpansion(Mul->getOperand(1), Processed, SE);
|
|
|
|
|
|
|
|
// If we have the value of one operand, check if an existing
|
|
|
|
// multiplication already generates this expression.
|
|
|
|
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Mul->getOperand(1))) {
|
|
|
|
Value *UVal = U->getValue();
|
|
|
|
for (Value::use_iterator UI = UVal->use_begin(), UE = UVal->use_end();
|
|
|
|
UI != UE; ++UI) {
|
|
|
|
Instruction *User = cast<Instruction>(*UI);
|
|
|
|
if (User->getOpcode() == Instruction::Mul
|
|
|
|
&& SE.isSCEVable(User->getType())) {
|
|
|
|
return SE.getSCEV(User) == Mul;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
|
|
|
|
if (isExistingPhi(AR, SE))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fow now, consider any other type of expression (div/mul/min/max) high cost.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +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.
|
|
|
|
static bool
|
|
|
|
DeleteTriviallyDeadInstructions(SmallVectorImpl<WeakVH> &DeadInsts) {
|
|
|
|
bool Changed = false;
|
2009-02-19 19:23:27 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
while (!DeadInsts.empty()) {
|
2010-09-18 11:55:34 +00:00
|
|
|
Instruction *I = dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val());
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (I == 0 || !isInstructionTriviallyDead(I))
|
|
|
|
continue;
|
2006-02-04 07:36:50 +00:00
|
|
|
|
2010-02-12 10:34:29 +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;
|
|
|
|
if (U->use_empty())
|
|
|
|
DeadInsts.push_back(U);
|
|
|
|
}
|
2006-02-04 07:36:50 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
I->eraseFromParent();
|
|
|
|
Changed = true;
|
|
|
|
}
|
2009-02-19 19:23:27 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
return Changed;
|
2010-01-22 00:46:49 +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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
namespace {
|
2009-02-19 19:23:27 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// Cost - This class is used to measure and compare candidate formulae.
|
|
|
|
class Cost {
|
|
|
|
/// TODO: Some of these could be merged. Also, a lexical ordering
|
|
|
|
/// isn't always optimal.
|
|
|
|
unsigned NumRegs;
|
|
|
|
unsigned AddRecCost;
|
|
|
|
unsigned NumIVMuls;
|
|
|
|
unsigned NumBaseAdds;
|
|
|
|
unsigned ImmCost;
|
|
|
|
unsigned SetupCost;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Cost()
|
|
|
|
: NumRegs(0), AddRecCost(0), NumIVMuls(0), NumBaseAdds(0), ImmCost(0),
|
|
|
|
SetupCost(0) {}
|
|
|
|
|
|
|
|
bool operator<(const Cost &Other) const;
|
|
|
|
|
|
|
|
void Loose();
|
|
|
|
|
2011-09-26 23:11:04 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
// Once any of the metrics loses, they must all remain losers.
|
|
|
|
bool isValid() {
|
|
|
|
return ((NumRegs | AddRecCost | NumIVMuls | NumBaseAdds
|
|
|
|
| ImmCost | SetupCost) != ~0u)
|
|
|
|
|| ((NumRegs & AddRecCost & NumIVMuls & NumBaseAdds
|
|
|
|
& ImmCost & SetupCost) == ~0u);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool isLoser() {
|
|
|
|
assert(isValid() && "invalid cost");
|
|
|
|
return NumRegs == ~0u;
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void RateFormula(const Formula &F,
|
|
|
|
SmallPtrSet<const SCEV *, 16> &Regs,
|
|
|
|
const DenseSet<const SCEV *> &VisitedRegs,
|
|
|
|
const Loop *L,
|
|
|
|
const SmallVectorImpl<int64_t> &Offsets,
|
2011-12-06 03:13:31 +00:00
|
|
|
ScalarEvolution &SE, DominatorTree &DT,
|
|
|
|
SmallPtrSet<const SCEV *, 16> *LoserRegs = 0);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void RateRegister(const SCEV *Reg,
|
|
|
|
SmallPtrSet<const SCEV *, 16> &Regs,
|
|
|
|
const Loop *L,
|
|
|
|
ScalarEvolution &SE, DominatorTree &DT);
|
2010-02-13 02:06:02 +00:00
|
|
|
void RatePrimaryRegister(const SCEV *Reg,
|
|
|
|
SmallPtrSet<const SCEV *, 16> &Regs,
|
|
|
|
const Loop *L,
|
2011-12-06 03:13:31 +00:00
|
|
|
ScalarEvolution &SE, DominatorTree &DT,
|
|
|
|
SmallPtrSet<const SCEV *, 16> *LoserRegs);
|
2010-02-12 10:34:29 +00:00
|
|
|
};
|
2007-10-30 23:45:15 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// RateRegister - Tally up interesting quantities from the given register.
|
|
|
|
void Cost::RateRegister(const SCEV *Reg,
|
|
|
|
SmallPtrSet<const SCEV *, 16> &Regs,
|
|
|
|
const Loop *L,
|
|
|
|
ScalarEvolution &SE, DominatorTree &DT) {
|
2010-02-13 02:06:02 +00:00
|
|
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Reg)) {
|
|
|
|
if (AR->getLoop() == L)
|
|
|
|
AddRecCost += 1; /// TODO: This should be a function of the stride.
|
|
|
|
|
2011-09-29 01:33:38 +00:00
|
|
|
// If this is an addrec for another loop, don't second-guess its addrec phi
|
|
|
|
// nodes. LSR isn't currently smart enough to reason about more than one
|
|
|
|
// loop at a time. LSR has either already run on inner loops, will not run
|
|
|
|
// on other loops, and cannot be expected to change sibling loops. If the
|
|
|
|
// AddRec exists, consider it's register free and leave it alone. Otherwise,
|
|
|
|
// do not consider this formula at all.
|
|
|
|
else if (!EnableNested || L->contains(AR->getLoop()) ||
|
2010-02-13 02:06:02 +00:00
|
|
|
(!AR->getLoop()->contains(L) &&
|
|
|
|
DT.dominates(L->getHeader(), AR->getLoop()->getHeader()))) {
|
2011-12-06 03:13:31 +00:00
|
|
|
if (isExistingPhi(AR, SE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// For !EnableNested, never rewrite IVs in other loops.
|
2011-09-29 01:33:38 +00:00
|
|
|
if (!EnableNested) {
|
|
|
|
Loose();
|
|
|
|
return;
|
|
|
|
}
|
2010-02-13 02:06:02 +00:00
|
|
|
// If this isn't one of the addrecs that the loop already has, it
|
|
|
|
// would require a costly new phi and add. TODO: This isn't
|
|
|
|
// precisely modeled right now.
|
|
|
|
++NumBaseAdds;
|
2011-09-26 23:11:04 +00:00
|
|
|
if (!Regs.count(AR->getStart())) {
|
2010-02-12 10:34:29 +00:00
|
|
|
RateRegister(AR->getStart(), Regs, L, SE, DT);
|
2011-09-26 23:11:04 +00:00
|
|
|
if (isLoser())
|
|
|
|
return;
|
|
|
|
}
|
2010-02-13 02:06:02 +00:00
|
|
|
}
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-02-13 02:06:02 +00:00
|
|
|
// Add the step value register, if it needs one.
|
|
|
|
// TODO: The non-affine case isn't precisely modeled here.
|
2011-09-26 23:35:25 +00:00
|
|
|
if (!AR->isAffine() || !isa<SCEVConstant>(AR->getOperand(1))) {
|
|
|
|
if (!Regs.count(AR->getOperand(1))) {
|
2010-02-12 10:34:29 +00:00
|
|
|
RateRegister(AR->getOperand(1), Regs, L, SE, DT);
|
2011-09-26 23:35:25 +00:00
|
|
|
if (isLoser())
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2010-02-13 02:06:02 +00:00
|
|
|
++NumRegs;
|
|
|
|
|
|
|
|
// Rough heuristic; favor registers which don't require extra setup
|
|
|
|
// instructions in the preheader.
|
|
|
|
if (!isa<SCEVUnknown>(Reg) &&
|
|
|
|
!isa<SCEVConstant>(Reg) &&
|
|
|
|
!(isa<SCEVAddRecExpr>(Reg) &&
|
|
|
|
(isa<SCEVUnknown>(cast<SCEVAddRecExpr>(Reg)->getStart()) ||
|
|
|
|
isa<SCEVConstant>(cast<SCEVAddRecExpr>(Reg)->getStart()))))
|
|
|
|
++SetupCost;
|
2010-10-07 23:41:58 +00:00
|
|
|
|
|
|
|
NumIVMuls += isa<SCEVMulExpr>(Reg) &&
|
2010-11-17 21:23:15 +00:00
|
|
|
SE.hasComputableLoopEvolution(Reg, L);
|
2010-02-13 02:06:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// RatePrimaryRegister - Record this register in the set. If we haven't seen it
|
2011-12-06 03:13:31 +00:00
|
|
|
/// before, rate it. Optional LoserRegs provides a way to declare any formula
|
|
|
|
/// that refers to one of those regs an instant loser.
|
2010-02-13 02:06:02 +00:00
|
|
|
void Cost::RatePrimaryRegister(const SCEV *Reg,
|
2010-02-16 19:42:34 +00:00
|
|
|
SmallPtrSet<const SCEV *, 16> &Regs,
|
|
|
|
const Loop *L,
|
2011-12-06 03:13:31 +00:00
|
|
|
ScalarEvolution &SE, DominatorTree &DT,
|
|
|
|
SmallPtrSet<const SCEV *, 16> *LoserRegs) {
|
|
|
|
if (LoserRegs && LoserRegs->count(Reg)) {
|
|
|
|
Loose();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Regs.insert(Reg)) {
|
2010-02-13 02:06:02 +00:00
|
|
|
RateRegister(Reg, Regs, L, SE, DT);
|
2011-12-06 03:13:31 +00:00
|
|
|
if (isLoser())
|
|
|
|
LoserRegs->insert(Reg);
|
|
|
|
}
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void Cost::RateFormula(const Formula &F,
|
|
|
|
SmallPtrSet<const SCEV *, 16> &Regs,
|
|
|
|
const DenseSet<const SCEV *> &VisitedRegs,
|
|
|
|
const Loop *L,
|
|
|
|
const SmallVectorImpl<int64_t> &Offsets,
|
2011-12-06 03:13:31 +00:00
|
|
|
ScalarEvolution &SE, DominatorTree &DT,
|
|
|
|
SmallPtrSet<const SCEV *, 16> *LoserRegs) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Tally up the registers.
|
|
|
|
if (const SCEV *ScaledReg = F.ScaledReg) {
|
|
|
|
if (VisitedRegs.count(ScaledReg)) {
|
|
|
|
Loose();
|
|
|
|
return;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2011-12-06 03:13:31 +00:00
|
|
|
RatePrimaryRegister(ScaledReg, Regs, L, SE, DT, LoserRegs);
|
2011-09-26 23:11:04 +00:00
|
|
|
if (isLoser())
|
|
|
|
return;
|
2005-08-08 06:25:50 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
|
|
|
|
E = F.BaseRegs.end(); I != E; ++I) {
|
|
|
|
const SCEV *BaseReg = *I;
|
|
|
|
if (VisitedRegs.count(BaseReg)) {
|
|
|
|
Loose();
|
|
|
|
return;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2011-12-06 03:13:31 +00:00
|
|
|
RatePrimaryRegister(BaseReg, Regs, L, SE, DT, LoserRegs);
|
2011-09-26 23:11:04 +00:00
|
|
|
if (isLoser())
|
|
|
|
return;
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
2011-05-03 00:46:49 +00:00
|
|
|
// Determine how many (unfolded) adds we'll need inside the loop.
|
|
|
|
size_t NumBaseParts = F.BaseRegs.size() + (F.UnfoldedOffset != 0);
|
|
|
|
if (NumBaseParts > 1)
|
|
|
|
NumBaseAdds += NumBaseParts - 1;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Tally up the non-zero immediates.
|
|
|
|
for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
|
|
|
|
E = Offsets.end(); I != E; ++I) {
|
|
|
|
int64_t Offset = (uint64_t)*I + F.AM.BaseOffs;
|
|
|
|
if (F.AM.BaseGV)
|
|
|
|
ImmCost += 64; // Handle symbolic values conservatively.
|
|
|
|
// TODO: This should probably be the pointer size.
|
|
|
|
else if (Offset != 0)
|
|
|
|
ImmCost += APInt(64, Offset, true).getMinSignedBits();
|
|
|
|
}
|
2011-09-26 23:11:04 +00:00
|
|
|
assert(isValid() && "invalid cost");
|
2005-07-30 00:15:07 +00:00
|
|
|
}
|
|
|
|
|
2011-04-15 05:18:47 +00:00
|
|
|
/// Loose - Set this cost to a losing value.
|
2010-02-12 10:34:29 +00:00
|
|
|
void Cost::Loose() {
|
|
|
|
NumRegs = ~0u;
|
|
|
|
AddRecCost = ~0u;
|
|
|
|
NumIVMuls = ~0u;
|
|
|
|
NumBaseAdds = ~0u;
|
|
|
|
ImmCost = ~0u;
|
|
|
|
SetupCost = ~0u;
|
|
|
|
}
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// operator< - Choose the lower cost.
|
|
|
|
bool Cost::operator<(const Cost &Other) const {
|
|
|
|
if (NumRegs != Other.NumRegs)
|
|
|
|
return NumRegs < Other.NumRegs;
|
|
|
|
if (AddRecCost != Other.AddRecCost)
|
|
|
|
return AddRecCost < Other.AddRecCost;
|
|
|
|
if (NumIVMuls != Other.NumIVMuls)
|
|
|
|
return NumIVMuls < Other.NumIVMuls;
|
|
|
|
if (NumBaseAdds != Other.NumBaseAdds)
|
|
|
|
return NumBaseAdds < Other.NumBaseAdds;
|
|
|
|
if (ImmCost != Other.ImmCost)
|
|
|
|
return ImmCost < Other.ImmCost;
|
|
|
|
if (SetupCost != Other.SetupCost)
|
|
|
|
return SetupCost < Other.SetupCost;
|
|
|
|
return false;
|
|
|
|
}
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void Cost::print(raw_ostream &OS) const {
|
|
|
|
OS << NumRegs << " reg" << (NumRegs == 1 ? "" : "s");
|
|
|
|
if (AddRecCost != 0)
|
|
|
|
OS << ", with addrec cost " << AddRecCost;
|
|
|
|
if (NumIVMuls != 0)
|
|
|
|
OS << ", plus " << NumIVMuls << " IV mul" << (NumIVMuls == 1 ? "" : "s");
|
|
|
|
if (NumBaseAdds != 0)
|
|
|
|
OS << ", plus " << NumBaseAdds << " base add"
|
|
|
|
<< (NumBaseAdds == 1 ? "" : "s");
|
|
|
|
if (ImmCost != 0)
|
|
|
|
OS << ", plus " << ImmCost << " imm cost";
|
|
|
|
if (SetupCost != 0)
|
|
|
|
OS << ", plus " << SetupCost << " setup cost";
|
|
|
|
}
|
2005-08-08 22:32:34 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void Cost::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
2005-08-08 22:32:34 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
namespace {
|
2005-08-08 22:32:34 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// LSRFixup - An operand value in an instruction which is to be replaced
|
|
|
|
/// with some equivalent, possibly strength-reduced, replacement.
|
|
|
|
struct LSRFixup {
|
|
|
|
/// UserInst - The instruction which will be updated.
|
|
|
|
Instruction *UserInst;
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// OperandValToReplace - The operand of the instruction which will
|
|
|
|
/// be replaced. The operand may be used more than once; every instance
|
|
|
|
/// will be replaced.
|
|
|
|
Value *OperandValToReplace;
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-04-07 22:27:08 +00:00
|
|
|
/// PostIncLoops - If this user is to use the post-incremented value of an
|
2010-02-12 10:34:29 +00:00
|
|
|
/// induction variable, this variable is non-null and holds the loop
|
|
|
|
/// associated with the induction variable.
|
2010-04-07 22:27:08 +00:00
|
|
|
PostIncLoopSet PostIncLoops;
|
2005-08-04 22:34:05 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// LUIdx - The index of the LSRUse describing the expression which
|
|
|
|
/// this fixup needs, minus an offset (below).
|
|
|
|
size_t LUIdx;
|
2005-08-04 22:34:05 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// Offset - A constant offset to be added to the LSRUse expression.
|
|
|
|
/// This allows multiple fixups to share the same LSRUse with different
|
|
|
|
/// offsets, for example in an unrolled loop.
|
|
|
|
int64_t Offset;
|
|
|
|
|
2010-04-07 22:27:08 +00:00
|
|
|
bool isUseFullyOutsideLoop(const Loop *L) const;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
LSRFixup();
|
|
|
|
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
LSRFixup::LSRFixup()
|
2010-05-20 19:44:23 +00:00
|
|
|
: UserInst(0), OperandValToReplace(0), LUIdx(~size_t(0)), Offset(0) {}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-04-07 22:27:08 +00:00
|
|
|
/// isUseFullyOutsideLoop - Test whether this fixup always uses its
|
|
|
|
/// value outside of the given loop.
|
|
|
|
bool LSRFixup::isUseFullyOutsideLoop(const Loop *L) const {
|
|
|
|
// PHI nodes use their value in their incoming blocks.
|
|
|
|
if (const PHINode *PN = dyn_cast<PHINode>(UserInst)) {
|
|
|
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
|
|
|
if (PN->getIncomingValue(i) == OperandValToReplace &&
|
|
|
|
L->contains(PN->getIncomingBlock(i)))
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !L->contains(UserInst);
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRFixup::print(raw_ostream &OS) const {
|
|
|
|
OS << "UserInst=";
|
|
|
|
// Store is common and interesting enough to be worth special-casing.
|
|
|
|
if (StoreInst *Store = dyn_cast<StoreInst>(UserInst)) {
|
|
|
|
OS << "store ";
|
|
|
|
WriteAsOperand(OS, Store->getOperand(0), /*PrintType=*/false);
|
|
|
|
} else if (UserInst->getType()->isVoidTy())
|
|
|
|
OS << UserInst->getOpcodeName();
|
|
|
|
else
|
|
|
|
WriteAsOperand(OS, UserInst, /*PrintType=*/false);
|
|
|
|
|
|
|
|
OS << ", OperandValToReplace=";
|
|
|
|
WriteAsOperand(OS, OperandValToReplace, /*PrintType=*/false);
|
|
|
|
|
2010-04-07 22:27:08 +00:00
|
|
|
for (PostIncLoopSet::const_iterator I = PostIncLoops.begin(),
|
|
|
|
E = PostIncLoops.end(); I != E; ++I) {
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << ", PostIncLoop=";
|
2010-04-07 22:27:08 +00:00
|
|
|
WriteAsOperand(OS, (*I)->getHeader(), /*PrintType=*/false);
|
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
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (LUIdx != ~size_t(0))
|
|
|
|
OS << ", LUIdx=" << LUIdx;
|
|
|
|
|
|
|
|
if (Offset != 0)
|
|
|
|
OS << ", Offset=" << Offset;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRFixup::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
namespace {
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// UniquifierDenseMapInfo - A DenseMapInfo implementation for holding
|
|
|
|
/// DenseMaps and DenseSets of sorted SmallVectors of const SCEV*.
|
|
|
|
struct UniquifierDenseMapInfo {
|
|
|
|
static SmallVector<const SCEV *, 2> getEmptyKey() {
|
|
|
|
SmallVector<const SCEV *, 2> V;
|
|
|
|
V.push_back(reinterpret_cast<const SCEV *>(-1));
|
|
|
|
return V;
|
|
|
|
}
|
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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
static SmallVector<const SCEV *, 2> getTombstoneKey() {
|
|
|
|
SmallVector<const SCEV *, 2> V;
|
|
|
|
V.push_back(reinterpret_cast<const SCEV *>(-2));
|
|
|
|
return V;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned getHashValue(const SmallVector<const SCEV *, 2> &V) {
|
|
|
|
unsigned Result = 0;
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = V.begin(),
|
|
|
|
E = V.end(); I != E; ++I)
|
|
|
|
Result ^= DenseMapInfo<const SCEV *>::getHashValue(*I);
|
2010-01-22 00:46:49 +00:00
|
|
|
return Result;
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
static bool isEqual(const SmallVector<const SCEV *, 2> &LHS,
|
|
|
|
const SmallVector<const SCEV *, 2> &RHS) {
|
|
|
|
return LHS == RHS;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// LSRUse - This class holds the state that LSR keeps for each use in
|
|
|
|
/// IVUsers, as well as uses invented by LSR itself. It includes information
|
|
|
|
/// about what kinds of things can be folded into the user, information about
|
|
|
|
/// the user itself, and information about how the use may be satisfied.
|
|
|
|
/// TODO: Represent multiple users of the same expression in common?
|
|
|
|
class LSRUse {
|
|
|
|
DenseSet<SmallVector<const SCEV *, 2>, UniquifierDenseMapInfo> Uniquifier;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// KindType - An enum for a kind of use, indicating what types of
|
|
|
|
/// scaled and immediate operands it might support.
|
|
|
|
enum KindType {
|
|
|
|
Basic, ///< A normal use, with no folding.
|
|
|
|
Special, ///< A special case of basic, allowing -1 scales.
|
|
|
|
Address, ///< An address use; folding according to TargetLowering
|
|
|
|
ICmpZero ///< An equality icmp with both operands folded into one.
|
|
|
|
// TODO: Add a generic icmp too?
|
|
|
|
};
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
KindType Kind;
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *AccessTy;
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallVector<int64_t, 8> Offsets;
|
|
|
|
int64_t MinOffset;
|
|
|
|
int64_t MaxOffset;
|
2008-12-05 21:47:27 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// AllFixupsOutsideLoop - This records whether all of the fixups using this
|
|
|
|
/// LSRUse are outside of the loop, in which case some special-case heuristics
|
|
|
|
/// may be used.
|
|
|
|
bool AllFixupsOutsideLoop;
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-07-15 20:24:58 +00:00
|
|
|
/// WidestFixupType - This records the widest use type for any fixup using
|
|
|
|
/// this LSRUse. FindUseWithSimilarFormula can't consider uses with different
|
|
|
|
/// max fixup widths to be equivalent, because the narrower one may be relying
|
|
|
|
/// on the implicit truncation to truncate away bogus bits.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *WidestFixupType;
|
2010-07-15 20:24:58 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// Formulae - A list of ways to build a value that can satisfy this user.
|
|
|
|
/// After the list is populated, one of these is selected heuristically and
|
|
|
|
/// used to formulate a replacement for OperandValToReplace in UserInst.
|
|
|
|
SmallVector<Formula, 12> Formulae;
|
2008-12-01 22:00:01 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// Regs - The set of register candidates used by all formulae in this LSRUse.
|
|
|
|
SmallPtrSet<const SCEV *, 4> Regs;
|
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
|
|
|
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse(KindType K, Type *T) : Kind(K), AccessTy(T),
|
2010-02-12 10:34:29 +00:00
|
|
|
MinOffset(INT64_MAX),
|
|
|
|
MaxOffset(INT64_MIN),
|
2010-07-15 20:24:58 +00:00
|
|
|
AllFixupsOutsideLoop(true),
|
|
|
|
WidestFixupType(0) {}
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
bool HasFormulaWithSameRegs(const Formula &F) const;
|
2010-02-22 04:11:59 +00:00
|
|
|
bool InsertFormula(const Formula &F);
|
2010-05-18 22:39:15 +00:00
|
|
|
void DeleteFormula(Formula &F);
|
2010-05-18 23:42:37 +00:00
|
|
|
void RecomputeRegs(size_t LUIdx, RegUseTracker &Reguses);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
2010-06-19 21:21:39 +00:00
|
|
|
}
|
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
/// HasFormula - Test whether this use as a formula which has the same
|
|
|
|
/// registers as the given formula.
|
|
|
|
bool LSRUse::HasFormulaWithSameRegs(const Formula &F) const {
|
|
|
|
SmallVector<const SCEV *, 2> Key = F.BaseRegs;
|
|
|
|
if (F.ScaledReg) Key.push_back(F.ScaledReg);
|
|
|
|
// Unstable sort by host order ok, because this is only used for uniquifying.
|
|
|
|
std::sort(Key.begin(), Key.end());
|
|
|
|
return Uniquifier.count(Key);
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// InsertFormula - If the given formula has not yet been inserted, add it to
|
|
|
|
/// the list, and return true. Return false otherwise.
|
2010-02-22 04:11:59 +00:00
|
|
|
bool LSRUse::InsertFormula(const Formula &F) {
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallVector<const SCEV *, 2> Key = F.BaseRegs;
|
|
|
|
if (F.ScaledReg) Key.push_back(F.ScaledReg);
|
|
|
|
// Unstable sort by host order ok, because this is only used for uniquifying.
|
|
|
|
std::sort(Key.begin(), Key.end());
|
|
|
|
|
|
|
|
if (!Uniquifier.insert(Key).second)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Using a register to hold the value of 0 is not profitable.
|
|
|
|
assert((!F.ScaledReg || !F.ScaledReg->isZero()) &&
|
|
|
|
"Zero allocated in a scaled register!");
|
|
|
|
#ifndef NDEBUG
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I =
|
|
|
|
F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I)
|
|
|
|
assert(!(*I)->isZero() && "Zero allocated in a base register!");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Add the formula to the list.
|
|
|
|
Formulae.push_back(F);
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Record registers now being used by this use.
|
|
|
|
Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-05-18 22:39:15 +00:00
|
|
|
/// DeleteFormula - Remove the given formula from this use's list.
|
|
|
|
void LSRUse::DeleteFormula(Formula &F) {
|
2010-05-20 15:17:54 +00:00
|
|
|
if (&F != &Formulae.back())
|
|
|
|
std::swap(F, Formulae.back());
|
2010-05-18 22:39:15 +00:00
|
|
|
Formulae.pop_back();
|
|
|
|
}
|
|
|
|
|
2010-05-18 23:42:37 +00:00
|
|
|
/// RecomputeRegs - Recompute the Regs field, and update RegUses.
|
|
|
|
void LSRUse::RecomputeRegs(size_t LUIdx, RegUseTracker &RegUses) {
|
|
|
|
// Now that we've filtered out some formulae, recompute the Regs set.
|
|
|
|
SmallPtrSet<const SCEV *, 4> OldRegs = Regs;
|
|
|
|
Regs.clear();
|
2010-05-20 20:33:18 +00:00
|
|
|
for (SmallVectorImpl<Formula>::const_iterator I = Formulae.begin(),
|
|
|
|
E = Formulae.end(); I != E; ++I) {
|
|
|
|
const Formula &F = *I;
|
2010-05-18 23:42:37 +00:00
|
|
|
if (F.ScaledReg) Regs.insert(F.ScaledReg);
|
|
|
|
Regs.insert(F.BaseRegs.begin(), F.BaseRegs.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the RegTracker.
|
|
|
|
for (SmallPtrSet<const SCEV *, 4>::iterator I = OldRegs.begin(),
|
|
|
|
E = OldRegs.end(); I != E; ++I)
|
|
|
|
if (!Regs.count(*I))
|
|
|
|
RegUses.DropRegister(*I, LUIdx);
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRUse::print(raw_ostream &OS) const {
|
|
|
|
OS << "LSR Use: Kind=";
|
|
|
|
switch (Kind) {
|
|
|
|
case Basic: OS << "Basic"; break;
|
|
|
|
case Special: OS << "Special"; break;
|
|
|
|
case ICmpZero: OS << "ICmpZero"; break;
|
|
|
|
case Address:
|
|
|
|
OS << "Address of ";
|
2010-02-16 11:11:14 +00:00
|
|
|
if (AccessTy->isPointerTy())
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << "pointer"; // the full pointer type could be really verbose
|
2010-01-22 00:46:49 +00:00
|
|
|
else
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << *AccessTy;
|
2010-01-22 00:46:49 +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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << ", Offsets={";
|
|
|
|
for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
|
|
|
|
E = Offsets.end(); I != E; ++I) {
|
|
|
|
OS << *I;
|
2010-08-02 06:00:15 +00:00
|
|
|
if (llvm::next(I) != E)
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << ',';
|
|
|
|
}
|
|
|
|
OS << '}';
|
|
|
|
|
|
|
|
if (AllFixupsOutsideLoop)
|
|
|
|
OS << ", all-fixups-outside-loop";
|
2010-07-15 20:24:58 +00:00
|
|
|
|
|
|
|
if (WidestFixupType)
|
|
|
|
OS << ", widest fixup type: " << *WidestFixupType;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2007-12-19 23:33:23 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRUse::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
|
|
|
}
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// isLegalUse - Test whether the use described by AM is "legal", meaning it can
|
|
|
|
/// be completely folded into the user instruction at isel time. This includes
|
|
|
|
/// address-mode folding and special icmp tricks.
|
|
|
|
static bool isLegalUse(const TargetLowering::AddrMode &AM,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy,
|
2010-02-12 10:34:29 +00:00
|
|
|
const TargetLowering *TLI) {
|
|
|
|
switch (Kind) {
|
|
|
|
case LSRUse::Address:
|
|
|
|
// If we have low-level target information, ask the target if it can
|
|
|
|
// completely fold this address.
|
|
|
|
if (TLI) return TLI->isLegalAddressingMode(AM, AccessTy);
|
|
|
|
|
|
|
|
// Otherwise, just guess that reg+reg addressing is legal.
|
|
|
|
return !AM.BaseGV && AM.BaseOffs == 0 && AM.Scale <= 1;
|
|
|
|
|
|
|
|
case LSRUse::ICmpZero:
|
|
|
|
// There's not even a target hook for querying whether it would be legal to
|
|
|
|
// fold a GV into an ICmp.
|
|
|
|
if (AM.BaseGV)
|
|
|
|
return false;
|
2007-04-09 22:20:14 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// ICmp only has two operands; don't allow more than two non-trivial parts.
|
|
|
|
if (AM.Scale != 0 && AM.HasBaseReg && AM.BaseOffs != 0)
|
|
|
|
return false;
|
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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// ICmp only supports no scale or a -1 scale, as we can "fold" a -1 scale by
|
|
|
|
// putting the scaled register in the other operand of the icmp.
|
|
|
|
if (AM.Scale != 0 && AM.Scale != -1)
|
2010-01-22 00:46:49 +00:00
|
|
|
return false;
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// If we have low-level target information, ask the target if it can fold an
|
|
|
|
// integer immediate on an icmp.
|
|
|
|
if (AM.BaseOffs != 0) {
|
2011-10-13 23:48:33 +00:00
|
|
|
if (TLI) return TLI->isLegalICmpImmediate(-(uint64_t)AM.BaseOffs);
|
2010-02-12 10:34:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
return true;
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
case LSRUse::Basic:
|
|
|
|
// Only handle single-register values.
|
|
|
|
return !AM.BaseGV && AM.Scale == 0 && AM.BaseOffs == 0;
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
case LSRUse::Special:
|
|
|
|
// Only handle -1 scales, or no scale.
|
|
|
|
return AM.Scale == 0 || AM.Scale == -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2009-05-12 02:17:14 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
static bool isLegalUse(TargetLowering::AddrMode AM,
|
|
|
|
int64_t MinOffset, int64_t MaxOffset,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy,
|
2010-02-12 10:34:29 +00:00
|
|
|
const TargetLowering *TLI) {
|
|
|
|
// Check for overflow.
|
|
|
|
if (((int64_t)((uint64_t)AM.BaseOffs + MinOffset) > AM.BaseOffs) !=
|
|
|
|
(MinOffset > 0))
|
|
|
|
return false;
|
|
|
|
AM.BaseOffs = (uint64_t)AM.BaseOffs + MinOffset;
|
|
|
|
if (isLegalUse(AM, Kind, AccessTy, TLI)) {
|
|
|
|
AM.BaseOffs = (uint64_t)AM.BaseOffs - MinOffset;
|
|
|
|
// Check for overflow.
|
|
|
|
if (((int64_t)((uint64_t)AM.BaseOffs + MaxOffset) > AM.BaseOffs) !=
|
|
|
|
(MaxOffset > 0))
|
2010-01-22 00:46:49 +00:00
|
|
|
return false;
|
2010-02-12 10:34:29 +00:00
|
|
|
AM.BaseOffs = (uint64_t)AM.BaseOffs + MaxOffset;
|
|
|
|
return isLegalUse(AM, Kind, AccessTy, TLI);
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
return false;
|
2007-10-25 22:45:20 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
static bool isAlwaysFoldable(int64_t BaseOffs,
|
|
|
|
GlobalValue *BaseGV,
|
|
|
|
bool HasBaseReg,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy,
|
2010-02-22 04:11:59 +00:00
|
|
|
const TargetLowering *TLI) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Fast-path: zero is always foldable.
|
|
|
|
if (BaseOffs == 0 && !BaseGV) return true;
|
|
|
|
|
|
|
|
// Conservatively, create an address with an immediate and a
|
|
|
|
// base and a scale.
|
|
|
|
TargetLowering::AddrMode AM;
|
|
|
|
AM.BaseOffs = BaseOffs;
|
|
|
|
AM.BaseGV = BaseGV;
|
|
|
|
AM.HasBaseReg = HasBaseReg;
|
|
|
|
AM.Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
|
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
// Canonicalize a scale of 1 to a base register if the formula doesn't
|
|
|
|
// already have a base register.
|
|
|
|
if (!AM.HasBaseReg && AM.Scale == 1) {
|
|
|
|
AM.Scale = 0;
|
|
|
|
AM.HasBaseReg = true;
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
return isLegalUse(AM, Kind, AccessTy, TLI);
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
static bool isAlwaysFoldable(const SCEV *S,
|
|
|
|
int64_t MinOffset, int64_t MaxOffset,
|
|
|
|
bool HasBaseReg,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy,
|
2010-02-12 10:34:29 +00:00
|
|
|
const TargetLowering *TLI,
|
|
|
|
ScalarEvolution &SE) {
|
|
|
|
// Fast-path: zero is always foldable.
|
|
|
|
if (S->isZero()) return true;
|
|
|
|
|
|
|
|
// Conservatively, create an address with an immediate and a
|
|
|
|
// base and a scale.
|
|
|
|
int64_t BaseOffs = ExtractImmediate(S, SE);
|
|
|
|
GlobalValue *BaseGV = ExtractSymbol(S, SE);
|
|
|
|
|
|
|
|
// If there's anything else involved, it's not foldable.
|
|
|
|
if (!S->isZero()) return false;
|
|
|
|
|
|
|
|
// Fast-path: zero is always foldable.
|
|
|
|
if (BaseOffs == 0 && !BaseGV) return true;
|
|
|
|
|
|
|
|
// Conservatively, create an address with an immediate and a
|
|
|
|
// base and a scale.
|
|
|
|
TargetLowering::AddrMode AM;
|
|
|
|
AM.BaseOffs = BaseOffs;
|
|
|
|
AM.BaseGV = BaseGV;
|
|
|
|
AM.HasBaseReg = HasBaseReg;
|
|
|
|
AM.Scale = Kind == LSRUse::ICmpZero ? -1 : 1;
|
|
|
|
|
|
|
|
return isLegalUse(AM, MinOffset, MaxOffset, Kind, AccessTy, TLI);
|
|
|
|
}
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2010-06-19 21:21:39 +00:00
|
|
|
namespace {
|
|
|
|
|
2010-06-19 21:29:59 +00:00
|
|
|
/// UseMapDenseMapInfo - A DenseMapInfo implementation for holding
|
|
|
|
/// DenseMaps and DenseSets of pairs of const SCEV* and LSRUse::Kind.
|
|
|
|
struct UseMapDenseMapInfo {
|
|
|
|
static std::pair<const SCEV *, LSRUse::KindType> getEmptyKey() {
|
|
|
|
return std::make_pair(reinterpret_cast<const SCEV *>(-1), LSRUse::Basic);
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::pair<const SCEV *, LSRUse::KindType> getTombstoneKey() {
|
|
|
|
return std::make_pair(reinterpret_cast<const SCEV *>(-2), LSRUse::Basic);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
getHashValue(const std::pair<const SCEV *, LSRUse::KindType> &V) {
|
|
|
|
unsigned Result = DenseMapInfo<const SCEV *>::getHashValue(V.first);
|
|
|
|
Result ^= DenseMapInfo<unsigned>::getHashValue(unsigned(V.second));
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isEqual(const std::pair<const SCEV *, LSRUse::KindType> &LHS,
|
|
|
|
const std::pair<const SCEV *, LSRUse::KindType> &RHS) {
|
|
|
|
return LHS == RHS;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-01-09 19:50:34 +00:00
|
|
|
/// IVInc - An individual increment in a Chain of IV increments.
|
|
|
|
/// Relate an IV user to an expression that computes the IV it uses from the IV
|
|
|
|
/// used by the previous link in the Chain.
|
|
|
|
///
|
|
|
|
/// For the head of a chain, IncExpr holds the absolute SCEV expression for the
|
|
|
|
/// original IVOperand. The head of the chain's IVOperand is only valid during
|
|
|
|
/// chain collection, before LSR replaces IV users. During chain generation,
|
|
|
|
/// IncExpr can be used to find the new IVOperand that computes the same
|
|
|
|
/// expression.
|
|
|
|
struct IVInc {
|
|
|
|
Instruction *UserInst;
|
|
|
|
Value* IVOperand;
|
|
|
|
const SCEV *IncExpr;
|
|
|
|
|
|
|
|
IVInc(Instruction *U, Value *O, const SCEV *E):
|
|
|
|
UserInst(U), IVOperand(O), IncExpr(E) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// IVChain - The list of IV increments in program order.
|
|
|
|
// We typically add the head of a chain without finding subsequent links.
|
|
|
|
typedef SmallVector<IVInc,1> IVChain;
|
|
|
|
|
|
|
|
/// ChainUsers - Helper for CollectChains to track multiple IV increment uses.
|
|
|
|
/// Distinguish between FarUsers that definitely cross IV increments and
|
|
|
|
/// NearUsers that may be used between IV increments.
|
|
|
|
struct ChainUsers {
|
|
|
|
SmallPtrSet<Instruction*, 4> FarUsers;
|
|
|
|
SmallPtrSet<Instruction*, 4> NearUsers;
|
|
|
|
};
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// LSRInstance - This class holds state for the main loop strength reduction
|
|
|
|
/// logic.
|
|
|
|
class LSRInstance {
|
|
|
|
IVUsers &IU;
|
|
|
|
ScalarEvolution &SE;
|
|
|
|
DominatorTree &DT;
|
2010-04-09 22:07:05 +00:00
|
|
|
LoopInfo &LI;
|
2010-02-12 10:34:29 +00:00
|
|
|
const TargetLowering *const TLI;
|
|
|
|
Loop *const L;
|
|
|
|
bool Changed;
|
|
|
|
|
|
|
|
/// IVIncInsertPos - This is the insert position that the current loop's
|
|
|
|
/// induction variable increment should be placed. In simple loops, this is
|
|
|
|
/// the latch block's terminator. But in more complicated cases, this is a
|
|
|
|
/// position which will dominate all the in-loop post-increment users.
|
|
|
|
Instruction *IVIncInsertPos;
|
|
|
|
|
|
|
|
/// Factors - Interesting factors between use strides.
|
|
|
|
SmallSetVector<int64_t, 8> Factors;
|
|
|
|
|
|
|
|
/// Types - Interesting use types, to facilitate truncation reuse.
|
2011-07-18 04:54:35 +00:00
|
|
|
SmallSetVector<Type *, 4> Types;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
/// Fixups - The list of operands which are to be replaced.
|
|
|
|
SmallVector<LSRFixup, 16> Fixups;
|
|
|
|
|
|
|
|
/// Uses - The list of interesting uses.
|
|
|
|
SmallVector<LSRUse, 16> Uses;
|
|
|
|
|
|
|
|
/// RegUses - Track which uses use which register candidates.
|
|
|
|
RegUseTracker RegUses;
|
|
|
|
|
2012-01-09 19:50:34 +00:00
|
|
|
// Limit the number of chains to avoid quadratic behavior. We don't expect to
|
|
|
|
// have more than a few IV increment chains in a loop. Missing a Chain falls
|
|
|
|
// back to normal LSR behavior for those uses.
|
|
|
|
static const unsigned MaxChains = 8;
|
|
|
|
|
|
|
|
/// IVChainVec - IV users can form a chain of IV increments.
|
|
|
|
SmallVector<IVChain, MaxChains> IVChainVec;
|
|
|
|
|
2012-01-09 21:18:52 +00:00
|
|
|
/// IVIncSet - IV users that belong to profitable IVChains.
|
|
|
|
SmallPtrSet<Use*, MaxChains> IVIncSet;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void OptimizeShadowIV();
|
|
|
|
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse);
|
|
|
|
ICmpInst *OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse);
|
2010-05-20 20:05:31 +00:00
|
|
|
void OptimizeLoopTermCond();
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2012-01-09 19:50:34 +00:00
|
|
|
void ChainInstruction(Instruction *UserInst, Instruction *IVOper,
|
|
|
|
SmallVectorImpl<ChainUsers> &ChainUsersVec);
|
2012-01-09 21:18:52 +00:00
|
|
|
void FinalizeChain(IVChain &Chain);
|
2012-01-09 19:50:34 +00:00
|
|
|
void CollectChains();
|
2012-01-09 21:18:52 +00:00
|
|
|
void GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts);
|
2012-01-09 19:50:34 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void CollectInterestingTypesAndFactors();
|
|
|
|
void CollectFixupsAndInitialFormulae();
|
|
|
|
|
|
|
|
LSRFixup &getNewFixup() {
|
|
|
|
Fixups.push_back(LSRFixup());
|
|
|
|
return Fixups.back();
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2007-12-20 02:20:53 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Support for sharing of LSRUses between LSRFixups.
|
2010-06-19 21:29:59 +00:00
|
|
|
typedef DenseMap<std::pair<const SCEV *, LSRUse::KindType>,
|
|
|
|
size_t,
|
|
|
|
UseMapDenseMapInfo> UseMapTy;
|
2010-02-12 10:34:29 +00:00
|
|
|
UseMapTy UseMap;
|
|
|
|
|
2010-09-01 01:45:53 +00:00
|
|
|
bool reconcileNewOffset(LSRUse &LU, int64_t NewOffset, bool HasBaseReg,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
std::pair<size_t, int64_t> getUse(const SCEV *&Expr,
|
|
|
|
LSRUse::KindType Kind,
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *AccessTy);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-10-07 23:33:43 +00:00
|
|
|
void DeleteUse(LSRUse &LU, size_t LUIdx);
|
2010-05-20 15:17:54 +00:00
|
|
|
|
2010-09-01 01:45:53 +00:00
|
|
|
LSRUse *FindUseWithSimilarFormula(const Formula &F, const LSRUse &OrigLU);
|
2010-05-19 23:43:12 +00:00
|
|
|
|
2010-02-22 04:11:59 +00:00
|
|
|
void InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx);
|
2010-02-12 10:34:29 +00:00
|
|
|
void InsertSupplementalFormula(const SCEV *S, LSRUse &LU, size_t LUIdx);
|
|
|
|
void CountRegisters(const Formula &F, size_t LUIdx);
|
|
|
|
bool InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F);
|
|
|
|
|
|
|
|
void CollectLoopInvariantFixupsAndFormulae();
|
|
|
|
|
|
|
|
void GenerateReassociations(LSRUse &LU, unsigned LUIdx, Formula Base,
|
|
|
|
unsigned Depth = 0);
|
|
|
|
void GenerateCombinations(LSRUse &LU, unsigned LUIdx, Formula Base);
|
|
|
|
void GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx, Formula Base);
|
|
|
|
void GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx, Formula Base);
|
|
|
|
void GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, Formula Base);
|
|
|
|
void GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base);
|
|
|
|
void GenerateTruncates(LSRUse &LU, unsigned LUIdx, Formula Base);
|
|
|
|
void GenerateCrossUseConstantOffsets();
|
|
|
|
void GenerateAllReuseFormulae();
|
|
|
|
|
|
|
|
void FilterOutUndesirableDedicatedRegisters();
|
2010-05-18 22:51:59 +00:00
|
|
|
|
|
|
|
size_t EstimateSearchSpaceComplexity() const;
|
2010-08-29 16:09:42 +00:00
|
|
|
void NarrowSearchSpaceByDetectingSupersets();
|
|
|
|
void NarrowSearchSpaceByCollapsingUnrolledCode();
|
2010-08-29 16:39:22 +00:00
|
|
|
void NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
|
2010-08-29 16:09:42 +00:00
|
|
|
void NarrowSearchSpaceByPickingWinnerRegs();
|
2010-02-12 10:34:29 +00:00
|
|
|
void NarrowSearchSpaceUsingHeuristics();
|
|
|
|
|
|
|
|
void SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
|
|
|
|
Cost &SolutionCost,
|
|
|
|
SmallVectorImpl<const Formula *> &Workspace,
|
|
|
|
const Cost &CurCost,
|
|
|
|
const SmallPtrSet<const SCEV *, 16> &CurRegs,
|
|
|
|
DenseSet<const SCEV *> &VisitedRegs) const;
|
|
|
|
void Solve(SmallVectorImpl<const Formula *> &Solution) const;
|
|
|
|
|
2010-04-09 22:07:05 +00:00
|
|
|
BasicBlock::iterator
|
|
|
|
HoistInsertPosition(BasicBlock::iterator IP,
|
|
|
|
const SmallVectorImpl<Instruction *> &Inputs) const;
|
2012-01-20 07:41:13 +00:00
|
|
|
BasicBlock::iterator
|
|
|
|
AdjustInsertPositionForExpand(BasicBlock::iterator IP,
|
|
|
|
const LSRFixup &LF,
|
|
|
|
const LSRUse &LU,
|
|
|
|
SCEVExpander &Rewriter) const;
|
2010-04-09 02:00:38 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
Value *Expand(const LSRFixup &LF,
|
|
|
|
const Formula &F,
|
2010-02-22 04:11:59 +00:00
|
|
|
BasicBlock::iterator IP,
|
2010-02-12 10:34:29 +00:00
|
|
|
SCEVExpander &Rewriter,
|
2010-02-22 04:11:59 +00:00
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts) const;
|
2010-02-16 20:25:07 +00:00
|
|
|
void RewriteForPHI(PHINode *PN, const LSRFixup &LF,
|
|
|
|
const Formula &F,
|
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts,
|
|
|
|
Pass *P) const;
|
2010-02-12 10:34:29 +00:00
|
|
|
void Rewrite(const LSRFixup &LF,
|
|
|
|
const Formula &F,
|
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts,
|
|
|
|
Pass *P) const;
|
|
|
|
void ImplementSolution(const SmallVectorImpl<const Formula *> &Solution,
|
|
|
|
Pass *P);
|
|
|
|
|
2011-12-13 00:55:33 +00:00
|
|
|
public:
|
2010-02-12 10:34:29 +00:00
|
|
|
LSRInstance(const TargetLowering *tli, Loop *l, Pass *P);
|
|
|
|
|
|
|
|
bool getChanged() const { return Changed; }
|
|
|
|
|
|
|
|
void print_factors_and_types(raw_ostream &OS) const;
|
|
|
|
void print_fixups(raw_ostream &OS) const;
|
|
|
|
void print_uses(raw_ostream &OS) const;
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
};
|
2010-01-22 00:46:49 +00:00
|
|
|
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// OptimizeShadowIV - If IV is used in a int-to-float cast
|
2010-03-01 17:49:51 +00:00
|
|
|
/// inside the loop then try to eliminate the cast operation.
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::OptimizeShadowIV() {
|
|
|
|
const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L);
|
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
|
|
|
return;
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
for (IVUsers::const_iterator UI = IU.begin(), E = IU.end();
|
|
|
|
UI != E; /* empty */) {
|
|
|
|
IVUsers::const_iterator CandidateUI = UI;
|
|
|
|
++UI;
|
|
|
|
Instruction *ShadowUse = CandidateUI->getUser();
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *DestTy = NULL;
|
2011-07-21 01:05:01 +00:00
|
|
|
bool IsSigned = false;
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/* If shadow use is a int->float cast then insert a second IV
|
|
|
|
to eliminate this cast.
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
for (unsigned i = 0; i < n; ++i)
|
|
|
|
foo((double)i);
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
is transformed into
|
2009-02-20 04:17:46 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
double d = 0.0;
|
|
|
|
for (unsigned i = 0; i < n; ++i, ++d)
|
|
|
|
foo(d);
|
|
|
|
*/
|
2011-07-21 01:05:01 +00:00
|
|
|
if (UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->getUser())) {
|
|
|
|
IsSigned = false;
|
2010-02-12 10:34:29 +00:00
|
|
|
DestTy = UCast->getDestTy();
|
2011-07-21 01:05:01 +00:00
|
|
|
}
|
|
|
|
else if (SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->getUser())) {
|
|
|
|
IsSigned = true;
|
2010-02-12 10:34:29 +00:00
|
|
|
DestTy = SCast->getDestTy();
|
2011-07-21 01:05:01 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!DestTy) continue;
|
2009-05-11 22:33:01 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (TLI) {
|
|
|
|
// If target does not support DestTy natively then do not apply
|
|
|
|
// this transformation.
|
|
|
|
EVT DVT = TLI->getValueType(DestTy);
|
|
|
|
if (!TLI->isTypeLegal(DVT)) continue;
|
2006-08-03 06:34:50 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
|
|
|
|
if (!PH) continue;
|
|
|
|
if (PH->getNumIncomingValues() != 2) continue;
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *SrcTy = PH->getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
int Mantissa = DestTy->getFPMantissaWidth();
|
|
|
|
if (Mantissa == -1) continue;
|
|
|
|
if ((int)SE.getTypeSizeInBits(SrcTy) > Mantissa)
|
|
|
|
continue;
|
Fix the time regression I introduced in 464.h264ref with
my earlier patch to this file.
The issue there was that all uses of an IV inside a loop
are actually references to Base[IV*2], and there was one
use outside that was the same but LSR didn't see the base
or the scaling because it didn't recurse into uses outside
the loop; thus, it used base+IV*scale mode inside the loop
instead of pulling base out of the loop. This was extra bad
because register pressure later forced both base and IV into
memory. Doing that recursion, at least enough
to figure out addressing modes, is a good idea in general;
the change in AddUsersIfInteresting does this. However,
there were side effects....
It is also possible for recursing outside the loop to
introduce another IV where there was only 1 before (if
the refs inside are not scaled and the ref outside is).
I don't think this is a common case, but it's in the testsuite.
It is right to be very aggressive about getting rid of
such introduced IVs (CheckForIVReuse and the handling of
nonzero RewriteFactor in StrengthReduceStridedIVUsers).
In the testcase in question the new IV produced this way
has both a nonconstant stride and a nonzero base, neither
of which was handled before. And when inserting
new code that feeds into a PHI, it's right to put such
code at the original location rather than in the PHI's
immediate predecessor(s) when the original location is outside
the loop (a case that couldn't happen before)
(RewriteInstructionToUseNewBase); better to avoid making
multiple copies of it in this case.
Also, the mechanism for keeping SCEV's corresponding to GEP's
no longer works, as the GEP might change after its SCEV
is remembered, invalidating the SCEV, and we might get a bad
SCEV value when looking up the GEP again for a later loop.
This also couldn't happen before, as we weren't recursing
into GEP's outside the loop.
Also, when we build an expression that involves a (possibly
non-affine) IV from a different loop as well as an IV from
the one we're interested in (containsAddRecFromDifferentLoop),
don't recurse into that. We can't do much with it and will
get in trouble if we try to create new non-affine IVs or something.
More testcases are coming.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62212 91177308-0d34-0410-b5e6-96231b3b80d8
2009-01-14 02:35:31 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
unsigned Entry, Latch;
|
|
|
|
if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
|
|
|
|
Entry = 0;
|
|
|
|
Latch = 1;
|
|
|
|
} else {
|
|
|
|
Entry = 1;
|
|
|
|
Latch = 0;
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
|
|
|
|
if (!Init) continue;
|
2011-07-21 01:05:01 +00:00
|
|
|
Constant *NewInit = ConstantFP::get(DestTy, IsSigned ?
|
2011-07-21 01:45:54 +00:00
|
|
|
(double)Init->getSExtValue() :
|
|
|
|
(double)Init->getZExtValue());
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
BinaryOperator *Incr =
|
|
|
|
dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
|
|
|
|
if (!Incr) continue;
|
|
|
|
if (Incr->getOpcode() != Instruction::Add
|
|
|
|
&& Incr->getOpcode() != Instruction::Sub)
|
|
|
|
continue;
|
2007-04-03 05:11:24 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/* 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;
|
2009-02-13 00:26:43 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!C) continue;
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Ignore negative constants, as the code below doesn't handle them
|
|
|
|
// correctly. TODO: Remove this restriction.
|
|
|
|
if (!C->getValue().isStrictlyPositive()) continue;
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/* Add new PHINode. */
|
2011-03-30 11:28:46 +00:00
|
|
|
PHINode *NewPH = PHINode::Create(DestTy, 2, "IV.S.", PH);
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/* create new increment. '++d' in above example. */
|
|
|
|
Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
|
|
|
|
BinaryOperator *NewIncr =
|
|
|
|
BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
|
|
|
|
Instruction::FAdd : Instruction::FSub,
|
|
|
|
NewPH, CFP, "IV.S.next.", Incr);
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
|
|
|
|
NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
|
2010-01-21 22:42:49 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/* Remove cast operation */
|
|
|
|
ShadowUse->replaceAllUsesWith(NewPH);
|
|
|
|
ShadowUse->eraseFromParent();
|
2010-05-20 20:05:31 +00:00
|
|
|
Changed = true;
|
2010-02-12 10:34:29 +00:00
|
|
|
break;
|
2010-01-22 00:46:49 +00:00
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
/// FindIVUserForCond - If Cond has an operand that is an expression of an IV,
|
|
|
|
/// set the IV user and stride information and return true, otherwise return
|
|
|
|
/// false.
|
2010-05-20 19:44:23 +00:00
|
|
|
bool LSRInstance::FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse) {
|
2010-02-12 10:34:29 +00:00
|
|
|
for (IVUsers::iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI)
|
|
|
|
if (UI->getUser() == Cond) {
|
|
|
|
// NOTE: we could handle setcc instructions with multiple uses here, but
|
|
|
|
// InstCombine does it as well for simple uses, it's not clear that it
|
|
|
|
// occurs enough in real life to handle.
|
|
|
|
CondUse = UI;
|
|
|
|
return true;
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
return false;
|
2007-10-25 09:11:16 +00:00
|
|
|
}
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
/// OptimizeMax - Rewrite the loop's terminating condition if it uses
|
|
|
|
/// a max computation.
|
|
|
|
///
|
|
|
|
/// This is a narrow solution to a specific, but acute, problem. For loops
|
|
|
|
/// like this:
|
|
|
|
///
|
|
|
|
/// i = 0;
|
|
|
|
/// do {
|
|
|
|
/// p[i] = 0.0;
|
|
|
|
/// } while (++i < n);
|
|
|
|
///
|
|
|
|
/// 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:
|
|
|
|
//
|
|
|
|
/// 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
|
|
|
|
/// max expression, which allows it to give the loop a canonical
|
|
|
|
/// induction variable:
|
|
|
|
///
|
|
|
|
/// i = 0;
|
|
|
|
/// max = n < 1 ? 1 : n;
|
|
|
|
/// do {
|
|
|
|
/// p[i] = 0.0;
|
|
|
|
/// } while (++i != max);
|
|
|
|
///
|
|
|
|
/// 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
|
2010-02-12 10:34:29 +00:00
|
|
|
/// needed, and it does this using a simple analysis that only succeeds if
|
2010-01-22 00:46:49 +00:00
|
|
|
/// 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.
|
|
|
|
///
|
2010-02-12 10:34:29 +00:00
|
|
|
ICmpInst *LSRInstance::OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse) {
|
2010-01-22 00:46:49 +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;
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
SelectInst *Sel = dyn_cast<SelectInst>(Cond->getOperand(1));
|
|
|
|
if (!Sel || !Sel->hasOneUse()) return Cond;
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L);
|
2010-01-22 00:46:49 +00:00
|
|
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
|
|
|
return Cond;
|
2010-05-03 22:09:21 +00:00
|
|
|
const SCEV *One = SE.getConstant(BackedgeTakenCount->getType(), 1);
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// Add one to the backedge-taken count to get the trip count.
|
2010-08-16 15:39:27 +00:00
|
|
|
const SCEV *IterationCount = SE.getAddExpr(One, BackedgeTakenCount);
|
2010-04-24 03:13:44 +00:00
|
|
|
if (IterationCount != SE.getSCEV(Sel)) return Cond;
|
|
|
|
|
|
|
|
// Check for a max calculation that matches the pattern. There's no check
|
|
|
|
// for ICMP_ULE here because the comparison would be with zero, which
|
|
|
|
// isn't interesting.
|
|
|
|
CmpInst::Predicate Pred = ICmpInst::BAD_ICMP_PREDICATE;
|
|
|
|
const SCEVNAryExpr *Max = 0;
|
|
|
|
if (const SCEVSMaxExpr *S = dyn_cast<SCEVSMaxExpr>(BackedgeTakenCount)) {
|
|
|
|
Pred = ICmpInst::ICMP_SLE;
|
|
|
|
Max = S;
|
|
|
|
} else if (const SCEVSMaxExpr *S = dyn_cast<SCEVSMaxExpr>(IterationCount)) {
|
|
|
|
Pred = ICmpInst::ICMP_SLT;
|
|
|
|
Max = S;
|
|
|
|
} else if (const SCEVUMaxExpr *U = dyn_cast<SCEVUMaxExpr>(IterationCount)) {
|
|
|
|
Pred = ICmpInst::ICMP_ULT;
|
|
|
|
Max = U;
|
|
|
|
} else {
|
|
|
|
// No match; bail.
|
2010-01-22 00:46:49 +00:00
|
|
|
return Cond;
|
2010-04-24 03:13:44 +00:00
|
|
|
}
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// To handle a max with more than two operands, this optimization would
|
|
|
|
// require additional checking and setup.
|
|
|
|
if (Max->getNumOperands() != 2)
|
|
|
|
return Cond;
|
|
|
|
|
|
|
|
const SCEV *MaxLHS = Max->getOperand(0);
|
|
|
|
const SCEV *MaxRHS = Max->getOperand(1);
|
2010-04-24 03:13:44 +00:00
|
|
|
|
|
|
|
// ScalarEvolution canonicalizes constants to the left. For < and >, look
|
|
|
|
// for a comparison with 1. For <= and >=, a comparison with zero.
|
|
|
|
if (!MaxLHS ||
|
|
|
|
(ICmpInst::isTrueWhenEqual(Pred) ? !MaxLHS->isZero() : (MaxLHS != One)))
|
|
|
|
return Cond;
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// Check the relevant induction variable for conformance to
|
|
|
|
// the pattern.
|
2010-02-12 10:34:29 +00:00
|
|
|
const SCEV *IV = SE.getSCEV(Cond->getOperand(0));
|
2010-01-22 00:46:49 +00:00
|
|
|
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
|
|
|
if (!AR || !AR->isAffine() ||
|
|
|
|
AR->getStart() != One ||
|
2010-02-12 10:34:29 +00:00
|
|
|
AR->getStepRecurrence(SE) != One)
|
2010-01-22 00:46:49 +00:00
|
|
|
return Cond;
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
assert(AR->getLoop() == L &&
|
|
|
|
"Loop condition operand is an addrec in a different loop!");
|
2009-03-04 20:49:01 +00:00
|
|
|
|
2010-01-22 00:46:49 +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;
|
2010-04-24 03:13:44 +00:00
|
|
|
if (ICmpInst::isTrueWhenEqual(Pred)) {
|
|
|
|
// Look for n+1, and grab n.
|
|
|
|
if (AddOperator *BO = dyn_cast<AddOperator>(Sel->getOperand(1)))
|
|
|
|
if (isa<ConstantInt>(BO->getOperand(1)) &&
|
|
|
|
cast<ConstantInt>(BO->getOperand(1))->isOne() &&
|
|
|
|
SE.getSCEV(BO->getOperand(0)) == MaxRHS)
|
|
|
|
NewRHS = BO->getOperand(0);
|
|
|
|
if (AddOperator *BO = dyn_cast<AddOperator>(Sel->getOperand(2)))
|
|
|
|
if (isa<ConstantInt>(BO->getOperand(1)) &&
|
|
|
|
cast<ConstantInt>(BO->getOperand(1))->isOne() &&
|
|
|
|
SE.getSCEV(BO->getOperand(0)) == MaxRHS)
|
|
|
|
NewRHS = BO->getOperand(0);
|
|
|
|
if (!NewRHS)
|
|
|
|
return Cond;
|
|
|
|
} else if (SE.getSCEV(Sel->getOperand(1)) == MaxRHS)
|
2010-01-22 00:46:49 +00:00
|
|
|
NewRHS = Sel->getOperand(1);
|
2010-02-12 10:34:29 +00:00
|
|
|
else if (SE.getSCEV(Sel->getOperand(2)) == MaxRHS)
|
2010-01-22 00:46:49 +00:00
|
|
|
NewRHS = Sel->getOperand(2);
|
2010-06-22 23:07:13 +00:00
|
|
|
else if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(MaxRHS))
|
|
|
|
NewRHS = SU->getValue();
|
2010-04-24 03:13:44 +00:00
|
|
|
else
|
2010-06-22 23:07:13 +00:00
|
|
|
// Max doesn't match expected pattern.
|
|
|
|
return Cond;
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// Determine the new comparison opcode. It may be signed or unsigned,
|
|
|
|
// and the original comparison may be either equality or inequality.
|
|
|
|
if (Cond->getPredicate() == CmpInst::ICMP_EQ)
|
|
|
|
Pred = CmpInst::getInversePredicate(Pred);
|
2009-06-19 23:23:27 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// Ok, everything looks ok to change the condition into an SLT or SGE and
|
|
|
|
// delete the max calculation.
|
|
|
|
ICmpInst *NewCond =
|
|
|
|
new ICmpInst(Cond, Pred, Cond->getOperand(0), NewRHS, "scmp");
|
2008-09-15 21:22:06 +00:00
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// Delete the max calculation instructions.
|
|
|
|
Cond->replaceAllUsesWith(NewCond);
|
|
|
|
CondUse->setUser(NewCond);
|
|
|
|
Instruction *Cmp = cast<Instruction>(Sel->getOperand(0));
|
|
|
|
Cond->eraseFromParent();
|
|
|
|
Sel->eraseFromParent();
|
|
|
|
if (Cmp->use_empty())
|
|
|
|
Cmp->eraseFromParent();
|
|
|
|
return NewCond;
|
2008-09-15 21:22:06 +00:00
|
|
|
}
|
|
|
|
|
2009-11-17 17:53:56 +00:00
|
|
|
/// OptimizeLoopTermCond - Change loop terminating condition to use the
|
2009-05-09 01:08:24 +00:00
|
|
|
/// postinc iv when possible.
|
2010-05-20 20:05:31 +00:00
|
|
|
void
|
2010-02-12 10:34:29 +00:00
|
|
|
LSRInstance::OptimizeLoopTermCond() {
|
|
|
|
SmallPtrSet<Instruction *, 4> PostIncs;
|
|
|
|
|
2009-05-11 22:33:01 +00:00
|
|
|
BasicBlock *LatchBlock = L->getLoopLatch();
|
2009-11-17 18:10:11 +00:00
|
|
|
SmallVector<BasicBlock*, 8> ExitingBlocks;
|
|
|
|
L->getExitingBlocks(ExitingBlocks);
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2009-11-17 18:10:11 +00:00
|
|
|
for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
|
|
|
|
BasicBlock *ExitingBlock = ExitingBlocks[i];
|
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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Get the terminating condition for the loop if possible. If we
|
2009-11-17 18:10:11 +00:00
|
|
|
// can, we want to change it to use a post-incremented version of its
|
|
|
|
// induction variable, to allow coalescing the live ranges for the IV into
|
|
|
|
// one register value.
|
2007-10-25 09:11:16 +00:00
|
|
|
|
2009-11-17 18:10:11 +00:00
|
|
|
BranchInst *TermBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
|
|
|
|
if (!TermBr)
|
|
|
|
continue;
|
|
|
|
// FIXME: Overly conservative, termination condition could be an 'or' etc..
|
|
|
|
if (TermBr->isUnconditional() || !isa<ICmpInst>(TermBr->getCondition()))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Search IVUsesByStride to find Cond's IVUse if there is one.
|
|
|
|
IVStrideUse *CondUse = 0;
|
|
|
|
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!FindIVUserForCond(Cond, CondUse))
|
2009-11-17 18:10:11 +00:00
|
|
|
continue;
|
|
|
|
|
2010-01-22 00:46:49 +00:00
|
|
|
// If the trip count is computed in terms of a max (due to ScalarEvolution
|
|
|
|
// being unable to find a sufficient guard, for example), change the loop
|
|
|
|
// comparison to use SLT or ULT instead of NE.
|
2010-02-12 10:34:29 +00:00
|
|
|
// One consequence of doing this now is that it disrupts the count-down
|
|
|
|
// optimization. That's not always a bad thing though, because in such
|
|
|
|
// cases it may still be worthwhile to avoid a max.
|
|
|
|
Cond = OptimizeMax(Cond, CondUse);
|
|
|
|
|
|
|
|
// If this exiting block dominates the latch block, it may also use
|
|
|
|
// the post-inc value if it won't be shared with other uses.
|
|
|
|
// Check for dominance.
|
|
|
|
if (!DT.dominates(ExitingBlock, LatchBlock))
|
2010-01-22 00:46:49 +00:00
|
|
|
continue;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Conservatively avoid trying to use the post-inc value in non-latch
|
|
|
|
// exits if there may be pre-inc users in intervening blocks.
|
2010-02-14 03:21:49 +00:00
|
|
|
if (LatchBlock != ExitingBlock)
|
2010-02-12 10:34:29 +00:00
|
|
|
for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI)
|
|
|
|
// Test if the use is reachable from the exiting block. This dominator
|
|
|
|
// query is a conservative approximation of reachability.
|
|
|
|
if (&*UI != CondUse &&
|
|
|
|
!DT.properlyDominates(UI->getUser()->getParent(), ExitingBlock)) {
|
|
|
|
// Conservatively assume there may be reuse if the quotient of their
|
|
|
|
// strides could be a legal scale.
|
2010-04-19 21:48:58 +00:00
|
|
|
const SCEV *A = IU.getStride(*CondUse, L);
|
|
|
|
const SCEV *B = IU.getStride(*UI, L);
|
2010-04-07 22:27:08 +00:00
|
|
|
if (!A || !B) continue;
|
2010-02-12 10:34:29 +00:00
|
|
|
if (SE.getTypeSizeInBits(A->getType()) !=
|
|
|
|
SE.getTypeSizeInBits(B->getType())) {
|
|
|
|
if (SE.getTypeSizeInBits(A->getType()) >
|
|
|
|
SE.getTypeSizeInBits(B->getType()))
|
|
|
|
B = SE.getSignExtendExpr(B, A->getType());
|
|
|
|
else
|
|
|
|
A = SE.getSignExtendExpr(A, B->getType());
|
|
|
|
}
|
|
|
|
if (const SCEVConstant *D =
|
2010-02-19 19:35:48 +00:00
|
|
|
dyn_cast_or_null<SCEVConstant>(getExactSDiv(B, A, SE))) {
|
2010-05-20 22:25:20 +00:00
|
|
|
const ConstantInt *C = D->getValue();
|
2010-02-12 10:34:29 +00:00
|
|
|
// Stride of one or negative one can have reuse with non-addresses.
|
2010-05-20 22:25:20 +00:00
|
|
|
if (C->isOne() || C->isAllOnesValue())
|
2010-02-12 10:34:29 +00:00
|
|
|
goto decline_post_inc;
|
|
|
|
// Avoid weird situations.
|
2010-05-20 22:25:20 +00:00
|
|
|
if (C->getValue().getMinSignedBits() >= 64 ||
|
|
|
|
C->getValue().isMinSignedValue())
|
2010-02-12 10:34:29 +00:00
|
|
|
goto decline_post_inc;
|
2010-02-14 03:21:49 +00:00
|
|
|
// Without TLI, assume that any stride might be valid, and so any
|
|
|
|
// use might be shared.
|
|
|
|
if (!TLI)
|
|
|
|
goto decline_post_inc;
|
2010-02-12 10:34:29 +00:00
|
|
|
// Check for possible scaled-address reuse.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *AccessTy = getAccessType(UI->getUser());
|
2010-02-12 10:34:29 +00:00
|
|
|
TargetLowering::AddrMode AM;
|
2010-05-20 22:25:20 +00:00
|
|
|
AM.Scale = C->getSExtValue();
|
2010-02-14 02:45:21 +00:00
|
|
|
if (TLI->isLegalAddressingMode(AM, AccessTy))
|
2010-02-12 10:34:29 +00:00
|
|
|
goto decline_post_inc;
|
|
|
|
AM.Scale = -AM.Scale;
|
2010-02-14 02:45:21 +00:00
|
|
|
if (TLI->isLegalAddressingMode(AM, AccessTy))
|
2010-02-12 10:34:29 +00:00
|
|
|
goto decline_post_inc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-23 22:58:38 +00:00
|
|
|
DEBUG(dbgs() << " Change loop exiting icmp to use postinc iv: "
|
2010-02-12 10:34:29 +00:00
|
|
|
<< *Cond << '\n');
|
2009-11-17 17:53:56 +00:00
|
|
|
|
2009-11-17 18:10:11 +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 exiting block branch, move it.
|
2010-02-12 10:34:29 +00:00
|
|
|
if (&*++BasicBlock::iterator(Cond) != TermBr) {
|
|
|
|
if (Cond->hasOneUse()) {
|
2009-11-17 18:10:11 +00:00
|
|
|
Cond->moveBefore(TermBr);
|
|
|
|
} else {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Clone the terminating condition and insert into the loopend.
|
|
|
|
ICmpInst *OldCond = Cond;
|
2009-11-17 18:10:11 +00:00
|
|
|
Cond = cast<ICmpInst>(Cond->clone());
|
|
|
|
Cond->setName(L->getHeader()->getName() + ".termcond");
|
|
|
|
ExitingBlock->getInstList().insert(TermBr, Cond);
|
|
|
|
|
|
|
|
// Clone the IVUse, as the old use still exists!
|
2011-06-21 15:43:52 +00:00
|
|
|
CondUse = &IU.AddUser(Cond, CondUse->getOperandValToReplace());
|
2010-02-12 10:34:29 +00:00
|
|
|
TermBr->replaceUsesOfWith(OldCond, Cond);
|
2009-11-17 18:10:11 +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
|
|
|
}
|
|
|
|
|
2009-11-17 18:10:11 +00:00
|
|
|
// If we get to here, we know that we can transform the setcc instruction to
|
|
|
|
// use the post-incremented version of the IV, allowing us to coalesce the
|
|
|
|
// live ranges for the IV correctly.
|
2010-04-07 22:27:08 +00:00
|
|
|
CondUse->transformToPostInc(L);
|
2009-11-17 18:10:11 +00:00
|
|
|
Changed = true;
|
2009-05-11 22:33:01 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
PostIncs.insert(Cond);
|
|
|
|
decline_post_inc:;
|
2009-05-11 17:15:42 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Determine an insertion point for the loop induction variable increment. It
|
|
|
|
// must dominate all the post-inc comparisons we just set up, and it must
|
|
|
|
// dominate the loop latch edge.
|
|
|
|
IVIncInsertPos = L->getLoopLatch()->getTerminator();
|
|
|
|
for (SmallPtrSet<Instruction *, 4>::const_iterator I = PostIncs.begin(),
|
|
|
|
E = PostIncs.end(); I != E; ++I) {
|
|
|
|
BasicBlock *BB =
|
|
|
|
DT.findNearestCommonDominator(IVIncInsertPos->getParent(),
|
|
|
|
(*I)->getParent());
|
|
|
|
if (BB == (*I)->getParent())
|
|
|
|
IVIncInsertPos = *I;
|
|
|
|
else if (BB != IVIncInsertPos->getParent())
|
|
|
|
IVIncInsertPos = BB->getTerminator();
|
|
|
|
}
|
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2011-04-15 05:18:47 +00:00
|
|
|
/// reconcileNewOffset - Determine if the given use can accommodate a fixup
|
2010-05-20 20:52:00 +00:00
|
|
|
/// at the given offset and other details. If so, update the use and
|
|
|
|
/// return true.
|
2010-02-12 10:34:29 +00:00
|
|
|
bool
|
2010-09-01 01:45:53 +00:00
|
|
|
LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset, bool HasBaseReg,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy) {
|
2010-09-01 01:45:53 +00:00
|
|
|
int64_t NewMinOffset = LU.MinOffset;
|
|
|
|
int64_t NewMaxOffset = LU.MaxOffset;
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *NewAccessTy = AccessTy;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Check for a mismatched kind. It's tempting to collapse mismatched kinds to
|
|
|
|
// something conservative, however this can pessimize in the case that one of
|
|
|
|
// the uses will have all its uses outside the loop, for example.
|
|
|
|
if (LU.Kind != Kind)
|
|
|
|
return false;
|
|
|
|
// Conservatively assume HasBaseReg is true for now.
|
2010-09-01 01:45:53 +00:00
|
|
|
if (NewOffset < LU.MinOffset) {
|
|
|
|
if (!isAlwaysFoldable(LU.MaxOffset - NewOffset, 0, HasBaseReg,
|
2010-02-22 04:11:59 +00:00
|
|
|
Kind, AccessTy, TLI))
|
2010-01-22 00:46:49 +00:00
|
|
|
return false;
|
2010-09-01 01:45:53 +00:00
|
|
|
NewMinOffset = NewOffset;
|
|
|
|
} else if (NewOffset > LU.MaxOffset) {
|
|
|
|
if (!isAlwaysFoldable(NewOffset - LU.MinOffset, 0, HasBaseReg,
|
2010-02-22 04:11:59 +00:00
|
|
|
Kind, AccessTy, TLI))
|
2010-01-22 00:46:49 +00:00
|
|
|
return false;
|
2010-09-01 01:45:53 +00:00
|
|
|
NewMaxOffset = NewOffset;
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
// Check for a mismatched access type, and fall back conservatively as needed.
|
2010-06-19 21:30:18 +00:00
|
|
|
// TODO: Be less conservative when the type is similar and can use the same
|
|
|
|
// addressing modes.
|
2010-02-12 10:34:29 +00:00
|
|
|
if (Kind == LSRUse::Address && AccessTy != LU.AccessTy)
|
2010-09-01 01:45:53 +00:00
|
|
|
NewAccessTy = Type::getVoidTy(AccessTy->getContext());
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Update the use.
|
2010-09-01 01:45:53 +00:00
|
|
|
LU.MinOffset = NewMinOffset;
|
|
|
|
LU.MaxOffset = NewMaxOffset;
|
|
|
|
LU.AccessTy = NewAccessTy;
|
|
|
|
if (NewOffset != LU.Offsets.back())
|
|
|
|
LU.Offsets.push_back(NewOffset);
|
2010-02-12 10:34:29 +00:00
|
|
|
return true;
|
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// getUse - Return an LSRUse index and an offset value for a fixup which
|
|
|
|
/// needs the given expression, with the given kind and optional access type.
|
2010-03-01 17:49:51 +00:00
|
|
|
/// Either reuse an existing use or create a new one, as needed.
|
2010-02-12 10:34:29 +00:00
|
|
|
std::pair<size_t, int64_t>
|
|
|
|
LSRInstance::getUse(const SCEV *&Expr,
|
2011-07-18 04:54:35 +00:00
|
|
|
LSRUse::KindType Kind, Type *AccessTy) {
|
2010-02-12 10:34:29 +00:00
|
|
|
const SCEV *Copy = Expr;
|
|
|
|
int64_t Offset = ExtractImmediate(Expr, SE);
|
|
|
|
|
|
|
|
// Basic uses can't accept any offset, for example.
|
2010-02-22 04:11:59 +00:00
|
|
|
if (!isAlwaysFoldable(Offset, 0, /*HasBaseReg=*/true, Kind, AccessTy, TLI)) {
|
2010-02-12 10:34:29 +00:00
|
|
|
Expr = Copy;
|
|
|
|
Offset = 0;
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
std::pair<UseMapTy::iterator, bool> P =
|
2010-06-19 21:29:59 +00:00
|
|
|
UseMap.insert(std::make_pair(std::make_pair(Expr, Kind), 0));
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!P.second) {
|
|
|
|
// A use already existed with this base.
|
|
|
|
size_t LUIdx = P.first->second;
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-09-01 01:45:53 +00:00
|
|
|
if (reconcileNewOffset(LU, Offset, /*HasBaseReg=*/true, Kind, AccessTy))
|
2010-02-12 10:34:29 +00:00
|
|
|
// Reuse this use.
|
|
|
|
return std::make_pair(LUIdx, Offset);
|
|
|
|
}
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Create a new use.
|
|
|
|
size_t LUIdx = Uses.size();
|
|
|
|
P.first->second = LUIdx;
|
|
|
|
Uses.push_back(LSRUse(Kind, AccessTy));
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-09-01 01:45:53 +00:00
|
|
|
// We don't need to track redundant offsets, but we don't need to go out
|
|
|
|
// of our way here to avoid them.
|
|
|
|
if (LU.Offsets.empty() || Offset != LU.Offsets.back())
|
|
|
|
LU.Offsets.push_back(Offset);
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
LU.MinOffset = Offset;
|
|
|
|
LU.MaxOffset = Offset;
|
|
|
|
return std::make_pair(LUIdx, Offset);
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
|
|
|
|
2010-05-20 15:17:54 +00:00
|
|
|
/// DeleteUse - Delete the given use from the Uses list.
|
2010-10-07 23:33:43 +00:00
|
|
|
void LSRInstance::DeleteUse(LSRUse &LU, size_t LUIdx) {
|
2010-09-01 01:45:53 +00:00
|
|
|
if (&LU != &Uses.back())
|
2010-05-20 15:17:54 +00:00
|
|
|
std::swap(LU, Uses.back());
|
|
|
|
Uses.pop_back();
|
2010-10-07 23:33:43 +00:00
|
|
|
|
|
|
|
// Update RegUses.
|
|
|
|
RegUses.SwapAndDropUse(LUIdx, Uses.size());
|
2010-05-20 15:17:54 +00:00
|
|
|
}
|
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
/// FindUseWithFormula - Look for a use distinct from OrigLU which is has
|
|
|
|
/// a formula that has the same registers as the given formula.
|
|
|
|
LSRUse *
|
|
|
|
LSRInstance::FindUseWithSimilarFormula(const Formula &OrigF,
|
2010-09-01 01:45:53 +00:00
|
|
|
const LSRUse &OrigLU) {
|
|
|
|
// Search all uses for the formula. This could be more clever.
|
2010-05-19 23:43:12 +00:00
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-08-29 15:27:08 +00:00
|
|
|
// Check whether this use is close enough to OrigLU, to see whether it's
|
|
|
|
// worthwhile looking through its formulae.
|
|
|
|
// Ignore ICmpZero uses because they may contain formulae generated by
|
|
|
|
// GenerateICmpZeroScales, in which case adding fixup offsets may
|
|
|
|
// be invalid.
|
2010-05-19 23:43:12 +00:00
|
|
|
if (&LU != &OrigLU &&
|
|
|
|
LU.Kind != LSRUse::ICmpZero &&
|
|
|
|
LU.Kind == OrigLU.Kind && OrigLU.AccessTy == LU.AccessTy &&
|
2010-07-15 20:24:58 +00:00
|
|
|
LU.WidestFixupType == OrigLU.WidestFixupType &&
|
2010-05-19 23:43:12 +00:00
|
|
|
LU.HasFormulaWithSameRegs(OrigF)) {
|
2010-08-29 15:27:08 +00:00
|
|
|
// Scan through this use's formulae.
|
2010-05-20 20:33:18 +00:00
|
|
|
for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
|
|
|
|
E = LU.Formulae.end(); I != E; ++I) {
|
|
|
|
const Formula &F = *I;
|
2010-08-29 15:27:08 +00:00
|
|
|
// Check to see if this formula has the same registers and symbols
|
|
|
|
// as OrigF.
|
2010-05-19 23:43:12 +00:00
|
|
|
if (F.BaseRegs == OrigF.BaseRegs &&
|
|
|
|
F.ScaledReg == OrigF.ScaledReg &&
|
|
|
|
F.AM.BaseGV == OrigF.AM.BaseGV &&
|
2011-05-03 00:46:49 +00:00
|
|
|
F.AM.Scale == OrigF.AM.Scale &&
|
|
|
|
F.UnfoldedOffset == OrigF.UnfoldedOffset) {
|
2010-09-01 01:45:53 +00:00
|
|
|
if (F.AM.BaseOffs == 0)
|
2010-05-19 23:43:12 +00:00
|
|
|
return &LU;
|
2010-08-29 15:27:08 +00:00
|
|
|
// This is the formula where all the registers and symbols matched;
|
|
|
|
// there aren't going to be any others. Since we declined it, we
|
|
|
|
// can skip the rest of the formulae and procede to the next LSRUse.
|
2010-05-19 23:43:12 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-29 15:27:08 +00:00
|
|
|
// Nothing looked good.
|
2010-05-19 23:43:12 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::CollectInterestingTypesAndFactors() {
|
|
|
|
SmallSetVector<const SCEV *, 4> Strides;
|
|
|
|
|
2010-02-19 00:05:23 +00:00
|
|
|
// Collect interesting types and strides.
|
2010-04-07 22:27:08 +00:00
|
|
|
SmallVector<const SCEV *, 4> Worklist;
|
2010-02-12 10:34:29 +00:00
|
|
|
for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
|
2010-04-19 21:48:58 +00:00
|
|
|
const SCEV *Expr = IU.getExpr(*UI);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Collect interesting types.
|
2010-04-07 22:27:08 +00:00
|
|
|
Types.insert(SE.getEffectiveSCEVType(Expr->getType()));
|
|
|
|
|
|
|
|
// Add strides for mentioned loops.
|
|
|
|
Worklist.push_back(Expr);
|
|
|
|
do {
|
|
|
|
const SCEV *S = Worklist.pop_back_val();
|
|
|
|
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
|
2011-12-10 00:25:00 +00:00
|
|
|
if (EnableNested || AR->getLoop() == L)
|
|
|
|
Strides.insert(AR->getStepRecurrence(SE));
|
2010-04-07 22:27:08 +00:00
|
|
|
Worklist.push_back(AR->getStart());
|
|
|
|
} else if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
2010-06-21 19:47:52 +00:00
|
|
|
Worklist.append(Add->op_begin(), Add->op_end());
|
2010-04-07 22:27:08 +00:00
|
|
|
}
|
|
|
|
} while (!Worklist.empty());
|
2010-02-19 00:05:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Compute interesting factors from the set of interesting strides.
|
|
|
|
for (SmallSetVector<const SCEV *, 4>::const_iterator
|
|
|
|
I = Strides.begin(), E = Strides.end(); I != E; ++I)
|
2010-02-12 10:34:29 +00:00
|
|
|
for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter =
|
2010-08-02 06:00:15 +00:00
|
|
|
llvm::next(I); NewStrideIter != E; ++NewStrideIter) {
|
2010-02-19 00:05:23 +00:00
|
|
|
const SCEV *OldStride = *I;
|
2010-02-12 10:34:29 +00:00
|
|
|
const SCEV *NewStride = *NewStrideIter;
|
2010-01-21 02:09:26 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (SE.getTypeSizeInBits(OldStride->getType()) !=
|
|
|
|
SE.getTypeSizeInBits(NewStride->getType())) {
|
|
|
|
if (SE.getTypeSizeInBits(OldStride->getType()) >
|
|
|
|
SE.getTypeSizeInBits(NewStride->getType()))
|
|
|
|
NewStride = SE.getSignExtendExpr(NewStride, OldStride->getType());
|
|
|
|
else
|
|
|
|
OldStride = SE.getSignExtendExpr(OldStride, NewStride->getType());
|
|
|
|
}
|
|
|
|
if (const SCEVConstant *Factor =
|
2010-02-19 19:35:48 +00:00
|
|
|
dyn_cast_or_null<SCEVConstant>(getExactSDiv(NewStride, OldStride,
|
|
|
|
SE, true))) {
|
2010-02-12 10:34:29 +00:00
|
|
|
if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
|
|
|
|
Factors.insert(Factor->getValue()->getValue().getSExtValue());
|
|
|
|
} else if (const SCEVConstant *Factor =
|
2010-02-22 04:11:59 +00:00
|
|
|
dyn_cast_or_null<SCEVConstant>(getExactSDiv(OldStride,
|
|
|
|
NewStride,
|
2010-02-19 19:35:48 +00:00
|
|
|
SE, true))) {
|
2010-02-12 10:34:29 +00:00
|
|
|
if (Factor->getValue()->getValue().getMinSignedBits() <= 64)
|
|
|
|
Factors.insert(Factor->getValue()->getValue().getSExtValue());
|
2010-01-21 02:09:26 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-12 07:35:05 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// If all uses use the same type, don't bother looking for truncation-based
|
|
|
|
// reuse.
|
|
|
|
if (Types.size() == 1)
|
|
|
|
Types.clear();
|
|
|
|
|
|
|
|
DEBUG(print_factors_and_types(dbgs()));
|
2009-05-11 17:15:42 +00:00
|
|
|
}
|
|
|
|
|
2012-01-09 19:50:34 +00:00
|
|
|
/// findIVOperand - Helper for CollectChains that finds an IV operand (computed
|
|
|
|
/// by an AddRec in this loop) within [OI,OE) or returns OE. If IVUsers mapped
|
|
|
|
/// Instructions to IVStrideUses, we could partially skip this.
|
|
|
|
static User::op_iterator
|
|
|
|
findIVOperand(User::op_iterator OI, User::op_iterator OE,
|
|
|
|
Loop *L, ScalarEvolution &SE) {
|
|
|
|
for(; OI != OE; ++OI) {
|
|
|
|
if (Instruction *Oper = dyn_cast<Instruction>(*OI)) {
|
|
|
|
if (!SE.isSCEVable(Oper->getType()))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (const SCEVAddRecExpr *AR =
|
|
|
|
dyn_cast<SCEVAddRecExpr>(SE.getSCEV(Oper))) {
|
|
|
|
if (AR->getLoop() == L)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return OI;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// getWideOperand - IVChain logic must consistenctly peek base TruncInst
|
|
|
|
/// operands, so wrap it in a convenient helper.
|
|
|
|
static Value *getWideOperand(Value *Oper) {
|
|
|
|
if (TruncInst *Trunc = dyn_cast<TruncInst>(Oper))
|
|
|
|
return Trunc->getOperand(0);
|
|
|
|
return Oper;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isCompatibleIVType - Return true if we allow an IV chain to include both
|
|
|
|
/// types.
|
|
|
|
static bool isCompatibleIVType(Value *LVal, Value *RVal) {
|
|
|
|
Type *LType = LVal->getType();
|
|
|
|
Type *RType = RVal->getType();
|
|
|
|
return (LType == RType) || (LType->isPointerTy() && RType->isPointerTy());
|
|
|
|
}
|
|
|
|
|
2012-01-10 01:45:08 +00:00
|
|
|
/// getExprBase - Return an approximation of this SCEV expression's "base", or
|
|
|
|
/// NULL for any constant. Returning the expression itself is
|
|
|
|
/// conservative. Returning a deeper subexpression is more precise and valid as
|
|
|
|
/// long as it isn't less complex than another subexpression. For expressions
|
|
|
|
/// involving multiple unscaled values, we need to return the pointer-type
|
|
|
|
/// SCEVUnknown. This avoids forming chains across objects, such as:
|
|
|
|
/// PrevOper==a[i], IVOper==b[i], IVInc==b-a.
|
|
|
|
///
|
|
|
|
/// Since SCEVUnknown is the rightmost type, and pointers are the rightmost
|
|
|
|
/// SCEVUnknown, we simply return the rightmost SCEV operand.
|
|
|
|
static const SCEV *getExprBase(const SCEV *S) {
|
|
|
|
switch (S->getSCEVType()) {
|
|
|
|
default: // uncluding scUnknown.
|
|
|
|
return S;
|
|
|
|
case scConstant:
|
|
|
|
return 0;
|
|
|
|
case scTruncate:
|
|
|
|
return getExprBase(cast<SCEVTruncateExpr>(S)->getOperand());
|
|
|
|
case scZeroExtend:
|
|
|
|
return getExprBase(cast<SCEVZeroExtendExpr>(S)->getOperand());
|
|
|
|
case scSignExtend:
|
|
|
|
return getExprBase(cast<SCEVSignExtendExpr>(S)->getOperand());
|
|
|
|
case scAddExpr: {
|
|
|
|
// Skip over scaled operands (scMulExpr) to follow add operands as long as
|
|
|
|
// there's nothing more complex.
|
|
|
|
// FIXME: not sure if we want to recognize negation.
|
|
|
|
const SCEVAddExpr *Add = cast<SCEVAddExpr>(S);
|
|
|
|
for (std::reverse_iterator<SCEVAddExpr::op_iterator> I(Add->op_end()),
|
|
|
|
E(Add->op_begin()); I != E; ++I) {
|
|
|
|
const SCEV *SubExpr = *I;
|
|
|
|
if (SubExpr->getSCEVType() == scAddExpr)
|
|
|
|
return getExprBase(SubExpr);
|
|
|
|
|
|
|
|
if (SubExpr->getSCEVType() != scMulExpr)
|
|
|
|
return SubExpr;
|
|
|
|
}
|
|
|
|
return S; // all operands are scaled, be conservative.
|
|
|
|
}
|
|
|
|
case scAddRecExpr:
|
|
|
|
return getExprBase(cast<SCEVAddRecExpr>(S)->getStart());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-09 21:18:52 +00:00
|
|
|
/// Return true if the chain increment is profitable to expand into a loop
|
|
|
|
/// invariant value, which may require its own register. A profitable chain
|
|
|
|
/// increment will be an offset relative to the same base. We allow such offsets
|
|
|
|
/// to potentially be used as chain increment as long as it's not obviously
|
|
|
|
/// expensive to expand using real instructions.
|
|
|
|
static const SCEV *
|
|
|
|
getProfitableChainIncrement(Value *NextIV, Value *PrevIV,
|
|
|
|
const IVChain &Chain, Loop *L,
|
|
|
|
ScalarEvolution &SE, const TargetLowering *TLI) {
|
2012-01-10 01:45:08 +00:00
|
|
|
// Prune the solution space aggressively by checking that both IV operands
|
|
|
|
// are expressions that operate on the same unscaled SCEVUnknown. This
|
|
|
|
// "base" will be canceled by the subsequent getMinusSCEV call. Checking first
|
|
|
|
// avoids creating extra SCEV expressions.
|
|
|
|
const SCEV *OperExpr = SE.getSCEV(NextIV);
|
|
|
|
const SCEV *PrevExpr = SE.getSCEV(PrevIV);
|
|
|
|
if (getExprBase(OperExpr) != getExprBase(PrevExpr) && !StressIVChain)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const SCEV *IncExpr = SE.getMinusSCEV(OperExpr, PrevExpr);
|
2012-01-09 21:18:52 +00:00
|
|
|
if (!SE.isLoopInvariant(IncExpr, L))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// We are not able to expand an increment unless it is loop invariant,
|
|
|
|
// however, the following checks are purely for profitability.
|
|
|
|
if (StressIVChain)
|
|
|
|
return IncExpr;
|
|
|
|
|
2012-01-10 01:45:08 +00:00
|
|
|
// Do not replace a constant offset from IV head with a nonconstant IV
|
|
|
|
// increment.
|
|
|
|
if (!isa<SCEVConstant>(IncExpr)) {
|
|
|
|
const SCEV *HeadExpr = SE.getSCEV(getWideOperand(Chain[0].IVOperand));
|
|
|
|
if (isa<SCEVConstant>(SE.getMinusSCEV(OperExpr, HeadExpr)))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SmallPtrSet<const SCEV*, 8> Processed;
|
|
|
|
if (isHighCostExpansion(IncExpr, Processed, SE))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return IncExpr;
|
2012-01-09 21:18:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return true if the number of registers needed for the chain is estimated to
|
|
|
|
/// be less than the number required for the individual IV users. First prohibit
|
|
|
|
/// any IV users that keep the IV live across increments (the Users set should
|
|
|
|
/// be empty). Next count the number and type of increments in the chain.
|
|
|
|
///
|
|
|
|
/// Chaining IVs can lead to considerable code bloat if ISEL doesn't
|
|
|
|
/// effectively use postinc addressing modes. Only consider it profitable it the
|
|
|
|
/// increments can be computed in fewer registers when chained.
|
|
|
|
///
|
|
|
|
/// TODO: Consider IVInc free if it's already used in another chains.
|
|
|
|
static bool
|
|
|
|
isProfitableChain(IVChain &Chain, SmallPtrSet<Instruction*, 4> &Users,
|
|
|
|
ScalarEvolution &SE, const TargetLowering *TLI) {
|
|
|
|
if (StressIVChain)
|
|
|
|
return true;
|
|
|
|
|
2012-01-10 01:45:08 +00:00
|
|
|
if (Chain.size() <= 2)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!Users.empty()) {
|
|
|
|
DEBUG(dbgs() << "Chain: " << *Chain[0].UserInst << " users:\n";
|
|
|
|
for (SmallPtrSet<Instruction*, 4>::const_iterator I = Users.begin(),
|
|
|
|
E = Users.end(); I != E; ++I) {
|
|
|
|
dbgs() << " " << **I << "\n";
|
|
|
|
});
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
assert(!Chain.empty() && "empty IV chains are not allowed");
|
|
|
|
|
|
|
|
// The chain itself may require a register, so intialize cost to 1.
|
|
|
|
int cost = 1;
|
|
|
|
|
|
|
|
// A complete chain likely eliminates the need for keeping the original IV in
|
|
|
|
// a register. LSR does not currently know how to form a complete chain unless
|
|
|
|
// the header phi already exists.
|
|
|
|
if (isa<PHINode>(Chain.back().UserInst)
|
|
|
|
&& SE.getSCEV(Chain.back().UserInst) == Chain[0].IncExpr) {
|
|
|
|
--cost;
|
|
|
|
}
|
|
|
|
const SCEV *LastIncExpr = 0;
|
|
|
|
unsigned NumConstIncrements = 0;
|
|
|
|
unsigned NumVarIncrements = 0;
|
|
|
|
unsigned NumReusedIncrements = 0;
|
|
|
|
for (IVChain::const_iterator I = llvm::next(Chain.begin()), E = Chain.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
|
|
|
|
if (I->IncExpr->isZero())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Incrementing by zero or some constant is neutral. We assume constants can
|
|
|
|
// be folded into an addressing mode or an add's immediate operand.
|
|
|
|
if (isa<SCEVConstant>(I->IncExpr)) {
|
|
|
|
++NumConstIncrements;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (I->IncExpr == LastIncExpr)
|
|
|
|
++NumReusedIncrements;
|
|
|
|
else
|
|
|
|
++NumVarIncrements;
|
|
|
|
|
|
|
|
LastIncExpr = I->IncExpr;
|
|
|
|
}
|
|
|
|
// An IV chain with a single increment is handled by LSR's postinc
|
|
|
|
// uses. However, a chain with multiple increments requires keeping the IV's
|
|
|
|
// value live longer than it needs to be if chained.
|
|
|
|
if (NumConstIncrements > 1)
|
|
|
|
--cost;
|
|
|
|
|
|
|
|
// Materializing increment expressions in the preheader that didn't exist in
|
|
|
|
// the original code may cost a register. For example, sign-extended array
|
|
|
|
// indices can produce ridiculous increments like this:
|
|
|
|
// IV + ((sext i32 (2 * %s) to i64) + (-1 * (sext i32 %s to i64)))
|
|
|
|
cost += NumVarIncrements;
|
|
|
|
|
|
|
|
// Reusing variable increments likely saves a register to hold the multiple of
|
|
|
|
// the stride.
|
|
|
|
cost -= NumReusedIncrements;
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Chain: " << *Chain[0].UserInst << " Cost: " << cost << "\n");
|
|
|
|
|
|
|
|
return cost < 0;
|
2012-01-09 21:18:52 +00:00
|
|
|
}
|
|
|
|
|
2012-01-09 19:50:34 +00:00
|
|
|
/// ChainInstruction - Add this IV user to an existing chain or make it the head
|
|
|
|
/// of a new chain.
|
|
|
|
void LSRInstance::ChainInstruction(Instruction *UserInst, Instruction *IVOper,
|
|
|
|
SmallVectorImpl<ChainUsers> &ChainUsersVec) {
|
|
|
|
// When IVs are used as types of varying widths, they are generally converted
|
|
|
|
// to a wider type with some uses remaining narrow under a (free) trunc.
|
|
|
|
Value *NextIV = getWideOperand(IVOper);
|
|
|
|
|
|
|
|
// Visit all existing chains. Check if its IVOper can be computed as a
|
|
|
|
// profitable loop invariant increment from the last link in the Chain.
|
|
|
|
unsigned ChainIdx = 0, NChains = IVChainVec.size();
|
|
|
|
const SCEV *LastIncExpr = 0;
|
|
|
|
for (; ChainIdx < NChains; ++ChainIdx) {
|
|
|
|
Value *PrevIV = getWideOperand(IVChainVec[ChainIdx].back().IVOperand);
|
|
|
|
if (!isCompatibleIVType(PrevIV, NextIV))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// A phi nodes terminates a chain.
|
|
|
|
if (isa<PHINode>(UserInst)
|
|
|
|
&& isa<PHINode>(IVChainVec[ChainIdx].back().UserInst))
|
|
|
|
continue;
|
|
|
|
|
2012-01-09 21:18:52 +00:00
|
|
|
if (const SCEV *IncExpr =
|
|
|
|
getProfitableChainIncrement(NextIV, PrevIV, IVChainVec[ChainIdx],
|
|
|
|
L, SE, TLI)) {
|
2012-01-09 19:50:34 +00:00
|
|
|
LastIncExpr = IncExpr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If we haven't found a chain, create a new one, unless we hit the max. Don't
|
|
|
|
// bother for phi nodes, because they must be last in the chain.
|
|
|
|
if (ChainIdx == NChains) {
|
|
|
|
if (isa<PHINode>(UserInst))
|
|
|
|
return;
|
2012-01-09 21:18:52 +00:00
|
|
|
if (NChains >= MaxChains && !StressIVChain) {
|
2012-01-09 19:50:34 +00:00
|
|
|
DEBUG(dbgs() << "IV Chain Limit\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
++NChains;
|
|
|
|
IVChainVec.resize(NChains);
|
|
|
|
ChainUsersVec.resize(NChains);
|
|
|
|
LastIncExpr = SE.getSCEV(NextIV);
|
|
|
|
assert(isa<SCEVAddRecExpr>(LastIncExpr) && "expect recurrence at IV user");
|
|
|
|
DEBUG(dbgs() << "IV Head: (" << *UserInst << ") IV=" << *LastIncExpr
|
|
|
|
<< "\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DEBUG(dbgs() << "IV Inc: (" << *UserInst << ") IV+" << *LastIncExpr
|
|
|
|
<< "\n");
|
|
|
|
|
|
|
|
// Add this IV user to the end of the chain.
|
|
|
|
IVChainVec[ChainIdx].push_back(IVInc(UserInst, IVOper, LastIncExpr));
|
|
|
|
|
|
|
|
SmallPtrSet<Instruction*,4> &NearUsers = ChainUsersVec[ChainIdx].NearUsers;
|
|
|
|
// This chain's NearUsers become FarUsers.
|
|
|
|
if (!LastIncExpr->isZero()) {
|
|
|
|
ChainUsersVec[ChainIdx].FarUsers.insert(NearUsers.begin(),
|
|
|
|
NearUsers.end());
|
|
|
|
NearUsers.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// All other uses of IVOperand become near uses of the chain.
|
|
|
|
// We currently ignore intermediate values within SCEV expressions, assuming
|
|
|
|
// they will eventually be used be the current chain, or can be computed
|
|
|
|
// from one of the chain increments. To be more precise we could
|
|
|
|
// transitively follow its user and only add leaf IV users to the set.
|
|
|
|
for (Value::use_iterator UseIter = IVOper->use_begin(),
|
|
|
|
UseEnd = IVOper->use_end(); UseIter != UseEnd; ++UseIter) {
|
|
|
|
Instruction *OtherUse = dyn_cast<Instruction>(*UseIter);
|
|
|
|
if (SE.isSCEVable(OtherUse->getType())
|
|
|
|
&& !isa<SCEVUnknown>(SE.getSCEV(OtherUse))
|
|
|
|
&& IU.isIVUserOrOperand(OtherUse)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (OtherUse && OtherUse != UserInst)
|
|
|
|
NearUsers.insert(OtherUse);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Since this user is part of the chain, it's no longer considered a use
|
|
|
|
// of the chain.
|
|
|
|
ChainUsersVec[ChainIdx].FarUsers.erase(UserInst);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// CollectChains - Populate the vector of Chains.
|
|
|
|
///
|
|
|
|
/// This decreases ILP at the architecture level. Targets with ample registers,
|
|
|
|
/// multiple memory ports, and no register renaming probably don't want
|
|
|
|
/// this. However, such targets should probably disable LSR altogether.
|
|
|
|
///
|
|
|
|
/// The job of LSR is to make a reasonable choice of induction variables across
|
|
|
|
/// the loop. Subsequent passes can easily "unchain" computation exposing more
|
|
|
|
/// ILP *within the loop* if the target wants it.
|
|
|
|
///
|
|
|
|
/// Finding the best IV chain is potentially a scheduling problem. Since LSR
|
|
|
|
/// will not reorder memory operations, it will recognize this as a chain, but
|
|
|
|
/// will generate redundant IV increments. Ideally this would be corrected later
|
|
|
|
/// by a smart scheduler:
|
|
|
|
/// = A[i]
|
|
|
|
/// = A[i+x]
|
|
|
|
/// A[i] =
|
|
|
|
/// A[i+x] =
|
|
|
|
///
|
|
|
|
/// TODO: Walk the entire domtree within this loop, not just the path to the
|
|
|
|
/// loop latch. This will discover chains on side paths, but requires
|
|
|
|
/// maintaining multiple copies of the Chains state.
|
|
|
|
void LSRInstance::CollectChains() {
|
|
|
|
SmallVector<ChainUsers, 8> ChainUsersVec;
|
|
|
|
|
|
|
|
SmallVector<BasicBlock *,8> LatchPath;
|
|
|
|
BasicBlock *LoopHeader = L->getHeader();
|
|
|
|
for (DomTreeNode *Rung = DT.getNode(L->getLoopLatch());
|
|
|
|
Rung->getBlock() != LoopHeader; Rung = Rung->getIDom()) {
|
|
|
|
LatchPath.push_back(Rung->getBlock());
|
|
|
|
}
|
|
|
|
LatchPath.push_back(LoopHeader);
|
|
|
|
|
|
|
|
// Walk the instruction stream from the loop header to the loop latch.
|
|
|
|
for (SmallVectorImpl<BasicBlock *>::reverse_iterator
|
|
|
|
BBIter = LatchPath.rbegin(), BBEnd = LatchPath.rend();
|
|
|
|
BBIter != BBEnd; ++BBIter) {
|
|
|
|
for (BasicBlock::iterator I = (*BBIter)->begin(), E = (*BBIter)->end();
|
|
|
|
I != E; ++I) {
|
|
|
|
// Skip instructions that weren't seen by IVUsers analysis.
|
|
|
|
if (isa<PHINode>(I) || !IU.isIVUserOrOperand(I))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Ignore users that are part of a SCEV expression. This way we only
|
|
|
|
// consider leaf IV Users. This effectively rediscovers a portion of
|
|
|
|
// IVUsers analysis but in program order this time.
|
|
|
|
if (SE.isSCEVable(I->getType()) && !isa<SCEVUnknown>(SE.getSCEV(I)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Remove this instruction from any NearUsers set it may be in.
|
|
|
|
for (unsigned ChainIdx = 0, NChains = IVChainVec.size();
|
|
|
|
ChainIdx < NChains; ++ChainIdx) {
|
|
|
|
ChainUsersVec[ChainIdx].NearUsers.erase(I);
|
|
|
|
}
|
|
|
|
// Search for operands that can be chained.
|
|
|
|
SmallPtrSet<Instruction*, 4> UniqueOperands;
|
|
|
|
User::op_iterator IVOpEnd = I->op_end();
|
|
|
|
User::op_iterator IVOpIter = findIVOperand(I->op_begin(), IVOpEnd, L, SE);
|
|
|
|
while (IVOpIter != IVOpEnd) {
|
|
|
|
Instruction *IVOpInst = cast<Instruction>(*IVOpIter);
|
|
|
|
if (UniqueOperands.insert(IVOpInst))
|
|
|
|
ChainInstruction(I, IVOpInst, ChainUsersVec);
|
|
|
|
IVOpIter = findIVOperand(llvm::next(IVOpIter), IVOpEnd, L, SE);
|
|
|
|
}
|
|
|
|
} // Continue walking down the instructions.
|
|
|
|
} // Continue walking down the domtree.
|
|
|
|
// Visit phi backedges to determine if the chain can generate the IV postinc.
|
|
|
|
for (BasicBlock::iterator I = L->getHeader()->begin();
|
|
|
|
PHINode *PN = dyn_cast<PHINode>(I); ++I) {
|
|
|
|
if (!SE.isSCEVable(PN->getType()))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Instruction *IncV =
|
|
|
|
dyn_cast<Instruction>(PN->getIncomingValueForBlock(L->getLoopLatch()));
|
|
|
|
if (IncV)
|
|
|
|
ChainInstruction(PN, IncV, ChainUsersVec);
|
|
|
|
}
|
2012-01-09 21:18:52 +00:00
|
|
|
// Remove any unprofitable chains.
|
|
|
|
unsigned ChainIdx = 0;
|
|
|
|
for (unsigned UsersIdx = 0, NChains = IVChainVec.size();
|
|
|
|
UsersIdx < NChains; ++UsersIdx) {
|
|
|
|
if (!isProfitableChain(IVChainVec[UsersIdx],
|
|
|
|
ChainUsersVec[UsersIdx].FarUsers, SE, TLI))
|
|
|
|
continue;
|
|
|
|
// Preserve the chain at UsesIdx.
|
|
|
|
if (ChainIdx != UsersIdx)
|
|
|
|
IVChainVec[ChainIdx] = IVChainVec[UsersIdx];
|
|
|
|
FinalizeChain(IVChainVec[ChainIdx]);
|
|
|
|
++ChainIdx;
|
|
|
|
}
|
|
|
|
IVChainVec.resize(ChainIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LSRInstance::FinalizeChain(IVChain &Chain) {
|
|
|
|
assert(!Chain.empty() && "empty IV chains are not allowed");
|
|
|
|
DEBUG(dbgs() << "Final Chain: " << *Chain[0].UserInst << "\n");
|
|
|
|
|
|
|
|
for (IVChain::const_iterator I = llvm::next(Chain.begin()), E = Chain.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
DEBUG(dbgs() << " Inc: " << *I->UserInst << "\n");
|
|
|
|
User::op_iterator UseI =
|
|
|
|
std::find(I->UserInst->op_begin(), I->UserInst->op_end(), I->IVOperand);
|
|
|
|
assert(UseI != I->UserInst->op_end() && "cannot find IV operand");
|
|
|
|
IVIncSet.insert(UseI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return true if the IVInc can be folded into an addressing mode.
|
|
|
|
static bool canFoldIVIncExpr(const SCEV *IncExpr, Instruction *UserInst,
|
|
|
|
Value *Operand, const TargetLowering *TLI) {
|
|
|
|
const SCEVConstant *IncConst = dyn_cast<SCEVConstant>(IncExpr);
|
|
|
|
if (!IncConst || !isAddressUse(UserInst, Operand))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (IncConst->getValue()->getValue().getMinSignedBits() > 64)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int64_t IncOffset = IncConst->getValue()->getSExtValue();
|
|
|
|
if (!isAlwaysFoldable(IncOffset, /*BaseGV=*/0, /*HaseBaseReg=*/false,
|
|
|
|
LSRUse::Address, getAccessType(UserInst), TLI))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateIVChains - Generate an add or subtract for each IVInc in a chain to
|
|
|
|
/// materialize the IV user's operand from the previous IV user's operand.
|
|
|
|
void LSRInstance::GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts) {
|
|
|
|
// Find the new IVOperand for the head of the chain. It may have been replaced
|
|
|
|
// by LSR.
|
|
|
|
const IVInc &Head = Chain[0];
|
|
|
|
User::op_iterator IVOpEnd = Head.UserInst->op_end();
|
|
|
|
User::op_iterator IVOpIter = findIVOperand(Head.UserInst->op_begin(),
|
|
|
|
IVOpEnd, L, SE);
|
|
|
|
Value *IVSrc = 0;
|
|
|
|
while (IVOpIter != IVOpEnd) {
|
|
|
|
IVSrc = getWideOperand(*IVOpIter);
|
|
|
|
|
|
|
|
// If this operand computes the expression that the chain needs, we may use
|
|
|
|
// it. (Check this after setting IVSrc which is used below.)
|
|
|
|
//
|
|
|
|
// Note that if Head.IncExpr is wider than IVSrc, then this phi is too
|
|
|
|
// narrow for the chain, so we can no longer use it. We do allow using a
|
|
|
|
// wider phi, assuming the LSR checked for free truncation. In that case we
|
|
|
|
// should already have a truncate on this operand such that
|
|
|
|
// getSCEV(IVSrc) == IncExpr.
|
|
|
|
if (SE.getSCEV(*IVOpIter) == Head.IncExpr
|
|
|
|
|| SE.getSCEV(IVSrc) == Head.IncExpr) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
IVOpIter = findIVOperand(llvm::next(IVOpIter), IVOpEnd, L, SE);
|
|
|
|
}
|
|
|
|
if (IVOpIter == IVOpEnd) {
|
|
|
|
// Gracefully give up on this chain.
|
|
|
|
DEBUG(dbgs() << "Concealed chain head: " << *Head.UserInst << "\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Generate chain at: " << *IVSrc << "\n");
|
|
|
|
Type *IVTy = IVSrc->getType();
|
|
|
|
Type *IntTy = SE.getEffectiveSCEVType(IVTy);
|
|
|
|
const SCEV *LeftOverExpr = 0;
|
|
|
|
for (IVChain::const_iterator IncI = llvm::next(Chain.begin()),
|
|
|
|
IncE = Chain.end(); IncI != IncE; ++IncI) {
|
|
|
|
|
|
|
|
Instruction *InsertPt = IncI->UserInst;
|
|
|
|
if (isa<PHINode>(InsertPt))
|
|
|
|
InsertPt = L->getLoopLatch()->getTerminator();
|
|
|
|
|
|
|
|
// IVOper will replace the current IV User's operand. IVSrc is the IV
|
|
|
|
// value currently held in a register.
|
|
|
|
Value *IVOper = IVSrc;
|
|
|
|
if (!IncI->IncExpr->isZero()) {
|
|
|
|
// IncExpr was the result of subtraction of two narrow values, so must
|
|
|
|
// be signed.
|
|
|
|
const SCEV *IncExpr = SE.getNoopOrSignExtend(IncI->IncExpr, IntTy);
|
|
|
|
LeftOverExpr = LeftOverExpr ?
|
|
|
|
SE.getAddExpr(LeftOverExpr, IncExpr) : IncExpr;
|
|
|
|
}
|
|
|
|
if (LeftOverExpr && !LeftOverExpr->isZero()) {
|
|
|
|
// Expand the IV increment.
|
|
|
|
Rewriter.clearPostInc();
|
|
|
|
Value *IncV = Rewriter.expandCodeFor(LeftOverExpr, IntTy, InsertPt);
|
|
|
|
const SCEV *IVOperExpr = SE.getAddExpr(SE.getUnknown(IVSrc),
|
|
|
|
SE.getUnknown(IncV));
|
|
|
|
IVOper = Rewriter.expandCodeFor(IVOperExpr, IVTy, InsertPt);
|
|
|
|
|
|
|
|
// If an IV increment can't be folded, use it as the next IV value.
|
|
|
|
if (!canFoldIVIncExpr(LeftOverExpr, IncI->UserInst, IncI->IVOperand,
|
|
|
|
TLI)) {
|
|
|
|
assert(IVTy == IVOper->getType() && "inconsistent IV increment type");
|
|
|
|
IVSrc = IVOper;
|
|
|
|
LeftOverExpr = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Type *OperTy = IncI->IVOperand->getType();
|
|
|
|
if (IVTy != OperTy) {
|
|
|
|
assert(SE.getTypeSizeInBits(IVTy) >= SE.getTypeSizeInBits(OperTy) &&
|
|
|
|
"cannot extend a chained IV");
|
|
|
|
IRBuilder<> Builder(InsertPt);
|
|
|
|
IVOper = Builder.CreateTruncOrBitCast(IVOper, OperTy, "lsr.chain");
|
|
|
|
}
|
|
|
|
IncI->UserInst->replaceUsesOfWith(IncI->IVOperand, IVOper);
|
|
|
|
DeadInsts.push_back(IncI->IVOperand);
|
|
|
|
}
|
|
|
|
// If LSR created a new, wider phi, we may also replace its postinc. We only
|
|
|
|
// do this if we also found a wide value for the head of the chain.
|
|
|
|
if (isa<PHINode>(Chain.back().UserInst)) {
|
|
|
|
for (BasicBlock::iterator I = L->getHeader()->begin();
|
|
|
|
PHINode *Phi = dyn_cast<PHINode>(I); ++I) {
|
|
|
|
if (!isCompatibleIVType(Phi, IVSrc))
|
|
|
|
continue;
|
|
|
|
Instruction *PostIncV = dyn_cast<Instruction>(
|
|
|
|
Phi->getIncomingValueForBlock(L->getLoopLatch()));
|
|
|
|
if (!PostIncV || (SE.getSCEV(PostIncV) != SE.getSCEV(IVSrc)))
|
|
|
|
continue;
|
|
|
|
Value *IVOper = IVSrc;
|
|
|
|
Type *PostIncTy = PostIncV->getType();
|
|
|
|
if (IVTy != PostIncTy) {
|
|
|
|
assert(PostIncTy->isPointerTy() && "mixing int/ptr IV types");
|
|
|
|
IRBuilder<> Builder(L->getLoopLatch()->getTerminator());
|
|
|
|
Builder.SetCurrentDebugLocation(PostIncV->getDebugLoc());
|
|
|
|
IVOper = Builder.CreatePointerCast(IVSrc, PostIncTy, "lsr.chain");
|
|
|
|
}
|
|
|
|
Phi->replaceUsesOfWith(PostIncV, IVOper);
|
|
|
|
DeadInsts.push_back(PostIncV);
|
|
|
|
}
|
|
|
|
}
|
2012-01-09 19:50:34 +00:00
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::CollectFixupsAndInitialFormulae() {
|
|
|
|
for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) {
|
2012-01-09 21:18:52 +00:00
|
|
|
Instruction *UserInst = UI->getUser();
|
|
|
|
// Skip IV users that are part of profitable IV Chains.
|
|
|
|
User::op_iterator UseI = std::find(UserInst->op_begin(), UserInst->op_end(),
|
|
|
|
UI->getOperandValToReplace());
|
|
|
|
assert(UseI != UserInst->op_end() && "cannot find IV operand");
|
|
|
|
if (IVIncSet.count(UseI))
|
|
|
|
continue;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Record the uses.
|
|
|
|
LSRFixup &LF = getNewFixup();
|
2012-01-09 21:18:52 +00:00
|
|
|
LF.UserInst = UserInst;
|
2010-02-12 10:34:29 +00:00
|
|
|
LF.OperandValToReplace = UI->getOperandValToReplace();
|
2010-04-07 22:27:08 +00:00
|
|
|
LF.PostIncLoops = UI->getPostIncLoops();
|
2007-03-06 21:14:09 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
LSRUse::KindType Kind = LSRUse::Basic;
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *AccessTy = 0;
|
2010-02-12 10:34:29 +00:00
|
|
|
if (isAddressUse(LF.UserInst, LF.OperandValToReplace)) {
|
|
|
|
Kind = LSRUse::Address;
|
|
|
|
AccessTy = getAccessType(LF.UserInst);
|
|
|
|
}
|
|
|
|
|
2010-04-19 21:48:58 +00:00
|
|
|
const SCEV *S = IU.getExpr(*UI);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Equality (== and !=) ICmps are special. We can rewrite (i == N) as
|
|
|
|
// (N - i == 0), and this allows (N - i) to be the expression that we work
|
|
|
|
// with rather than just N or i, so we can consider the register
|
|
|
|
// requirements for both N and i at the same time. Limiting this code to
|
|
|
|
// equality icmps is not a problem because all interesting loops use
|
|
|
|
// equality icmps, thanks to IndVarSimplify.
|
|
|
|
if (ICmpInst *CI = dyn_cast<ICmpInst>(LF.UserInst))
|
|
|
|
if (CI->isEquality()) {
|
|
|
|
// Swap the operands if needed to put the OperandValToReplace on the
|
|
|
|
// left, for consistency.
|
|
|
|
Value *NV = CI->getOperand(1);
|
|
|
|
if (NV == LF.OperandValToReplace) {
|
|
|
|
CI->setOperand(1, CI->getOperand(0));
|
|
|
|
CI->setOperand(0, NV);
|
2010-05-20 19:26:52 +00:00
|
|
|
NV = CI->getOperand(1);
|
2010-05-20 19:16:03 +00:00
|
|
|
Changed = true;
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// x == y --> x - y == 0
|
|
|
|
const SCEV *N = SE.getSCEV(NV);
|
2010-11-17 21:23:15 +00:00
|
|
|
if (SE.isLoopInvariant(N, L)) {
|
2011-05-18 21:02:18 +00:00
|
|
|
// S is normalized, so normalize N before folding it into S
|
|
|
|
// to keep the result normalized.
|
|
|
|
N = TransformForPostIncUse(Normalize, N, CI, 0,
|
|
|
|
LF.PostIncLoops, SE, DT);
|
2010-02-12 10:34:29 +00:00
|
|
|
Kind = LSRUse::ICmpZero;
|
|
|
|
S = SE.getMinusSCEV(N, S);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -1 and the negations of all interesting strides (except the negation
|
|
|
|
// of -1) are now also interesting.
|
|
|
|
for (size_t i = 0, e = Factors.size(); i != e; ++i)
|
|
|
|
if (Factors[i] != -1)
|
|
|
|
Factors.insert(-(uint64_t)Factors[i]);
|
|
|
|
Factors.insert(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set up the initial formula for this use.
|
|
|
|
std::pair<size_t, int64_t> P = getUse(S, Kind, AccessTy);
|
|
|
|
LF.LUIdx = P.first;
|
|
|
|
LF.Offset = P.second;
|
|
|
|
LSRUse &LU = Uses[LF.LUIdx];
|
2010-04-07 22:27:08 +00:00
|
|
|
LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
|
2010-07-15 20:24:58 +00:00
|
|
|
if (!LU.WidestFixupType ||
|
|
|
|
SE.getTypeSizeInBits(LU.WidestFixupType) <
|
|
|
|
SE.getTypeSizeInBits(LF.OperandValToReplace->getType()))
|
|
|
|
LU.WidestFixupType = LF.OperandValToReplace->getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// If this is the first use of this LSRUse, give it a formula.
|
|
|
|
if (LU.Formulae.empty()) {
|
2010-02-22 04:11:59 +00:00
|
|
|
InsertInitialFormula(S, LU, LF.LUIdx);
|
2010-02-12 10:34:29 +00:00
|
|
|
CountRegisters(LU.Formulae.back(), LF.LUIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(print_fixups(dbgs()));
|
|
|
|
}
|
|
|
|
|
2010-05-20 20:52:00 +00:00
|
|
|
/// InsertInitialFormula - Insert a formula for the given expression into
|
|
|
|
/// the given use, separating out loop-variant portions from loop-invariant
|
|
|
|
/// and loop-computable portions.
|
2010-02-12 10:34:29 +00:00
|
|
|
void
|
2010-02-22 04:11:59 +00:00
|
|
|
LSRInstance::InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx) {
|
2010-02-12 10:34:29 +00:00
|
|
|
Formula F;
|
2010-11-17 21:41:58 +00:00
|
|
|
F.InitialMatch(S, L, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
bool Inserted = InsertFormula(LU, LUIdx, F);
|
|
|
|
assert(Inserted && "Initial formula already exists!"); (void)Inserted;
|
|
|
|
}
|
|
|
|
|
2010-05-20 20:52:00 +00:00
|
|
|
/// InsertSupplementalFormula - Insert a simple single-register formula for
|
|
|
|
/// the given expression into the given use.
|
2010-02-12 10:34:29 +00:00
|
|
|
void
|
|
|
|
LSRInstance::InsertSupplementalFormula(const SCEV *S,
|
|
|
|
LSRUse &LU, size_t LUIdx) {
|
|
|
|
Formula F;
|
|
|
|
F.BaseRegs.push_back(S);
|
|
|
|
F.AM.HasBaseReg = true;
|
|
|
|
bool Inserted = InsertFormula(LU, LUIdx, F);
|
|
|
|
assert(Inserted && "Supplemental formula already exists!"); (void)Inserted;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// CountRegisters - Note which registers are used by the given formula,
|
|
|
|
/// updating RegUses.
|
|
|
|
void LSRInstance::CountRegisters(const Formula &F, size_t LUIdx) {
|
|
|
|
if (F.ScaledReg)
|
|
|
|
RegUses.CountRegister(F.ScaledReg, LUIdx);
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
|
|
|
|
E = F.BaseRegs.end(); I != E; ++I)
|
|
|
|
RegUses.CountRegister(*I, LUIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// InsertFormula - If the given formula has not yet been inserted, add it to
|
|
|
|
/// the list, and return true. Return false otherwise.
|
|
|
|
bool LSRInstance::InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F) {
|
2010-02-22 04:11:59 +00:00
|
|
|
if (!LU.InsertFormula(F))
|
2010-01-22 00:46:49 +00:00
|
|
|
return false;
|
2009-03-09 20:34:59 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
CountRegisters(F, LUIdx);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// CollectLoopInvariantFixupsAndFormulae - Check for other uses of
|
|
|
|
/// loop-invariant values which we're tracking. These other uses will pin these
|
|
|
|
/// values in registers, making them less profitable for elimination.
|
|
|
|
/// TODO: This currently misses non-constant addrec step registers.
|
|
|
|
/// TODO: Should this give more weight to users inside the loop?
|
|
|
|
void
|
|
|
|
LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
|
|
|
|
SmallVector<const SCEV *, 8> Worklist(RegUses.begin(), RegUses.end());
|
|
|
|
SmallPtrSet<const SCEV *, 8> Inserted;
|
|
|
|
|
|
|
|
while (!Worklist.empty()) {
|
|
|
|
const SCEV *S = Worklist.pop_back_val();
|
|
|
|
|
|
|
|
if (const SCEVNAryExpr *N = dyn_cast<SCEVNAryExpr>(S))
|
2010-06-21 19:47:52 +00:00
|
|
|
Worklist.append(N->op_begin(), N->op_end());
|
2010-02-12 10:34:29 +00:00
|
|
|
else if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
|
|
|
|
Worklist.push_back(C->getOperand());
|
|
|
|
else if (const SCEVUDivExpr *D = dyn_cast<SCEVUDivExpr>(S)) {
|
|
|
|
Worklist.push_back(D->getLHS());
|
|
|
|
Worklist.push_back(D->getRHS());
|
|
|
|
} else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
|
|
|
|
if (!Inserted.insert(U)) continue;
|
|
|
|
const Value *V = U->getValue();
|
2010-06-04 23:16:05 +00:00
|
|
|
if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
|
|
|
|
// Look for instructions defined outside the loop.
|
2010-02-12 10:34:29 +00:00
|
|
|
if (L->contains(Inst)) continue;
|
2010-06-04 23:16:05 +00:00
|
|
|
} else if (isa<UndefValue>(V))
|
|
|
|
// Undef doesn't have a live range, so it doesn't matter.
|
|
|
|
continue;
|
2010-03-25 23:06:16 +00:00
|
|
|
for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
|
2010-02-12 10:34:29 +00:00
|
|
|
UI != UE; ++UI) {
|
|
|
|
const Instruction *UserInst = dyn_cast<Instruction>(*UI);
|
|
|
|
// Ignore non-instructions.
|
|
|
|
if (!UserInst)
|
|
|
|
continue;
|
|
|
|
// Ignore instructions in other functions (as can happen with
|
|
|
|
// Constants).
|
|
|
|
if (UserInst->getParent()->getParent() != L->getHeader()->getParent())
|
|
|
|
continue;
|
|
|
|
// Ignore instructions not dominated by the loop.
|
|
|
|
const BasicBlock *UseBB = !isa<PHINode>(UserInst) ?
|
|
|
|
UserInst->getParent() :
|
|
|
|
cast<PHINode>(UserInst)->getIncomingBlock(
|
|
|
|
PHINode::getIncomingValueNumForOperand(UI.getOperandNo()));
|
|
|
|
if (!DT.dominates(L->getHeader(), UseBB))
|
|
|
|
continue;
|
|
|
|
// Ignore uses which are part of other SCEV expressions, to avoid
|
|
|
|
// analyzing them multiple times.
|
2010-04-09 19:12:34 +00:00
|
|
|
if (SE.isSCEVable(UserInst->getType())) {
|
|
|
|
const SCEV *UserS = SE.getSCEV(const_cast<Instruction *>(UserInst));
|
|
|
|
// If the user is a no-op, look through to its uses.
|
|
|
|
if (!isa<SCEVUnknown>(UserS))
|
|
|
|
continue;
|
|
|
|
if (UserS == U) {
|
|
|
|
Worklist.push_back(
|
|
|
|
SE.getUnknown(const_cast<Instruction *>(UserInst)));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
// Ignore icmp instructions which are already being analyzed.
|
|
|
|
if (const ICmpInst *ICI = dyn_cast<ICmpInst>(UserInst)) {
|
|
|
|
unsigned OtherIdx = !UI.getOperandNo();
|
|
|
|
Value *OtherOp = const_cast<Value *>(ICI->getOperand(OtherIdx));
|
2010-11-17 21:23:15 +00:00
|
|
|
if (SE.hasComputableLoopEvolution(SE.getSCEV(OtherOp), L))
|
2010-02-12 10:34:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
LSRFixup &LF = getNewFixup();
|
|
|
|
LF.UserInst = const_cast<Instruction *>(UserInst);
|
|
|
|
LF.OperandValToReplace = UI.getUse();
|
|
|
|
std::pair<size_t, int64_t> P = getUse(S, LSRUse::Basic, 0);
|
|
|
|
LF.LUIdx = P.first;
|
|
|
|
LF.Offset = P.second;
|
|
|
|
LSRUse &LU = Uses[LF.LUIdx];
|
2010-04-07 22:27:08 +00:00
|
|
|
LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
|
2010-07-15 20:24:58 +00:00
|
|
|
if (!LU.WidestFixupType ||
|
|
|
|
SE.getTypeSizeInBits(LU.WidestFixupType) <
|
|
|
|
SE.getTypeSizeInBits(LF.OperandValToReplace->getType()))
|
|
|
|
LU.WidestFixupType = LF.OperandValToReplace->getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
InsertSupplementalFormula(U, LU, LF.LUIdx);
|
|
|
|
CountRegisters(LU.Formulae.back(), Uses.size() - 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// CollectSubexprs - Split S into subexpressions which can be pulled out into
|
|
|
|
/// separate registers. If C is non-null, multiply each subexpression by C.
|
|
|
|
static void CollectSubexprs(const SCEV *S, const SCEVConstant *C,
|
|
|
|
SmallVectorImpl<const SCEV *> &Ops,
|
2010-06-25 22:32:18 +00:00
|
|
|
const Loop *L,
|
2010-02-12 10:34:29 +00:00
|
|
|
ScalarEvolution &SE) {
|
|
|
|
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
|
|
|
|
// Break out add operands.
|
|
|
|
for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
|
|
|
|
I != E; ++I)
|
2010-08-16 15:50:00 +00:00
|
|
|
CollectSubexprs(*I, C, Ops, L, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
return;
|
|
|
|
} else if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S)) {
|
|
|
|
// Split a non-zero base out of an addrec.
|
|
|
|
if (!AR->getStart()->isZero()) {
|
2010-05-03 22:09:21 +00:00
|
|
|
CollectSubexprs(SE.getAddRecExpr(SE.getConstant(AR->getType(), 0),
|
2010-02-12 10:34:29 +00:00
|
|
|
AR->getStepRecurrence(SE),
|
2011-03-14 16:50:06 +00:00
|
|
|
AR->getLoop(),
|
|
|
|
//FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
|
|
|
|
SCEV::FlagAnyWrap),
|
2010-08-16 15:50:00 +00:00
|
|
|
C, Ops, L, SE);
|
|
|
|
CollectSubexprs(AR->getStart(), C, Ops, L, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
|
|
|
|
// Break (C * (a + b + c)) into C*a + C*b + C*c.
|
|
|
|
if (Mul->getNumOperands() == 2)
|
|
|
|
if (const SCEVConstant *Op0 =
|
|
|
|
dyn_cast<SCEVConstant>(Mul->getOperand(0))) {
|
|
|
|
CollectSubexprs(Mul->getOperand(1),
|
|
|
|
C ? cast<SCEVConstant>(SE.getMulExpr(C, Op0)) : Op0,
|
2010-08-16 15:50:00 +00:00
|
|
|
Ops, L, SE);
|
2010-02-12 10:34:29 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-16 15:50:00 +00:00
|
|
|
// Otherwise use the value itself, optionally with a scale applied.
|
|
|
|
Ops.push_back(C ? SE.getMulExpr(C, S) : S);
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateReassociations - Split out subexpressions from adds and the bases of
|
|
|
|
/// addrecs.
|
|
|
|
void LSRInstance::GenerateReassociations(LSRUse &LU, unsigned LUIdx,
|
|
|
|
Formula Base,
|
|
|
|
unsigned Depth) {
|
|
|
|
// Arbitrarily cap recursion to protect compile time.
|
|
|
|
if (Depth >= 3) return;
|
|
|
|
|
|
|
|
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
|
|
|
|
const SCEV *BaseReg = Base.BaseRegs[i];
|
|
|
|
|
2010-08-16 15:50:00 +00:00
|
|
|
SmallVector<const SCEV *, 8> AddOps;
|
|
|
|
CollectSubexprs(BaseReg, 0, AddOps, L, SE);
|
2010-06-25 22:32:18 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (AddOps.size() == 1) continue;
|
|
|
|
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator J = AddOps.begin(),
|
|
|
|
JE = AddOps.end(); J != JE; ++J) {
|
2010-08-16 15:50:00 +00:00
|
|
|
|
|
|
|
// Loop-variant "unknown" values are uninteresting; we won't be able to
|
|
|
|
// do anything meaningful with them.
|
2010-11-17 21:23:15 +00:00
|
|
|
if (isa<SCEVUnknown>(*J) && !SE.isLoopInvariant(*J, L))
|
2010-08-16 15:50:00 +00:00
|
|
|
continue;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Don't pull a constant into a register if the constant could be folded
|
|
|
|
// into an immediate field.
|
|
|
|
if (isAlwaysFoldable(*J, LU.MinOffset, LU.MaxOffset,
|
|
|
|
Base.getNumRegs() > 1,
|
|
|
|
LU.Kind, LU.AccessTy, TLI, SE))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Collect all operands except *J.
|
2010-06-21 19:47:52 +00:00
|
|
|
SmallVector<const SCEV *, 8> InnerAddOps
|
2010-08-04 17:43:57 +00:00
|
|
|
(((const SmallVector<const SCEV *, 8> &)AddOps).begin(), J);
|
2010-06-21 19:47:52 +00:00
|
|
|
InnerAddOps.append
|
2010-08-02 06:00:15 +00:00
|
|
|
(llvm::next(J), ((const SmallVector<const SCEV *, 8> &)AddOps).end());
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Don't leave just a constant behind in a register if the constant could
|
|
|
|
// be folded into an immediate field.
|
|
|
|
if (InnerAddOps.size() == 1 &&
|
|
|
|
isAlwaysFoldable(InnerAddOps[0], LU.MinOffset, LU.MaxOffset,
|
|
|
|
Base.getNumRegs() > 1,
|
|
|
|
LU.Kind, LU.AccessTy, TLI, SE))
|
|
|
|
continue;
|
|
|
|
|
2010-04-23 01:55:05 +00:00
|
|
|
const SCEV *InnerSum = SE.getAddExpr(InnerAddOps);
|
|
|
|
if (InnerSum->isZero())
|
|
|
|
continue;
|
2010-02-12 10:34:29 +00:00
|
|
|
Formula F = Base;
|
2011-05-03 00:46:49 +00:00
|
|
|
|
|
|
|
// Add the remaining pieces of the add back into the new formula.
|
|
|
|
const SCEVConstant *InnerSumSC = dyn_cast<SCEVConstant>(InnerSum);
|
|
|
|
if (TLI && InnerSumSC &&
|
|
|
|
SE.getTypeSizeInBits(InnerSumSC->getType()) <= 64 &&
|
|
|
|
TLI->isLegalAddImmediate((uint64_t)F.UnfoldedOffset +
|
|
|
|
InnerSumSC->getValue()->getZExtValue())) {
|
|
|
|
F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset +
|
|
|
|
InnerSumSC->getValue()->getZExtValue();
|
|
|
|
F.BaseRegs.erase(F.BaseRegs.begin() + i);
|
|
|
|
} else
|
|
|
|
F.BaseRegs[i] = InnerSum;
|
|
|
|
|
|
|
|
// Add J as its own register, or an unfolded immediate.
|
|
|
|
const SCEVConstant *SC = dyn_cast<SCEVConstant>(*J);
|
|
|
|
if (TLI && SC && SE.getTypeSizeInBits(SC->getType()) <= 64 &&
|
|
|
|
TLI->isLegalAddImmediate((uint64_t)F.UnfoldedOffset +
|
|
|
|
SC->getValue()->getZExtValue()))
|
|
|
|
F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset +
|
|
|
|
SC->getValue()->getZExtValue();
|
|
|
|
else
|
|
|
|
F.BaseRegs.push_back(*J);
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
if (InsertFormula(LU, LUIdx, F))
|
|
|
|
// If that formula hadn't been seen before, recurse to find more like
|
|
|
|
// it.
|
|
|
|
GenerateReassociations(LU, LUIdx, LU.Formulae.back(), Depth+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateCombinations - Generate a formula consisting of all of the
|
|
|
|
/// loop-dominating registers added into a single register.
|
|
|
|
void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx,
|
2010-02-14 18:51:39 +00:00
|
|
|
Formula Base) {
|
2010-03-01 17:49:51 +00:00
|
|
|
// This method is only interesting on a plurality of registers.
|
2010-02-12 10:34:29 +00:00
|
|
|
if (Base.BaseRegs.size() <= 1) return;
|
|
|
|
|
|
|
|
Formula F = Base;
|
|
|
|
F.BaseRegs.clear();
|
|
|
|
SmallVector<const SCEV *, 4> Ops;
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator
|
|
|
|
I = Base.BaseRegs.begin(), E = Base.BaseRegs.end(); I != E; ++I) {
|
|
|
|
const SCEV *BaseReg = *I;
|
2010-11-17 21:41:58 +00:00
|
|
|
if (SE.properlyDominates(BaseReg, L->getHeader()) &&
|
2010-11-17 21:23:15 +00:00
|
|
|
!SE.hasComputableLoopEvolution(BaseReg, L))
|
2010-02-12 10:34:29 +00:00
|
|
|
Ops.push_back(BaseReg);
|
|
|
|
else
|
|
|
|
F.BaseRegs.push_back(BaseReg);
|
|
|
|
}
|
|
|
|
if (Ops.size() > 1) {
|
2010-02-14 18:50:49 +00:00
|
|
|
const SCEV *Sum = SE.getAddExpr(Ops);
|
|
|
|
// TODO: If Sum is zero, it probably means ScalarEvolution missed an
|
|
|
|
// opportunity to fold something. For now, just ignore such cases
|
2010-03-01 17:49:51 +00:00
|
|
|
// rather than proceed with zero in a register.
|
2010-02-14 18:50:49 +00:00
|
|
|
if (!Sum->isZero()) {
|
|
|
|
F.BaseRegs.push_back(Sum);
|
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateSymbolicOffsets - Generate reuse formulae using symbolic offsets.
|
|
|
|
void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx,
|
|
|
|
Formula Base) {
|
|
|
|
// We can't add a symbolic offset if the address already contains one.
|
|
|
|
if (Base.AM.BaseGV) return;
|
|
|
|
|
|
|
|
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
|
|
|
|
const SCEV *G = Base.BaseRegs[i];
|
|
|
|
GlobalValue *GV = ExtractSymbol(G, SE);
|
|
|
|
if (G->isZero() || !GV)
|
|
|
|
continue;
|
|
|
|
Formula F = Base;
|
|
|
|
F.AM.BaseGV = GV;
|
|
|
|
if (!isLegalUse(F.AM, LU.MinOffset, LU.MaxOffset,
|
|
|
|
LU.Kind, LU.AccessTy, TLI))
|
|
|
|
continue;
|
|
|
|
F.BaseRegs[i] = G;
|
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateConstantOffsets - Generate reuse formulae using symbolic offsets.
|
|
|
|
void LSRInstance::GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx,
|
|
|
|
Formula Base) {
|
|
|
|
// TODO: For now, just add the min and max offset, because it usually isn't
|
|
|
|
// worthwhile looking at everything inbetween.
|
2010-07-15 15:14:45 +00:00
|
|
|
SmallVector<int64_t, 2> Worklist;
|
2010-02-12 10:34:29 +00:00
|
|
|
Worklist.push_back(LU.MinOffset);
|
|
|
|
if (LU.MaxOffset != LU.MinOffset)
|
|
|
|
Worklist.push_back(LU.MaxOffset);
|
|
|
|
|
|
|
|
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
|
|
|
|
const SCEV *G = Base.BaseRegs[i];
|
|
|
|
|
|
|
|
for (SmallVectorImpl<int64_t>::const_iterator I = Worklist.begin(),
|
|
|
|
E = Worklist.end(); I != E; ++I) {
|
|
|
|
Formula F = Base;
|
|
|
|
F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs - *I;
|
|
|
|
if (isLegalUse(F.AM, LU.MinOffset - *I, LU.MaxOffset - *I,
|
|
|
|
LU.Kind, LU.AccessTy, TLI)) {
|
2010-07-15 15:14:45 +00:00
|
|
|
// Add the offset to the base register.
|
2010-08-16 15:39:27 +00:00
|
|
|
const SCEV *NewG = SE.getAddExpr(SE.getConstant(G->getType(), *I), G);
|
2010-07-15 15:14:45 +00:00
|
|
|
// If it cancelled out, drop the base register, otherwise update it.
|
|
|
|
if (NewG->isZero()) {
|
|
|
|
std::swap(F.BaseRegs[i], F.BaseRegs.back());
|
|
|
|
F.BaseRegs.pop_back();
|
|
|
|
} else
|
|
|
|
F.BaseRegs[i] = NewG;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t Imm = ExtractImmediate(G, SE);
|
|
|
|
if (G->isZero() || Imm == 0)
|
|
|
|
continue;
|
|
|
|
Formula F = Base;
|
|
|
|
F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Imm;
|
|
|
|
if (!isLegalUse(F.AM, LU.MinOffset, LU.MaxOffset,
|
|
|
|
LU.Kind, LU.AccessTy, TLI))
|
|
|
|
continue;
|
|
|
|
F.BaseRegs[i] = G;
|
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateICmpZeroScales - For ICmpZero, check to see if we can scale up
|
|
|
|
/// the comparison. For example, x == y -> x*c == y*c.
|
|
|
|
void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
|
|
|
|
Formula Base) {
|
|
|
|
if (LU.Kind != LSRUse::ICmpZero) return;
|
|
|
|
|
|
|
|
// Determine the integer type for the base formula.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *IntTy = Base.getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!IntTy) return;
|
|
|
|
if (SE.getTypeSizeInBits(IntTy) > 64) return;
|
|
|
|
|
|
|
|
// Don't do this if there is more than one offset.
|
|
|
|
if (LU.MinOffset != LU.MaxOffset) return;
|
|
|
|
|
|
|
|
assert(!Base.AM.BaseGV && "ICmpZero use is not legal!");
|
|
|
|
|
|
|
|
// Check each interesting stride.
|
|
|
|
for (SmallSetVector<int64_t, 8>::const_iterator
|
|
|
|
I = Factors.begin(), E = Factors.end(); I != E; ++I) {
|
|
|
|
int64_t Factor = *I;
|
|
|
|
|
|
|
|
// Check that the multiplication doesn't overflow.
|
2010-06-24 16:57:52 +00:00
|
|
|
if (Base.AM.BaseOffs == INT64_MIN && Factor == -1)
|
2010-02-17 00:41:53 +00:00
|
|
|
continue;
|
2010-06-24 16:57:52 +00:00
|
|
|
int64_t NewBaseOffs = (uint64_t)Base.AM.BaseOffs * Factor;
|
|
|
|
if (NewBaseOffs / Factor != Base.AM.BaseOffs)
|
2010-02-12 10:34:29 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// Check that multiplying with the use offset doesn't overflow.
|
|
|
|
int64_t Offset = LU.MinOffset;
|
2010-02-17 00:41:53 +00:00
|
|
|
if (Offset == INT64_MIN && Factor == -1)
|
|
|
|
continue;
|
2010-02-12 10:34:29 +00:00
|
|
|
Offset = (uint64_t)Offset * Factor;
|
2010-02-17 00:42:19 +00:00
|
|
|
if (Offset / Factor != LU.MinOffset)
|
2010-02-12 10:34:29 +00:00
|
|
|
continue;
|
|
|
|
|
2010-06-24 16:57:52 +00:00
|
|
|
Formula F = Base;
|
|
|
|
F.AM.BaseOffs = NewBaseOffs;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Check that this scale is legal.
|
|
|
|
if (!isLegalUse(F.AM, Offset, Offset, LU.Kind, LU.AccessTy, TLI))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Compensate for the use having MinOffset built into it.
|
|
|
|
F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Offset - LU.MinOffset;
|
|
|
|
|
2010-05-03 22:09:21 +00:00
|
|
|
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Check that multiplying with each base register doesn't overflow.
|
|
|
|
for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) {
|
|
|
|
F.BaseRegs[i] = SE.getMulExpr(F.BaseRegs[i], FactorS);
|
2010-02-19 19:35:48 +00:00
|
|
|
if (getExactSDiv(F.BaseRegs[i], FactorS, SE) != Base.BaseRegs[i])
|
2010-02-12 10:34:29 +00:00
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that multiplying with the scaled register doesn't overflow.
|
|
|
|
if (F.ScaledReg) {
|
|
|
|
F.ScaledReg = SE.getMulExpr(F.ScaledReg, FactorS);
|
2010-02-19 19:35:48 +00:00
|
|
|
if (getExactSDiv(F.ScaledReg, FactorS, SE) != Base.ScaledReg)
|
2010-02-12 10:34:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-05-03 00:46:49 +00:00
|
|
|
// Check that multiplying with the unfolded offset doesn't overflow.
|
|
|
|
if (F.UnfoldedOffset != 0) {
|
2011-05-23 21:07:39 +00:00
|
|
|
if (F.UnfoldedOffset == INT64_MIN && Factor == -1)
|
|
|
|
continue;
|
2011-05-03 00:46:49 +00:00
|
|
|
F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset * Factor;
|
|
|
|
if (F.UnfoldedOffset / Factor != Base.UnfoldedOffset)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// If we make it here and it's legal, add it.
|
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
next:;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateScales - Generate stride factor reuse formulae by making use of
|
|
|
|
/// scaled-offset address modes, for example.
|
2010-05-20 19:44:23 +00:00
|
|
|
void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Determine the integer type for the base formula.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *IntTy = Base.getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!IntTy) return;
|
|
|
|
|
|
|
|
// If this Formula already has a scaled register, we can't add another one.
|
|
|
|
if (Base.AM.Scale != 0) return;
|
|
|
|
|
|
|
|
// Check each interesting stride.
|
|
|
|
for (SmallSetVector<int64_t, 8>::const_iterator
|
|
|
|
I = Factors.begin(), E = Factors.end(); I != E; ++I) {
|
|
|
|
int64_t Factor = *I;
|
|
|
|
|
|
|
|
Base.AM.Scale = Factor;
|
|
|
|
Base.AM.HasBaseReg = Base.BaseRegs.size() > 1;
|
|
|
|
// Check whether this scale is going to be legal.
|
|
|
|
if (!isLegalUse(Base.AM, LU.MinOffset, LU.MaxOffset,
|
|
|
|
LU.Kind, LU.AccessTy, TLI)) {
|
|
|
|
// As a special-case, handle special out-of-loop Basic users specially.
|
|
|
|
// TODO: Reconsider this special case.
|
|
|
|
if (LU.Kind == LSRUse::Basic &&
|
|
|
|
isLegalUse(Base.AM, LU.MinOffset, LU.MaxOffset,
|
|
|
|
LSRUse::Special, LU.AccessTy, TLI) &&
|
|
|
|
LU.AllFixupsOutsideLoop)
|
|
|
|
LU.Kind = LSRUse::Special;
|
|
|
|
else
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// For an ICmpZero, negating a solitary base register won't lead to
|
|
|
|
// new solutions.
|
|
|
|
if (LU.Kind == LSRUse::ICmpZero &&
|
|
|
|
!Base.AM.HasBaseReg && Base.AM.BaseOffs == 0 && !Base.AM.BaseGV)
|
|
|
|
continue;
|
|
|
|
// For each addrec base reg, apply the scale, if possible.
|
|
|
|
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i)
|
|
|
|
if (const SCEVAddRecExpr *AR =
|
|
|
|
dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i])) {
|
2010-05-03 22:09:21 +00:00
|
|
|
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
|
2010-02-12 10:34:29 +00:00
|
|
|
if (FactorS->isZero())
|
|
|
|
continue;
|
|
|
|
// Divide out the factor, ignoring high bits, since we'll be
|
|
|
|
// scaling the value back up in the end.
|
2010-02-19 19:35:48 +00:00
|
|
|
if (const SCEV *Quotient = getExactSDiv(AR, FactorS, SE, true)) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// TODO: This could be optimized to avoid all the copying.
|
|
|
|
Formula F = Base;
|
|
|
|
F.ScaledReg = Quotient;
|
2010-05-20 15:17:54 +00:00
|
|
|
F.DeleteBaseReg(F.BaseRegs[i]);
|
2010-02-12 10:34:29 +00:00
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateTruncates - Generate reuse formulae from different IV types.
|
2010-05-20 19:44:23 +00:00
|
|
|
void LSRInstance::GenerateTruncates(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// This requires TargetLowering to tell us which truncates are free.
|
|
|
|
if (!TLI) return;
|
|
|
|
|
|
|
|
// Don't bother truncating symbolic values.
|
|
|
|
if (Base.AM.BaseGV) return;
|
|
|
|
|
|
|
|
// Determine the integer type for the base formula.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *DstTy = Base.getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!DstTy) return;
|
|
|
|
DstTy = SE.getEffectiveSCEVType(DstTy);
|
|
|
|
|
2011-07-18 04:54:35 +00:00
|
|
|
for (SmallSetVector<Type *, 4>::const_iterator
|
2010-02-12 10:34:29 +00:00
|
|
|
I = Types.begin(), E = Types.end(); I != E; ++I) {
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *SrcTy = *I;
|
2010-02-12 10:34:29 +00:00
|
|
|
if (SrcTy != DstTy && TLI->isTruncateFree(SrcTy, DstTy)) {
|
|
|
|
Formula F = Base;
|
|
|
|
|
|
|
|
if (F.ScaledReg) F.ScaledReg = SE.getAnyExtendExpr(F.ScaledReg, *I);
|
|
|
|
for (SmallVectorImpl<const SCEV *>::iterator J = F.BaseRegs.begin(),
|
|
|
|
JE = F.BaseRegs.end(); J != JE; ++J)
|
|
|
|
*J = SE.getAnyExtendExpr(*J, SrcTy);
|
|
|
|
|
|
|
|
// TODO: This assumes we've done basic processing on all uses and
|
|
|
|
// have an idea what the register usage is.
|
|
|
|
if (!F.hasRegsUsedByUsesOtherThan(LUIdx, RegUses))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
(void)InsertFormula(LU, LUIdx, F);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2010-02-14 18:51:20 +00:00
|
|
|
/// WorkItem - Helper class for GenerateCrossUseConstantOffsets. It's used to
|
2010-02-12 10:34:29 +00:00
|
|
|
/// defer modifications so that the search phase doesn't have to worry about
|
|
|
|
/// the data structures moving underneath it.
|
|
|
|
struct WorkItem {
|
|
|
|
size_t LUIdx;
|
|
|
|
int64_t Imm;
|
|
|
|
const SCEV *OrigReg;
|
|
|
|
|
|
|
|
WorkItem(size_t LI, int64_t I, const SCEV *R)
|
|
|
|
: LUIdx(LI), Imm(I), OrigReg(R) {}
|
|
|
|
|
|
|
|
void print(raw_ostream &OS) const;
|
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void WorkItem::print(raw_ostream &OS) const {
|
|
|
|
OS << "in formulae referencing " << *OrigReg << " in use " << LUIdx
|
|
|
|
<< " , add offset " << Imm;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WorkItem::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateCrossUseConstantOffsets - Look for registers which are a constant
|
|
|
|
/// distance apart and try to form reuse opportunities between them.
|
|
|
|
void LSRInstance::GenerateCrossUseConstantOffsets() {
|
|
|
|
// Group the registers by their value without any added constant offset.
|
|
|
|
typedef std::map<int64_t, const SCEV *> ImmMapTy;
|
|
|
|
typedef DenseMap<const SCEV *, ImmMapTy> RegMapTy;
|
|
|
|
RegMapTy Map;
|
|
|
|
DenseMap<const SCEV *, SmallBitVector> UsedByIndicesMap;
|
|
|
|
SmallVector<const SCEV *, 8> Sequence;
|
|
|
|
for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
const SCEV *Reg = *I;
|
|
|
|
int64_t Imm = ExtractImmediate(Reg, SE);
|
|
|
|
std::pair<RegMapTy::iterator, bool> Pair =
|
|
|
|
Map.insert(std::make_pair(Reg, ImmMapTy()));
|
|
|
|
if (Pair.second)
|
|
|
|
Sequence.push_back(Reg);
|
|
|
|
Pair.first->second.insert(std::make_pair(Imm, *I));
|
|
|
|
UsedByIndicesMap[Reg] |= RegUses.getUsedByIndices(*I);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now examine each set of registers with the same base value. Build up
|
|
|
|
// a list of work to do and do the work in a separate step so that we're
|
|
|
|
// not adding formulae and register counts while we're searching.
|
2010-09-01 01:45:53 +00:00
|
|
|
SmallVector<WorkItem, 32> WorkItems;
|
|
|
|
SmallSet<std::pair<size_t, int64_t>, 32> UniqueItems;
|
2010-02-12 10:34:29 +00:00
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = Sequence.begin(),
|
|
|
|
E = Sequence.end(); I != E; ++I) {
|
|
|
|
const SCEV *Reg = *I;
|
|
|
|
const ImmMapTy &Imms = Map.find(Reg)->second;
|
|
|
|
|
2010-02-12 19:20:37 +00:00
|
|
|
// It's not worthwhile looking for reuse if there's only one offset.
|
|
|
|
if (Imms.size() == 1)
|
|
|
|
continue;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
DEBUG(dbgs() << "Generating cross-use offsets for " << *Reg << ':';
|
|
|
|
for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
|
|
|
|
J != JE; ++J)
|
|
|
|
dbgs() << ' ' << J->first;
|
|
|
|
dbgs() << '\n');
|
|
|
|
|
|
|
|
// Examine each offset.
|
|
|
|
for (ImmMapTy::const_iterator J = Imms.begin(), JE = Imms.end();
|
|
|
|
J != JE; ++J) {
|
|
|
|
const SCEV *OrigReg = J->second;
|
|
|
|
|
|
|
|
int64_t JImm = J->first;
|
|
|
|
const SmallBitVector &UsedByIndices = RegUses.getUsedByIndices(OrigReg);
|
|
|
|
|
|
|
|
if (!isa<SCEVConstant>(OrigReg) &&
|
|
|
|
UsedByIndicesMap[Reg].count() == 1) {
|
|
|
|
DEBUG(dbgs() << "Skipping cross-use reuse for " << *OrigReg << '\n');
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Conservatively examine offsets between this orig reg a few selected
|
|
|
|
// other orig regs.
|
|
|
|
ImmMapTy::const_iterator OtherImms[] = {
|
|
|
|
Imms.begin(), prior(Imms.end()),
|
2011-05-03 00:46:49 +00:00
|
|
|
Imms.lower_bound((Imms.begin()->first + prior(Imms.end())->first) / 2)
|
2010-02-12 10:34:29 +00:00
|
|
|
};
|
|
|
|
for (size_t i = 0, e = array_lengthof(OtherImms); i != e; ++i) {
|
|
|
|
ImmMapTy::const_iterator M = OtherImms[i];
|
2010-02-12 19:20:37 +00:00
|
|
|
if (M == J || M == JE) continue;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Compute the difference between the two.
|
|
|
|
int64_t Imm = (uint64_t)JImm - M->first;
|
|
|
|
for (int LUIdx = UsedByIndices.find_first(); LUIdx != -1;
|
2010-09-01 01:45:53 +00:00
|
|
|
LUIdx = UsedByIndices.find_next(LUIdx))
|
2010-02-12 10:34:29 +00:00
|
|
|
// Make a memo of this use, offset, and register tuple.
|
2010-09-01 01:45:53 +00:00
|
|
|
if (UniqueItems.insert(std::make_pair(LUIdx, Imm)))
|
|
|
|
WorkItems.push_back(WorkItem(LUIdx, Imm, OrigReg));
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Map.clear();
|
|
|
|
Sequence.clear();
|
|
|
|
UsedByIndicesMap.clear();
|
2010-09-01 01:45:53 +00:00
|
|
|
UniqueItems.clear();
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Now iterate through the worklist and add new formulae.
|
|
|
|
for (SmallVectorImpl<WorkItem>::const_iterator I = WorkItems.begin(),
|
|
|
|
E = WorkItems.end(); I != E; ++I) {
|
|
|
|
const WorkItem &WI = *I;
|
|
|
|
size_t LUIdx = WI.LUIdx;
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
|
|
|
int64_t Imm = WI.Imm;
|
|
|
|
const SCEV *OrigReg = WI.OrigReg;
|
|
|
|
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *IntTy = SE.getEffectiveSCEVType(OrigReg->getType());
|
2010-02-12 10:34:29 +00:00
|
|
|
const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm));
|
|
|
|
unsigned BitWidth = SE.getTypeSizeInBits(IntTy);
|
|
|
|
|
2010-03-01 17:49:51 +00:00
|
|
|
// TODO: Use a more targeted data structure.
|
2010-02-12 10:34:29 +00:00
|
|
|
for (size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) {
|
2010-05-20 22:25:20 +00:00
|
|
|
const Formula &F = LU.Formulae[L];
|
2010-02-12 10:34:29 +00:00
|
|
|
// Use the immediate in the scaled register.
|
|
|
|
if (F.ScaledReg == OrigReg) {
|
|
|
|
int64_t Offs = (uint64_t)F.AM.BaseOffs +
|
|
|
|
Imm * (uint64_t)F.AM.Scale;
|
|
|
|
// Don't create 50 + reg(-50).
|
|
|
|
if (F.referencesReg(SE.getSCEV(
|
|
|
|
ConstantInt::get(IntTy, -(uint64_t)Offs))))
|
|
|
|
continue;
|
|
|
|
Formula NewF = F;
|
|
|
|
NewF.AM.BaseOffs = Offs;
|
|
|
|
if (!isLegalUse(NewF.AM, LU.MinOffset, LU.MaxOffset,
|
|
|
|
LU.Kind, LU.AccessTy, TLI))
|
|
|
|
continue;
|
|
|
|
NewF.ScaledReg = SE.getAddExpr(NegImmS, NewF.ScaledReg);
|
|
|
|
|
|
|
|
// If the new scale is a constant in a register, and adding the constant
|
|
|
|
// value to the immediate would produce a value closer to zero than the
|
|
|
|
// immediate itself, then the formula isn't worthwhile.
|
|
|
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(NewF.ScaledReg))
|
2011-07-15 06:08:15 +00:00
|
|
|
if (C->getValue()->isNegative() !=
|
2010-02-12 10:34:29 +00:00
|
|
|
(NewF.AM.BaseOffs < 0) &&
|
|
|
|
(C->getValue()->getValue().abs() * APInt(BitWidth, F.AM.Scale))
|
2010-04-08 23:03:40 +00:00
|
|
|
.ule(abs64(NewF.AM.BaseOffs)))
|
2010-02-12 10:34:29 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// OK, looks good.
|
|
|
|
(void)InsertFormula(LU, LUIdx, NewF);
|
|
|
|
} else {
|
|
|
|
// Use the immediate in a base register.
|
|
|
|
for (size_t N = 0, NE = F.BaseRegs.size(); N != NE; ++N) {
|
|
|
|
const SCEV *BaseReg = F.BaseRegs[N];
|
|
|
|
if (BaseReg != OrigReg)
|
|
|
|
continue;
|
|
|
|
Formula NewF = F;
|
|
|
|
NewF.AM.BaseOffs = (uint64_t)NewF.AM.BaseOffs + Imm;
|
|
|
|
if (!isLegalUse(NewF.AM, LU.MinOffset, LU.MaxOffset,
|
2011-05-03 00:46:49 +00:00
|
|
|
LU.Kind, LU.AccessTy, TLI)) {
|
|
|
|
if (!TLI ||
|
|
|
|
!TLI->isLegalAddImmediate((uint64_t)NewF.UnfoldedOffset + Imm))
|
|
|
|
continue;
|
|
|
|
NewF = F;
|
|
|
|
NewF.UnfoldedOffset = (uint64_t)NewF.UnfoldedOffset + Imm;
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
NewF.BaseRegs[N] = SE.getAddExpr(NegImmS, BaseReg);
|
|
|
|
|
|
|
|
// If the new formula has a constant in a register, and adding the
|
|
|
|
// constant value to the immediate would produce a value closer to
|
|
|
|
// zero than the immediate itself, then the formula isn't worthwhile.
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator
|
|
|
|
J = NewF.BaseRegs.begin(), JE = NewF.BaseRegs.end();
|
|
|
|
J != JE; ++J)
|
|
|
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*J))
|
2010-05-18 23:48:08 +00:00
|
|
|
if ((C->getValue()->getValue() + NewF.AM.BaseOffs).abs().slt(
|
|
|
|
abs64(NewF.AM.BaseOffs)) &&
|
|
|
|
(C->getValue()->getValue() +
|
|
|
|
NewF.AM.BaseOffs).countTrailingZeros() >=
|
|
|
|
CountTrailingZeros_64(NewF.AM.BaseOffs))
|
2010-02-12 10:34:29 +00:00
|
|
|
goto skip_formula;
|
|
|
|
|
|
|
|
// Ok, looks good.
|
|
|
|
(void)InsertFormula(LU, LUIdx, NewF);
|
|
|
|
break;
|
|
|
|
skip_formula:;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GenerateAllReuseFormulae - Generate formulae for each use.
|
|
|
|
void
|
|
|
|
LSRInstance::GenerateAllReuseFormulae() {
|
2010-02-16 01:42:53 +00:00
|
|
|
// This is split into multiple loops so that hasRegsUsedByUsesOtherThan
|
2010-02-12 10:34:29 +00:00
|
|
|
// queries are more precise.
|
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateReassociations(LU, LUIdx, LU.Formulae[i]);
|
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateCombinations(LU, LUIdx, LU.Formulae[i]);
|
|
|
|
}
|
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateSymbolicOffsets(LU, LUIdx, LU.Formulae[i]);
|
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateConstantOffsets(LU, LUIdx, LU.Formulae[i]);
|
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateICmpZeroScales(LU, LUIdx, LU.Formulae[i]);
|
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateScales(LU, LUIdx, LU.Formulae[i]);
|
2010-02-16 01:42:53 +00:00
|
|
|
}
|
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-02-12 10:34:29 +00:00
|
|
|
for (size_t i = 0, f = LU.Formulae.size(); i != f; ++i)
|
|
|
|
GenerateTruncates(LU, LUIdx, LU.Formulae[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
GenerateCrossUseConstantOffsets();
|
2010-08-29 15:21:38 +00:00
|
|
|
|
|
|
|
DEBUG(dbgs() << "\n"
|
|
|
|
"After generating reuse formulae:\n";
|
|
|
|
print_uses(dbgs()));
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
2010-10-07 23:43:09 +00:00
|
|
|
/// If there are multiple formulae with the same set of registers used
|
2010-02-12 10:34:29 +00:00
|
|
|
/// by other uses, pick the best one and delete the others.
|
|
|
|
void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
|
2010-10-07 23:52:18 +00:00
|
|
|
DenseSet<const SCEV *> VisitedRegs;
|
|
|
|
SmallPtrSet<const SCEV *, 16> Regs;
|
2011-12-06 03:13:31 +00:00
|
|
|
SmallPtrSet<const SCEV *, 16> LoserRegs;
|
2010-02-12 10:34:29 +00:00
|
|
|
#ifndef NDEBUG
|
2010-05-20 20:05:31 +00:00
|
|
|
bool ChangedFormulae = false;
|
2010-02-12 10:34:29 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Collect the best formula for each unique set of shared registers. This
|
|
|
|
// is reset for each use.
|
|
|
|
typedef DenseMap<SmallVector<const SCEV *, 2>, size_t, UniquifierDenseMapInfo>
|
|
|
|
BestFormulaeTy;
|
|
|
|
BestFormulaeTy BestFormulae;
|
|
|
|
|
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-05-20 19:44:23 +00:00
|
|
|
DEBUG(dbgs() << "Filtering for use "; LU.print(dbgs()); dbgs() << '\n');
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-05-18 23:42:37 +00:00
|
|
|
bool Any = false;
|
2010-02-12 10:34:29 +00:00
|
|
|
for (size_t FIdx = 0, NumForms = LU.Formulae.size();
|
|
|
|
FIdx != NumForms; ++FIdx) {
|
|
|
|
Formula &F = LU.Formulae[FIdx];
|
|
|
|
|
2011-12-06 03:13:31 +00:00
|
|
|
// Some formulas are instant losers. For example, they may depend on
|
|
|
|
// nonexistent AddRecs from other loops. These need to be filtered
|
|
|
|
// immediately, otherwise heuristics could choose them over others leading
|
|
|
|
// to an unsatisfactory solution. Passing LoserRegs into RateFormula here
|
|
|
|
// avoids the need to recompute this information across formulae using the
|
|
|
|
// same bad AddRec. Passing LoserRegs is also essential unless we remove
|
|
|
|
// the corresponding bad register from the Regs set.
|
|
|
|
Cost CostF;
|
|
|
|
Regs.clear();
|
|
|
|
CostF.RateFormula(F, Regs, VisitedRegs, L, LU.Offsets, SE, DT,
|
|
|
|
&LoserRegs);
|
|
|
|
if (CostF.isLoser()) {
|
|
|
|
// During initial formula generation, undesirable formulae are generated
|
|
|
|
// by uses within other loops that have some non-trivial address mode or
|
|
|
|
// use the postinc form of the IV. LSR needs to provide these formulae
|
|
|
|
// as the basis of rediscovering the desired formula that uses an AddRec
|
|
|
|
// corresponding to the existing phi. Once all formulae have been
|
|
|
|
// generated, these initial losers may be pruned.
|
|
|
|
DEBUG(dbgs() << " Filtering loser "; F.print(dbgs());
|
|
|
|
dbgs() << "\n");
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
2011-12-06 03:13:31 +00:00
|
|
|
else {
|
|
|
|
SmallVector<const SCEV *, 2> Key;
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator J = F.BaseRegs.begin(),
|
|
|
|
JE = F.BaseRegs.end(); J != JE; ++J) {
|
|
|
|
const SCEV *Reg = *J;
|
|
|
|
if (RegUses.isRegUsedByUsesOtherThan(Reg, LUIdx))
|
|
|
|
Key.push_back(Reg);
|
|
|
|
}
|
|
|
|
if (F.ScaledReg &&
|
|
|
|
RegUses.isRegUsedByUsesOtherThan(F.ScaledReg, LUIdx))
|
|
|
|
Key.push_back(F.ScaledReg);
|
|
|
|
// Unstable sort by host order ok, because this is only used for
|
|
|
|
// uniquifying.
|
|
|
|
std::sort(Key.begin(), Key.end());
|
|
|
|
|
|
|
|
std::pair<BestFormulaeTy::const_iterator, bool> P =
|
|
|
|
BestFormulae.insert(std::make_pair(Key, FIdx));
|
|
|
|
if (P.second)
|
|
|
|
continue;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
Formula &Best = LU.Formulae[P.first->second];
|
2010-10-07 23:52:18 +00:00
|
|
|
|
|
|
|
Cost CostBest;
|
|
|
|
Regs.clear();
|
2011-12-06 03:13:31 +00:00
|
|
|
CostBest.RateFormula(Best, Regs, VisitedRegs, L, LU.Offsets, SE, DT);
|
2010-10-07 23:52:18 +00:00
|
|
|
if (CostF < CostBest)
|
2010-02-12 10:34:29 +00:00
|
|
|
std::swap(F, Best);
|
2010-05-18 22:37:37 +00:00
|
|
|
DEBUG(dbgs() << " Filtering out formula "; F.print(dbgs());
|
2010-02-12 10:34:29 +00:00
|
|
|
dbgs() << "\n"
|
2010-05-18 22:37:37 +00:00
|
|
|
" in favor of formula "; Best.print(dbgs());
|
2010-02-12 10:34:29 +00:00
|
|
|
dbgs() << '\n');
|
2011-12-06 03:13:31 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
#ifndef NDEBUG
|
2011-12-06 03:13:31 +00:00
|
|
|
ChangedFormulae = true;
|
2010-02-12 10:34:29 +00:00
|
|
|
#endif
|
2011-12-06 03:13:31 +00:00
|
|
|
LU.DeleteFormula(F);
|
|
|
|
--FIdx;
|
|
|
|
--NumForms;
|
|
|
|
Any = true;
|
2010-05-07 23:36:59 +00:00
|
|
|
}
|
|
|
|
|
2010-05-18 23:55:57 +00:00
|
|
|
// Now that we've filtered out some formulae, recompute the Regs set.
|
2010-05-18 23:42:37 +00:00
|
|
|
if (Any)
|
|
|
|
LU.RecomputeRegs(LUIdx, RegUses);
|
2010-05-07 23:36:59 +00:00
|
|
|
|
|
|
|
// Reset this to prepare for the next use.
|
2010-02-12 10:34:29 +00:00
|
|
|
BestFormulae.clear();
|
|
|
|
}
|
|
|
|
|
2010-05-20 20:05:31 +00:00
|
|
|
DEBUG(if (ChangedFormulae) {
|
2010-02-13 02:06:02 +00:00
|
|
|
dbgs() << "\n"
|
|
|
|
"After filtering out undesirable candidates:\n";
|
2010-02-12 10:34:29 +00:00
|
|
|
print_uses(dbgs());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2010-05-18 22:51:59 +00:00
|
|
|
// This is a rough guess that seems to work fairly well.
|
|
|
|
static const size_t ComplexityLimit = UINT16_MAX;
|
|
|
|
|
|
|
|
/// EstimateSearchSpaceComplexity - Estimate the worst-case number of
|
|
|
|
/// solutions the solver might have to consider. It almost never considers
|
|
|
|
/// this many solutions because it prune the search space, but the pruning
|
|
|
|
/// isn't always sufficient.
|
|
|
|
size_t LSRInstance::EstimateSearchSpaceComplexity() const {
|
2010-10-07 23:37:58 +00:00
|
|
|
size_t Power = 1;
|
2010-05-18 22:51:59 +00:00
|
|
|
for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
|
|
|
|
E = Uses.end(); I != E; ++I) {
|
|
|
|
size_t FSize = I->Formulae.size();
|
|
|
|
if (FSize >= ComplexityLimit) {
|
|
|
|
Power = ComplexityLimit;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Power *= FSize;
|
|
|
|
if (Power >= ComplexityLimit)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return Power;
|
|
|
|
}
|
|
|
|
|
2010-08-29 16:09:42 +00:00
|
|
|
/// NarrowSearchSpaceByDetectingSupersets - When one formula uses a superset
|
|
|
|
/// of the registers of another formula, it won't help reduce register
|
|
|
|
/// pressure (though it may not necessarily hurt register pressure); remove
|
|
|
|
/// it to simplify the system.
|
|
|
|
void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
|
2010-05-19 23:43:12 +00:00
|
|
|
if (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
|
|
|
|
DEBUG(dbgs() << "The search space is too complex.\n");
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Narrowing the search space by eliminating formulae "
|
|
|
|
"which use a superset of registers used by other "
|
|
|
|
"formulae.\n");
|
|
|
|
|
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
|
|
|
bool Any = false;
|
|
|
|
for (size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
|
|
|
|
Formula &F = LU.Formulae[i];
|
2010-05-20 20:00:41 +00:00
|
|
|
// Look for a formula with a constant or GV in a register. If the use
|
|
|
|
// also has a formula with that same value in an immediate field,
|
|
|
|
// delete the one that uses a register.
|
2010-05-19 23:43:12 +00:00
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator
|
|
|
|
I = F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I) {
|
|
|
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*I)) {
|
|
|
|
Formula NewF = F;
|
|
|
|
NewF.AM.BaseOffs += C->getValue()->getSExtValue();
|
|
|
|
NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
|
|
|
|
(I - F.BaseRegs.begin()));
|
|
|
|
if (LU.HasFormulaWithSameRegs(NewF)) {
|
|
|
|
DEBUG(dbgs() << " Deleting "; F.print(dbgs()); dbgs() << '\n');
|
|
|
|
LU.DeleteFormula(F);
|
|
|
|
--i;
|
|
|
|
--e;
|
|
|
|
Any = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(*I)) {
|
|
|
|
if (GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue()))
|
|
|
|
if (!F.AM.BaseGV) {
|
|
|
|
Formula NewF = F;
|
|
|
|
NewF.AM.BaseGV = GV;
|
|
|
|
NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
|
|
|
|
(I - F.BaseRegs.begin()));
|
|
|
|
if (LU.HasFormulaWithSameRegs(NewF)) {
|
|
|
|
DEBUG(dbgs() << " Deleting "; F.print(dbgs());
|
|
|
|
dbgs() << '\n');
|
|
|
|
LU.DeleteFormula(F);
|
|
|
|
--i;
|
|
|
|
--e;
|
|
|
|
Any = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Any)
|
|
|
|
LU.RecomputeRegs(LUIdx, RegUses);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "After pre-selection:\n";
|
|
|
|
print_uses(dbgs()));
|
|
|
|
}
|
2010-08-29 16:09:42 +00:00
|
|
|
}
|
2010-05-19 23:43:12 +00:00
|
|
|
|
2010-08-29 16:09:42 +00:00
|
|
|
/// NarrowSearchSpaceByCollapsingUnrolledCode - When there are many registers
|
|
|
|
/// for expressions like A, A+1, A+2, etc., allocate a single register for
|
|
|
|
/// them.
|
|
|
|
void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
|
2010-05-19 23:43:12 +00:00
|
|
|
if (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
|
|
|
|
DEBUG(dbgs() << "The search space is too complex.\n");
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Narrowing the search space by assuming that uses "
|
|
|
|
"separated by a constant offset will use the same "
|
|
|
|
"registers.\n");
|
|
|
|
|
2010-05-20 20:00:41 +00:00
|
|
|
// This is especially useful for unrolled loops.
|
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-05-20 20:33:18 +00:00
|
|
|
for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
|
|
|
|
E = LU.Formulae.end(); I != E; ++I) {
|
|
|
|
const Formula &F = *I;
|
2010-05-19 23:43:12 +00:00
|
|
|
if (F.AM.BaseOffs != 0 && F.AM.Scale == 0) {
|
2010-09-01 01:45:53 +00:00
|
|
|
if (LSRUse *LUThatHas = FindUseWithSimilarFormula(F, LU)) {
|
|
|
|
if (reconcileNewOffset(*LUThatHas, F.AM.BaseOffs,
|
2010-05-19 23:43:12 +00:00
|
|
|
/*HasBaseReg=*/false,
|
|
|
|
LU.Kind, LU.AccessTy)) {
|
|
|
|
DEBUG(dbgs() << " Deleting use "; LU.print(dbgs());
|
|
|
|
dbgs() << '\n');
|
|
|
|
|
|
|
|
LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
|
|
|
|
|
2010-09-01 01:45:53 +00:00
|
|
|
// Update the relocs to reference the new use.
|
|
|
|
for (SmallVectorImpl<LSRFixup>::iterator I = Fixups.begin(),
|
|
|
|
E = Fixups.end(); I != E; ++I) {
|
|
|
|
LSRFixup &Fixup = *I;
|
|
|
|
if (Fixup.LUIdx == LUIdx) {
|
|
|
|
Fixup.LUIdx = LUThatHas - &Uses.front();
|
|
|
|
Fixup.Offset += F.AM.BaseOffs;
|
2010-10-07 23:36:45 +00:00
|
|
|
// Add the new offset to LUThatHas' offset list.
|
|
|
|
if (LUThatHas->Offsets.back() != Fixup.Offset) {
|
|
|
|
LUThatHas->Offsets.push_back(Fixup.Offset);
|
|
|
|
if (Fixup.Offset > LUThatHas->MaxOffset)
|
|
|
|
LUThatHas->MaxOffset = Fixup.Offset;
|
|
|
|
if (Fixup.Offset < LUThatHas->MinOffset)
|
|
|
|
LUThatHas->MinOffset = Fixup.Offset;
|
|
|
|
}
|
2010-09-01 01:45:53 +00:00
|
|
|
DEBUG(dbgs() << "New fixup has offset "
|
|
|
|
<< Fixup.Offset << '\n');
|
|
|
|
}
|
|
|
|
if (Fixup.LUIdx == NumUses-1)
|
|
|
|
Fixup.LUIdx = LUIdx;
|
|
|
|
}
|
|
|
|
|
2010-10-08 19:33:26 +00:00
|
|
|
// Delete formulae from the new use which are no longer legal.
|
|
|
|
bool Any = false;
|
|
|
|
for (size_t i = 0, e = LUThatHas->Formulae.size(); i != e; ++i) {
|
|
|
|
Formula &F = LUThatHas->Formulae[i];
|
|
|
|
if (!isLegalUse(F.AM,
|
|
|
|
LUThatHas->MinOffset, LUThatHas->MaxOffset,
|
|
|
|
LUThatHas->Kind, LUThatHas->AccessTy, TLI)) {
|
|
|
|
DEBUG(dbgs() << " Deleting "; F.print(dbgs());
|
|
|
|
dbgs() << '\n');
|
|
|
|
LUThatHas->DeleteFormula(F);
|
|
|
|
--i;
|
|
|
|
--e;
|
|
|
|
Any = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Any)
|
|
|
|
LUThatHas->RecomputeRegs(LUThatHas - &Uses.front(), RegUses);
|
|
|
|
|
2010-05-19 23:43:12 +00:00
|
|
|
// Delete the old use.
|
2010-10-07 23:33:43 +00:00
|
|
|
DeleteUse(LU, LUIdx);
|
2010-05-19 23:43:12 +00:00
|
|
|
--LUIdx;
|
|
|
|
--NumUses;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "After pre-selection:\n";
|
|
|
|
print_uses(dbgs()));
|
|
|
|
}
|
2010-08-29 16:09:42 +00:00
|
|
|
}
|
2010-05-19 23:43:12 +00:00
|
|
|
|
2011-03-14 16:50:06 +00:00
|
|
|
/// NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters - Call
|
2010-08-29 16:39:22 +00:00
|
|
|
/// FilterOutUndesirableDedicatedRegisters again, if necessary, now that
|
|
|
|
/// we've done more filtering, as it may be able to find more formulae to
|
|
|
|
/// eliminate.
|
|
|
|
void LSRInstance::NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters(){
|
|
|
|
if (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
|
|
|
|
DEBUG(dbgs() << "The search space is too complex.\n");
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Narrowing the search space by re-filtering out "
|
|
|
|
"undesirable dedicated registers.\n");
|
|
|
|
|
|
|
|
FilterOutUndesirableDedicatedRegisters();
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "After pre-selection:\n";
|
|
|
|
print_uses(dbgs()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-29 16:09:42 +00:00
|
|
|
/// NarrowSearchSpaceByPickingWinnerRegs - Pick a register which seems likely
|
|
|
|
/// to be profitable, and then in any use which has any reference to that
|
|
|
|
/// register, delete all formulae which do not reference that register.
|
|
|
|
void LSRInstance::NarrowSearchSpaceByPickingWinnerRegs() {
|
2010-05-20 20:52:00 +00:00
|
|
|
// With all other options exhausted, loop until the system is simple
|
|
|
|
// enough to handle.
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallPtrSet<const SCEV *, 4> Taken;
|
2010-05-18 22:51:59 +00:00
|
|
|
while (EstimateSearchSpaceComplexity() >= ComplexityLimit) {
|
2010-02-12 10:34:29 +00:00
|
|
|
// Ok, we have too many of formulae on our hands to conveniently handle.
|
|
|
|
// Use a rough heuristic to thin out the list.
|
2010-05-18 22:41:32 +00:00
|
|
|
DEBUG(dbgs() << "The search space is too complex.\n");
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Pick the register which is used by the most LSRUses, which is likely
|
|
|
|
// to be a good reuse register candidate.
|
|
|
|
const SCEV *Best = 0;
|
|
|
|
unsigned BestNum = 0;
|
|
|
|
for (RegUseTracker::const_iterator I = RegUses.begin(), E = RegUses.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
const SCEV *Reg = *I;
|
|
|
|
if (Taken.count(Reg))
|
|
|
|
continue;
|
|
|
|
if (!Best)
|
|
|
|
Best = Reg;
|
|
|
|
else {
|
|
|
|
unsigned Count = RegUses.getUsedByIndices(Reg).count();
|
|
|
|
if (Count > BestNum) {
|
|
|
|
Best = Reg;
|
|
|
|
BestNum = Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "Narrowing the search space by assuming " << *Best
|
2010-03-01 17:49:51 +00:00
|
|
|
<< " will yield profitable reuse.\n");
|
2010-02-12 10:34:29 +00:00
|
|
|
Taken.insert(Best);
|
|
|
|
|
|
|
|
// In any use with formulae which references this register, delete formulae
|
|
|
|
// which don't reference it.
|
2010-05-18 23:42:37 +00:00
|
|
|
for (size_t LUIdx = 0, NumUses = Uses.size(); LUIdx != NumUses; ++LUIdx) {
|
|
|
|
LSRUse &LU = Uses[LUIdx];
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!LU.Regs.count(Best)) continue;
|
|
|
|
|
2010-05-18 23:42:37 +00:00
|
|
|
bool Any = false;
|
2010-02-12 10:34:29 +00:00
|
|
|
for (size_t i = 0, e = LU.Formulae.size(); i != e; ++i) {
|
|
|
|
Formula &F = LU.Formulae[i];
|
|
|
|
if (!F.referencesReg(Best)) {
|
|
|
|
DEBUG(dbgs() << " Deleting "; F.print(dbgs()); dbgs() << '\n');
|
2010-05-18 22:39:15 +00:00
|
|
|
LU.DeleteFormula(F);
|
2010-02-12 10:34:29 +00:00
|
|
|
--e;
|
|
|
|
--i;
|
2010-05-18 23:42:37 +00:00
|
|
|
Any = true;
|
2010-05-07 23:36:59 +00:00
|
|
|
assert(e != 0 && "Use has no formulae left! Is Regs inconsistent?");
|
2010-02-12 10:34:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2010-05-18 23:42:37 +00:00
|
|
|
|
|
|
|
if (Any)
|
|
|
|
LU.RecomputeRegs(LUIdx, RegUses);
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "After pre-selection:\n";
|
|
|
|
print_uses(dbgs()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-29 16:09:42 +00:00
|
|
|
/// NarrowSearchSpaceUsingHeuristics - If there are an extraordinary number of
|
|
|
|
/// formulae to choose from, use some rough heuristics to prune down the number
|
|
|
|
/// of formulae. This keeps the main solver from taking an extraordinary amount
|
|
|
|
/// of time in some worst-case scenarios.
|
|
|
|
void LSRInstance::NarrowSearchSpaceUsingHeuristics() {
|
|
|
|
NarrowSearchSpaceByDetectingSupersets();
|
|
|
|
NarrowSearchSpaceByCollapsingUnrolledCode();
|
2010-08-29 16:39:22 +00:00
|
|
|
NarrowSearchSpaceByRefilteringUndesirableDedicatedRegisters();
|
2010-08-29 16:09:42 +00:00
|
|
|
NarrowSearchSpaceByPickingWinnerRegs();
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// SolveRecurse - This is the recursive solver.
|
|
|
|
void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
|
|
|
|
Cost &SolutionCost,
|
|
|
|
SmallVectorImpl<const Formula *> &Workspace,
|
|
|
|
const Cost &CurCost,
|
|
|
|
const SmallPtrSet<const SCEV *, 16> &CurRegs,
|
|
|
|
DenseSet<const SCEV *> &VisitedRegs) const {
|
|
|
|
// Some ideas:
|
|
|
|
// - prune more:
|
|
|
|
// - use more aggressive filtering
|
|
|
|
// - sort the formula so that the most profitable solutions are found first
|
|
|
|
// - sort the uses too
|
|
|
|
// - search faster:
|
2010-03-01 17:49:51 +00:00
|
|
|
// - don't compute a cost, and then compare. compare while computing a cost
|
2010-02-12 10:34:29 +00:00
|
|
|
// and bail early.
|
|
|
|
// - track register sets with SmallBitVector
|
|
|
|
|
|
|
|
const LSRUse &LU = Uses[Workspace.size()];
|
|
|
|
|
|
|
|
// If this use references any register that's already a part of the
|
|
|
|
// in-progress solution, consider it a requirement that a formula must
|
|
|
|
// reference that register in order to be considered. This prunes out
|
|
|
|
// unprofitable searching.
|
|
|
|
SmallSetVector<const SCEV *, 4> ReqRegs;
|
|
|
|
for (SmallPtrSet<const SCEV *, 16>::const_iterator I = CurRegs.begin(),
|
|
|
|
E = CurRegs.end(); I != E; ++I)
|
2010-02-13 02:06:02 +00:00
|
|
|
if (LU.Regs.count(*I))
|
2010-02-12 10:34:29 +00:00
|
|
|
ReqRegs.insert(*I);
|
|
|
|
|
2010-02-13 02:06:02 +00:00
|
|
|
bool AnySatisfiedReqRegs = false;
|
2010-02-12 10:34:29 +00:00
|
|
|
SmallPtrSet<const SCEV *, 16> NewRegs;
|
|
|
|
Cost NewCost;
|
2010-02-13 02:06:02 +00:00
|
|
|
retry:
|
2010-02-12 10:34:29 +00:00
|
|
|
for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
|
|
|
|
E = LU.Formulae.end(); I != E; ++I) {
|
|
|
|
const Formula &F = *I;
|
|
|
|
|
|
|
|
// Ignore formulae which do not use any of the required registers.
|
|
|
|
for (SmallSetVector<const SCEV *, 4>::const_iterator J = ReqRegs.begin(),
|
|
|
|
JE = ReqRegs.end(); J != JE; ++J) {
|
|
|
|
const SCEV *Reg = *J;
|
|
|
|
if ((!F.ScaledReg || F.ScaledReg != Reg) &&
|
|
|
|
std::find(F.BaseRegs.begin(), F.BaseRegs.end(), Reg) ==
|
|
|
|
F.BaseRegs.end())
|
|
|
|
goto skip;
|
|
|
|
}
|
2010-02-13 02:06:02 +00:00
|
|
|
AnySatisfiedReqRegs = true;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Evaluate the cost of the current formula. If it's already worse than
|
|
|
|
// the current best, prune the search at that point.
|
|
|
|
NewCost = CurCost;
|
|
|
|
NewRegs = CurRegs;
|
|
|
|
NewCost.RateFormula(F, NewRegs, VisitedRegs, L, LU.Offsets, SE, DT);
|
|
|
|
if (NewCost < SolutionCost) {
|
|
|
|
Workspace.push_back(&F);
|
|
|
|
if (Workspace.size() != Uses.size()) {
|
|
|
|
SolveRecurse(Solution, SolutionCost, Workspace, NewCost,
|
|
|
|
NewRegs, VisitedRegs);
|
|
|
|
if (F.getNumRegs() == 1 && Workspace.size() == 1)
|
|
|
|
VisitedRegs.insert(F.ScaledReg ? F.ScaledReg : F.BaseRegs[0]);
|
|
|
|
} else {
|
|
|
|
DEBUG(dbgs() << "New best at "; NewCost.print(dbgs());
|
2012-01-09 18:58:16 +00:00
|
|
|
dbgs() << ".\n Regs:";
|
2010-02-12 10:34:29 +00:00
|
|
|
for (SmallPtrSet<const SCEV *, 16>::const_iterator
|
|
|
|
I = NewRegs.begin(), E = NewRegs.end(); I != E; ++I)
|
|
|
|
dbgs() << ' ' << **I;
|
|
|
|
dbgs() << '\n');
|
|
|
|
|
|
|
|
SolutionCost = NewCost;
|
|
|
|
Solution = Workspace;
|
|
|
|
}
|
|
|
|
Workspace.pop_back();
|
|
|
|
}
|
|
|
|
skip:;
|
|
|
|
}
|
2010-02-13 02:06:02 +00:00
|
|
|
|
2011-09-27 00:44:14 +00:00
|
|
|
if (!EnableRetry && !AnySatisfiedReqRegs)
|
|
|
|
return;
|
|
|
|
|
2010-02-13 02:06:02 +00:00
|
|
|
// If none of the formulae had all of the required registers, relax the
|
|
|
|
// constraint so that we don't exclude all formulae.
|
|
|
|
if (!AnySatisfiedReqRegs) {
|
2010-05-07 23:36:59 +00:00
|
|
|
assert(!ReqRegs.empty() && "Solver failed even without required registers");
|
2010-02-13 02:06:02 +00:00
|
|
|
ReqRegs.clear();
|
|
|
|
goto retry;
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
2010-05-20 20:52:00 +00:00
|
|
|
/// Solve - Choose one formula from each use. Return the results in the given
|
|
|
|
/// Solution vector.
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::Solve(SmallVectorImpl<const Formula *> &Solution) const {
|
|
|
|
SmallVector<const Formula *, 8> Workspace;
|
|
|
|
Cost SolutionCost;
|
|
|
|
SolutionCost.Loose();
|
|
|
|
Cost CurCost;
|
|
|
|
SmallPtrSet<const SCEV *, 16> CurRegs;
|
|
|
|
DenseSet<const SCEV *> VisitedRegs;
|
|
|
|
Workspace.reserve(Uses.size());
|
|
|
|
|
2010-05-20 20:00:41 +00:00
|
|
|
// SolveRecurse does all the work.
|
2010-02-12 10:34:29 +00:00
|
|
|
SolveRecurse(Solution, SolutionCost, Workspace, CurCost,
|
|
|
|
CurRegs, VisitedRegs);
|
2011-09-27 00:44:14 +00:00
|
|
|
if (Solution.empty()) {
|
|
|
|
DEBUG(dbgs() << "\nNo Satisfactory Solution\n");
|
|
|
|
return;
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Ok, we've now made all our decisions.
|
|
|
|
DEBUG(dbgs() << "\n"
|
|
|
|
"The chosen solution requires "; SolutionCost.print(dbgs());
|
|
|
|
dbgs() << ":\n";
|
|
|
|
for (size_t i = 0, e = Uses.size(); i != e; ++i) {
|
|
|
|
dbgs() << " ";
|
|
|
|
Uses[i].print(dbgs());
|
|
|
|
dbgs() << "\n"
|
|
|
|
" ";
|
|
|
|
Solution[i]->print(dbgs());
|
|
|
|
dbgs() << '\n';
|
|
|
|
});
|
2010-05-20 20:59:23 +00:00
|
|
|
|
|
|
|
assert(Solution.size() == Uses.size() && "Malformed solution!");
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
2010-04-09 22:07:05 +00:00
|
|
|
/// HoistInsertPosition - Helper for AdjustInsertPositionForExpand. Climb up
|
|
|
|
/// the dominator tree far as we can go while still being dominated by the
|
|
|
|
/// input positions. This helps canonicalize the insert position, which
|
|
|
|
/// encourages sharing.
|
|
|
|
BasicBlock::iterator
|
|
|
|
LSRInstance::HoistInsertPosition(BasicBlock::iterator IP,
|
|
|
|
const SmallVectorImpl<Instruction *> &Inputs)
|
|
|
|
const {
|
|
|
|
for (;;) {
|
|
|
|
const Loop *IPLoop = LI.getLoopFor(IP->getParent());
|
|
|
|
unsigned IPLoopDepth = IPLoop ? IPLoop->getLoopDepth() : 0;
|
|
|
|
|
|
|
|
BasicBlock *IDom;
|
2010-05-20 20:00:25 +00:00
|
|
|
for (DomTreeNode *Rung = DT.getNode(IP->getParent()); ; ) {
|
2010-05-20 22:46:54 +00:00
|
|
|
if (!Rung) return IP;
|
2010-05-20 20:00:25 +00:00
|
|
|
Rung = Rung->getIDom();
|
|
|
|
if (!Rung) return IP;
|
|
|
|
IDom = Rung->getBlock();
|
2010-04-09 22:07:05 +00:00
|
|
|
|
|
|
|
// Don't climb into a loop though.
|
|
|
|
const Loop *IDomLoop = LI.getLoopFor(IDom);
|
|
|
|
unsigned IDomDepth = IDomLoop ? IDomLoop->getLoopDepth() : 0;
|
|
|
|
if (IDomDepth <= IPLoopDepth &&
|
|
|
|
(IDomDepth != IPLoopDepth || IDomLoop == IPLoop))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AllDominate = true;
|
|
|
|
Instruction *BetterPos = 0;
|
|
|
|
Instruction *Tentative = IDom->getTerminator();
|
|
|
|
for (SmallVectorImpl<Instruction *>::const_iterator I = Inputs.begin(),
|
|
|
|
E = Inputs.end(); I != E; ++I) {
|
|
|
|
Instruction *Inst = *I;
|
|
|
|
if (Inst == Tentative || !DT.dominates(Inst, Tentative)) {
|
|
|
|
AllDominate = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// Attempt to find an insert position in the middle of the block,
|
|
|
|
// instead of at the end, so that it can be used for other expansions.
|
|
|
|
if (IDom == Inst->getParent() &&
|
|
|
|
(!BetterPos || DT.dominates(BetterPos, Inst)))
|
2010-05-11 06:17:44 +00:00
|
|
|
BetterPos = llvm::next(BasicBlock::iterator(Inst));
|
2010-04-09 22:07:05 +00:00
|
|
|
}
|
|
|
|
if (!AllDominate)
|
|
|
|
break;
|
|
|
|
if (BetterPos)
|
|
|
|
IP = BetterPos;
|
|
|
|
else
|
|
|
|
IP = Tentative;
|
|
|
|
}
|
|
|
|
|
|
|
|
return IP;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// AdjustInsertPositionForExpand - Determine an input position which will be
|
2010-04-09 02:00:38 +00:00
|
|
|
/// dominated by the operands and which will dominate the result.
|
|
|
|
BasicBlock::iterator
|
2012-01-20 07:41:13 +00:00
|
|
|
LSRInstance::AdjustInsertPositionForExpand(BasicBlock::iterator LowestIP,
|
2010-04-09 22:07:05 +00:00
|
|
|
const LSRFixup &LF,
|
2012-01-20 07:41:13 +00:00
|
|
|
const LSRUse &LU,
|
|
|
|
SCEVExpander &Rewriter) const {
|
2010-04-09 02:00:38 +00:00
|
|
|
// Collect some instructions which must be dominated by the
|
2010-04-07 22:27:08 +00:00
|
|
|
// expanding replacement. These must be dominated by any operands that
|
2010-02-12 10:34:29 +00:00
|
|
|
// will be required in the expansion.
|
|
|
|
SmallVector<Instruction *, 4> Inputs;
|
|
|
|
if (Instruction *I = dyn_cast<Instruction>(LF.OperandValToReplace))
|
|
|
|
Inputs.push_back(I);
|
|
|
|
if (LU.Kind == LSRUse::ICmpZero)
|
|
|
|
if (Instruction *I =
|
|
|
|
dyn_cast<Instruction>(cast<ICmpInst>(LF.UserInst)->getOperand(1)))
|
|
|
|
Inputs.push_back(I);
|
2010-04-07 22:27:08 +00:00
|
|
|
if (LF.PostIncLoops.count(L)) {
|
|
|
|
if (LF.isUseFullyOutsideLoop(L))
|
2010-03-02 01:59:21 +00:00
|
|
|
Inputs.push_back(L->getLoopLatch()->getTerminator());
|
|
|
|
else
|
|
|
|
Inputs.push_back(IVIncInsertPos);
|
|
|
|
}
|
2010-04-08 05:57:57 +00:00
|
|
|
// The expansion must also be dominated by the increment positions of any
|
|
|
|
// loops it for which it is using post-inc mode.
|
|
|
|
for (PostIncLoopSet::const_iterator I = LF.PostIncLoops.begin(),
|
|
|
|
E = LF.PostIncLoops.end(); I != E; ++I) {
|
|
|
|
const Loop *PIL = *I;
|
|
|
|
if (PIL == L) continue;
|
|
|
|
|
2010-04-09 22:07:05 +00:00
|
|
|
// Be dominated by the loop exit.
|
2010-04-08 05:57:57 +00:00
|
|
|
SmallVector<BasicBlock *, 4> ExitingBlocks;
|
|
|
|
PIL->getExitingBlocks(ExitingBlocks);
|
|
|
|
if (!ExitingBlocks.empty()) {
|
|
|
|
BasicBlock *BB = ExitingBlocks[0];
|
|
|
|
for (unsigned i = 1, e = ExitingBlocks.size(); i != e; ++i)
|
|
|
|
BB = DT.findNearestCommonDominator(BB, ExitingBlocks[i]);
|
|
|
|
Inputs.push_back(BB->getTerminator());
|
|
|
|
}
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2012-01-20 07:41:13 +00:00
|
|
|
assert(!isa<PHINode>(LowestIP) && !isa<LandingPadInst>(LowestIP)
|
|
|
|
&& !isa<DbgInfoIntrinsic>(LowestIP) &&
|
|
|
|
"Insertion point must be a normal instruction");
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Then, climb up the immediate dominator tree as far as we can go while
|
|
|
|
// still being dominated by the input positions.
|
2012-01-20 07:41:13 +00:00
|
|
|
BasicBlock::iterator IP = HoistInsertPosition(LowestIP, Inputs);
|
2010-04-09 02:00:38 +00:00
|
|
|
|
|
|
|
// Don't insert instructions before PHI nodes.
|
2010-02-12 10:34:29 +00:00
|
|
|
while (isa<PHINode>(IP)) ++IP;
|
2010-04-09 02:00:38 +00:00
|
|
|
|
2011-08-24 21:06:46 +00:00
|
|
|
// Ignore landingpad instructions.
|
|
|
|
while (isa<LandingPadInst>(IP)) ++IP;
|
|
|
|
|
2010-04-09 02:00:38 +00:00
|
|
|
// Ignore debug intrinsics.
|
2010-03-26 00:33:27 +00:00
|
|
|
while (isa<DbgInfoIntrinsic>(IP)) ++IP;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2012-01-20 07:41:13 +00:00
|
|
|
// Set IP below instructions recently inserted by SCEVExpander. This keeps the
|
|
|
|
// IP consistent across expansions and allows the previously inserted
|
|
|
|
// instructions to be reused by subsequent expansion.
|
|
|
|
while (Rewriter.isInsertedInstruction(IP) && IP != LowestIP) ++IP;
|
|
|
|
|
2010-04-09 02:00:38 +00:00
|
|
|
return IP;
|
|
|
|
}
|
|
|
|
|
2010-05-20 20:52:00 +00:00
|
|
|
/// Expand - Emit instructions for the leading candidate expression for this
|
|
|
|
/// LSRUse (this is called "expanding").
|
2010-04-09 02:00:38 +00:00
|
|
|
Value *LSRInstance::Expand(const LSRFixup &LF,
|
|
|
|
const Formula &F,
|
|
|
|
BasicBlock::iterator IP,
|
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts) const {
|
|
|
|
const LSRUse &LU = Uses[LF.LUIdx];
|
|
|
|
|
|
|
|
// Determine an input position which will be dominated by the operands and
|
|
|
|
// which will dominate the result.
|
2012-01-20 07:41:13 +00:00
|
|
|
IP = AdjustInsertPositionForExpand(IP, LF, LU, Rewriter);
|
2010-04-09 02:00:38 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Inform the Rewriter if we have a post-increment use, so that it can
|
|
|
|
// perform an advantageous expansion.
|
2010-04-07 22:27:08 +00:00
|
|
|
Rewriter.setPostInc(LF.PostIncLoops);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// This is the type that the user actually needs.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *OpTy = LF.OperandValToReplace->getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
// This will be the type that we'll initially expand to.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *Ty = F.getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
if (!Ty)
|
|
|
|
// No type known; just expand directly to the ultimate type.
|
|
|
|
Ty = OpTy;
|
|
|
|
else if (SE.getEffectiveSCEVType(Ty) == SE.getEffectiveSCEVType(OpTy))
|
|
|
|
// Expand directly to the ultimate type if it's the right size.
|
|
|
|
Ty = OpTy;
|
|
|
|
// This is the type to do integer arithmetic in.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *IntTy = SE.getEffectiveSCEVType(Ty);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// Build up a list of operands to add together to form the full base.
|
|
|
|
SmallVector<const SCEV *, 8> Ops;
|
|
|
|
|
|
|
|
// Expand the BaseRegs portion.
|
|
|
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = F.BaseRegs.begin(),
|
|
|
|
E = F.BaseRegs.end(); I != E; ++I) {
|
|
|
|
const SCEV *Reg = *I;
|
|
|
|
assert(!Reg->isZero() && "Zero allocated in a base register!");
|
|
|
|
|
2010-04-07 22:27:08 +00:00
|
|
|
// If we're expanding for a post-inc user, make the post-inc adjustment.
|
|
|
|
PostIncLoopSet &Loops = const_cast<PostIncLoopSet &>(LF.PostIncLoops);
|
|
|
|
Reg = TransformForPostIncUse(Denormalize, Reg,
|
|
|
|
LF.UserInst, LF.OperandValToReplace,
|
|
|
|
Loops, SE, DT);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
Ops.push_back(SE.getUnknown(Rewriter.expandCodeFor(Reg, 0, IP)));
|
|
|
|
}
|
|
|
|
|
2010-03-03 05:29:13 +00:00
|
|
|
// Flush the operand list to suppress SCEVExpander hoisting.
|
|
|
|
if (!Ops.empty()) {
|
|
|
|
Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
|
|
|
|
Ops.clear();
|
|
|
|
Ops.push_back(SE.getUnknown(FullV));
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Expand the ScaledReg portion.
|
|
|
|
Value *ICmpScaledV = 0;
|
|
|
|
if (F.AM.Scale != 0) {
|
|
|
|
const SCEV *ScaledS = F.ScaledReg;
|
|
|
|
|
2010-04-07 22:27:08 +00:00
|
|
|
// If we're expanding for a post-inc user, make the post-inc adjustment.
|
|
|
|
PostIncLoopSet &Loops = const_cast<PostIncLoopSet &>(LF.PostIncLoops);
|
|
|
|
ScaledS = TransformForPostIncUse(Denormalize, ScaledS,
|
|
|
|
LF.UserInst, LF.OperandValToReplace,
|
|
|
|
Loops, SE, DT);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
if (LU.Kind == LSRUse::ICmpZero) {
|
|
|
|
// An interesting way of "folding" with an icmp is to use a negated
|
|
|
|
// scale, which we'll implement by inserting it into the other operand
|
|
|
|
// of the icmp.
|
|
|
|
assert(F.AM.Scale == -1 &&
|
|
|
|
"The only scale supported by ICmpZero uses is -1!");
|
|
|
|
ICmpScaledV = Rewriter.expandCodeFor(ScaledS, 0, IP);
|
|
|
|
} else {
|
|
|
|
// Otherwise just expand the scaled register and an explicit scale,
|
|
|
|
// which is expected to be matched as part of the address.
|
|
|
|
ScaledS = SE.getUnknown(Rewriter.expandCodeFor(ScaledS, 0, IP));
|
|
|
|
ScaledS = SE.getMulExpr(ScaledS,
|
2010-05-03 22:09:21 +00:00
|
|
|
SE.getConstant(ScaledS->getType(), F.AM.Scale));
|
2010-02-12 10:34:29 +00:00
|
|
|
Ops.push_back(ScaledS);
|
2010-03-03 05:29:13 +00:00
|
|
|
|
|
|
|
// Flush the operand list to suppress SCEVExpander hoisting.
|
|
|
|
Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
|
|
|
|
Ops.clear();
|
|
|
|
Ops.push_back(SE.getUnknown(FullV));
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-03 05:29:13 +00:00
|
|
|
// Expand the GV portion.
|
|
|
|
if (F.AM.BaseGV) {
|
|
|
|
Ops.push_back(SE.getUnknown(F.AM.BaseGV));
|
|
|
|
|
|
|
|
// Flush the operand list to suppress SCEVExpander hoisting.
|
|
|
|
Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
|
|
|
|
Ops.clear();
|
|
|
|
Ops.push_back(SE.getUnknown(FullV));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expand the immediate portion.
|
2010-02-12 10:34:29 +00:00
|
|
|
int64_t Offset = (uint64_t)F.AM.BaseOffs + LF.Offset;
|
|
|
|
if (Offset != 0) {
|
|
|
|
if (LU.Kind == LSRUse::ICmpZero) {
|
|
|
|
// The other interesting way of "folding" with an ICmpZero is to use a
|
|
|
|
// negated immediate.
|
|
|
|
if (!ICmpScaledV)
|
2011-10-13 23:48:33 +00:00
|
|
|
ICmpScaledV = ConstantInt::get(IntTy, -(uint64_t)Offset);
|
2010-02-12 10:34:29 +00:00
|
|
|
else {
|
|
|
|
Ops.push_back(SE.getUnknown(ICmpScaledV));
|
|
|
|
ICmpScaledV = ConstantInt::get(IntTy, Offset);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Just add the immediate values. These again are expected to be matched
|
|
|
|
// as part of the address.
|
2010-03-03 05:29:13 +00:00
|
|
|
Ops.push_back(SE.getUnknown(ConstantInt::getSigned(IntTy, Offset)));
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-03 00:46:49 +00:00
|
|
|
// Expand the unfolded offset portion.
|
|
|
|
int64_t UnfoldedOffset = F.UnfoldedOffset;
|
|
|
|
if (UnfoldedOffset != 0) {
|
|
|
|
// Just add the immediate values.
|
|
|
|
Ops.push_back(SE.getUnknown(ConstantInt::getSigned(IntTy,
|
|
|
|
UnfoldedOffset)));
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Emit instructions summing all the operands.
|
|
|
|
const SCEV *FullS = Ops.empty() ?
|
2010-05-03 22:09:21 +00:00
|
|
|
SE.getConstant(IntTy, 0) :
|
2010-02-12 10:34:29 +00:00
|
|
|
SE.getAddExpr(Ops);
|
|
|
|
Value *FullV = Rewriter.expandCodeFor(FullS, Ty, IP);
|
|
|
|
|
|
|
|
// We're done expanding now, so reset the rewriter.
|
2010-04-07 22:27:08 +00:00
|
|
|
Rewriter.clearPostInc();
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// An ICmpZero Formula represents an ICmp which we're handling as a
|
|
|
|
// comparison against zero. Now that we've expanded an expression for that
|
|
|
|
// form, update the ICmp's other operand.
|
|
|
|
if (LU.Kind == LSRUse::ICmpZero) {
|
|
|
|
ICmpInst *CI = cast<ICmpInst>(LF.UserInst);
|
|
|
|
DeadInsts.push_back(CI->getOperand(1));
|
|
|
|
assert(!F.AM.BaseGV && "ICmp does not support folding a global value and "
|
|
|
|
"a scale at the same time!");
|
|
|
|
if (F.AM.Scale == -1) {
|
|
|
|
if (ICmpScaledV->getType() != OpTy) {
|
|
|
|
Instruction *Cast =
|
|
|
|
CastInst::Create(CastInst::getCastOpcode(ICmpScaledV, false,
|
|
|
|
OpTy, false),
|
|
|
|
ICmpScaledV, OpTy, "tmp", CI);
|
|
|
|
ICmpScaledV = Cast;
|
|
|
|
}
|
|
|
|
CI->setOperand(1, ICmpScaledV);
|
|
|
|
} else {
|
|
|
|
assert(F.AM.Scale == 0 &&
|
|
|
|
"ICmp does not support folding a global value and "
|
|
|
|
"a scale at the same time!");
|
|
|
|
Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy),
|
|
|
|
-(uint64_t)Offset);
|
|
|
|
if (C->getType() != OpTy)
|
|
|
|
C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
|
|
|
|
OpTy, false),
|
|
|
|
C, OpTy);
|
|
|
|
|
|
|
|
CI->setOperand(1, C);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FullV;
|
|
|
|
}
|
|
|
|
|
2010-02-16 20:25:07 +00:00
|
|
|
/// RewriteForPHI - Helper for Rewrite. PHI nodes are special because the use
|
|
|
|
/// of their operands effectively happens in their predecessor blocks, so the
|
|
|
|
/// expression may need to be expanded in multiple places.
|
|
|
|
void LSRInstance::RewriteForPHI(PHINode *PN,
|
|
|
|
const LSRFixup &LF,
|
|
|
|
const Formula &F,
|
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts,
|
|
|
|
Pass *P) const {
|
|
|
|
DenseMap<BasicBlock *, Value *> Inserted;
|
|
|
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
|
|
|
if (PN->getIncomingValue(i) == LF.OperandValToReplace) {
|
|
|
|
BasicBlock *BB = PN->getIncomingBlock(i);
|
|
|
|
|
|
|
|
// 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, which complicates post-inc
|
|
|
|
// users.
|
|
|
|
if (e != 1 && BB->getTerminator()->getNumSuccessors() > 1 &&
|
2011-02-08 00:55:13 +00:00
|
|
|
!isa<IndirectBrInst>(BB->getTerminator())) {
|
2011-08-25 01:08:34 +00:00
|
|
|
BasicBlock *Parent = PN->getParent();
|
|
|
|
Loop *PNLoop = LI.getLoopFor(Parent);
|
|
|
|
if (!PNLoop || Parent != PNLoop->getHeader()) {
|
2011-02-08 00:55:13 +00:00
|
|
|
// Split the critical edge.
|
2011-08-25 05:55:40 +00:00
|
|
|
BasicBlock *NewBB = 0;
|
|
|
|
if (!Parent->isLandingPad()) {
|
2011-10-04 03:50:44 +00:00
|
|
|
NewBB = SplitCriticalEdge(BB, Parent, P,
|
|
|
|
/*MergeIdenticalEdges=*/true,
|
|
|
|
/*DontDeleteUselessPhis=*/true);
|
2011-08-25 05:55:40 +00:00
|
|
|
} else {
|
|
|
|
SmallVector<BasicBlock*, 2> NewBBs;
|
|
|
|
SplitLandingPadPredecessors(Parent, BB, "", "", P, NewBBs);
|
|
|
|
NewBB = NewBBs[0];
|
|
|
|
}
|
2011-02-08 00:55:13 +00:00
|
|
|
|
|
|
|
// If PN is outside of the loop and BB is in the loop, we want to
|
|
|
|
// move the block to be immediately before the PHI block, not
|
|
|
|
// immediately after BB.
|
|
|
|
if (L->contains(BB) && !L->contains(PN))
|
|
|
|
NewBB->moveBefore(PN->getParent());
|
|
|
|
|
|
|
|
// Splitting the edge can reduce the number of PHI entries we have.
|
|
|
|
e = PN->getNumIncomingValues();
|
|
|
|
BB = NewBB;
|
|
|
|
i = PN->getBasicBlockIndex(BB);
|
|
|
|
}
|
2010-02-16 20:25:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> Pair =
|
|
|
|
Inserted.insert(std::make_pair(BB, static_cast<Value *>(0)));
|
|
|
|
if (!Pair.second)
|
|
|
|
PN->setIncomingValue(i, Pair.first->second);
|
|
|
|
else {
|
2010-02-22 04:11:59 +00:00
|
|
|
Value *FullV = Expand(LF, F, BB->getTerminator(), Rewriter, DeadInsts);
|
2010-02-16 20:25:07 +00:00
|
|
|
|
|
|
|
// If this is reuse-by-noop-cast, insert the noop cast.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *OpTy = LF.OperandValToReplace->getType();
|
2010-02-16 20:25:07 +00:00
|
|
|
if (FullV->getType() != OpTy)
|
|
|
|
FullV =
|
|
|
|
CastInst::Create(CastInst::getCastOpcode(FullV, false,
|
|
|
|
OpTy, false),
|
|
|
|
FullV, LF.OperandValToReplace->getType(),
|
|
|
|
"tmp", BB->getTerminator());
|
|
|
|
|
|
|
|
PN->setIncomingValue(i, FullV);
|
|
|
|
Pair.first->second = FullV;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
/// Rewrite - Emit instructions for the leading candidate expression for this
|
|
|
|
/// LSRUse (this is called "expanding"), and update the UserInst to reference
|
|
|
|
/// the newly expanded value.
|
|
|
|
void LSRInstance::Rewrite(const LSRFixup &LF,
|
|
|
|
const Formula &F,
|
|
|
|
SCEVExpander &Rewriter,
|
|
|
|
SmallVectorImpl<WeakVH> &DeadInsts,
|
|
|
|
Pass *P) const {
|
|
|
|
// First, find an insertion point that dominates UserInst. For PHI nodes,
|
|
|
|
// find the nearest block which dominates all the relevant uses.
|
|
|
|
if (PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) {
|
2010-02-22 04:11:59 +00:00
|
|
|
RewriteForPHI(PN, LF, F, Rewriter, DeadInsts, P);
|
2010-02-12 10:34:29 +00:00
|
|
|
} else {
|
2010-02-22 04:11:59 +00:00
|
|
|
Value *FullV = Expand(LF, F, LF.UserInst, Rewriter, DeadInsts);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
// If this is reuse-by-noop-cast, insert the noop cast.
|
2011-07-18 04:54:35 +00:00
|
|
|
Type *OpTy = LF.OperandValToReplace->getType();
|
2010-02-12 10:34:29 +00:00
|
|
|
if (FullV->getType() != OpTy) {
|
|
|
|
Instruction *Cast =
|
|
|
|
CastInst::Create(CastInst::getCastOpcode(FullV, false, OpTy, false),
|
|
|
|
FullV, OpTy, "tmp", LF.UserInst);
|
|
|
|
FullV = Cast;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the user. ICmpZero is handled specially here (for now) because
|
|
|
|
// Expand may have updated one of the operands of the icmp already, and
|
|
|
|
// its new value may happen to be equal to LF.OperandValToReplace, in
|
|
|
|
// which case doing replaceUsesOfWith leads to replacing both operands
|
|
|
|
// with the same value. TODO: Reorganize this.
|
|
|
|
if (Uses[LF.LUIdx].Kind == LSRUse::ICmpZero)
|
|
|
|
LF.UserInst->setOperand(0, FullV);
|
|
|
|
else
|
|
|
|
LF.UserInst->replaceUsesOfWith(LF.OperandValToReplace, FullV);
|
|
|
|
}
|
|
|
|
|
|
|
|
DeadInsts.push_back(LF.OperandValToReplace);
|
|
|
|
}
|
|
|
|
|
2010-05-20 20:52:00 +00:00
|
|
|
/// ImplementSolution - Rewrite all the fixup locations with new values,
|
|
|
|
/// following the chosen solution.
|
2010-02-12 10:34:29 +00:00
|
|
|
void
|
|
|
|
LSRInstance::ImplementSolution(const SmallVectorImpl<const Formula *> &Solution,
|
|
|
|
Pass *P) {
|
|
|
|
// Keep track of instructions we may have made dead, so that
|
|
|
|
// we can remove them after we are done working.
|
|
|
|
SmallVector<WeakVH, 16> DeadInsts;
|
|
|
|
|
2011-06-28 05:07:32 +00:00
|
|
|
SCEVExpander Rewriter(SE, "lsr");
|
2012-01-09 18:58:16 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
Rewriter.setDebugType(DEBUG_TYPE);
|
|
|
|
#endif
|
2010-02-12 10:34:29 +00:00
|
|
|
Rewriter.disableCanonicalMode();
|
2011-10-07 23:46:21 +00:00
|
|
|
Rewriter.enableLSRMode();
|
2010-02-12 10:34:29 +00:00
|
|
|
Rewriter.setIVIncInsertPos(L, IVIncInsertPos);
|
|
|
|
|
2012-01-10 01:45:08 +00:00
|
|
|
// Mark phi nodes that terminate chains so the expander tries to reuse them.
|
|
|
|
for (SmallVectorImpl<IVChain>::const_iterator ChainI = IVChainVec.begin(),
|
|
|
|
ChainE = IVChainVec.end(); ChainI != ChainE; ++ChainI) {
|
|
|
|
if (PHINode *PN = dyn_cast<PHINode>(ChainI->back().UserInst))
|
|
|
|
Rewriter.setChainedPhi(PN);
|
|
|
|
}
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Expand the new value definitions and update the users.
|
2010-05-20 20:33:18 +00:00
|
|
|
for (SmallVectorImpl<LSRFixup>::const_iterator I = Fixups.begin(),
|
|
|
|
E = Fixups.end(); I != E; ++I) {
|
|
|
|
const LSRFixup &Fixup = *I;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2010-05-20 20:33:18 +00:00
|
|
|
Rewrite(Fixup, *Solution[Fixup.LUIdx], Rewriter, DeadInsts, P);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
Changed = true;
|
|
|
|
}
|
|
|
|
|
2012-01-09 21:18:52 +00:00
|
|
|
for (SmallVectorImpl<IVChain>::const_iterator ChainI = IVChainVec.begin(),
|
|
|
|
ChainE = IVChainVec.end(); ChainI != ChainE; ++ChainI) {
|
|
|
|
GenerateIVChain(*ChainI, Rewriter, DeadInsts);
|
|
|
|
Changed = true;
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
// Clean up after ourselves. This must be done before deleting any
|
|
|
|
// instructions.
|
|
|
|
Rewriter.clear();
|
2009-03-09 20:46:50 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
Changed |= DeleteTriviallyDeadInstructions(DeadInsts);
|
|
|
|
}
|
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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
LSRInstance::LSRInstance(const TargetLowering *tli, Loop *l, Pass *P)
|
|
|
|
: IU(P->getAnalysis<IVUsers>()),
|
|
|
|
SE(P->getAnalysis<ScalarEvolution>()),
|
|
|
|
DT(P->getAnalysis<DominatorTree>()),
|
2010-04-09 22:07:05 +00:00
|
|
|
LI(P->getAnalysis<LoopInfo>()),
|
2010-02-12 10:34:29 +00:00
|
|
|
TLI(tli), L(l), Changed(false), IVIncInsertPos(0) {
|
2009-05-11 22:33:01 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// If LoopSimplify form is not available, stay out of trouble.
|
2012-01-07 03:16:50 +00:00
|
|
|
if (!L->isLoopSimplifyForm())
|
|
|
|
return;
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2012-01-17 06:45:52 +00:00
|
|
|
// All dominating loops must have preheaders, or SCEVExpander may not be able
|
|
|
|
// to materialize an AddRecExpr whose Start is an outer AddRecExpr.
|
|
|
|
//
|
|
|
|
// FIXME: This is a little absurd. I think LoopSimplify should be taught
|
|
|
|
// to create a preheader under any circumstance.
|
|
|
|
for (DomTreeNode *Rung = DT.getNode(L->getLoopPreheader());
|
|
|
|
Rung; Rung = Rung->getIDom()) {
|
|
|
|
BasicBlock *BB = Rung->getBlock();
|
|
|
|
const Loop *DomLoop = LI.getLoopFor(BB);
|
|
|
|
if (DomLoop && DomLoop->getHeader() == BB) {
|
|
|
|
if (!DomLoop->getLoopPreheader())
|
|
|
|
return;
|
|
|
|
}
|
2012-01-07 03:16:50 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
// If there's no interesting work to be done, bail early.
|
|
|
|
if (IU.empty()) return;
|
|
|
|
|
|
|
|
DEBUG(dbgs() << "\nLSR on loop ";
|
|
|
|
WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false);
|
|
|
|
dbgs() << ":\n");
|
|
|
|
|
2010-05-20 20:33:18 +00:00
|
|
|
// First, perform some low-level loop optimizations.
|
2010-02-12 10:34:29 +00:00
|
|
|
OptimizeShadowIV();
|
2010-05-20 20:05:31 +00:00
|
|
|
OptimizeLoopTermCond();
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2011-07-21 00:40:04 +00:00
|
|
|
// If loop preparation eliminates all interesting IV users, bail.
|
|
|
|
if (IU.empty()) return;
|
|
|
|
|
2011-09-29 01:53:08 +00:00
|
|
|
// Skip nested loops until we can model them better with formulae.
|
2011-09-29 01:33:38 +00:00
|
|
|
if (!EnableNested && !L->empty()) {
|
|
|
|
DEBUG(dbgs() << "LSR skipping outer loop " << *L << "\n");
|
2011-09-29 01:53:08 +00:00
|
|
|
return;
|
2011-09-29 01:33:38 +00:00
|
|
|
}
|
|
|
|
|
2010-05-20 20:33:18 +00:00
|
|
|
// Start collecting data and preparing for the solver.
|
2012-01-09 19:50:34 +00:00
|
|
|
CollectChains();
|
2010-02-12 10:34:29 +00:00
|
|
|
CollectInterestingTypesAndFactors();
|
|
|
|
CollectFixupsAndInitialFormulae();
|
|
|
|
CollectLoopInvariantFixupsAndFormulae();
|
|
|
|
|
2012-01-09 21:18:52 +00:00
|
|
|
assert(!Uses.empty() && "IVUsers reported at least one use");
|
2010-02-12 10:34:29 +00:00
|
|
|
DEBUG(dbgs() << "LSR found " << Uses.size() << " uses:\n";
|
|
|
|
print_uses(dbgs()));
|
|
|
|
|
|
|
|
// Now use the reuse data to generate a bunch of interesting ways
|
|
|
|
// to formulate the values needed for the uses.
|
|
|
|
GenerateAllReuseFormulae();
|
|
|
|
|
|
|
|
FilterOutUndesirableDedicatedRegisters();
|
|
|
|
NarrowSearchSpaceUsingHeuristics();
|
|
|
|
|
|
|
|
SmallVector<const Formula *, 8> Solution;
|
|
|
|
Solve(Solution);
|
|
|
|
|
|
|
|
// Release memory that is no longer needed.
|
|
|
|
Factors.clear();
|
|
|
|
Types.clear();
|
|
|
|
RegUses.clear();
|
|
|
|
|
2011-09-27 00:44:14 +00:00
|
|
|
if (Solution.empty())
|
|
|
|
return;
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
// Formulae should be legal.
|
|
|
|
for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
|
|
|
|
E = Uses.end(); I != E; ++I) {
|
|
|
|
const LSRUse &LU = *I;
|
|
|
|
for (SmallVectorImpl<Formula>::const_iterator J = LU.Formulae.begin(),
|
|
|
|
JE = LU.Formulae.end(); J != JE; ++J)
|
|
|
|
assert(isLegalUse(J->AM, LU.MinOffset, LU.MaxOffset,
|
|
|
|
LU.Kind, LU.AccessTy, TLI) &&
|
|
|
|
"Illegal formula generated!");
|
|
|
|
};
|
|
|
|
#endif
|
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
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
// Now that we've decided what we want, make it so.
|
|
|
|
ImplementSolution(Solution, P);
|
|
|
|
}
|
2005-07-30 00:15:07 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::print_factors_and_types(raw_ostream &OS) const {
|
|
|
|
if (Factors.empty() && Types.empty()) return;
|
2008-07-07 19:51:32 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << "LSR has identified the following interesting factors and types: ";
|
|
|
|
bool First = true;
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
for (SmallSetVector<int64_t, 8>::const_iterator
|
|
|
|
I = Factors.begin(), E = Factors.end(); I != E; ++I) {
|
|
|
|
if (!First) OS << ", ";
|
|
|
|
First = false;
|
|
|
|
OS << '*' << *I;
|
|
|
|
}
|
2010-01-21 22:42:49 +00:00
|
|
|
|
2011-07-18 04:54:35 +00:00
|
|
|
for (SmallSetVector<Type *, 4>::const_iterator
|
2010-02-12 10:34:29 +00:00
|
|
|
I = Types.begin(), E = Types.end(); I != E; ++I) {
|
|
|
|
if (!First) OS << ", ";
|
|
|
|
First = false;
|
|
|
|
OS << '(' << **I << ')';
|
|
|
|
}
|
|
|
|
OS << '\n';
|
|
|
|
}
|
2009-05-11 17:15:42 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::print_fixups(raw_ostream &OS) const {
|
|
|
|
OS << "LSR is examining the following fixup sites:\n";
|
|
|
|
for (SmallVectorImpl<LSRFixup>::const_iterator I = Fixups.begin(),
|
|
|
|
E = Fixups.end(); I != E; ++I) {
|
|
|
|
dbgs() << " ";
|
2010-05-20 22:25:20 +00:00
|
|
|
I->print(OS);
|
2010-02-12 10:34:29 +00:00
|
|
|
OS << '\n';
|
|
|
|
}
|
|
|
|
}
|
2008-05-21 00:54:12 +00:00
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
void LSRInstance::print_uses(raw_ostream &OS) const {
|
|
|
|
OS << "LSR is examining the following uses:\n";
|
|
|
|
for (SmallVectorImpl<LSRUse>::const_iterator I = Uses.begin(),
|
|
|
|
E = Uses.end(); I != E; ++I) {
|
|
|
|
const LSRUse &LU = *I;
|
|
|
|
dbgs() << " ";
|
|
|
|
LU.print(OS);
|
|
|
|
OS << '\n';
|
|
|
|
for (SmallVectorImpl<Formula>::const_iterator J = LU.Formulae.begin(),
|
|
|
|
JE = LU.Formulae.end(); J != JE; ++J) {
|
|
|
|
OS << " ";
|
|
|
|
J->print(OS);
|
|
|
|
OS << '\n';
|
|
|
|
}
|
2009-12-18 00:06:20 +00:00
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LSRInstance::print(raw_ostream &OS) const {
|
|
|
|
print_factors_and_types(OS);
|
|
|
|
print_fixups(OS);
|
|
|
|
print_uses(OS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LSRInstance::dump() const {
|
|
|
|
print(errs()); errs() << '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class LoopStrengthReduce : public LoopPass {
|
|
|
|
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
|
|
|
/// transformation profitability.
|
|
|
|
const TargetLowering *const TLI;
|
|
|
|
|
|
|
|
public:
|
|
|
|
static char ID; // Pass ID, replacement for typeid
|
|
|
|
explicit LoopStrengthReduce(const TargetLowering *tli = 0);
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool runOnLoop(Loop *L, LPPassManager &LPM);
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
char LoopStrengthReduce::ID = 0;
|
2010-10-12 19:48:12 +00:00
|
|
|
INITIALIZE_PASS_BEGIN(LoopStrengthReduce, "loop-reduce",
|
2010-10-07 22:25:06 +00:00
|
|
|
"Loop Strength Reduction", false, false)
|
2010-10-12 19:48:12 +00:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
|
|
|
|
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
|
|
|
|
INITIALIZE_PASS_DEPENDENCY(IVUsers)
|
2010-10-19 20:08:44 +00:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
|
|
|
|
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
2010-10-12 19:48:12 +00:00
|
|
|
INITIALIZE_PASS_END(LoopStrengthReduce, "loop-reduce",
|
|
|
|
"Loop Strength Reduction", false, false)
|
|
|
|
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
Pass *llvm::createLoopStrengthReducePass(const TargetLowering *TLI) {
|
|
|
|
return new LoopStrengthReduce(TLI);
|
|
|
|
}
|
|
|
|
|
|
|
|
LoopStrengthReduce::LoopStrengthReduce(const TargetLowering *tli)
|
2010-10-19 17:21:58 +00:00
|
|
|
: LoopPass(ID), TLI(tli) {
|
|
|
|
initializeLoopStrengthReducePass(*PassRegistry::getPassRegistry());
|
|
|
|
}
|
2010-02-12 10:34:29 +00:00
|
|
|
|
|
|
|
void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
|
|
// We split critical edges, so we change the CFG. However, we do update
|
|
|
|
// many analyses if they are around.
|
2011-02-10 01:48:24 +00:00
|
|
|
AU.addPreservedID(LoopSimplifyID);
|
2010-02-12 10:34:29 +00:00
|
|
|
|
2011-02-10 01:48:24 +00:00
|
|
|
AU.addRequired<LoopInfo>();
|
|
|
|
AU.addPreserved<LoopInfo>();
|
|
|
|
AU.addRequiredID(LoopSimplifyID);
|
2010-02-12 10:34:29 +00:00
|
|
|
AU.addRequired<DominatorTree>();
|
|
|
|
AU.addPreserved<DominatorTree>();
|
|
|
|
AU.addRequired<ScalarEvolution>();
|
|
|
|
AU.addPreserved<ScalarEvolution>();
|
2011-02-10 23:53:14 +00:00
|
|
|
// Requiring LoopSimplify a second time here prevents IVUsers from running
|
|
|
|
// twice, since LoopSimplify was invalidated by running ScalarEvolution.
|
|
|
|
AU.addRequiredID(LoopSimplifyID);
|
2010-02-12 10:34:29 +00:00
|
|
|
AU.addRequired<IVUsers>();
|
|
|
|
AU.addPreserved<IVUsers>();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & /*LPM*/) {
|
|
|
|
bool Changed = false;
|
|
|
|
|
|
|
|
// Run the main LSR transformation.
|
|
|
|
Changed |= LSRInstance(TLI, L, this).getChanged();
|
2004-10-18 21:08:22 +00:00
|
|
|
|
2012-01-07 01:36:44 +00:00
|
|
|
// Remove any extra phis created by processing inner loops.
|
2010-01-05 16:31:45 +00:00
|
|
|
Changed |= DeleteDeadPHIs(L->getHeader());
|
2012-01-07 01:36:44 +00:00
|
|
|
if (EnablePhiElim) {
|
|
|
|
SmallVector<WeakVH, 16> DeadInsts;
|
|
|
|
SCEVExpander Rewriter(getAnalysis<ScalarEvolution>(), "lsr");
|
|
|
|
#ifndef NDEBUG
|
|
|
|
Rewriter.setDebugType(DEBUG_TYPE);
|
|
|
|
#endif
|
|
|
|
unsigned numFolded = Rewriter.
|
|
|
|
replaceCongruentIVs(L, &getAnalysis<DominatorTree>(), DeadInsts, TLI);
|
|
|
|
if (numFolded) {
|
|
|
|
Changed = true;
|
|
|
|
DeleteTriviallyDeadInstructions(DeadInsts);
|
|
|
|
DeleteDeadPHIs(L->getHeader());
|
|
|
|
}
|
|
|
|
}
|
2008-07-07 19:51:32 +00:00
|
|
|
return Changed;
|
2004-10-18 21:08:22 +00:00
|
|
|
}
|