Add some additional fields to TTI::UnrollingPreferences

In preparation for an upcoming commit implementing unrolling preferences for
x86, this adds additional fields to the UnrollingPreferences structure:

 - PartialThreshold and PartialOptSizeThreshold - Like Threshold and
   OptSizeThreshold, but used when not fully unrolling. These are necessary
   because we need different thresholds for full unrolling from those used when
   partially unrolling (the full unrolling thresholds are generally going to be
   larger).

 - MaxCount - A cap on the unrolling factor when partially unrolling. This can
   be used by a target to prevent the unrolled loop from exceeding some
   resource limit independent of the loop size (such as number of branches).

There should be no functionality change for any in-tree targets.

llvm-svn: 205347
This commit is contained in:
Hal Finkel 2014-04-01 18:50:30 +00:00
parent b4e001cc81
commit 6386cb8d4d
2 changed files with 25 additions and 4 deletions

View File

@ -198,11 +198,23 @@ public:
/// The cost threshold for the unrolled loop when optimizing for size (set /// The cost threshold for the unrolled loop when optimizing for size (set
/// to UINT_MAX to disable). /// to UINT_MAX to disable).
unsigned OptSizeThreshold; unsigned OptSizeThreshold;
/// The cost threshold for the unrolled loop, like Threshold, but used
/// for partial/runtime unrolling (set to UINT_MAX to disable).
unsigned PartialThreshold;
/// The cost threshold for the unrolled loop when optimizing for size, like
/// OptSizeThreshold, but used for partial/runtime unrolling (set to UINT_MAX
/// to disable).
unsigned PartialOptSizeThreshold;
/// A forced unrolling factor (the number of concatenated bodies of the /// A forced unrolling factor (the number of concatenated bodies of the
/// original loop in the unrolled loop body). When set to 0, the unrolling /// original loop in the unrolled loop body). When set to 0, the unrolling
/// transformation will select an unrolling factor based on the current cost /// transformation will select an unrolling factor based on the current cost
/// threshold and other factors. /// threshold and other factors.
unsigned Count; unsigned Count;
// Set the maximum unrolling factor. The unrolling factor may be selected
// using the appropriate cost threshold, but may not exceed this number
// (set to UINT_MAX to disable). This does not apply in cases where the
// loop is being fully unrolled.
unsigned MaxCount;
/// Allow partial unrolling (unrolling of loops to expand the size of the /// Allow partial unrolling (unrolling of loops to expand the size of the
/// loop body, not only to eliminate small constant-trip-count loops). /// loop body, not only to eliminate small constant-trip-count loops).
bool Partial; bool Partial;

View File

@ -166,7 +166,10 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
TargetTransformInfo::UnrollingPreferences UP; TargetTransformInfo::UnrollingPreferences UP;
UP.Threshold = CurrentThreshold; UP.Threshold = CurrentThreshold;
UP.OptSizeThreshold = OptSizeUnrollThreshold; UP.OptSizeThreshold = OptSizeUnrollThreshold;
UP.PartialThreshold = CurrentThreshold;
UP.PartialOptSizeThreshold = OptSizeUnrollThreshold;
UP.Count = CurrentCount; UP.Count = CurrentCount;
UP.MaxCount = UINT_MAX;
UP.Partial = CurrentAllowPartial; UP.Partial = CurrentAllowPartial;
UP.Runtime = CurrentRuntime; UP.Runtime = CurrentRuntime;
TTI.getUnrollingPreferences(L, UP); TTI.getUnrollingPreferences(L, UP);
@ -176,11 +179,15 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
// function is marked as optimize-for-size, and the unroll threshold was // function is marked as optimize-for-size, and the unroll threshold was
// not user specified. // not user specified.
unsigned Threshold = UserThreshold ? CurrentThreshold : UP.Threshold; unsigned Threshold = UserThreshold ? CurrentThreshold : UP.Threshold;
unsigned PartialThreshold =
UserThreshold ? CurrentThreshold : UP.PartialThreshold;
if (!UserThreshold && if (!UserThreshold &&
Header->getParent()->getAttributes(). Header->getParent()->getAttributes().
hasAttribute(AttributeSet::FunctionIndex, hasAttribute(AttributeSet::FunctionIndex,
Attribute::OptimizeForSize)) Attribute::OptimizeForSize)) {
Threshold = UP.OptSizeThreshold; Threshold = UP.OptSizeThreshold;
PartialThreshold = UP.PartialOptSizeThreshold;
}
// Find trip count and trip multiple if count is not available // Find trip count and trip multiple if count is not available
unsigned TripCount = 0; unsigned TripCount = 0;
@ -214,7 +221,7 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
} }
// Enforce the threshold. // Enforce the threshold.
if (Threshold != NoThreshold) { if (Threshold != NoThreshold && PartialThreshold != NoThreshold) {
unsigned NumInlineCandidates; unsigned NumInlineCandidates;
bool notDuplicatable; bool notDuplicatable;
unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates, unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates,
@ -241,17 +248,19 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
} }
if (TripCount) { if (TripCount) {
// Reduce unroll count to be modulo of TripCount for partial unrolling // Reduce unroll count to be modulo of TripCount for partial unrolling
Count = Threshold / LoopSize; Count = PartialThreshold / LoopSize;
while (Count != 0 && TripCount%Count != 0) while (Count != 0 && TripCount%Count != 0)
Count--; Count--;
} }
else if (Runtime) { else if (Runtime) {
// Reduce unroll count to be a lower power-of-two value // Reduce unroll count to be a lower power-of-two value
while (Count != 0 && Size > Threshold) { while (Count != 0 && Size > PartialThreshold) {
Count >>= 1; Count >>= 1;
Size = LoopSize*Count; Size = LoopSize*Count;
} }
} }
if (Count > UP.MaxCount)
Count = UP.MaxCount;
if (Count < 2) { if (Count < 2) {
DEBUG(dbgs() << " could not unroll partially\n"); DEBUG(dbgs() << " could not unroll partially\n");
return false; return false;