On Tue, May 14, 2019 at 5:09 AM <li...@linux.ibm.com> wrote:
>
> From: Kewen Lin <li...@linux.ibm.com>
>
> Previous version link:
> https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00912.html
>
> This is a NFC (no functional change) patch.  Ivopts has
> some codes to expand gimple to RTL seq, but before call
> expanding, we should call a preparation funciton
> prepare_decl_rtl.  This patch is to change it and its
> dependents to non-static, can be shared with other passes.
>
> Bootstrapped and regression testing passed on powerpc64le.
>
> Is OK for trunk?

Hum.  The function is somewhat of a hack, trying to produce
"reasonable" DECL_RTL, exposing it in expr.[ch] with this
name is eventually misleading.  Also you fail to "outline"
the most important part:

  FOR_EACH_VEC_ELT (decl_rtl_to_reset, i, obj)
    SET_DECL_RTL (obj, NULL_RTX);

which IMHO would warrant making this machinery a class
with the above done in its destructor?

Maybe name the functions prepare_guessed_decl_rtl ()
and the new class guessed_decl_rtl?

Now looking how you'll end up using this...

Richard.

> gcc/ChangeLog
>
> 2019-05-13  Kewen Lin  <li...@gcc.gnu.org>
>
>         PR middle-end/80791
>         * expr.c (produce_memory_decl_rtl): New function.
>         (prepare_decl_rtl): Likewise.
>         * expr.h (produce_memory_decl_rtl): New declaration.
>         (prepare_decl_rtl): Likewise.
>         * tree-ssa-loop-ivopts.c (produce_memory_decl_rtl): Remove.
>         (prepare_decl_rtl): Likewise.
>         (computation_cost): Updated to call refactored prepare_decl_rtl.
>
> ---
>  gcc/expr.c                 | 91 +++++++++++++++++++++++++++++++++++++++++++++
>  gcc/expr.h                 | 16 +++++++-
>  gcc/tree-ssa-loop-ivopts.c | 93 
> ++--------------------------------------------
>  3 files changed, 110 insertions(+), 90 deletions(-)
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index 9ff5e5f..1f2ad45 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -12539,3 +12539,94 @@ int_expr_size (tree exp)
>
>    return tree_to_shwi (size);
>  }
> +
> +/* Produce DECL_RTL for object obj so it looks like it is stored in memory.  
> */
> +
> +rtx
> +produce_memory_decl_rtl (tree obj, int *regno)
> +{
> +  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (obj));
> +  machine_mode address_mode = targetm.addr_space.address_mode (as);
> +  rtx x;
> +
> +  gcc_assert (obj);
> +  if (TREE_STATIC (obj) || DECL_EXTERNAL (obj))
> +    {
> +      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));
> +      x = gen_rtx_SYMBOL_REF (address_mode, name);
> +      SET_SYMBOL_REF_DECL (x, obj);
> +      x = gen_rtx_MEM (DECL_MODE (obj), x);
> +      set_mem_addr_space (x, as);
> +      targetm.encode_section_info (obj, x, true);
> +    }
> +  else
> +    {
> +      x = gen_raw_REG (address_mode, (*regno)++);
> +      x = gen_rtx_MEM (DECL_MODE (obj), x);
> +      set_mem_addr_space (x, as);
> +    }
> +
> +  return x;
> +}
> +
> +/* Prepares decl_rtl for variables referred in *EXPR_P.  Callback for
> +   walk_tree.  DATA contains the actual fake register number.  */
> +
> +tree
> +prepare_decl_rtl (tree *expr_p, int *ws, void *data)
> +{
> +  tree obj = NULL_TREE;
> +  rtx x = NULL_RTX;
> +  decl_rtl_data *info = (decl_rtl_data *) data;
> +  int *regno = info->regno;
> +  vec<tree> *treevec = info->treevec;
> +
> +  switch (TREE_CODE (*expr_p))
> +    {
> +    case ADDR_EXPR:
> +      for (expr_p = &TREE_OPERAND (*expr_p, 0); handled_component_p 
> (*expr_p);
> +          expr_p = &TREE_OPERAND (*expr_p, 0))
> +       continue;
> +      obj = *expr_p;
> +      if (DECL_P (obj) && HAS_RTL_P (obj) && !DECL_RTL_SET_P (obj))
> +       x = produce_memory_decl_rtl (obj, regno);
> +      break;
> +
> +    case SSA_NAME:
> +      *ws = 0;
> +      obj = SSA_NAME_VAR (*expr_p);
> +      /* Defer handling of anonymous SSA_NAMEs to the expander.  */
> +      if (!obj)
> +       return NULL_TREE;
> +      if (!DECL_RTL_SET_P (obj))
> +       x = gen_raw_REG (DECL_MODE (obj), (*regno)++);
> +      break;
> +
> +    case VAR_DECL:
> +    case PARM_DECL:
> +    case RESULT_DECL:
> +      *ws = 0;
> +      obj = *expr_p;
> +
> +      if (DECL_RTL_SET_P (obj))
> +       break;
> +
> +      if (DECL_MODE (obj) == BLKmode)
> +       x = produce_memory_decl_rtl (obj, regno);
> +      else
> +       x = gen_raw_REG (DECL_MODE (obj), (*regno)++);
> +
> +      break;
> +
> +    default:
> +      break;
> +    }
> +
> +  if (x)
> +    {
> +      treevec->safe_push (obj);
> +      SET_DECL_RTL (obj, x);
> +    }
> +
> +  return NULL_TREE;
> +}
> diff --git a/gcc/expr.h b/gcc/expr.h
> index 17c3962..b1894a6b 100644
> --- a/gcc/expr.h
> +++ b/gcc/expr.h
> @@ -53,7 +53,21 @@ typedef struct separate_ops
>    tree type;
>    tree op0, op1, op2;
>  } *sepops;
> -
> +
> +/* This structure is used to pass information to tree walker function
> +   prepare_decl_rtl.  */
> +typedef struct data_for_decl_rtl
> +{
> +  int *regno;
> +  vec<tree> *treevec;
> +} decl_rtl_data;
> +
> +/* Produce decl_rtl for object so it looks like it is stored in memory.  */
> +rtx produce_memory_decl_rtl (tree, int *);
> +
> +/* Prepares decl_rtl for variables referred.  Callback for walk_tree.  */
> +tree prepare_decl_rtl (tree *, int *, void *);
> +
>  /* This is run during target initialization to set up which modes can be
>     used directly in memory and to initialize the block move optab.  */
>  extern void init_expr_target (void);
> diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
> index a44b4cb..885c8e8 100644
> --- a/gcc/tree-ssa-loop-ivopts.c
> +++ b/gcc/tree-ssa-loop-ivopts.c
> @@ -3687,94 +3687,6 @@ get_group_iv_cost (struct ivopts_data *data, struct 
> iv_group *group,
>    return NULL;
>  }
>
> -/* Produce DECL_RTL for object obj so it looks like it is stored in memory.  
> */
> -static rtx
> -produce_memory_decl_rtl (tree obj, int *regno)
> -{
> -  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (obj));
> -  machine_mode address_mode = targetm.addr_space.address_mode (as);
> -  rtx x;
> -
> -  gcc_assert (obj);
> -  if (TREE_STATIC (obj) || DECL_EXTERNAL (obj))
> -    {
> -      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (obj));
> -      x = gen_rtx_SYMBOL_REF (address_mode, name);
> -      SET_SYMBOL_REF_DECL (x, obj);
> -      x = gen_rtx_MEM (DECL_MODE (obj), x);
> -      set_mem_addr_space (x, as);
> -      targetm.encode_section_info (obj, x, true);
> -    }
> -  else
> -    {
> -      x = gen_raw_REG (address_mode, (*regno)++);
> -      x = gen_rtx_MEM (DECL_MODE (obj), x);
> -      set_mem_addr_space (x, as);
> -    }
> -
> -  return x;
> -}
> -
> -/* Prepares decl_rtl for variables referred in *EXPR_P.  Callback for
> -   walk_tree.  DATA contains the actual fake register number.  */
> -
> -static tree
> -prepare_decl_rtl (tree *expr_p, int *ws, void *data)
> -{
> -  tree obj = NULL_TREE;
> -  rtx x = NULL_RTX;
> -  int *regno = (int *) data;
> -
> -  switch (TREE_CODE (*expr_p))
> -    {
> -    case ADDR_EXPR:
> -      for (expr_p = &TREE_OPERAND (*expr_p, 0);
> -          handled_component_p (*expr_p);
> -          expr_p = &TREE_OPERAND (*expr_p, 0))
> -       continue;
> -      obj = *expr_p;
> -      if (DECL_P (obj) && HAS_RTL_P (obj) && !DECL_RTL_SET_P (obj))
> -       x = produce_memory_decl_rtl (obj, regno);
> -      break;
> -
> -    case SSA_NAME:
> -      *ws = 0;
> -      obj = SSA_NAME_VAR (*expr_p);
> -      /* Defer handling of anonymous SSA_NAMEs to the expander.  */
> -      if (!obj)
> -       return NULL_TREE;
> -      if (!DECL_RTL_SET_P (obj))
> -       x = gen_raw_REG (DECL_MODE (obj), (*regno)++);
> -      break;
> -
> -    case VAR_DECL:
> -    case PARM_DECL:
> -    case RESULT_DECL:
> -      *ws = 0;
> -      obj = *expr_p;
> -
> -      if (DECL_RTL_SET_P (obj))
> -       break;
> -
> -      if (DECL_MODE (obj) == BLKmode)
> -       x = produce_memory_decl_rtl (obj, regno);
> -      else
> -       x = gen_raw_REG (DECL_MODE (obj), (*regno)++);
> -
> -      break;
> -
> -    default:
> -      break;
> -    }
> -
> -  if (x)
> -    {
> -      decl_rtl_to_reset.safe_push (obj);
> -      SET_DECL_RTL (obj, x);
> -    }
> -
> -  return NULL_TREE;
> -}
>
>  /* Determines cost of the computation of EXPR.  */
>
> @@ -3792,7 +3704,10 @@ computation_cost (tree expr, bool speed)
>
>    node->frequency = NODE_FREQUENCY_NORMAL;
>    crtl->maybe_hot_insn_p = speed;
> -  walk_tree (&expr, prepare_decl_rtl, &regno, NULL);
> +  decl_rtl_data data;
> +  data.regno = &regno;
> +  data.treevec = &decl_rtl_to_reset;
> +  walk_tree (&expr, prepare_decl_rtl, &data, NULL);
>    start_sequence ();
>    rslt = expand_expr (expr, NULL_RTX, TYPE_MODE (type), EXPAND_NORMAL);
>    seq = get_insns ();
> --
> 2.7.4
>

Reply via email to