On Thu, 3 Feb 2022, Richard Sandiford wrote:

> Richard Biener <rguent...@suse.de> writes:
> > On Thu, 3 Feb 2022, Richard Sandiford wrote:
> >
> >> Richard Biener <rguent...@suse.de> writes:
> >> > On Wed, 2 Feb 2022, Michael Matz wrote:
> >> >
> >> >> Hello,
> >> >> 
> >> >> On Wed, 2 Feb 2022, Richard Biener via Gcc-patches wrote:
> >> >> 
> >> >> > This adds a flag to CONSTRUCTOR nodes indicating that for clobbers 
> >> >> > this 
> >> >> > marks the end-of-life of storage as opposed to just ending the 
> >> >> > lifetime 
> >> >> > of the object that occupied it. The dangling pointer diagnostics uses 
> >> >> > CLOBBERs but is confused by those emitted by the C++ frontend for 
> >> >> > example which emits them for the second purpose at the start of 
> >> >> > CTORs.  
> >> >> > The issue is also appearant for aarch64 in PR104092.
> >> >> > 
> >> >> > Distinguishing the two cases is also necessary for the PR90348 fix.
> >> >> 
> >> >> (Just FWIW: I agree with the plan to have different types of CLOBBERs, 
> >> >> in 
> >> >> particular those for marking births)
> >> >> 
> >> >> A style nit:
> >> >> 
> >> >> >             tree clobber = build_clobber (TREE_TYPE (t));
> >> >> > +           CLOBBER_MARKS_EOL (clobber) = 1;
> >> >> 
> >> >> I think it really were better if build_clobber() gained an additional 
> >> >> argument (non-optional!) that sets the type of it.
> >> >
> >> > It indeed did occur to me as well, so as we're two now I tried to see
> >> > how it looks like.  It does like the following (didn't bother to
> >> > replace all build_clobber calls but defaulted the parameter - there
> >> > are too many).  With CLOBBER_BIRTH added for the fix for PR90348
> >> > the enum would be constructed like
> >> >
> >> > #define CLOBBER_KIND(NODE) \
> >> >   ((clobber_kind) (CONSTRUCTOR_CHECK (NODE)->base.private_flag << 1
> >> >                    | CONSTRUCTOR_CHECK (NODE)->base.protected_flag))
> >> >
> >> > or so (maybe different dependent on bitfield endianess to make
> >> > extracting the two adjacent bits cheap).  That would leave us space
> >> > for a fourth state.
> >> >
> >> > So do you think that makes it nicer?  What do others think?
> >> 
> >> This way looks cleaner to me FWIW.
> >> 
> >> Which arm of tree_base::u do constructors use?  If we need a 2-bit
> >> enum then maybe we can carve one out from there.
> >
> > constructors are tcc_exceptional but since they are used where
> > tree operands reside they need to be compatible to EXPR_P and
> > thus various things like TREE_SIDE_EFFECTS need to work.
> >
> > Which means, we can't.
> 
> But TREE_SIDE_EFFECTS is part of the main set of flags.  For tree_base::u
> we have:
> 
>   union {
>     /* The bits in the following structure should only be used with
>        accessor macros that constrain inputs with tree checking.  */
>     struct {
>       unsigned lang_flag_0 : 1;
>       unsigned lang_flag_1 : 1;
>       unsigned lang_flag_2 : 1;
>       unsigned lang_flag_3 : 1;
>       unsigned lang_flag_4 : 1;
>       unsigned lang_flag_5 : 1;
>       unsigned lang_flag_6 : 1;
>       unsigned saturating_flag : 1;
> 
>       unsigned unsigned_flag : 1;
>       unsigned packed_flag : 1;
>       unsigned user_align : 1;
>       unsigned nameless_flag : 1;
>       unsigned atomic_flag : 1;
>       unsigned unavailable_flag : 1;
>       unsigned spare0 : 2;
> 
>       unsigned spare1 : 8;
> 
>       /* This field is only used with TREE_TYPE nodes; the only reason it is
>        present in tree_base instead of tree_type is to save space.  The size
>        of the field must be large enough to hold addr_space_t values.  */
>       unsigned address_space : 8;
>     } bits;
> 
>     /* The following fields are present in tree_base to save space.  The
>        nodes using them do not require any of the flags above and so can
>        make better use of the 4-byte sized word.  */
> 
>     /* The number of HOST_WIDE_INTs in an INTEGER_CST.  */
>     struct {
>       /* The number of HOST_WIDE_INTs if the INTEGER_CST is accessed in
>        its native precision.  */
>       unsigned char unextended;
> 
>       /* The number of HOST_WIDE_INTs if the INTEGER_CST is extended to
>        wider precisions based on its TYPE_SIGN.  */
>       unsigned char extended;
> 
>       /* The number of HOST_WIDE_INTs if the INTEGER_CST is accessed in
>        offset_int precision, with smaller integers being extended
>        according to their TYPE_SIGN.  This is equal to one of the two
>        fields above but is cached for speed.  */
>       unsigned char offset;
>     } int_length;
> 
>     /* VEC length.  This field is only used with TREE_VEC.  */
>     int length;
> 
>     /* This field is only used with VECTOR_CST.  */
>     struct {
>       /* The value of VECTOR_CST_LOG2_NPATTERNS.  */
>       unsigned int log2_npatterns : 8;
> 
>       /* The value of VECTOR_CST_NELTS_PER_PATTERN.  */
>       unsigned int nelts_per_pattern : 8;
> 
>       /* For future expansion.  */
>       unsigned int unused : 16;
>     } vector_cst;
> 
>     /* SSA version number.  This field is only used with SSA_NAME.  */
>     unsigned int version;
> 
>     /* CHREC_VARIABLE.  This field is only used with POLYNOMIAL_CHREC.  */
>     unsigned int chrec_var;
> 
>     /* Internal function code.  */
>     enum internal_fn ifn;
> 
>     /* OMP_ATOMIC* memory order.  */
>     enum omp_memory_order omp_atomic_memory_order;
> 
>     /* The following two fields are used for MEM_REF and TARGET_MEM_REF
>        expression trees and specify known data non-dependences.  For
>        two memory references in a function they are known to not
>        alias if dependence_info.clique are equal and dependence_info.base
>        are distinct.  Clique number zero means there is no information,
>        clique number one is populated from function global information
>        and thus needs no remapping on transforms like loop unrolling.  */
>     struct {
>       unsigned short clique;
>       unsigned short base;
>     } dependence_info;
>   } GTY((skip(""))) u;
> 
> so there's spare room even if constructors use the general “bits” arm.

Ah, yes - I thought CTORs are using that for the number of elements
but they don't, they use a pointer to a vec<>.  So yes, for convenience
we could use bits in that section (with a bit more churn as they need to
be streamed for LTO, etc.)

I'll see to simply stick the plain enum there for CTORs.

Richard.

Reply via email to