forked from OSchip/llvm-project
[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 llvm-svn: 242011
This commit is contained in:
parent
8dadce78ed
commit
9a92d4fb04
|
@ -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;
|
||||
|
|
|
@ -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 *I,
|
|||
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(AnalysisUsage &AU) const {
|
|||
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.
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue