On Wed, 18 Jan 2023, Jan Hubicka wrote: > > On Tue, 17 Jan 2023, Jan Hubicka wrote: > > > > > > > We don't use same argumentation about other control flow statements. > > > > > The following: > > > > > > > > > > fn() > > > > > { > > > > > try { > > > > > i_read_no_global_memory (); > > > > > } catch (...) > > > > > { > > > > > reutrn 1; > > > > > } > > > > > return 0; > > > > > } > > > > > > > > > > should be detected as const. Marking throw pure would make fn pure > > > > > too. > > > > > > > > I suppose i_read_no_global_memory is const here. Not sure why that > > > Suppose we have: > > > > > > void > > > i_read_no_global_memory () > > > { > > > throw(0); > > > } > > > > > > If cxa_throw itself was annotated as 'p' rahter than 'c' ipa-modref will > > > believe that cxa_throw will read any global memory and will propagate it > > > to all callers. So fn() will be also marked as reading all global > > > memory. > > > > Sure - but for the purpose of local optimizations in > > i_read_no_global_memory cxa_throw has to appear to read memory. > > Yes, I think every stmt that can throw externally need VUSE (just like > return_stmt needs it). Even if throw(0) was replaced by a=b/c with > -fnon-call-exceptions. It is still not clear to me why this should > imply that we need 'p' instead of 'c' in fnspecs. > > So I think we should try to make the following to work: > > diff --git a/gcc/tree-ssa-operands.cc b/gcc/tree-ssa-operands.cc > index 57e393ae164..d24f1721eb2 100644 > --- a/gcc/tree-ssa-operands.cc > +++ b/gcc/tree-ssa-operands.cc > @@ -951,6 +951,9 @@ operands_scanner::parse_ssa_operands () > enum gimple_code code = gimple_code (stmt); > size_t i, n, start = 0; > > + if (stmt_can_throw_external (fn, stmt)) > + append_vuse (gimple_vop (fn)); > + > switch (code) > { > case GIMPLE_ASM:
It's going to be a bit tricky since in many places we use gimple_vuse () != NULL to check whether an assignment is a load/store. But yes, the above is sort-of what we'd need to do. > > Having a VUSE there dependent on whether the function performs any > > load or store would be quite ugly. Instead modref could special-case > > cxa_throw and not treat it as reading memory (like it already does > > for the return stmt I suppose - that also has a VUSE). > > modref looks into statements with VUSEs on them and checks what > reads/stores are done. So return statement with VUSE is walked and no > load is recorded because no actual load is found. > Similarly that would happen with __cxa_throw if it was 'c'. > With 'p' it has nothing to analyze so it would trust the fact that > cxa_throw itself reads some global state. I see. But does __cxa_throw stmt_can_throw_external ()? Otherwise the operand scanner elides VUSE on const function calls. > > > > The problem is IIRC GIMPLE_RESX which doesn't derive from > > gimple_statement_with_memory_ops_base. There's a bugzilla I can't find > > right now refering to this issue. > > I never tried to play with gimple hiearchy. It is hard to fix resx? I > wonder if we have other cases. I guess for a=b/c we are luck just > because gimple_assign can also be load or store so it has memory_ops... Fixing resx would come at the cost of deriving from _with_ops, but not sure if that waste of space is too important. Richard. > Thanks, > Honza > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; HRB 36809 (AG Nuernberg)