X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-dfa.c;h=4e65c5dffc8914698e20e83a9167b9aef4842015;hb=f816ec49370bf5b0c3a5abf6a4e0392db78af2b0;hp=f3fa63aa6d89620bb4164d1a5cb6d55575f56240;hpb=5135beeb0469cb7a97d30f237701d6362e5ceaf8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index f3fa63aa6d8..4e65c5dffc8 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -42,10 +42,10 @@ Boston, MA 02111-1307, USA. */ #include "tree-gimple.h" #include "tree-flow.h" #include "tree-inline.h" -#include "tree-alias-common.h" #include "tree-pass.h" #include "convert.h" #include "params.h" +#include "cgraph.h" /* Build and maintain data flow information for trees. */ @@ -59,8 +59,9 @@ struct dfa_stats_d long num_phis; long num_phi_args; int max_num_phi_args; - long num_vdefs; + long num_v_may_defs; long num_vuses; + long num_v_must_defs; }; @@ -80,8 +81,6 @@ static tree find_vars_r (tree *, int *, void *); static void add_referenced_var (tree, struct walk_state *); static void compute_immediate_uses_for_phi (tree, bool (*)(tree)); static void compute_immediate_uses_for_stmt (tree, int, bool (*)(tree)); -static void find_hidden_use_vars (tree); -static tree find_hidden_use_vars_r (tree *, int *, void *); /* Global declarations. */ @@ -108,26 +107,8 @@ find_referenced_vars (void) basic_block bb; block_stmt_iterator si; struct walk_state walk_state; - tree block; - - /* This is the very first pass in preparation for building the SSA - form of the function, so initialize internal data structures now. */ - init_tree_ssa (); - - /* Walk the lexical blocks in the function looking for variables that may - have been used to declare VLAs and for nested functions. Both - constructs create hidden uses of variables. - - Note that at this point we may have multiple blocks hung off - DECL_INITIAL chained through the BLOCK_CHAIN field due to - how inlining works. Egad. */ - block = DECL_INITIAL (current_function_decl); - while (block) - { - find_hidden_use_vars (block); - block = BLOCK_CHAIN (block); - } + cgraph_reset_static_var_maps (); vars_found = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL); memset (&walk_state, 0, sizeof (walk_state)); walk_state.vars_found = vars_found; @@ -155,12 +136,13 @@ struct tree_opt_pass pass_referenced_vars = PROP_referenced_vars, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; -/* Compute immediate uses. - +/* Compute immediate uses. + CALC_FOR is an optional function pointer which indicates whether immediate uses information should be calculated for a given SSA variable. If NULL, then information is computed for all @@ -180,8 +162,21 @@ compute_immediate_uses (int flags, bool (*calc_for)(tree)) { tree phi; - for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi)) - compute_immediate_uses_for_phi (phi, calc_for); + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + { + if (is_gimple_reg (PHI_RESULT (phi))) + { + if (!(flags & TDFA_USE_OPS)) + continue; + } + else + { + if (!(flags & TDFA_USE_VOPS)) + continue; + } + + compute_immediate_uses_for_phi (phi, calc_for); + } for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) { @@ -193,28 +188,46 @@ compute_immediate_uses (int flags, bool (*calc_for)(tree)) } -/* Invalidates dataflow information for a statement STMT. */ +/* Invalidates dataflow information for a statement STMT. */ -static void +void free_df_for_stmt (tree stmt) { - stmt_ann_t ann = stmt_ann (stmt); + dataflow_t *df; - if (ann && ann->df) + if (TREE_CODE (stmt) == PHI_NODE) + df = &PHI_DF (stmt); + else { - /* If we have a varray of immediate uses, then go ahead and release - it for re-use. */ - if (ann->df->immediate_uses) - ggc_free (ann->df->immediate_uses); - - /* Similarly for the main dataflow structure. */ - ggc_free (ann->df); - ann->df = NULL; + stmt_ann_t ann = stmt_ann (stmt); + + if (!ann) + return; + + df = &ann->df; } + + if (!*df) + return; + + /* If we have a varray of immediate uses, then go ahead and release + it for re-use. */ + if ((*df)->immediate_uses) + ggc_free ((*df)->immediate_uses); + + /* Similarly for the main dataflow structure. */ + ggc_free (*df); + *df = NULL; } -/* Invalidate dataflow information for the whole function. */ +/* Invalidate dataflow information for the whole function. + + Note this only invalidates dataflow information on statements and + PHI nodes which are reachable. + + A deleted statement may still have attached dataflow information + on it. */ void free_df (void) @@ -226,7 +239,7 @@ free_df (void) { tree phi; - for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi)) + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) free_df_for_stmt (phi); for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) @@ -250,17 +263,14 @@ compute_immediate_uses_for_phi (tree phi, bool (*calc_for)(tree)) { int i; -#ifdef ENABLE_CHECKING - if (TREE_CODE (phi) != PHI_NODE) - abort (); -#endif + gcc_assert (TREE_CODE (phi) == PHI_NODE); for (i = 0; i < PHI_NUM_ARGS (phi); i++) { tree arg = PHI_ARG_DEF (phi, i); if (TREE_CODE (arg) == SSA_NAME && (!calc_for || calc_for (arg))) - { + { tree imm_rdef_stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF (phi, i)); if (!IS_EMPTY_STMT (imm_rdef_stmt)) add_immediate_use (imm_rdef_stmt, phi); @@ -277,26 +287,17 @@ compute_immediate_uses_for_phi (tree phi, bool (*calc_for)(tree)) static void compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) { - size_t i; - use_optype uses; - vuse_optype vuses; - vdef_optype vdefs; - stmt_ann_t ann; + tree use; + ssa_op_iter iter; -#ifdef ENABLE_CHECKING /* PHI nodes are handled elsewhere. */ - if (TREE_CODE (stmt) == PHI_NODE) - abort (); -#endif + gcc_assert (TREE_CODE (stmt) != PHI_NODE); /* Look at USE_OPS or VUSE_OPS according to FLAGS. */ - ann = stmt_ann (stmt); if (flags & TDFA_USE_OPS) { - uses = USE_OPS (ann); - for (i = 0; i < NUM_USES (uses); i++) + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) { - tree use = USE_OP (uses, i); tree imm_stmt = SSA_NAME_DEF_STMT (use); if (!IS_EMPTY_STMT (imm_stmt) && (!calc_for || calc_for (use))) add_immediate_use (imm_stmt, stmt); @@ -305,21 +306,10 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) if (flags & TDFA_USE_VOPS) { - vuses = VUSE_OPS (ann); - for (i = 0; i < NUM_VUSES (vuses); i++) - { - tree vuse = VUSE_OP (vuses, i); - tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse); - if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse))) - add_immediate_use (imm_rdef_stmt, stmt); - } - - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES) { - tree vuse = VDEF_OP (vdefs, i); - tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse); - if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse))) + tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use); + if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use))) add_immediate_use (imm_rdef_stmt, stmt); } } @@ -332,38 +322,44 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) static void add_immediate_use (tree stmt, tree use_stmt) { - stmt_ann_t ann = get_stmt_ann (stmt); - struct dataflow_d *df; + struct dataflow_d **df; - df = ann->df; - if (df == NULL) + if (TREE_CODE (stmt) == PHI_NODE) + df = &PHI_DF (stmt); + else { - df = ann->df = ggc_alloc (sizeof (struct dataflow_d)); - memset ((void *) df, 0, sizeof (struct dataflow_d)); - df->uses[0] = use_stmt; + stmt_ann_t ann = get_stmt_ann (stmt); + df = &ann->df; + } + + if (*df == NULL) + { + *df = ggc_alloc (sizeof (struct dataflow_d)); + memset ((void *) *df, 0, sizeof (struct dataflow_d)); + (*df)->uses[0] = use_stmt; return; } - if (!df->uses[1]) + if (!(*df)->uses[1]) { - df->uses[1] = use_stmt; + (*df)->uses[1] = use_stmt; return; } - if (ann->df->immediate_uses == NULL) - VARRAY_TREE_INIT (ann->df->immediate_uses, 4, "immediate_uses"); + if ((*df)->immediate_uses == NULL) + VARRAY_TREE_INIT ((*df)->immediate_uses, 4, "immediate_uses"); - VARRAY_PUSH_TREE (ann->df->immediate_uses, use_stmt); + VARRAY_PUSH_TREE ((*df)->immediate_uses, use_stmt); } /* If the immediate use of USE points to OLD, then redirect it to NEW. */ - + static void redirect_immediate_use (tree use, tree old, tree new) { tree imm_stmt = SSA_NAME_DEF_STMT (use); - struct dataflow_d *df = get_stmt_ann (imm_stmt)->df; + struct dataflow_d *df = get_immediate_uses (imm_stmt); unsigned int num_uses = num_immediate_uses (df); unsigned int i; @@ -387,21 +383,11 @@ redirect_immediate_use (tree use, tree old, tree new) void redirect_immediate_uses (tree old, tree new) { - stmt_ann_t ann = get_stmt_ann (old); - use_optype uses = USE_OPS (ann); - vuse_optype vuses = VUSE_OPS (ann); - vdef_optype vdefs = VDEF_OPS (ann); - unsigned int i; + ssa_op_iter iter; + tree val; - /* Look at USE_OPS or VUSE_OPS according to FLAGS. */ - for (i = 0; i < NUM_USES (uses); i++) - redirect_immediate_use (USE_OP (uses, i), old, new); - - for (i = 0; i < NUM_VUSES (vuses); i++) - redirect_immediate_use (VUSE_OP (vuses, i), old, new); - - for (i = 0; i < NUM_VDEFS (vdefs); i++) - redirect_immediate_use (VDEF_OP (vdefs, i), old, new); + FOR_EACH_SSA_TREE_OPERAND (val, old, iter, SSA_OP_ALL_USES) + redirect_immediate_use (val, old, new); } @@ -415,20 +401,16 @@ create_var_ann (tree t) { var_ann_t ann; -#if defined ENABLE_CHECKING - if (t == NULL_TREE - || !DECL_P (t) - || (t->common.ann - && t->common.ann->common.type != VAR_ANN)) - abort (); -#endif + gcc_assert (t); + gcc_assert (DECL_P (t)); + gcc_assert (!t->common.ann || t->common.ann->common.type == VAR_ANN); ann = ggc_alloc (sizeof (*ann)); memset ((void *) ann, 0, sizeof (*ann)); ann->common.type = VAR_ANN; - t->common.ann = (tree_ann) ann; + t->common.ann = (tree_ann_t) ann; return ann; } @@ -441,12 +423,8 @@ create_stmt_ann (tree t) { stmt_ann_t ann; -#if defined ENABLE_CHECKING - if ((!is_gimple_stmt (t) && !is_essa_node (t)) - || (t->common.ann - && t->common.ann->common.type != STMT_ANN)) - abort (); -#endif + gcc_assert (is_gimple_stmt (t)); + gcc_assert (!t->common.ann || t->common.ann->common.type == STMT_ANN); ann = ggc_alloc (sizeof (*ann)); memset ((void *) ann, 0, sizeof (*ann)); @@ -456,44 +434,42 @@ create_stmt_ann (tree t) /* Since we just created the annotation, mark the statement modified. */ ann->modified = true; - t->common.ann = (tree_ann) ann; + t->common.ann = (tree_ann_t) ann; return ann; } -/* Create a new annotation for an SSA name T. */ +/* Create a new annotation for a tree T. */ -ssa_name_ann_t -create_ssa_name_ann (tree t) +tree_ann_t +create_tree_ann (tree t) { - ssa_name_ann_t ann; + tree_ann_t ann; -#if defined ENABLE_CHECKING - if (t == NULL_TREE - || (t->common.ann - && t->common.ann->common.type != SSA_NAME_ANN)) - abort (); -#endif + gcc_assert (t); + gcc_assert (!t->common.ann || t->common.ann->common.type == TREE_ANN_COMMON); ann = ggc_alloc (sizeof (*ann)); memset ((void *) ann, 0, sizeof (*ann)); - ann->common.type = SSA_NAME_ANN; - t->common.ann = (tree_ann) ann; + ann->common.type = TREE_ANN_COMMON; + t->common.ann = ann; return ann; } - /* Build a temporary. Make sure and register it to be renamed. */ tree make_rename_temp (tree type, const char *prefix) { tree t = create_tmp_var (type, prefix); - add_referenced_tmp_var (t); - bitmap_set_bit (vars_to_rename, var_ann (t)->uid); + if (referenced_vars) + { + add_referenced_tmp_var (t); + bitmap_set_bit (vars_to_rename, var_ann (t)->uid); + } return t; } @@ -510,7 +486,7 @@ dump_referenced_vars (FILE *file) { size_t i; - fprintf (file, "\nReferenced variables in %s: %u\n\n", + fprintf (file, "\nReferenced variables in %s: %u\n\n", get_name (current_function_decl), (unsigned) num_referenced_vars); for (i = 0; i < num_referenced_vars; i++) @@ -539,6 +515,13 @@ dump_variable (FILE *file, tree var) { var_ann_t ann; + if (TREE_CODE (var) == SSA_NAME) + { + if (POINTER_TYPE_P (TREE_TYPE (var))) + dump_points_to_info_for (file, var); + var = SSA_NAME_VAR (var); + } + if (var == NULL_TREE) { fprintf (file, ""); @@ -546,16 +529,13 @@ dump_variable (FILE *file, tree var) } print_generic_expr (file, var, dump_flags); - - if (TREE_CODE (var) == SSA_NAME) - var = SSA_NAME_VAR (var); ann = var_ann (var); fprintf (file, ", UID %u", (unsigned) ann->uid); - if (ann->has_hidden_use) - fprintf (file, ", has hidden uses"); + fprintf (file, ", "); + print_generic_expr (file, TREE_TYPE (var), dump_flags); if (ann->type_mem_tag) { @@ -566,8 +546,11 @@ dump_variable (FILE *file, tree var) if (ann->is_alias_tag) fprintf (file, ", is an alias tag"); - if (needs_to_live_in_memory (var)) - fprintf (file, ", is %s", TREE_STATIC (var) ? "static" : "global"); + if (TREE_ADDRESSABLE (var)) + fprintf (file, ", is addressable"); + + if (is_global_var (var)) + fprintf (file, ", is global"); if (is_call_clobbered (var)) fprintf (file, ", call clobbered"); @@ -613,7 +596,7 @@ dump_immediate_uses (FILE *file) { tree phi; - for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi)) + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) dump_immediate_uses_for (file, phi); for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) @@ -695,7 +678,7 @@ dump_dfa_stats (FILE *file) size = num_referenced_vars * sizeof (tree); total += size; - fprintf (file, fmt_str_1, "Referenced variables", num_referenced_vars, + fprintf (file, fmt_str_1, "Referenced variables", num_referenced_vars, SCALE (size), LABEL (size)); size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d); @@ -723,9 +706,14 @@ dump_dfa_stats (FILE *file) fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses, SCALE (size), LABEL (size)); - size = dfa_stats.num_vdefs * sizeof (tree *); + size = dfa_stats.num_v_may_defs * sizeof (tree *); total += size; - fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs, + fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs, + SCALE (size), LABEL (size)); + + size = dfa_stats.num_v_must_defs * sizeof (tree *); + total += size; + fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs, SCALE (size), LABEL (size)); size = dfa_stats.num_phis * sizeof (struct tree_phi_node); @@ -772,8 +760,7 @@ collect_dfa_stats (struct dfa_stats_d *dfa_stats_p) basic_block bb; block_stmt_iterator i; - if (dfa_stats_p == NULL) - abort (); + gcc_assert (dfa_stats_p); memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d)); @@ -790,7 +777,7 @@ collect_dfa_stats (struct dfa_stats_d *dfa_stats_p) FOR_EACH_BB (bb) { tree phi; - for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi)) + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) { dfa_stats_p->num_phis++; dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi); @@ -821,8 +808,11 @@ collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, dfa_stats_p->num_stmt_anns++; dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann)); dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann)); - dfa_stats_p->num_vdefs += NUM_VDEFS (VDEF_OPS (ann)); + dfa_stats_p->num_v_may_defs += + NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)); dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann)); + dfa_stats_p->num_v_must_defs += + NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)); break; } @@ -848,24 +838,17 @@ collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, static tree find_vars_r (tree *tp, int *walk_subtrees, void *data) { - tree t = *tp; - struct walk_state *walk_state = (struct walk_state *)data; + struct walk_state *walk_state = (struct walk_state *) data; - if (SSA_VAR_P (t)) - { - /* If T is a regular variable that the optimizers are interested - in, add it to the list of variables. */ - add_referenced_var (t, walk_state); - } - else if (DECL_P (t) - || TYPE_P (t) - || TREE_CODE_CLASS (TREE_CODE (t)) == 'c') - { - /* Type, _DECL and constant nodes have no interesting children. - Ignore them. */ - *walk_subtrees = 0; - } + /* If T is a regular variable that the optimizers are interested + in, add it to the list of variables. */ + if (SSA_VAR_P (*tp)) + add_referenced_var (*tp, walk_state); + /* Type, _DECL and constant nodes have no interesting children. + Ignore them. */ + else if (IS_TYPE_OR_DECL_P (*tp) || CONSTANT_CLASS_P (*tp)) + *walk_subtrees = 0; return NULL_TREE; } @@ -901,14 +884,17 @@ add_referenced_var (tree var, struct walk_state *walk_state) v_ann->uid = num_referenced_vars; VARRAY_PUSH_TREE (referenced_vars, var); - /* Global and static variables are call-clobbered, always. */ - if (needs_to_live_in_memory (var)) + /* Global variables are always call-clobbered. */ + if (is_global_var (var)) mark_call_clobbered (var); - /* DECL_NONLOCAL variables should not be removed, as they are needed - to emit nested functions. */ - if (DECL_NONLOCAL (var)) - v_ann->used = 1; + /* If an initialized global variable then register the initializer + as well. */ + if (POINTER_TYPE_P (TREE_TYPE (var)) + && TREE_READONLY (var) + && DECL_INITIAL (var) + && TREE_CODE (DECL_INITIAL (var)) == ADDR_EXPR) + walk_tree (&DECL_INITIAL (var), find_vars_r, walk_state, 0); } } @@ -918,112 +904,24 @@ add_referenced_var (tree var, struct walk_state *walk_state) tree get_virtual_var (tree var) { - enum tree_code code; - STRIP_NOPS (var); if (TREE_CODE (var) == SSA_NAME) var = SSA_NAME_VAR (var); - code = TREE_CODE (var); + while (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR + || handled_component_p (var)) + var = TREE_OPERAND (var, 0); - while (code == ARRAY_REF - || code == COMPONENT_REF - || code == REALPART_EXPR - || code == IMAGPART_EXPR) - { - var = TREE_OPERAND (var, 0); - code = TREE_CODE (var); - } - -#ifdef ENABLE_CHECKING /* Treating GIMPLE registers as virtual variables makes no sense. Also complain if we couldn't extract a _DECL out of the original expression. */ - if (!SSA_VAR_P (var) - || is_gimple_reg (var)) - abort (); -#endif + gcc_assert (SSA_VAR_P (var)); + gcc_assert (!is_gimple_reg (var)); return var; } - -/* Mark variables in BLOCK that have hidden uses. A hidden use can - occur due to VLA declarations or nested functions. */ - -static void -find_hidden_use_vars (tree block) -{ - tree sub, decl, tem; - - /* Check all the arrays declared in the block for VLAs. - While scanning the block's variables, also see if there is - a nested function at this scope. */ - for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) - { - int inside_vla = 0; - walk_tree (&decl, find_hidden_use_vars_r, &inside_vla, NULL); - } - - /* Now repeat the search in any sub-blocks. */ - for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub)) - find_hidden_use_vars (sub); - - /* A VLA parameter may use a variable which as set from another - parameter to declare the size of the VLA. We need to mark the - variable as having a hidden use since it is used to declare the - VLA parameter and that declaration is not seen by the SSA code. - - Note get_pending_sizes clears the PENDING_SIZES chain, so we - must restore it. */ - tem = get_pending_sizes (); - put_pending_sizes (tem); - for (; tem; tem = TREE_CHAIN (tem)) - { - int inside_vla = 1; - walk_tree (&TREE_VALUE (tem), find_hidden_use_vars_r, &inside_vla, NULL); - } -} - - -/* Callback for walk_tree used by find_hidden_use_vars to analyze each - variable in a lexical block. If the variable's size has a variable - size, then mark all objects needed to compute the variable's size - as having hidden uses. */ - -static tree -find_hidden_use_vars_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) -{ - int *inside_vla = (int *) data; - - /* We need to look for hidden uses due to VLAs in variable - definitions. We originally used to look for these hidden - uses in the variable's type, but that's unreliable if the - type's size contains a SAVE_EXPR for a different function - context than the variable is used within. */ - if (SSA_VAR_P (*tp) - && ((DECL_SIZE (*tp) - && ! really_constant_p (DECL_SIZE (*tp))) - || (DECL_SIZE_UNIT (*tp) - && ! really_constant_p (DECL_SIZE_UNIT (*tp))))) - { - int save = *inside_vla; - - *inside_vla = 1; - walk_tree (&DECL_SIZE (*tp), find_hidden_use_vars_r, inside_vla, NULL); - walk_tree (&DECL_SIZE_UNIT (*tp), find_hidden_use_vars_r, - inside_vla, NULL); - *inside_vla = save; - } - else if (*inside_vla && SSA_VAR_P (*tp)) - set_has_hidden_use (*tp); - - return NULL_TREE; -} - - /* Add a temporary variable to REFERENCED_VARS. This is similar to add_referenced_var, but is used by passes that need to add new temps to the REFERENCED_VARS array after the program has been scanned for @@ -1037,41 +935,18 @@ add_referenced_tmp_var (tree var) } -/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE. - Note that this assumes that both varrays are VDEF operands for the same - statement. */ - -static inline bool -vdefs_disappeared_p (vdef_optype vdefs_before, vdef_optype vdefs_after) -{ - /* If there was nothing before, nothing could've disappeared. */ - if (vdefs_before == NULL) - return false; - - /* All/some of them gone. */ - if (vdefs_after == NULL - || NUM_VDEFS (vdefs_before) > NUM_VDEFS (vdefs_after)) - return true; - - return false; -} - - /* Add all the non-SSA variables found in STMT's operands to the bitmap VARS_TO_RENAME. */ void mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) { - def_optype defs; - use_optype uses; - vdef_optype vdefs; - vuse_optype vuses; - size_t i; + ssa_op_iter iter; + tree val; bitmap vars_in_vops_to_rename; bool found_exposed_symbol = false; - vdef_optype vdefs_before, vdefs_after; - stmt_ann_t ann; + int v_may_defs_before, v_may_defs_after; + int v_must_defs_before, v_must_defs_after; vars_in_vops_to_rename = BITMAP_XMALLOC (); @@ -1084,23 +959,15 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) We flag them in a separate bitmap because we don't really want to rename them if there are not any newly exposed symbols in the statement operands. */ - ann = stmt_ann (stmt); - vdefs_before = vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) - { - tree var = VDEF_RESULT (vdefs, i); - if (!DECL_P (var)) - var = SSA_NAME_VAR (var); - bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid); - } + v_may_defs_before = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)); + v_must_defs_before = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)); - vuses = VUSE_OPS (ann); - for (i = 0; i < NUM_VUSES (vuses); i++) + FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, + SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF) { - tree var = VUSE_OP (vuses, i); - if (!DECL_P (var)) - var = SSA_NAME_VAR (var); - bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid); + if (!DECL_P (val)) + val = SSA_NAME_VAR (val); + bitmap_set_bit (vars_in_vops_to_rename, var_ann (val)->uid); } /* Now force an operand re-scan on the statement and mark any newly @@ -1108,47 +975,17 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) modify_stmt (stmt); get_stmt_operands (stmt); - defs = DEF_OPS (ann); - for (i = 0; i < NUM_DEFS (defs); i++) - { - tree var = DEF_OP (defs, i); - if (DECL_P (var)) - { - found_exposed_symbol = true; - bitmap_set_bit (vars_to_rename, var_ann (var)->uid); - } - } - - uses = USE_OPS (ann); - for (i = 0; i < NUM_USES (uses); i++) - { - tree var = USE_OP (uses, i); - if (DECL_P (var)) - { - found_exposed_symbol = true; - bitmap_set_bit (vars_to_rename, var_ann (var)->uid); - } - } + v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)); + v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)); - vdefs_after = vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) - { - tree var = VDEF_RESULT (vdefs, i); - if (DECL_P (var)) - { - found_exposed_symbol = true; - bitmap_set_bit (vars_to_rename, var_ann (var)->uid); - } - } + FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, + SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF) - vuses = VUSE_OPS (ann); - for (i = 0; i < NUM_VUSES (vuses); i++) { - tree var = VUSE_OP (vuses, i); - if (DECL_P (var)) + if (DECL_P (val)) { found_exposed_symbol = true; - bitmap_set_bit (vars_to_rename, var_ann (var)->uid); + bitmap_set_bit (vars_to_rename, var_ann (val)->uid); } } @@ -1158,7 +995,8 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) vanishing VDEFs because in those cases, the names that were formerly generated by this statement are not going to be available anymore. */ if (found_exposed_symbol - || vdefs_disappeared_p (vdefs_before, vdefs_after)) + || v_may_defs_before > v_may_defs_after + || v_must_defs_before > v_must_defs_after) bitmap_a_or_b (vars_to_rename, vars_to_rename, vars_in_vops_to_rename); BITMAP_XFREE (vars_in_vops_to_rename);