On Wed, Jan 18, 2017 at 3:11 PM, Alexander Monakov <amona...@ispras.ru> wrote:
> On Wed, 18 Jan 2017, Richard Biener wrote:
>> > After OpenMP lowering, inlining might break this by inlining functions with
>> > address-taken locals into SIMD regions.  For now, such inlining is 
>> > disallowed
>> > (this penalizes only SIMT code), but eventually that can be handled by
>> > collecting those locals into an allocated struct in a similar manner.
>>
>> Can you do the allocation fully after inlining instead?
>
> Hm.  I'm not really sure what you mean, because I may not emit GIMPLE that 
> takes
> addresses of an incomplete struct's fields, and changing layout of an existing
> completely layed out struct is not trivial either.  But I have an idea, see 
> below.
>
> Let's consider what the last patch implements; starting from
>
>   #pragma omp simd private(tmp)
>   for (int i = n1; i < n2; i++)
>     foo (&tmp);
>
> it emits GIMPLE that looks like this:
>
>   struct {
>     int tmp;
>   } *omp_simt = IFN_GOMP_SIMT_ENTER (sizeof *omp_simt);
>
>   /* This temporary is needed because we populate the struct and (re)gimplify
>      references to privatized variables in one pass; replacing 'tmp' directly
>      with '&omp_simt->tmp' wouldn't work, because struct layout is not known
>      until all fields are added, and gimplification wouldn't be able to emit
>      the corresponding MEM_REF.  */
>   int *tmp_ptr = &omp_simt->tmp;
>
>   for (int i = n1; i < n2; i++)
>     foo (tmp_ptr);
>
>   *.omp_simt = {CLOBBER};
>   IFN_GOMP_SIMT_EXIT (.omp_simt);
>
>
> So I guess a way to keep allocation layout implicit until after inlining is
> this: instead of exposing the helper struct in the IR immediately, somehow 
> keep
> it on the side, associated only with the SIMT region, and not finalized.  This
> would allow to populate it as needed during inlining, but the downside is that
> references to privatized vars would get weirder: they would need to be via 
> IFNs
> that track association with the loop and the privatized variable.  Like this:
>
>   void *omp_simt = IFN_GOMP_SIMT_ENTER_BY_UID (simduid);
>
>   int *tmp_ptr = IFN_GOMP_SIMT_VAR_REF (omp_simt, simduid, uid_for_tmp);
>
>   for (...)
>     foo (tmp_ptr);
>
>   *tmp_ptr = {CLOBBER}; /* ??? for each privatized variable? */
>   IFN_GOMP_SIMT_EXIT (.omp_simt);
>
> (note how in this scheme we'd need to emit separate CLOBBERs for each field)
>
> But absence of explicit struct would hurt alias analysis I'm afraid: it 
> wouldn't
> be able to deduce that references to different privatized variable do not 
> alias
> until after calls to SIMT_VAR_REF are replaced.  Or is that not an issue?

It probably is.

But I guess I was asking whether you could initially emit

 void *omp_simt = IFN_GOMP_SIMT_ENTER (0);

  for (int i = n1; i < n2; i++)
     foo (&tmp);

  IFN_GOMP_SIMT_EXIT (omp_simt);

and only after inlining do liveness / use analysis of everything between
SIMT_ENTER and SIMT_EXIT doing the rewriting only at that point.

Richard.

> Thanks.
> Alexander

Reply via email to