[llvm-commits] [llvm] r147935 - in /llvm/trunk: lib/Transforms/Scalar/LoopUnswitch.cpp test/Transforms/LoopUnswitch/2011-11-18-TwoSwitches-Threshold.ll
Stepan Dyatkovskiy
STPWORLD at narod.ru
Mon Jan 16 12:52:30 PST 2012
Oh... Sorry. It was changed on purpose. 100 is approximately equals to 50 for previous implementation. Comment fixed in r148252.
--
Truly yours,
Stepan Dyatkovskiy
17.01.2012, 00:05, "Chad Rosier" <mcrosier at apple.com>:
> 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