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? 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