Richard Biener <rguent...@suse.de> writes:
> On Wed, 10 May 2023, pan2...@intel.com wrote:
>
>> From: Pan Li <pan2...@intel.com>
>> 
>> The decl_or_value is defined as void * before this PATCH. It will take
>> care of both the tree_node and rtx_def. Unfortunately, given a void
>> pointer cannot tell the input is tree_node or rtx_def.
>> 
>> Then we have some implicit structure layout requirement similar as
>> below. Or we will touch unreasonable bits when cast void * to tree_node
>> or rtx_def.
>> 
>> +--------+-----------+----------+
>> | offset | tree_node | rtx_def  |
>> +--------+-----------+----------+
>> |      0 | code: 16  | code: 16 | <- require the location and bitssize
>> +--------+-----------+----------+
>> |     16 | ...       | mode: 8  |
>> +--------+-----------+----------+
>> | ...                           |
>> +--------+-----------+----------+
>> |     24 | ...       | ...      |
>> +--------+-----------+----------+
>> 
>> This behavior blocks the PATCH that extend the rtx_def mode from 8 to
>> 16 bits for running out of machine mode. This PATCH introduced the
>> pointer_mux to tell the input is tree_node or rtx_def, and decouple
>> the above implicition dependency.
>> 
>> Signed-off-by: Pan Li <pan2...@intel.com>
>> Co-Authored-By: Richard Sandiford <richard.sandif...@arm.com>
>> Co-Authored-By: Richard Biener <rguent...@suse.de>
>> 
>> gcc/ChangeLog:
>> 
>>      * var-tracking.cc (DECL_OR_VALUE_OR_DEFAULT): New macro for
>>        clean code.
>>      (dv_is_decl_p): Adjust type changes to pointer_mux.
>>      (dv_as_decl): Likewise.
>>      (dv_as_value): Likewise.
>>      (dv_as_opaque): Likewise.
>>      (variable_hasher::equal): Likewise.
>>      (dv_from_decl): Likewise.
>>      (dv_from_value): Likewise.
>>      (shared_hash_find_slot_unshare_1): Likewise.
>>      (shared_hash_find_slot_1): Likewise.
>>      (shared_hash_find_slot_noinsert_1): Likewise.
>>      (shared_hash_find_1): Likewise.
>>      (unshare_variable): Likewise.
>>      (vars_copy): Likewise.
>>      (find_loc_in_1pdv): Likewise.
>>      (find_mem_expr_in_1pdv): Likewise.
>>      (dataflow_set_different): Likewise.
>>      (variable_from_dropped): Likewise.
>>      (variable_was_changed): Likewise.
>>      (loc_exp_insert_dep): Likewise.
>>      (notify_dependents_of_resolved_value): Likewise.
>>      (vt_expand_loc_callback): Likewise.
>>      (remove_value_from_changed_variables): Likewise.
>>      (notify_dependents_of_changed_value): Likewise.
>>      (emit_notes_for_differences_1): Likewise.
>>      (emit_notes_for_differences_2): Likewise.
>> ---
>>  gcc/var-tracking.cc | 119 +++++++++++++++++++++++++++-----------------
>>  1 file changed, 74 insertions(+), 45 deletions(-)
>> 
>> diff --git a/gcc/var-tracking.cc b/gcc/var-tracking.cc
>> index fae0c73e02f..9bc9d21e5ba 100644
>> --- a/gcc/var-tracking.cc
>> +++ b/gcc/var-tracking.cc
>> @@ -116,9 +116,17 @@
>>  #include "fibonacci_heap.h"
>>  #include "print-rtl.h"
>>  #include "function-abi.h"
>> +#include "mux-utils.h"
>>  
>>  typedef fibonacci_heap <long, basic_block_def> bb_heap_t;
>>  
>> +/* A declaration of a variable, or an RTL value being handled like a
>> +   declaration by pointer_mux.  */
>> +typedef pointer_mux<tree_node, rtx_def> decl_or_value;
>> +
>> +#define DECL_OR_VALUE_OR_DEFAULT(ptr) \
>> +  ((ptr) ? decl_or_value (ptr) : decl_or_value ())
>> +
>>  /* var-tracking.cc assumes that tree code with the same value as VALUE rtx 
>> code
>>     has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
>>     Currently the value is the same as IDENTIFIER_NODE, which has such
>> @@ -196,15 +204,21 @@ struct micro_operation
>>  };
>>  
>>  
>> -/* A declaration of a variable, or an RTL value being handled like a
>> -   declaration.  */
>> -typedef void *decl_or_value;
>> -
>>  /* Return true if a decl_or_value DV is a DECL or NULL.  */
>>  static inline bool
>>  dv_is_decl_p (decl_or_value dv)
>>  {
>> -  return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
>> +  bool is_decl = !dv;
>> +
>> +  if (dv)
>> +    {
>> +      if (dv.is_first ())
>> +    is_decl = (int) TREE_CODE (dv.known_first ()) != (int) VALUE;
>> +      else if (!dv.is_first () && !dv.is_second ())
>> +    is_decl = true;
>> +    }
>> +
>> +  return is_decl;
>
> This all looks very confused, shouldn't it just be
>
>      return dv.is_first ();
>
> ?  All the keying on VALUE should no longer be necessary.
>
>>  }
>>  
>>  /* Return true if a decl_or_value is a VALUE rtl.  */
>> @@ -219,7 +233,7 @@ static inline tree
>>  dv_as_decl (decl_or_value dv)
>>  {
>>    gcc_checking_assert (dv_is_decl_p (dv));
>> -  return (tree) dv;
>> +  return dv.is_first () ? dv.known_first () : NULL_TREE;
>
> and this should be
>
>      return dv.known_first ();
>
> ?  (knowing that ptr-mux will not mutate 'first' and thus preserves
> a nullptr there)
>
>>  }
>>  
>>  /* Return the value in the decl_or_value.  */
>> @@ -227,14 +241,20 @@ static inline rtx
>>  dv_as_value (decl_or_value dv)
>>  {
>>    gcc_checking_assert (dv_is_value_p (dv));
>> -  return (rtx)dv;
>> +  return dv.is_second () ? dv.known_second () : NULL_RTX;;
>
> return dv.known_second ();  (the assert makes sure it isn't nullptr)
>
>>  }
>>  
>>  /* Return the opaque pointer in the decl_or_value.  */
>>  static inline void *
>>  dv_as_opaque (decl_or_value dv)
>>  {
>> -  return dv;
>> +  if (dv.is_first ())
>> +    return dv.known_first ();
>> +
>> +  if (dv.is_second ())
>> +    return dv.known_second ();
>> +
>> +  return NULL;
>>  }
>
> I think this function should go away

Was just about to say the same thing :)

Admittedly, I think I might be missing some of the intended abstraction
here, but at least for variable_table_type, it seems that the void *
compare_type in:

struct variable_hasher : pointer_hash <variable>
{
  typedef void *compare_type;
  static inline hashval_t hash (const variable *);
  static inline bool equal (const variable *, const void *);
  static inline void remove (variable *);
};

could/should really be decl_or_value, even under the current scheme.
Perhaps the current code predates strongly-typed hash containers.

> - for equality compares
> ptr-mux should probably get an operator== overload (or alternatively
> an access to the raw pointer value).  For cases like
>
>   gcc_checking_assert (loc != dv_as_opaque (var->dv));
>
> one could also use var->dv.second_or_null ().  But as said
> most uses are doing sth like
>
>   if (dv_as_opaque (list->dv) == dv_as_opaque (cdv)
>
> which should just become
>
>   if (list->dv == cdv)
>
> Richard - any preference here?  Go for operator==/!= or go
> for an accessor to m_ptr (maybe as uintptr_t)?

Would prefer ==/!= for now.  Kind-of wary of providing access to the
underlying representation.

Thanks,
Richard

Reply via email to