[llvm-commits] [llvm] r60374 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll
Dale Johannesen
dalej at apple.com
Mon Dec 1 14:00:02 PST 2008
Author: johannes
Date: Mon Dec 1 16:00:01 2008
New Revision: 60374
URL: http://llvm.org/viewvc/llvm-project?rev=60374&view=rev
Log:
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).
Added:
llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=60374&r1=60373&r2=60374&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Dec 1 16:00:01 2008
@@ -643,7 +643,9 @@
// 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 @@
/// (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 @@
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 @@
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 @@
// 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 @@
// "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 @@
// 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);
Added: llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll?rev=60374&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2008-12-01-loop-iv-used-outside-loop.ll Mon Dec 1 16:00:01 2008
@@ -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
+}
More information about the llvm-commits
mailing list