[llvm-commits] [llvm] r84661 - /llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
Dan Gohman
gohman at apple.com
Tue Oct 20 13:06:09 PDT 2009
Author: djg
Date: Tue Oct 20 15:06:09 2009
New Revision: 84661
URL: http://llvm.org/viewvc/llvm-project?rev=84661&view=rev
Log:
Restore LoopUnswitch's block-oriented threshold. LoopUnswitch now checks both
the estimated code size and the number of blocks when deciding whether to
do a non-trivial unswitch. This protects it from some very undesirable
worst-case behavior on large numbers of loop-unswitchable conditions, such
as in the testcase in PR5259.
Modified:
llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=84661&r1=84660&r2=84661&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Tue Oct 20 15:06:09 2009
@@ -138,7 +138,6 @@
void SplitExitEdges(Loop *L, const SmallVector<BasicBlock *, 8> &ExitBlocks);
bool UnswitchIfProfitable(Value *LoopCond, Constant *Val);
- unsigned getLoopUnswitchCost(Value *LIC);
void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
BasicBlock *ExitBlock);
void UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L);
@@ -400,25 +399,6 @@
return true;
}
-/// getLoopUnswitchCost - Return the cost (code size growth) that will happen if
-/// we choose to unswitch current loop on the specified value.
-///
-unsigned LoopUnswitch::getLoopUnswitchCost(Value *LIC) {
- // If the condition is trivial, always unswitch. There is no code growth for
- // this case.
- if (IsTrivialUnswitchCondition(LIC))
- return 0;
-
- // FIXME: This is overly conservative because it does not take into
- // consideration code simplification opportunities.
- CodeMetrics Metrics;
- for (Loop::block_iterator I = currentLoop->block_begin(),
- E = currentLoop->block_end();
- I != E; ++I)
- Metrics.analyzeBasicBlock(*I);
- return Metrics.NumInsts;
-}
-
/// UnswitchIfProfitable - We have found that we can unswitch currentLoop when
/// LoopCond == Val to simplify the loop. If we decide that this is profitable,
/// unswitch the loop, reprocess the pieces, then return true.
@@ -427,24 +407,35 @@
initLoopData();
Function *F = loopHeader->getParent();
+ // If the condition is trivial, always unswitch. There is no code growth for
+ // this case.
+ if (!IsTrivialUnswitchCondition(LoopCond)) {
+ // Check to see if it would be profitable to unswitch current loop.
- // Check to see if it would be profitable to unswitch current loop.
- unsigned Cost = getLoopUnswitchCost(LoopCond);
+ // Do not do non-trivial unswitch while optimizing for size.
+ if (OptimizeForSize || F->hasFnAttr(Attribute::OptimizeForSize))
+ return false;
- // Do not do non-trivial unswitch while optimizing for size.
- if (Cost && OptimizeForSize)
- return false;
- if (Cost && !F->isDeclaration() && F->hasFnAttr(Attribute::OptimizeForSize))
- return false;
-
- if (Cost > Threshold) {
- // FIXME: this should estimate growth by the amount of code shared by the
- // resultant unswitched loops.
- //
- DEBUG(errs() << "NOT unswitching loop %"
- << currentLoop->getHeader()->getName() << ", cost too high: "
- << currentLoop->getBlocks().size() << "\n");
- return false;
+ // FIXME: This is overly conservative because it does not take into
+ // consideration code simplification opportunities and code that can
+ // be shared by the resultant unswitched loops.
+ CodeMetrics Metrics;
+ for (Loop::block_iterator I = currentLoop->block_begin(),
+ E = currentLoop->block_end();
+ I != E; ++I)
+ Metrics.analyzeBasicBlock(*I);
+
+ // Limit the number of instructions to avoid causing significant code
+ // expansion, and the number of basic blocks, to avoid loops with
+ // large numbers of branches which cause loop unswitching to go crazy.
+ // This is a very ad-hoc heuristic.
+ if (Metrics.NumInsts > Threshold ||
+ Metrics.NumBlocks * 5 > Threshold) {
+ DEBUG(errs() << "NOT unswitching loop %"
+ << currentLoop->getHeader()->getName() << ", cost too high: "
+ << currentLoop->getBlocks().size() << "\n");
+ return false;
+ }
}
Constant *CondVal;
More information about the llvm-commits
mailing list