[llvm-dev] CFG SCCs vs Loops and loop breaking transformations

Philip Reames via llvm-dev llvm-dev at lists.llvm.org
Wed Jan 20 08:35:51 PST 2016



On 01/19/2016 09:55 PM, Tobias Grosser wrote:
> On 01/19/2016 08:17 PM, Philip Reames via llvm-dev wrote:
>> I ran across an interesting case and wanted to share it.  I'm not
>> proposing any particular changes, but the experience seemed interesting
>> to discuss.
>>
>> First, a bit of background.  An LLVM Loop models a specific type of
>> cycle in the CFG.  Not all cycles are Loops.  Many of our optimization
>> transforms are phrased over loops, which means that a non-loop cycle
>> tends to be less well optimized.
>>
>> I had some initial IR that had a very complex, oddly written loop. After
>> running this through my pass order, I discovered that there was no
>> longer a Loop representing the loop.  One of the transforms -
>> SimplifyCFG is my guess, but I haven't confirmed - had taken something
>> representable as a Loop and converted into a non-Loop SCC.  This seems
>> unfortunate and raises a general issue with how we model and
>> canonicalize loops.
>>
>> Long term, I see a couple of options:
>> 1) Introduce a new notion for SCCs in the CFG, and rephrase select
>> optimizations like LICM over them.  A Loop then becomes a particular
>> special case of our more generic SCC concept.
>> 2) Avoid breaking loops until some point late in the optimizer.
>> Essentially, we designate the Loop representable form as being canonical
>> and then lower later.
>> 3) Introduce a SCC to Loop conversion pass which tries to take non-loop
>> SCCs and make them representable as Loops.  We probably don't want to go
>> full out here, but catching the "easy" cases might help a lot in
>> practice.  Running this at the start of each LoopPassManager pipeline
>> might be an option.  I was slightly surprised to notice we didn't
>> already have this.
>>
>> None of these seem great.  Anyone have another idea on how we could
>> approach this?
>
> Hi Philip,
>
> how did the loop look like? Could you provide an example? AFAIU LLVM 
> detects all natural loops (cycles with a single entry block that 
> dominates all basic blocks in the cycle). The only cycles that are not 
> natural loops should be irregular control flow. Is this the case for 
> your test case? Or do I miss something?
The particular test case ended up looking something like this:
loop:
   br i1 %c, label %left, label %right

left:
   ;; normal loop stuff here
   br label %left

right:
   ;; do something
   br %left

(Note that that's from memory and I may have gotten something slightly 
wrong.)

This could easily be converted into a natural loop nest.  I suspect most 
interesting cases could without falling back to the general solution 
which requires exponential code growth (if I remember correctly).
>
> I would be very surprised if a transformation introduces irregular 
> control flow and would like to understand why this would be needed. 
My best guess is either simplify-cfg or jump-threading.  The original 
example was written as a single natural loop, but effectively had 
another loop inside it.  It was using a "reset all variables to starting 
state and continue" idiom which I suspect one of our passes (correctly) 
eliminated entirely.
> I currently work on the assumption that irregular control flow is rare
> and likely not worth optimizing. 
I think this is still a reasonable assumption overall.
> If it is still performance relevant, I would probably just introduce 
> some code duplication to introduce
> proper natural loops.
This is definitely one option.  This was what I meant by my original 
option 3.
>
> Best,
> Tobias
>
>>
>> Philip
>>
>> p.s. Thankfully, the code I noticed this in is not performance sensitive
>> so I don't need a near term answer here.
>>
>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>



More information about the llvm-dev mailing list