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