[Unroll] Add an option to control complete unrolling

Add an ability to specify the max full unroll count for LoopUnrollPass pass
in pass options.

Reviewers: fhahn, fedor.sergeev
Reviewed By: fedor.sergeev
Subscribers: hiraditya, zzheng, dmgreen, llvm-commits
Differential Revision: https://reviews.llvm.org/D67701

llvm-svn: 372305
This commit is contained in:
Serguei Katkov 2019-09-19 06:57:29 +00:00
parent c2d25ed1b3
commit a44768858c
6 changed files with 72 additions and 10 deletions

View File

@ -63,6 +63,7 @@ struct LoopUnrollOptions {
Optional<bool> AllowRuntime; Optional<bool> AllowRuntime;
Optional<bool> AllowUpperBound; Optional<bool> AllowUpperBound;
Optional<bool> AllowProfileBasedPeeling; Optional<bool> AllowProfileBasedPeeling;
Optional<unsigned> FullUnrollMaxCount;
int OptLevel; int OptLevel;
/// If false, use a cost model to determine whether unrolling of a loop is /// If false, use a cost model to determine whether unrolling of a loop is
@ -117,6 +118,12 @@ struct LoopUnrollOptions {
AllowProfileBasedPeeling = O; AllowProfileBasedPeeling = O;
return *this; return *this;
} }
// Sets the max full unroll count.
LoopUnrollOptions &setFullUnrollMaxCount(unsigned O) {
FullUnrollMaxCount = O;
return *this;
}
}; };
/// Loop unroll pass that will support both full and partial unrolling. /// Loop unroll pass that will support both full and partial unrolling.

View File

@ -133,7 +133,8 @@ TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(
Optional<unsigned> UserThreshold, Optional<unsigned> UserCount, Optional<unsigned> UserThreshold, Optional<unsigned> UserCount,
Optional<bool> UserAllowPartial, Optional<bool> UserRuntime, Optional<bool> UserAllowPartial, Optional<bool> UserRuntime,
Optional<bool> UserUpperBound, Optional<bool> UserAllowPeeling, Optional<bool> UserUpperBound, Optional<bool> UserAllowPeeling,
Optional<bool> UserAllowProfileBasedPeeling); Optional<bool> UserAllowProfileBasedPeeling,
Optional<unsigned> UserFullUnrollMaxCount);
unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls, unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
bool &NotDuplicatable, bool &Convergent, bool &NotDuplicatable, bool &Convergent,

View File

@ -1460,6 +1460,15 @@ Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
UnrollOpts.setOptLevel(OptLevel); UnrollOpts.setOptLevel(OptLevel);
continue; continue;
} }
if (ParamName.consume_front("full-unroll-max=")) {
int Count;
if (ParamName.getAsInteger(0, Count))
return make_error<StringError>(
formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
inconvertibleErrorCode());
UnrollOpts.setFullUnrollMaxCount(Count);
continue;
}
bool Enable = !ParamName.consume_front("no-"); bool Enable = !ParamName.consume_front("no-");
if (ParamName == "partial") { if (ParamName == "partial") {

View File

@ -295,7 +295,7 @@ tryToUnrollAndJamLoop(Loop *L, DominatorTree &DT, LoopInfo *LI,
TargetTransformInfo::UnrollingPreferences UP = TargetTransformInfo::UnrollingPreferences UP =
gatherUnrollingPreferences(L, SE, TTI, nullptr, nullptr, OptLevel, None, gatherUnrollingPreferences(L, SE, TTI, nullptr, nullptr, OptLevel, None,
None, None, None, None, None, None); None, None, None, None, None, None, None);
if (AllowUnrollAndJam.getNumOccurrences() > 0) if (AllowUnrollAndJam.getNumOccurrences() > 0)
UP.UnrollAndJam = AllowUnrollAndJam; UP.UnrollAndJam = AllowUnrollAndJam;
if (UnrollAndJamThreshold.getNumOccurrences() > 0) if (UnrollAndJamThreshold.getNumOccurrences() > 0)

View File

@ -179,7 +179,8 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
Optional<unsigned> UserThreshold, Optional<unsigned> UserCount, Optional<unsigned> UserThreshold, Optional<unsigned> UserCount,
Optional<bool> UserAllowPartial, Optional<bool> UserRuntime, Optional<bool> UserAllowPartial, Optional<bool> UserRuntime,
Optional<bool> UserUpperBound, Optional<bool> UserAllowPeeling, Optional<bool> UserUpperBound, Optional<bool> UserAllowPeeling,
Optional<bool> UserAllowProfileBasedPeeling) { Optional<bool> UserAllowProfileBasedPeeling,
Optional<unsigned> UserFullUnrollMaxCount) {
TargetTransformInfo::UnrollingPreferences UP; TargetTransformInfo::UnrollingPreferences UP;
// Set up the defaults // Set up the defaults
@ -261,6 +262,8 @@ TargetTransformInfo::UnrollingPreferences llvm::gatherUnrollingPreferences(
UP.AllowPeeling = *UserAllowPeeling; UP.AllowPeeling = *UserAllowPeeling;
if (UserAllowProfileBasedPeeling.hasValue()) if (UserAllowProfileBasedPeeling.hasValue())
UP.PeelProfiledIterations = *UserAllowProfileBasedPeeling; UP.PeelProfiledIterations = *UserAllowProfileBasedPeeling;
if (UserFullUnrollMaxCount.hasValue())
UP.FullUnrollMaxCount = *UserFullUnrollMaxCount;
return UP; return UP;
} }
@ -986,7 +989,8 @@ static LoopUnrollResult tryToUnrollLoop(
Optional<unsigned> ProvidedThreshold, Optional<bool> ProvidedAllowPartial, Optional<unsigned> ProvidedThreshold, Optional<bool> ProvidedAllowPartial,
Optional<bool> ProvidedRuntime, Optional<bool> ProvidedUpperBound, Optional<bool> ProvidedRuntime, Optional<bool> ProvidedUpperBound,
Optional<bool> ProvidedAllowPeeling, Optional<bool> ProvidedAllowPeeling,
Optional<bool> ProvidedAllowProfileBasedPeeling) { Optional<bool> ProvidedAllowProfileBasedPeeling,
Optional<unsigned> ProvidedFullUnrollMaxCount) {
LLVM_DEBUG(dbgs() << "Loop Unroll: F[" LLVM_DEBUG(dbgs() << "Loop Unroll: F["
<< L->getHeader()->getParent()->getName() << "] Loop %" << L->getHeader()->getParent()->getName() << "] Loop %"
<< L->getHeader()->getName() << "\n"); << L->getHeader()->getName() << "\n");
@ -1011,7 +1015,8 @@ static LoopUnrollResult tryToUnrollLoop(
TargetTransformInfo::UnrollingPreferences UP = gatherUnrollingPreferences( TargetTransformInfo::UnrollingPreferences UP = gatherUnrollingPreferences(
L, SE, TTI, BFI, PSI, OptLevel, ProvidedThreshold, ProvidedCount, L, SE, TTI, BFI, PSI, OptLevel, ProvidedThreshold, ProvidedCount,
ProvidedAllowPartial, ProvidedRuntime, ProvidedUpperBound, ProvidedAllowPartial, ProvidedRuntime, ProvidedUpperBound,
ProvidedAllowPeeling, ProvidedAllowProfileBasedPeeling); ProvidedAllowPeeling, ProvidedAllowProfileBasedPeeling,
ProvidedFullUnrollMaxCount);
// Exit early if unrolling is disabled. For OptForSize, we pick the loop size // Exit early if unrolling is disabled. For OptForSize, we pick the loop size
// as threshold later on. // as threshold later on.
@ -1174,6 +1179,7 @@ public:
Optional<bool> ProvidedUpperBound; Optional<bool> ProvidedUpperBound;
Optional<bool> ProvidedAllowPeeling; Optional<bool> ProvidedAllowPeeling;
Optional<bool> ProvidedAllowProfileBasedPeeling; Optional<bool> ProvidedAllowProfileBasedPeeling;
Optional<unsigned> ProvidedFullUnrollMaxCount;
LoopUnroll(int OptLevel = 2, bool OnlyWhenForced = false, LoopUnroll(int OptLevel = 2, bool OnlyWhenForced = false,
bool ForgetAllSCEV = false, Optional<unsigned> Threshold = None, bool ForgetAllSCEV = false, Optional<unsigned> Threshold = None,
@ -1181,13 +1187,15 @@ public:
Optional<bool> AllowPartial = None, Optional<bool> Runtime = None, Optional<bool> AllowPartial = None, Optional<bool> Runtime = None,
Optional<bool> UpperBound = None, Optional<bool> UpperBound = None,
Optional<bool> AllowPeeling = None, Optional<bool> AllowPeeling = None,
Optional<bool> AllowProfileBasedPeeling = None) Optional<bool> AllowProfileBasedPeeling = None,
Optional<unsigned> ProvidedFullUnrollMaxCount = None)
: LoopPass(ID), OptLevel(OptLevel), OnlyWhenForced(OnlyWhenForced), : LoopPass(ID), OptLevel(OptLevel), OnlyWhenForced(OnlyWhenForced),
ForgetAllSCEV(ForgetAllSCEV), ProvidedCount(std::move(Count)), ForgetAllSCEV(ForgetAllSCEV), ProvidedCount(std::move(Count)),
ProvidedThreshold(Threshold), ProvidedAllowPartial(AllowPartial), ProvidedThreshold(Threshold), ProvidedAllowPartial(AllowPartial),
ProvidedRuntime(Runtime), ProvidedUpperBound(UpperBound), ProvidedRuntime(Runtime), ProvidedUpperBound(UpperBound),
ProvidedAllowPeeling(AllowPeeling), ProvidedAllowPeeling(AllowPeeling),
ProvidedAllowProfileBasedPeeling(AllowProfileBasedPeeling) { ProvidedAllowProfileBasedPeeling(AllowProfileBasedPeeling),
ProvidedFullUnrollMaxCount(ProvidedFullUnrollMaxCount) {
initializeLoopUnrollPass(*PassRegistry::getPassRegistry()); initializeLoopUnrollPass(*PassRegistry::getPassRegistry());
} }
@ -1213,7 +1221,8 @@ public:
L, DT, LI, SE, TTI, AC, ORE, nullptr, nullptr, PreserveLCSSA, OptLevel, L, DT, LI, SE, TTI, AC, ORE, nullptr, nullptr, PreserveLCSSA, OptLevel,
OnlyWhenForced, ForgetAllSCEV, ProvidedCount, ProvidedThreshold, OnlyWhenForced, ForgetAllSCEV, ProvidedCount, ProvidedThreshold,
ProvidedAllowPartial, ProvidedRuntime, ProvidedUpperBound, ProvidedAllowPartial, ProvidedRuntime, ProvidedUpperBound,
ProvidedAllowPeeling, ProvidedAllowProfileBasedPeeling); ProvidedAllowPeeling, ProvidedAllowProfileBasedPeeling,
ProvidedFullUnrollMaxCount);
if (Result == LoopUnrollResult::FullyUnrolled) if (Result == LoopUnrollResult::FullyUnrolled)
LPM.markLoopAsDeleted(*L); LPM.markLoopAsDeleted(*L);
@ -1297,7 +1306,8 @@ PreservedAnalyses LoopFullUnrollPass::run(Loop &L, LoopAnalysisManager &AM,
/*Threshold*/ None, /*AllowPartial*/ false, /*Threshold*/ None, /*AllowPartial*/ false,
/*Runtime*/ false, /*UpperBound*/ false, /*Runtime*/ false, /*UpperBound*/ false,
/*AllowPeeling*/ false, /*AllowPeeling*/ false,
/*AllowProfileBasedPeeling*/ false) != /*AllowProfileBasedPeeling*/ false,
/*FullUnrollMaxCount*/ None) !=
LoopUnrollResult::Unmodified; LoopUnrollResult::Unmodified;
if (!Changed) if (!Changed)
return PreservedAnalyses::all(); return PreservedAnalyses::all();
@ -1439,7 +1449,7 @@ PreservedAnalyses LoopUnrollPass::run(Function &F,
UnrollOpts.ForgetSCEV, /*Count*/ None, UnrollOpts.ForgetSCEV, /*Count*/ None,
/*Threshold*/ None, UnrollOpts.AllowPartial, UnrollOpts.AllowRuntime, /*Threshold*/ None, UnrollOpts.AllowPartial, UnrollOpts.AllowRuntime,
UnrollOpts.AllowUpperBound, LocalAllowPeeling, UnrollOpts.AllowUpperBound, LocalAllowPeeling,
UnrollOpts.AllowProfileBasedPeeling); UnrollOpts.AllowProfileBasedPeeling, UnrollOpts.FullUnrollMaxCount);
Changed |= Result != LoopUnrollResult::Unmodified; Changed |= Result != LoopUnrollResult::Unmodified;
// The parent must not be damaged by unrolling! // The parent must not be damaged by unrolling!

View File

@ -0,0 +1,35 @@
; Default behavior
; RUN: opt < %s -passes='unroll' -S | FileCheck %s -check-prefixes=ENABLE,COMMON
; Pass option
; RUN: opt < %s -passes='unroll<full-unroll-max=0>' -S | FileCheck %s -check-prefixes=DISABLE,COMMON
; RUN: opt < %s -passes='unroll<full-unroll-max=30>' -S | FileCheck %s -check-prefixes=DISABLE,COMMON
; RUN: opt < %s -passes='unroll<full-unroll-max=36>' -S | FileCheck %s -check-prefixes=ENABLE,COMMON
; cl::opt option
; RUN: opt < %s -passes='unroll' -unroll-full-max-count=0 -S | FileCheck %s -check-prefixes=DISABLE,COMMON
; RUN: opt < %s -passes='unroll' -unroll-full-max-count=30 -S | FileCheck %s -check-prefixes=DISABLE,COMMON
; RUN: opt < %s -passes='unroll' -unroll-full-max-count=36 -S | FileCheck %s -check-prefixes=ENABLE,COMMON
; Pass option has a priority over cl::opt
; RUN: opt < %s -passes='unroll<full-unroll-max=30>' -unroll-full-max-count=36 -S | FileCheck %s -check-prefixes=DISABLE,COMMON
; RUN: opt < %s -passes='unroll<full-unroll-max=36>' -unroll-full-max-count=30 -S | FileCheck %s -check-prefixes=ENABLE,COMMON
define void @test() {
; COMMON-LABEL: @test(
entry:
br label %loop
loop:
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ]
%idx.inc = add i32 %idx, 1
%be = icmp slt i32 %idx, 32
br i1 %be, label %loop, label %exit
; COMMON: loop:
; DISABLE: %be = icmp slt i32 %idx, 32
; ENABLE-NOT: %be = icmp slt i32 %idx, 32
exit:
ret void
}