[llvm] r242011 - [LSR] don't attempt to promote ephemeral values to indvars
Jingyue Wu
jingyue at google.com
Sun Jul 12 20:28:53 PDT 2015
Author: jingyue
Date: Sun Jul 12 22:28:53 2015
New Revision: 242011
URL: http://llvm.org/viewvc/llvm-project?rev=242011&view=rev
Log:
[LSR] don't attempt to promote ephemeral values to indvars
Summary:
This at least saves compile time. I also encountered a case where
ephemeral values affect whether other variables are promoted, causing
performance issues. It may be a bug in LSR, but I didn't manage to
reduce it yet. Anyhow, I believe it's in general not worth considering
ephemeral values in LSR.
Reviewers: atrick, hfinkel
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D11115
Added:
llvm/trunk/test/Transforms/LoopStrengthReduce/ephemeral.ll
Modified:
llvm/trunk/include/llvm/Analysis/IVUsers.h
llvm/trunk/lib/Analysis/IVUsers.cpp
Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IVUsers.h?rev=242011&r1=242010&r2=242011&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/IVUsers.h (original)
+++ llvm/trunk/include/llvm/Analysis/IVUsers.h Sun Jul 12 22:28:53 2015
@@ -21,6 +21,7 @@
namespace llvm {
+class AssumptionCache;
class DominatorTree;
class Instruction;
class Value;
@@ -119,15 +120,19 @@ private:
class IVUsers : public LoopPass {
friend class IVStrideUse;
Loop *L;
+ AssumptionCache *AC;
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- SmallPtrSet<Instruction*,16> Processed;
+ SmallPtrSet<Instruction*, 16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
ilist<IVStrideUse> IVUses;
+ // Ephemeral values used by @llvm.assume in this function.
+ SmallPtrSet<const Value *, 32> EphValues;
+
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
Modified: llvm/trunk/lib/Analysis/IVUsers.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IVUsers.cpp?rev=242011&r1=242010&r2=242011&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/IVUsers.cpp (original)
+++ llvm/trunk/lib/Analysis/IVUsers.cpp Sun Jul 12 22:28:53 2015
@@ -12,8 +12,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/IVUsers.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/CodeMetrics.h"
+#include "llvm/Analysis/IVUsers.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -34,6 +36,7 @@ using namespace llvm;
char IVUsers::ID = 0;
INITIALIZE_PASS_BEGIN(IVUsers, "iv-users",
"Induction Variable Users", false, true)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
@@ -137,6 +140,11 @@ bool IVUsers::AddUsersImpl(Instruction *
if (Width > 64 || !DL.isLegalInteger(Width))
return false;
+ // Don't attempt to promote ephemeral values to indvars. They will be removed
+ // later anyway.
+ if (EphValues.count(I))
+ return false;
+
// Get the symbolic expression for this instruction.
const SCEV *ISE = SE->getSCEV(I);
@@ -244,6 +252,7 @@ IVUsers::IVUsers()
}
void IVUsers::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<ScalarEvolution>();
@@ -253,10 +262,16 @@ void IVUsers::getAnalysisUsage(AnalysisU
bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
L = l;
+ AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
+ *L->getHeader()->getParent());
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
SE = &getAnalysis<ScalarEvolution>();
+ // Collect ephemeral values so that AddUsersIfInteresting skips them.
+ EphValues.clear();
+ CodeMetrics::collectEphemeralValues(L, AC, EphValues);
+
// Find all uses of induction variables in this loop, and categorize
// them by stride. Start by finding all of the PHI nodes in the header for
// this loop. If they are induction variables, inspect their uses.
Added: llvm/trunk/test/Transforms/LoopStrengthReduce/ephemeral.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/ephemeral.ll?rev=242011&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopStrengthReduce/ephemeral.ll (added)
+++ llvm/trunk/test/Transforms/LoopStrengthReduce/ephemeral.ll Sun Jul 12 22:28:53 2015
@@ -0,0 +1,41 @@
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+
+target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
+
+; for (int i = 0; i < n; ++i) {
+; use(i * 5 + 3);
+; // i * a + b is ephemeral and shouldn't be promoted by LSR
+; __builtin_assume(i * a + b >= 0);
+; }
+define void @ephemeral(i32 %a, i32 %b, i32 %n) {
+; CHECK-LABEL: @ephemeral(
+entry:
+ br label %loop
+
+loop:
+ %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
+ ; Only i and i * 5 + 3 should be indvars, not i * a + b.
+; CHECK: phi i32
+; CHECK: phi i32
+; CHECK-NOT: phi i32
+ %inc = add nsw i32 %i, 1
+ %exitcond = icmp eq i32 %inc, %n
+
+ %0 = mul nsw i32 %i, 5
+ %1 = add nsw i32 %0, 3
+ call void @use(i32 %1)
+
+ %2 = mul nsw i32 %i, %a
+ %3 = add nsw i32 %2, %b
+ %4 = icmp sgt i32 %3, -1
+ call void @llvm.assume(i1 %4)
+
+ br i1 %exitcond, label %exit, label %loop
+
+exit:
+ ret void
+}
+
+declare void @use(i32)
+
+declare void @llvm.assume(i1)
More information about the llvm-commits
mailing list