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, ®no, NULL); > + decl_rtl_data data; > + data.regno = ®no; > + 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 >