On August 27, 2021 5:47:58 PM GMT+02:00, Tobias Burnus 
<tob...@codesourcery.com> wrote:
>Hi all,
>
>Background: gfortran has its own array descriptor – and one which is defined in
>F2018 and used/usable from C (#include <ISO_Fortran_binding.h>).
>On mainline, the conversion is done via a void* pointer and calls to 
>libgfortran,
>which causes all kind of issues, including alias issues but also data 
>type/bounds
>issues etc.
>
>The attached patch tries to do this inline - and defines in the FE a proper
>type for the C descriptor.  ("CFI_cdesc_t" has a 'dim[]' as last member,
>'CFI_cdesc_t01' has dim[1].)
>
>
>But but I have a ME optimization issue, which removes an crucial
>assignment - any help/suggestion is welcome!
>(Additionally, there is room for improvement regarding the debugging
>experience. Suggestions are welcome as well, but it is not as crucial.)
>
>
>Do you have any suggestion or idea what goes wrong?
>
>
>It looks really nice with "-O1 -fno-inline"   :-)
>   The callee 'rank_p()' is mostly optimized and in the
>   caller only those struct elements are set, which are used:
>
>integer(kind=4) rank_p (struct CFI_cdesc_t & _this)
>{
>   _1 = _this_11(D)->base_addr;
>   _2 = _this_11(D)->rank;
>...
>   rnk_13 = (integer(kind=4)) _2;
>   return rnk_13;
>}
>
>void selr_p ()
>{
>...
>   struct CFI_cdesc_t01 cfi.7;
>...
>   <bb 2> [local count: 537730764]:
>   cfi.7.rank = 1;
>   cfi.7.base_addr = 0B;

You need to do the accesses above using the generic 't' type as well, otherwise 
they are non-conflicting TBAA wise. 

>   irnk_45 = rank_p (&cfi.7);
>   cfi.7 ={v} {CLOBBER};
>   if (irnk_45 != 1)
>
>
>BUT BAD RESULT with -O2 -fno-inline  :-(
>   The assignments on the caller side are gone,
>   which causes wrong code (run stops with 'stop 1'):
>
>integer(kind=4) rank_p (struct CFI_cdesc_t & _this)
>{
>...
>   <bb 2> [local count: 1073741824]:
>   _1 = _this_3(D)->rank;
>   rnk_4 = (integer(kind=4)) _1;
>   return rnk_4;
>}
>
>void selr_p ()
>{
>...
>   struct CFI_cdesc_t01 cfi.7;
>...
>   <bb 2> [local count: 537730764]:
>   irnk_30 = rank_p (&cfi.7);   ! <<<< ERROR: cfi.7.rank assignment missing
>   cfi.7 ={v} {CLOBBER};
>   if (irnk_30 != 1)
>
>  *  *  *
>
>Any idea / suggestion?
>
>  *  *  *
>
>* trans-type.c defines the new type
>* trans-decl.c handles the conversion from C descriptor to Fortran descriptor 
>in the callee
>* trans-expr.c handles the conversion to the C descriptor in the callee
>
>Attached:
>* Testcase 'test.f90'
>   - original dump
>   - -O1 -fno-inline optimized dump
>   - -O2 -fno-inline optimized dump
>* Full patch
>   - Testcase is lightly modified gfortran.dg/PR93963.f90
>
>Tobias
>
>  *  *  *
>
>PS: Current GCC (mainline w/o patch) generates the following.
>[-> with patch, see a-test.f90.*.original.]
>
>Namely, for the callee, casting the argument
>   (in reality pointer to a CFI descriptor,
>    but TREE_TYPE (PARM_DECL) is ptr to Fortran descriptor)
>to 'void *', passing it to a library function, which creates
>a new Fortran descriptor and pointer-assigning it to
>the PARM_DECL pointer, which now points to a Fortran
>descriptor:
>
>integer(kind=4) rank_p (struct array15_integer(kind=4) & this)
>{
>    gfc_desc_ptr.1 = &gfc_desc.0;
>    CFI_desc_ptr.2 = (void *) this;
>    _gfortran_cfi_desc_to_gfc_desc (gfc_desc_ptr.1, &CFI_desc_ptr.2);
>    this = (struct array15_integer(kind=4) &) gfc_desc_ptr.1;
>    rnk = (integer(kind=4)) this->dtype.rank;
>...
>void selr_p ()
>{
>   struct array01_integer(kind=4) intp;
>   integer(kind=4) irnk;
>   static integer(kind=4) rnk = 1;
>
>   intp.dtype = {.elem_len=4, .rank=1, .type=1};
>   intp.span = 0;
>...
>     _gfortran_gfc_desc_to_cfi_desc (&cfi.3, &intp);
>     intp.dtype.attribute = 0;
>     irnk = rank_p (cfi.3);
>     __builtin_free (cfi.3);
>
>  *  *  *
>
>-----------------
>Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
>München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
>Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
>München, HRB 106955

Reply via email to