2013/11/6 Richard Biener <richard.guent...@gmail.com>:
> On Wed, Nov 6, 2013 at 3:04 PM, Ilya Enkovich <enkovich....@gmail.com> wrote:
>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>:
>>> On Wed, Nov 6, 2013 at 2:31 PM, Ilya Enkovich <enkovich....@gmail.com> 
>>> wrote:
>>>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>:
>>>>> On Wed, Nov 6, 2013 at 12:59 PM, Ilya Enkovich <enkovich....@gmail.com> 
>>>>> wrote:
>>>>>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>:
>>>>>>> On Wed, Nov 6, 2013 at 12:00 PM, Ilya Enkovich <enkovich....@gmail.com> 
>>>>>>> wrote:
>>>>>>>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>:
>>>>>>>>> On Tue, Nov 5, 2013 at 3:24 PM, Ilya Enkovich 
>>>>>>>>> <enkovich....@gmail.com> wrote:
>>>>>>>>>> 2013/11/5 Richard Biener <richard.guent...@gmail.com>:
>>>>>>>>>>> On Tue, Nov 5, 2013 at 1:52 PM, Ilya Enkovich 
>>>>>>>>>>> <enkovich....@gmail.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> For input parameter P I need to have
>>>>>>>>>>>>   BOUNDS = __builtin_arg_bnd (P)
>>>>>>>>>>>> to somehow refer to bounds of P in GIMPLE.  Optimizations may 
>>>>>>>>>>>> modify
>>>>>>>>>>>> __builtin_arg_bnd (P) replacing P with its copy or some value. It
>>>>>>>>>>>> makes call useless because removes information about parameter 
>>>>>>>>>>>> whose
>>>>>>>>>>>> bounds we refer to. I want such optimization to ignore
>>>>>>>>>>>> __builtin_arg_bnd calls and always leave default SSA_NAME of 
>>>>>>>>>>>> PARM_DECL
>>>>>>>>>>>> there as arg.
>>>>>>>>>>>
>>>>>>>>>>> How does a compilable testcase look like that shows how the default 
>>>>>>>>>>> def
>>>>>>>>>>> is used?  And what transforms break that use?  I really cannot see
>>>>>>>>>>> how this would happen (and you didn't add a testcase).
>>>>>>>>>>
>>>>>>>>>> Here is a test source:
>>>>>>>>>>
>>>>>>>>>> extern int bar1 (int *p);
>>>>>>>>>> extern int bar2 (int);
>>>>>>>>>>
>>>>>>>>>> int foo (int *p)
>>>>>>>>>> {
>>>>>>>>>>   if (!p)
>>>>>>>>>>     return bar1 (p);
>>>>>>>>>>   return bar2 (10);
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> After instrumentation GIMPLE looks like:
>>>>>>>>>>
>>>>>>>>>> foo (int * p)
>>>>>>>>>> {
>>>>>>>>>>   <unnamed type> __bound_tmp.0;
>>>>>>>>>>   int _1;
>>>>>>>>>>   int _6;
>>>>>>>>>>   int _8;
>>>>>>>>>>
>>>>>>>>>>   <bb 6>:
>>>>>>>>>>   __bound_tmp.0_9 = __builtin_ia32_arg_bnd (p_3(D));
>>>>>>>>>>
>>>>>>>>>>   <bb 2>:
>>>>>>>>>>   if (p_3(D) == 0B)
>>>>>>>>>>     goto <bb 3>;
>>>>>>>>>>   else
>>>>>>>>>>     goto <bb 4>;
>>>>>>>>>>
>>>>>>>>>>   <bb 3>:
>>>>>>>>>>   _6 = bar1 (p_3(D), __bound_tmp.0_9);
>>>>>>>>>>   goto <bb 5>;
>>>>>>>>>>
>>>>>>>>>>   <bb 4>:
>>>>>>>>>>   _8 = bar2 (10);
>>>>>>>>>>
>>>>>>>>>>   <bb 5>:
>>>>>>>>>>   # _1 = PHI <_6(3), _8(4)>
>>>>>>>>>>   return _1;
>>>>>>>>>>
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> Here is optimized GIMPLE (if I do not apply my changes in 
>>>>>>>>>> tree-ssa-dom.c):
>>>>>>>>>>
>>>>>>>>>> foo (int * p)
>>>>>>>>>> {
>>>>>>>>>>   <unnamed type> __bound_tmp.0;
>>>>>>>>>>   int _1;
>>>>>>>>>>   int _6;
>>>>>>>>>>   int _8;
>>>>>>>>>>
>>>>>>>>>>   <bb 2>:
>>>>>>>>>>   if (p_3(D) == 0B)
>>>>>>>>>>     goto <bb 3>;
>>>>>>>>>>   else
>>>>>>>>>>     goto <bb 4>;
>>>>>>>>>>
>>>>>>>>>>   <bb 3>:
>>>>>>>>>>   __bound_tmp.0_9 = __builtin_ia32_arg_bnd (0B); [return slot 
>>>>>>>>>> optimization]
>>>>>>>>>>   _6 = bar1 (0B, __bound_tmp.0_9); [tail call]
>>>>>>>>>>   goto <bb 5>;
>>>>>>>>>>
>>>>>>>>>>   <bb 4>:
>>>>>>>>>>   _8 = bar2 (10); [tail call]
>>>>>>>>>>
>>>>>>>>>>   <bb 5>:
>>>>>>>>>>   # _1 = PHI <_6(3), _8(4)>
>>>>>>>>>>   return _1;
>>>>>>>>>>
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> Now during expand or inline of foo I cannot determine the value for
>>>>>>>>>> __bound_tmp.0_9.
>>>>>>>>>
>>>>>>>>> Well, but clearly you can see that bounds for p == NULL are
>>>>>>>>> useless and thus there is no problem with the transform.
>>>>>>>>
>>>>>>>> This example just demonstrates the issue. I may use some var's address
>>>>>>>> in comparison with the similar result. And value does not always allow
>>>>>>>> to determine bounds, because pointers with the same value may have
>>>>>>>> different bounds.
>>>>>>>
>>>>>>> Some vars address can be used for better bounds deriving though.
>>>>>>> Well, it clearly shows it's a "get me good results" issue and not
>>>>>>> a correctness issue.  And for "good results" you trade in missed
>>>>>>> general optimizations.  That doesn't sound very good to me.
>>>>>>
>>>>>> That is definitely a correctness issue.
>>>>>
>>>>> Then please add a runtime testcase that fails before and passes after
>>>>> your patch.
>>>>>
>>>>>> Compiler cannot assume bounds
>>>>>> by pointer value ignoring bounds passed to the function.
>>>>>
>>>>> But it can certainly drop bounds to "unknown"?  You certainly cannot
>>>>> rely on no such transform taking place.  Maybe this just shows that
>>>>> your "refering to the parameter" is done wrong and shouldn't have
>>>>> used the SSA name default def.  What do you do for parameters
>>>>> that have their address taken btw?  You'll get
>>>>>
>>>>> foo (void *p)
>>>>> {
>>>>>    p_2 = *p;
>>>>>    __builtin_ia32_arg_bnd (p_2);
>>>>>
>>>>> which isn't desired?
>>>>
>>>> In this case you just make a load and bounds for p_2 are obtained
>>>> using bndldx call. I would be glad to use better way to refer to the
>>>> argument but I do not see one.
>>>
>>> Err, my mistake - I meant
>>>
>>> foo (void *p)
>>> {
>>>   p_2 = p;
>>>   __builtin_ia32_arg_bnd (p_2);
>>
>> Well, it does not make much difference. Such params are allocated on
>> the stack by expand. So, here p_2 = p is load from memory and bounds
>> should be loaded by bndldx. Expand is responsible to store bounds
>> using bndstx when it allocates p on the stack.
>
> The parameter is incoming in a register still.

It does not matter. In GIMPLE it is still load. During expand
assign_parms allocates slot on the stack for it and stores reg to it.
DECL_RTL for PARM_DECL is set to stack slot.

I just added code to store corresponding bounds for stored param (I
did not send this patch yet).

Ilya
>
>>>
>>>>>
>>>>> Hmm, unfortunately on x86_64 I get
>>>>>
>>>>> ./cc1 -quiet t.c -fcheck-pointer-bounds
>>>>> t.c:1:0: error: -fcheck-pointers is not supported for this target
>>>>>  extern int bar1 (int *p);
>>>>>  ^
>>>>>
>>>>> trying a simple testcase.  Grepping shows me no target supports
>>>>> chkp_bound_mode ..?  What's this stuff in our tree that has no way
>>>>> of testing it ... :/
>>>>
>>>> You should pass -mmpx to enable it on the target. Current version in
>>>> the mpx tree should build most of tests correctly but it is not
>>>> updated to the current state.
>>>
>>>> ./cc1 -quiet t.c -fcheck-pointer-bounds -mmpx
>>> t.c:1:0: error: -fcheck-pointers is not supported for this target
>>>  extern int bar1 (int *p);
>>>  ^
>>>
>>> hmm, maybe it's configure disabled somehow (this is just my dev tree).
>>> But I still see no chkp_bound_mode implementation.
>>
>> I'll check it and probably update the branch.
>
> I'm looking at trunk which has loads of this stuff already.
>
>>>
>>> Note that POINTER_BOUNDS_TYPE shouldn't have been a new
>>> tree code either but should be a RECORD_TYPE.  See how
>>> va_list doesn't use a new TREE_CODE either.
>>
>> va_list is either a pointer or pointer to a record (array of one
>> record) and is handled as a regular pointer to a regular record.
>> Bounds are not a record of two pointers at least due to binary format.
>> You do not pass it as regular record, use special bound mode for whole
>> record. Why to use RECORD_TYPE for bounds if it'll never be handled as
>> regular RECORD_TYPE?
>
> Then you only can update it completely?  Seems awfully target specific
> for sth introduced at the GIMPLE level.  Oh well.
>
> Richard.
>
>> Ilya
>>
>>>
>>> Richard.
>>>
>>>> Ilya
>>>>
>>>>>
>>>>> Richard.
>>>>>
>>>>>> SSA_NAME_OCCURS_IN_ABNORMAL_PHI usage results in missed optimizations.
>>>>>>  My original patch does not.
>>>>>>
>>>>>> Ilya
>>>>>>
>>>>>>>
>>>>>>> Richard.
>>>>>>>
>>>>>>>>>
>>>>>>>>> Also sth weird is going on as your arg_bnd call gets [return slot 
>>>>>>>>> optimization].
>>>>>>>>> It seems that your POINTER_BOUNDS_TYPE is seen as aggregate somehow.
>>>>>>>>
>>>>>>>> Target is responsible for having return slot optimization here. And
>>>>>>>> target expands all such calls. So, do not see the problem here.
>>>>>>>>
>>>>>>>> Ilya
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Richard.
>>>>>>>>>
>>>>>>>>>> Ilya
>>>>>>>>>>>
>>>>>>>>>>> Richard.
>>>>>>>>>>>

Reply via email to