[llvm] r294341 - This patch adds a ssa_copy intrinsic, as part of splitting up D29316.

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 10 22:12:50 PST 2017


On Fri, Feb 10, 2017 at 9:49 PM, Daniel Berlin <dberlin at dberlin.org> wrote:

> Yes, the original implementation used single operand phi nodes, and
> besides chandler being against it for various reasons, you can't handle
> assume, or other middle-of-the-block instructions while doing it.
>
> In particular, there is not necessarily a placement point you can use
> where you can insert a single operand phi node.
>
> (It is obviously possible to handle all branch instructions, however,
> assuming you don't care about critical edges, because then you can't place
> a single operand one in the successors)
>
> Example:
>
> %foo = add i32 0, %a
> %bob = icmp eq i32 %foo, 0
> call llvm.assume(%bob)
>
>
(for those following along at home, while this is likely obvious to philip,
here is a complete example:

%foo = add i32 0, %a
%bob = icmp eq i32 %foo, 0
call llvm.assume(%bob)
%fred = icmp ne i32 %foo, 0
br i1 %fred, ....

We need to transform this into:
%foo = add i32 0, %a
%bob = icmp eq i32 %foo, 0
%foo.0 = ssa.copy(%foo)
%bob.0 = ssa.copy(%bob)
call llvm.assume(%bob.0)
%fred = icmp ne i32 %foo.0, 0
br i1 %fred, ....

Right before the assume is the only place you can insert that is guaranteed
to be dominated by all defs you are renaming, and dominates all uses you
are renaming.

You also may have a critical edge, or multiple critical edges, which leave
you no spot to insert.

 define i32 @f1(i32 %x) {
 bb0:
   %cmp = icmp eq i32 %x, 0
   br i1 %cmp, label %bb2, label %bb1
 bb1:
   br label %bb2
 bb2:
   %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
   %foo = add i32 %cond, %x
   ret i32 %foo
 }

Unless we split the critical edge, we have to do:
 define i32 @f1(i32 %x) {
 bb0:
   %cmp = icmp eq i32 %x, 0
   %x.0 = ssa.copy(%x)
   br i1 %cmp, label %bb2, label %bb1
 bb1:
   br label %bb2
 bb2:
   %cond = phi i32 [ %x.0, %bb0 ], [ 0, %bb1 ]
   %foo = add i32 %cond, %x
   ret i32 %foo
 }


There is no place i can place a single operand phi for %foo or %bob and
> have it cover everything it should.
>
> I can't place it in this block, because it would not dominate the
> definition of %foo or %bob
>
> Normally, with branches, you could place it in the successor block.
> However, i have a patch to support critical edges, so once tha goes in,
> you  have no guarantee the successors are not blocks with multiple preds.
>
> In that situation, the only safe insertion point is right before the
> assume/branch/switch, and you can't put a phi there.
>
> If you stare at the critical edges support that is upcoming, you'll come
> to the conclusion that you can't even "fudge it" well.
>
> The in-between state that used to exist was "we'd create single operand
> phis where we could, and ssa.copy where we couldn't", but that just seems
> more confusing, so i just went with ssa copy everywhere.
>
>
>
>
> On Fri, Feb 10, 2017 at 10:03 AM, Philip Reames <listmail at philipreames.com
> > wrote:
>
>> Out of curiosity, how is @llvm.ssa_copy different from a single entry phi
>> node?  We already use redundant PHI nodes in LCSSA, doing the same here
>> would seem to make sense.
>>
>> Philip
>>
>>
>> On 02/07/2017 11:29 AM, Daniel Berlin via llvm-commits wrote:
>>
>>> Author: dannyb
>>> Date: Tue Feb  7 13:29:25 2017
>>> New Revision: 294341
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=294341&view=rev
>>> Log:
>>> This patch adds a ssa_copy intrinsic, as part of splitting up D29316.
>>>
>>> Summary:
>>> The intrinsic, marked as returning it's first argument, has no code
>>> generation effect (though currently not every optimization pass knows
>>> that intrinsics with the returned attribute can be looked through).
>>>
>>> It is about to be used to by the PredicateInfo pass to attach
>>> predicate information to existing operands, and be able to tell what
>>> the predicate information affects.
>>>
>>> We deliberately do not attach any info through a second operand so
>>> that the intrinsics do not need to dominate the comparisons/etc (since
>>> in the case of assume, we may want to push them up the post-dominator
>>> tree).
>>>
>>> Reviewers: davide, sanjoy
>>>
>>> Subscribers: llvm-commits
>>>
>>> Differential Revision: https://reviews.llvm.org/D29517
>>>
>>> Modified:
>>>      llvm/trunk/docs/LangRef.rst
>>>      llvm/trunk/include/llvm/IR/Intrinsics.td
>>>
>>> Modified: llvm/trunk/docs/LangRef.rst
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.
>>> rst?rev=294341&r1=294340&r2=294341&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/docs/LangRef.rst (original)
>>> +++ llvm/trunk/docs/LangRef.rst Tue Feb  7 13:29:25 2017
>>> @@ -12700,6 +12700,33 @@ sufficient overall improvement in code q
>>>   that the optimizer can otherwise deduce or facts that are of little
>>> use to the
>>>   optimizer.
>>>   +.. _int_ssa_copy:
>>> +
>>> +'``llvm.ssa_copy``' Intrinsic
>>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> +
>>> +Syntax:
>>> +"""""""
>>> +
>>> +::
>>> +
>>> +      declare type @llvm.ssa_copy(type %operand) returned(1) readnone
>>> +
>>> +Arguments:
>>> +""""""""""
>>> +
>>> +The first argument is an operand which is used as the returned value.
>>> +
>>> +Overview:
>>> +""""""""""
>>> +
>>> +The ``llvm.ssa_copy`` intrinsic can be used to attach information to
>>> +operations by copying them and giving them new names.  For example,
>>> +the PredicateInfo utility uses it to build Extended SSA form, and
>>> +attach various forms of information to operands that dominate specific
>>> +uses.  It is not meant for general use, only for building temporary
>>> +renaming forms that require value splits at certain points.
>>> +
>>>   .. _type.test:
>>>     '``llvm.type.test``' Intrinsic
>>>
>>> Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>> IR/Intrinsics.td?rev=294341&r1=294340&r2=294341&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
>>> +++ llvm/trunk/include/llvm/IR/Intrinsics.td Tue Feb  7 13:29:25 2017
>>> @@ -781,6 +781,10 @@ def int_memcpy_element_atomic  : Intrins
>>>                                    [IntrArgMemOnly, NoCapture<0>,
>>> NoCapture<1>,
>>>                                     WriteOnly<0>, ReadOnly<1>]>;
>>>   +//===----- Intrinsics that are used to provide predicate information
>>> -----===//
>>> +
>>> +def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>],
>>> +                            [IntrNoMem, Returned<0>]>;
>>>   //===-------------------------------------------------------
>>> ---------------===//
>>>   // Target-specific intrinsics
>>>   //===-------------------------------------------------------
>>> ---------------===//
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170210/a2a4a3b8/attachment.html>


More information about the llvm-commits mailing list