[llvm-commits] [llvm] r147935 - in /llvm/trunk: lib/Transforms/Scalar/LoopUnswitch.cpp test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll
Chad Rosier
mcrosier at apple.com
Mon Jan 16 12:05:26 PST 2012
Hi Stepan,
See comment below.
On Jan 11, 2012, at 12:40 AM, Stepan Dyatkovskiy wrote:
> Author: dyatkovskiy
> Date: Wed Jan 11 02:40:51 2012
> New Revision: 147935
>
> URL: http://llvm.org/viewvc/llvm-project?rev=147935&view=rev
> Log:
> Improved compile time:
> 1. Size heuristics changed. Now we calculate number of unswitching
> branches only once per loop.
> 2. Some checks was moved from UnswitchIfProfitable to
> processCurrentLoop, since it is not changed during processCurrentLoop
> iteration. It allows decide to skip some loops at an early stage.
> Extended statistics:
> - Added total number of instructions analyzed.
>
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> llvm/trunk/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=147935&r1=147934&r2=147935&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Wed Jan 11 02:40:51 2012
> @@ -56,12 +56,13 @@
> STATISTIC(NumSelects , "Number of selects unswitched");
> STATISTIC(NumTrivial , "Number of unswitches that are trivial");
> STATISTIC(NumSimplify, "Number of simplifications of unswitched code");
> +STATISTIC(TotalInsts, "Total number of instructions analyzed");
>
> // The specific value of 50 here was chosen based only on intuition and a
> // few specific examples.
> static cl::opt<unsigned>
> Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"),
> - cl::init(50), cl::Hidden);
> + cl::init(100), cl::Hidden);
Was the default value changed from 50 to 100 on purpose? If so, please update the comment. Otherwise, please change back to 50.
Chad
> namespace {
> class LoopUnswitch : public LoopPass {
> @@ -72,6 +73,18 @@
> // after RewriteLoopBodyWithConditionConstant rewrites first loop.
> std::vector<Loop*> LoopProcessWorklist;
>
> + struct LoopProperties {
> + unsigned CanBeUnswitchedCount;
> + unsigned SizeEstimation;
> + };
> +
> + typedef DenseMap<const Loop*, LoopProperties> LoopPropsMap;
> + typedef LoopPropsMap::iterator LoopPropsMapIt;
> + LoopPropsMap LoopsProperties;
> +
> + // Max size of code we can produce on remained iterations.
> + unsigned MaxSize;
> +
> // FIXME: Consider custom class for this.
> std::map<const SwitchInst*, SmallPtrSet<const Value *,8> > UnswitchedVals;
>
> @@ -93,7 +106,7 @@
> public:
> static char ID; // Pass ID, replacement for typeid
> explicit LoopUnswitch(bool Os = false) :
> - LoopPass(ID), OptimizeForSize(Os), redoLoop(false),
> + LoopPass(ID), MaxSize(Threshold), OptimizeForSize(Os), redoLoop(false),
> currentLoop(NULL), DT(NULL), loopHeader(NULL),
> loopPreheader(NULL) {
> initializeLoopUnswitchPass(*PassRegistry::getPassRegistry());
> @@ -119,6 +132,15 @@
> private:
>
> virtual void releaseMemory() {
> +
> + LoopPropsMapIt LIt = LoopsProperties.find(currentLoop);
> +
> + if (LIt != LoopsProperties.end()) {
> + LoopProperties& Props = LIt->second;
> + MaxSize += Props.CanBeUnswitchedCount * Props.SizeEstimation;
> + LoopsProperties.erase(LIt);
> + }
> +
> // We need to forget about all switches in the current loop.
> // FIXME: Do it better than enumerating all blocks of code
> // and see if it is a switch instruction.
> @@ -143,7 +165,10 @@
> /// already unswitched and has redundant successors.
> /// Note, that new loop data is stored inside the VMap.
> void CloneUnswitchedVals(const ValueToValueMapTy& VMap,
> - const BasicBlock* SrcBB);
> + const BasicBlock* SrcBB);
> +
> + bool CountLoop(const Loop* L);
> + void CloneLoopProperties(const Loop* NewLoop, const Loop* OldLoop);
>
> void initLoopData() {
> loopHeader = currentLoop->getHeader();
> @@ -193,6 +218,10 @@
> /// invariant in the loop, or has an invariant piece, return the invariant.
> /// Otherwise, return null.
> static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
> +
> + // We started analyze new instruction, increment scanned instructions counter.
> + ++TotalInsts;
> +
> // We can never unswitch on vector conditions.
> if (Cond->getType()->isVectorTy())
> return 0;
> @@ -246,7 +275,19 @@
> /// and profitable.
> bool LoopUnswitch::processCurrentLoop() {
> bool Changed = false;
> - LLVMContext &Context = currentLoop->getHeader()->getContext();
> +
> + initLoopData();
> +
> + // If LoopSimplify was unable to form a preheader, don't do any unswitching.
> + if (!loopPreheader)
> + return false;
> +
> + LLVMContext &Context = loopHeader->getContext();
> +
> + // Probably we reach the quota of branches for this loop. If so
> + // stop unswitching.
> + if (!CountLoop(currentLoop))
> + return false;
>
> // Loop over all of the basic blocks in the loop. If we find an interior
> // block that is branching on a loop-invariant condition, we can unswitch this
> @@ -332,6 +373,58 @@
> }
> }
>
> +bool LoopUnswitch::CountLoop(const Loop* L) {
> + std::pair<LoopPropsMapIt, bool> InsertRes =
> + LoopsProperties.insert(std::make_pair(L, LoopProperties()));
> +
> + LoopProperties& Props = InsertRes.first->second;
> +
> + if (InsertRes.second) {
> + // New loop.
> +
> + // 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.
> +
> + // 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 = L->block_begin(),
> + E = L->block_end();
> + I != E; ++I)
> + Metrics.analyzeBasicBlock(*I);
> +
> + Props.SizeEstimation = std::min(Metrics.NumInsts, Metrics.NumBlocks * 5);
> + Props.CanBeUnswitchedCount = MaxSize / (Props.SizeEstimation);
> + MaxSize -= Props.SizeEstimation * Props.CanBeUnswitchedCount;
> + }
> +
> + if (!Props.CanBeUnswitchedCount) {
> + DEBUG(dbgs() << "NOT unswitching loop %"
> + << L->getHeader()->getName() << ", cost too high: "
> + << L->getBlocks().size() << "\n");
> +
> + return false;
> + }
> + return true;
> +}
> +
> +void LoopUnswitch::CloneLoopProperties(
> + const Loop* NewLoop, const Loop* OldLoop) {
> +
> + LoopProperties& OldLoopProps = LoopsProperties[OldLoop];
> + LoopProperties& NewLoopProps = LoopsProperties[NewLoop];
> +
> + --OldLoopProps.CanBeUnswitchedCount;
> + unsigned Quota = OldLoopProps.CanBeUnswitchedCount;
> + NewLoopProps.CanBeUnswitchedCount = Quota / 2;
> + OldLoopProps.CanBeUnswitchedCount = Quota - Quota / 2;
> +
> + NewLoopProps.SizeEstimation = OldLoopProps.SizeEstimation;
> +}
> +
> /// isTrivialLoopExitBlock - Check to see if all paths from BB exit the
> /// loop with no side effects (including infinite loops).
> ///
> @@ -468,12 +561,6 @@
> /// unswitch the loop, reprocess the pieces, then return true.
> bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) {
>
> - initLoopData();
> -
> - // If LoopSimplify was unable to form a preheader, don't do any unswitching.
> - if (!loopPreheader)
> - return false;
> -
> Function *F = loopHeader->getParent();
>
> Constant *CondVal = 0;
> @@ -491,34 +578,6 @@
> if (OptimizeForSize || F->hasFnAttr(Attribute::OptimizeForSize))
> 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.
> -
> - unsigned NumUnswitched =
> - (NumSwitches + NumBranches) + 1 /*take in account current iteration*/;
> -
> - unsigned NumInsts = Metrics.NumInsts * NumUnswitched;
> - unsigned NumBlocks = Metrics.NumBlocks * NumUnswitched;
> -
> - if (NumInsts > Threshold || NumBlocks * 5 > Threshold ||
> - Metrics.containsIndirectBr || Metrics.isRecursive) {
> - DEBUG(dbgs() << "NOT unswitching loop %"
> - << currentLoop->getHeader()->getName() << ", cost too high: "
> - << currentLoop->getBlocks().size() << "\n");
> - return false;
> - }
> -
> UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
> return true;
> }
> @@ -701,6 +760,7 @@
>
> // Now we create the new Loop object for the versioned loop.
> Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM);
> + CloneLoopProperties(NewLoop, L);
> Loop *ParentLoop = L->getParentLoop();
> if (ParentLoop) {
> // Make sure to add the cloned preheader and exit blocks to the parent loop
>
> Modified: llvm/trunk/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll?rev=147935&r1=147934&r2=147935&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll (original)
> +++ llvm/trunk/test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll Wed Jan 11 02:40:51 2012
> @@ -1,5 +1,5 @@
> -; RUN: opt -loop-unswitch -loop-unswitch-threshold 30 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
> -; RUN: opt -S -loop-unswitch -loop-unswitch-threshold 30 -verify-loop-info -verify-dom-info %s | FileCheck %s
> +; RUN: opt -loop-unswitch -loop-unswitch-threshold 13 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
> +; RUN: opt -S -loop-unswitch -loop-unswitch-threshold 13 -verify-loop-info -verify-dom-info %s | FileCheck %s
>
> ; STATS: 1 loop-simplify - Number of pre-header or exit blocks inserted
> ; STATS: 1 loop-unswitch - Number of switches unswitched
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list