forked from OSchip/llvm-project
Consider only references to an IV within the loop when
figuring out the base of the IV. This produces better code in the example. (Addresses use (IV) instead of (BASE,IV) - a significant improvement on low-register machines like x86). llvm-svn: 60374
This commit is contained in:
parent
90abb6dead
commit
069a4eee55
|
@ -643,7 +643,9 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
|||
// cases (e.g. use of a post-incremented induction variable) the NewBase
|
||||
// value will be pinned to live somewhere after the original computation.
|
||||
// In this case, we have to back off.
|
||||
if (!isUseOfPostIncrementedValue) {
|
||||
// However, do not insert new code inside the loop when the reference
|
||||
// is outside.
|
||||
if (!isUseOfPostIncrementedValue && L->contains(Inst->getParent())) {
|
||||
if (NewBasePt && isa<PHINode>(OperandValToReplace)) {
|
||||
InsertPt = NewBasePt;
|
||||
++InsertPt;
|
||||
|
@ -921,14 +923,16 @@ static void SeparateSubExprs(std::vector<SCEVHandle> &SubExprs,
|
|||
/// (a+c+d) -> (a+c). The common expression is *removed* from the Bases.
|
||||
static SCEVHandle
|
||||
RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||
ScalarEvolution *SE) {
|
||||
ScalarEvolution *SE, Loop *L) {
|
||||
unsigned NumUses = Uses.size();
|
||||
|
||||
// Only one use? Use its base, regardless of what it is!
|
||||
// Only one use? If inside the loop, use its base, regardless of what it is;
|
||||
// if outside, use 0.
|
||||
SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
|
||||
SCEVHandle Result = Zero;
|
||||
if (NumUses == 1) {
|
||||
std::swap(Result, Uses[0].Base);
|
||||
if (L->contains(Uses[0].Inst->getParent()))
|
||||
std::swap(Result, Uses[0].Base);
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -941,7 +945,13 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
|||
std::vector<SCEVHandle> UniqueSubExprs;
|
||||
|
||||
std::vector<SCEVHandle> SubExprs;
|
||||
uint64_t NumUsesInsideLoop = 0;
|
||||
for (unsigned i = 0; i != NumUses; ++i) {
|
||||
// For this purpose, consider only uses that are inside the loop.
|
||||
if (!L->contains(Uses[i].Inst->getParent()))
|
||||
continue;
|
||||
NumUsesInsideLoop++;
|
||||
|
||||
// If the base is zero (which is common), return zero now, there are no
|
||||
// CSEs we can find.
|
||||
if (Uses[i].Base == Zero) return Zero;
|
||||
|
@ -961,7 +971,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
|||
std::map<SCEVHandle, unsigned>::iterator I =
|
||||
SubExpressionUseCounts.find(UniqueSubExprs[i]);
|
||||
assert(I != SubExpressionUseCounts.end() && "Entry not found?");
|
||||
if (I->second == NumUses) { // Found CSE!
|
||||
if (I->second == NumUsesInsideLoop) { // Found CSE!
|
||||
Result = SE->getAddExpr(Result, I->first);
|
||||
} else {
|
||||
// Remove non-cse's from SubExpressionUseCounts.
|
||||
|
@ -974,6 +984,10 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
|||
|
||||
// Otherwise, remove all of the CSE's we found from each of the base values.
|
||||
for (unsigned i = 0; i != NumUses; ++i) {
|
||||
// For this purpose, consider only uses that are inside the loop.
|
||||
if (!L->contains(Uses[i].Inst->getParent()))
|
||||
continue;
|
||||
|
||||
// Split the expression into subexprs.
|
||||
SeparateSubExprs(SubExprs, Uses[i].Base, SE);
|
||||
|
||||
|
@ -1166,7 +1180,7 @@ SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
|||
// "A+B"), emit it to the preheader, then remove the expression from the
|
||||
// UsersToProcess base values.
|
||||
SCEVHandle CommonExprs =
|
||||
RemoveCommonExpressionsFromUseBases(UsersToProcess, SE);
|
||||
RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L);
|
||||
|
||||
// Next, figure out what we can represent in the immediate fields of
|
||||
// instructions. If we can represent anything there, move it to the imm
|
||||
|
@ -1450,6 +1464,12 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
|||
// Add BaseV to the PHI value if needed.
|
||||
RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV));
|
||||
|
||||
// If this reference is not in the loop and we have a Common base,
|
||||
// that has been added into the induction variable and must be
|
||||
// subtracted off here.
|
||||
if (HaveCommonExprs && !L->contains(User.Inst->getParent()))
|
||||
RewriteExpr = SE->getMinusSCEV(RewriteExpr, CommonExprs);
|
||||
|
||||
User.RewriteInstructionToUseNewBase(RewriteExpr, NewBasePt,
|
||||
Rewriter, L, this,
|
||||
DeadInsts);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | grep -v lea
|
||||
; ModuleID = '<stdin>'
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i386-apple-darwin9.5"
|
||||
|
||||
define i8* @test(i8* %Q, i32* %L) nounwind {
|
||||
entry:
|
||||
br label %bb1
|
||||
|
||||
bb: ; preds = %bb1, %bb1
|
||||
%indvar.next = add i32 %P.0.rec, 1 ; <i32> [#uses=1]
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb, %entry
|
||||
%P.0.rec = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=3]
|
||||
%P.0 = getelementptr i8* %Q, i32 %P.0.rec ; <i8*> [#uses=2]
|
||||
%0 = load i8* %P.0, align 1 ; <i8> [#uses=1]
|
||||
switch i8 %0, label %bb3 [
|
||||
i8 12, label %bb
|
||||
i8 42, label %bb
|
||||
]
|
||||
|
||||
bb3: ; preds = %bb1
|
||||
%P.0.sum = add i32 %P.0.rec, 2 ; <i32> [#uses=1]
|
||||
%1 = getelementptr i8* %Q, i32 %P.0.sum ; <i8*> [#uses=1]
|
||||
store i8 4, i8* %1, align 1
|
||||
ret i8* %P.0
|
||||
}
|
Loading…
Reference in New Issue