[llvm-commits] patch: preserve branch to unreachable until codegenprep time

Török Edwin edwintorok at gmail.com
Mon Oct 19 00:38:01 PDT 2009


On 2009-10-19 07:47, Chris Lattner wrote:
> On Oct 18, 2009, at 10:11 AM, Dan Gohman wrote:
>
>   
>> On Oct 18, 2009, at 12:16 AM, Nick Lewycky <nicholas at mxc.ca> wrote:
>>
>>     
>>> This patch moves the code that optimizes "branch to unreachable"
>>> from SimplifyCFG to CodeGenPrep. Most of this patch is just updating
>>> the unit tests that use unreachable everywhere. I've done my best to
>>> preserve the intent of the tests.
>>>       
>> I haven't read the patch, but I'm concerned about this interfering
>> with other optimizations.  Deleting the condition can expose further
>> dce and related optimizations.  Also if the branch is a loop exit,
>> deleting it makes it easier to compute a trip count.
>>     
>
> I agree, but I still think this is a good idea.  :)
>
> LSR and other passes can special case this for trip count handling.   
> We can make simplifycfg delete the branch to unreachable if the  
> condition is "too complicated" to be useful for the optimizer.
>
> One area that does concern me is in the various code size evaluations  
> (inlining, jump threading, unswitch,  ...).  This feature will make  
> those completely wrong for code involved in these sorts of checks.
>
>   

How about splitting the SSA value (like SSI does), and attach some
information to it that say:
conditionX is known to be true when this is reached, or conditionX is
known to be false.
Or perhaps a new intrinsic, that is not a terminator, something like this:

...
call @bar(%i)
%conditionX = icmp ult, i32 %i, i32 %n
%conditionY = icmp ult i32 %j, i32 %n
br i1 %conditionY, %tru1, %fals1
%tru1:
br i1 %conditionX, %true, %false
%true:
    unreachable
%false:
  call @foo(%i)
  br %for.cond
%fals1:
  call @bar(%j)
. ..

--becomes-->
call @bar(%i)
%conditionX = icmp ult, i32 %i, i32 %n
%conditionY = icmp ult, i32 %j, i32 %n
br i1 %conditionY, %tru1, %fals1
%tru1:
llvm.assume(@conditionX, 1)
call @foo(%i)
br %for.cond
%fals1:
call @bar(%j)

You can then do all sorts of optimizations knowing that conditionX is
always 1, and even constant propagate that.
Problem is that intrinsic cannot be moved over any branches and other
intrinsics of the same kind.
I'm not sure how that can be modeled, modeling as writes to global
memory may prohibit optimizations, so maybe we should just teach LICM
that this intrinsic is not hoistable, sinkable.
Is there any other pass that moves instructions across BBs?

Best regards,
--Edwin



More information about the llvm-commits mailing list