From d00ad49ba1c217ec55751ed6461890e8911bb001 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 17 Jun 2004 18:13:20 +0000 Subject: [PATCH] tree-cfg.c (tree_make_forwarder_block): Use SET_PHI_RESULT. 2004-06-16 Andrew MacLeod * tree-cfg.c (tree_make_forwarder_block): Use SET_PHI_RESULT. * tree-flow-inline.h (get_use_op_ptr): Return a use_operand_p. (get_use_from_ptr, get_def_from_ptr): New. Return operand pointers. (get_def_op_ptr): Return a def_operand_p instead of a 'tree *'. (get_v_may_def_result_ptr): Return a def_operand_p. (get_v_may_def_op_ptr, get_vuse_op_ptr): Return a use_operand_p. (get_v_must_def_op_ptr): Return a def_operand_p. (get_phi_result_ptr): New. Return a pointer to the result of a PHI. (get_phi_arg_def_ptr): New. Return a pointer to an argument of a PHI. (phi_element_for_edge): Remove. * tree-flow.h (propagate_value, replace_exp): Change prototype. (propagate_tree_value): Add new prototype. (phi_element_for_edge): Remove prototype. * tree-into-ssa.c (mark_def_sites): Use new operand types. (prepare_operand_for_rename): Split into two functions. (prepare_use_operand_for_rename): Prepare use operands. (prepare_def_operand_for_rename): Prepare def operands. (rewrite_stmt): Use new operand types. (rewrite_operand): Use new operand types, change parameter type. * tree-outof-ssa.c (replace_variable): Split into two functions. (replace_use_variable): Rewrite uses. (replace_def_variable): Rewrite defs. (rewrite_trees, rewrite_vars_out_of_ssa): Use new operand types. * tree-phinodes.c (make_phi_node, resize_phi_node): Use new types. (add_phi_arg, remove_phi_arg_num): Use new operand types. * tree-ssa-ccp.c (substitute_and_fold): Use new operand types. (ccp_fold, replace_uses_in): Use new operand types. * tree-ssa-copy.c (replace_ssa_names): Rename to replace_ssa_names_ann and no longer set the value, change parameter type. (replace_exp_1): Use new operand types. (propagate_value): Change parameter type, use new operand types. (propagate_tree_value): Propagate_value without SSA operands. (replace_exp, cprop_operand, cprop_into_stmt): Use new operand types. (cprop_into_successor_phis): Use new operand types. * tree-ssa-dom.c (thread_across_edge): Use new operand types. (eliminate_redundant_computations): Use new operand types. * tree-ssa-dse.c (fix_phi_uses): Use new operand_types. (fix_stmt_v_may_defs): Use new operand_types. * tree-ssa-live.c (create_ssa_var_map): Use new operand_types. (build_tree_conflict_graph): Use new operand_types. * tree-ssa-loop.c (duplicate_blocks): Use PHI_ARG_DEF_FROM_EDGE. * tree-ssa-operands.c (struct freelist_d): Remove. (check_optype_freelist, add_optype_freelist): Remove. (allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype, allocate_vuse_optype, allocate_v_must_def_optype): Call ggc_alloc. (free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs): Call ggc_free instead of add_optype_freelist. (init_ssa_operands, fini_ssa_operands): Remove free list code. (finalize_ssa_defs, finalize_ssa_uses): Set new use/def operands. * tree-ssa-operands.h (struct def_optype_d): Change underlying type. (struct use_optype_d): Change underlying type. (def_operand_p, use_operand_p): New types for pointers to operands. (USE_OP, DEF_OP, V_MAY_DEF_RESULT, V_MAY_DEF_OP, VUSE_OP, V_MUST_DEF_OP): Use new pointer type instead of dereferencing directly. (USE_FROM_PTR, DEF_FROM_PTR): New macros to "dereference" operand pointer types. (SET_USE, SET_DEF): New macros to set operands from their pointer. (SET_USE_OP, SET_DEF_OP, SET_V_MAY_DEF_RESULT, SET_V_MAY_DEF_OP, SET_VUSE_OP, SET_V_MUST_DEF_OP): New SET routines for operands. (PHI_RESULT_PTR, PHI_RESULT, SET_PHI_RESULT): Macros to manage the PHI result as an operand. (PHI_ARG_DEF_PTR, PHI_ARG_DEF, SET_PHI_ARG_DEF, PHI_ARG_DEF_FROM_EDGE, PHI_ARG_DEF_PTR_FROM_EDGE): Macros to manage the PHI arguments. * tree-ssa-pre.c (eliminate): Call propagate_tree_value. * tree-tailcall.c (independent_of_stmt_p, propagate_through_phis): Use PHI_ARG_DEF_FROM_EDGE. * tree.h (PHI_RESULT): Renamed to PHI_RESULT_TREE. (PHI_ARG_DEF): Renamed to PHI_ARG_DEF_TREE. From-SVN: r83298 --- gcc/ChangeLog | 71 +++++++++++++++++++++++++++ gcc/tree-cfg.c | 2 +- gcc/tree-flow-inline.h | 84 ++++++++++++++++++++----------- gcc/tree-flow.h | 6 +-- gcc/tree-into-ssa.c | 106 +++++++++++++++++++++++----------------- gcc/tree-outof-ssa.c | 69 +++++++++++++++++++------- gcc/tree-phinodes.c | 12 ++--- gcc/tree-ssa-ccp.c | 22 +++++---- gcc/tree-ssa-copy.c | 105 ++++++++++++++++++++++++--------------- gcc/tree-ssa-dom.c | 12 ++--- gcc/tree-ssa-dse.c | 5 +- gcc/tree-ssa-live.c | 24 ++++----- gcc/tree-ssa-loop.c | 2 +- gcc/tree-ssa-operands.c | 90 +++++----------------------------- gcc/tree-ssa-operands.h | 72 ++++++++++++++++++++++++--- gcc/tree-ssa-pre.c | 2 +- gcc/tree-ssa.c | 2 +- gcc/tree-tailcall.c | 4 +- gcc/tree.h | 16 +++--- 19 files changed, 434 insertions(+), 272 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3e237d10432..3c4f826df78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,74 @@ +2004-06-17 Andrew MacLeod + + * tree-cfg.c (tree_make_forwarder_block): Use SET_PHI_RESULT. + * tree-flow-inline.h (get_use_op_ptr): Return a use_operand_p. + (get_use_from_ptr, get_def_from_ptr): New. Return operand pointers. + (get_def_op_ptr): Return a def_operand_p instead of a 'tree *'. + (get_v_may_def_result_ptr): Return a def_operand_p. + (get_v_may_def_op_ptr, get_vuse_op_ptr): Return a use_operand_p. + (get_v_must_def_op_ptr): Return a def_operand_p. + (get_phi_result_ptr): New. Return a pointer to the result of a PHI. + (get_phi_arg_def_ptr): New. Return a pointer to an argument of a PHI. + (phi_element_for_edge): Remove. + * tree-flow.h (propagate_value, replace_exp): Change prototype. + (propagate_tree_value): Add new prototype. + (phi_element_for_edge): Remove prototype. + * tree-into-ssa.c (mark_def_sites): Use new operand types. + (prepare_operand_for_rename): Split into two functions. + (prepare_use_operand_for_rename): Prepare use operands. + (prepare_def_operand_for_rename): Prepare def operands. + (rewrite_stmt): Use new operand types. + (rewrite_operand): Use new operand types, change parameter type. + * tree-outof-ssa.c (replace_variable): Split into two functions. + (replace_use_variable): Rewrite uses. + (replace_def_variable): Rewrite defs. + (rewrite_trees, rewrite_vars_out_of_ssa): Use new operand types. + * tree-phinodes.c (make_phi_node, resize_phi_node): Use new types. + (add_phi_arg, remove_phi_arg_num): Use new operand types. + * tree-ssa-ccp.c (substitute_and_fold): Use new operand types. + (ccp_fold, replace_uses_in): Use new operand types. + * tree-ssa-copy.c (replace_ssa_names): Rename to replace_ssa_names_ann + and no longer set the value, change parameter type. + (replace_exp_1): Use new operand types. + (propagate_value): Change parameter type, use new operand types. + (propagate_tree_value): Propagate_value without SSA operands. + (replace_exp, cprop_operand, cprop_into_stmt): Use new operand types. + (cprop_into_successor_phis): Use new operand types. + * tree-ssa-dom.c (thread_across_edge): Use new operand types. + (eliminate_redundant_computations): Use new operand types. + * tree-ssa-dse.c (fix_phi_uses): Use new operand_types. + (fix_stmt_v_may_defs): Use new operand_types. + * tree-ssa-live.c (create_ssa_var_map): Use new operand_types. + (build_tree_conflict_graph): Use new operand_types. + * tree-ssa-loop.c (duplicate_blocks): Use PHI_ARG_DEF_FROM_EDGE. + * tree-ssa-operands.c (struct freelist_d): Remove. + (check_optype_freelist, add_optype_freelist): Remove. + (allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype, + allocate_vuse_optype, allocate_v_must_def_optype): Call ggc_alloc. + (free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs): + Call ggc_free instead of add_optype_freelist. + (init_ssa_operands, fini_ssa_operands): Remove free list code. + (finalize_ssa_defs, finalize_ssa_uses): Set new use/def operands. + * tree-ssa-operands.h (struct def_optype_d): Change underlying type. + (struct use_optype_d): Change underlying type. + (def_operand_p, use_operand_p): New types for pointers to operands. + (USE_OP, DEF_OP, V_MAY_DEF_RESULT, V_MAY_DEF_OP, VUSE_OP, + V_MUST_DEF_OP): Use new pointer type instead of dereferencing directly. + (USE_FROM_PTR, DEF_FROM_PTR): New macros to "dereference" operand + pointer types. + (SET_USE, SET_DEF): New macros to set operands from their pointer. + (SET_USE_OP, SET_DEF_OP, SET_V_MAY_DEF_RESULT, SET_V_MAY_DEF_OP, + SET_VUSE_OP, SET_V_MUST_DEF_OP): New SET routines for operands. + (PHI_RESULT_PTR, PHI_RESULT, SET_PHI_RESULT): Macros to manage the + PHI result as an operand. + (PHI_ARG_DEF_PTR, PHI_ARG_DEF, SET_PHI_ARG_DEF, PHI_ARG_DEF_FROM_EDGE, + PHI_ARG_DEF_PTR_FROM_EDGE): Macros to manage the PHI arguments. + * tree-ssa-pre.c (eliminate): Call propagate_tree_value. + * tree-tailcall.c (independent_of_stmt_p, propagate_through_phis): Use + PHI_ARG_DEF_FROM_EDGE. + * tree.h (PHI_RESULT): Renamed to PHI_RESULT_TREE. + (PHI_ARG_DEF): Renamed to PHI_ARG_DEF_TREE. + 2004-06-17 Zdenek Dvorak PR tree-optimization/15991 diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 4b3ca40d134..25d5b06ef47 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3747,7 +3747,7 @@ tree_make_forwarder_block (edge fallthru) var = PHI_RESULT (phi); new_phi = create_phi_node (var, bb); SSA_NAME_DEF_STMT (var) = new_phi; - PHI_RESULT (phi) = make_ssa_name (SSA_NAME_VAR (var), phi); + SET_PHI_RESULT (phi, make_ssa_name (SSA_NAME_VAR (var), phi)); add_phi_arg (&new_phi, PHI_RESULT (phi), fallthru); } diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index c47ba09c515..fbca4082b76 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -272,8 +272,22 @@ get_v_must_def_ops (stmt_ann_t ann) return ann ? ann->v_must_def_ops : NULL; } +/* Return the tree pointer to by USE. */ +static inline tree +get_use_from_ptr (use_operand_p use) +{ + return *(use.use); +} + +/* Return the tree pointer to by DEF. */ +static inline tree +get_def_from_ptr (def_operand_p def) +{ + return *(def.def); +} + /* Return a pointer to the tree that is at INDEX in the USES array. */ -static inline tree * +static inline use_operand_p get_use_op_ptr (use_optype uses, unsigned int index) { #ifdef ENABLE_CHECKING @@ -283,8 +297,8 @@ get_use_op_ptr (use_optype uses, unsigned int index) return uses->uses[index]; } -/* Return a pointer to the tree that is at INDEX in the DEFS array. */ -static inline tree * +/* Return a def_operand_p pointer for element INDEX of DEFS. */ +static inline def_operand_p get_def_op_ptr (def_optype defs, unsigned int index) { #ifdef ENABLE_CHECKING @@ -295,53 +309,79 @@ get_def_op_ptr (def_optype defs, unsigned int index) } -/* Return a pointer to the tree that is the V_MAY_DEF_RESULT for the V_MAY_DEF +/* Return the def_operand_p that is the V_MAY_DEF_RESULT for the V_MAY_DEF at INDEX in the V_MAY_DEFS array. */ -static inline tree * +static inline def_operand_p get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index) { + def_operand_p op; #ifdef ENABLE_CHECKING if (index >= v_may_defs->num_v_may_defs) abort(); #endif - return &(v_may_defs->v_may_defs[index * 2]); + op.def = &(v_may_defs->v_may_defs[index * 2]); + return op; } -/* Return a pointer to the tree that is the V_MAY_DEF_OP for the V_MAY_DEF at +/* Return a use_operand_p that is the V_MAY_DEF_OP for the V_MAY_DEF at INDEX in the V_MAY_DEFS array. */ -static inline tree * +static inline use_operand_p get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index) { + use_operand_p op; #ifdef ENABLE_CHECKING if (index >= v_may_defs->num_v_may_defs) abort(); #endif - return &(v_may_defs->v_may_defs[index * 2 + 1]); + op.use = &(v_may_defs->v_may_defs[index * 2 + 1]); + return op; } -/* Return a pointer to the tree that is at INDEX in the VUSES array. */ -static inline tree * +/* Return a use_operand_p that is at INDEX in the VUSES array. */ +static inline use_operand_p get_vuse_op_ptr(vuse_optype vuses, unsigned int index) { + use_operand_p op; #ifdef ENABLE_CHECKING if (index >= vuses->num_vuses) abort(); #endif - return &(vuses->vuses[index]); + op.use = &(vuses->vuses[index]); + return op; } -/* Return a pointer to the tree that is the V_MUST_DEF_OP for the +/* Return a def_operand_p that is the V_MUST_DEF_OP for the V_MUST_DEF at INDEX in the V_MUST_DEFS array. */ -static inline tree * +static inline def_operand_p get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index) { + def_operand_p op; #ifdef ENABLE_CHECKING if (index >= v_must_defs->num_v_must_defs) abort(); #endif - return &(v_must_defs->v_must_defs[index]); + op.def = &(v_must_defs->v_must_defs[index]); + return op; } +/* Return a def_operand_p pointer for the result of PHI. */ +static inline def_operand_p +get_phi_result_ptr (tree phi) +{ + def_operand_p op; + op.def = &(PHI_RESULT_TREE (phi)); + return op; +} + +/* Return a use_operand_p pointer for argument I of phinode PHI. */ +static inline use_operand_p +get_phi_arg_def_ptr (tree phi, int i) +{ + use_operand_p op; + op.use = &(PHI_ARG_DEF_TREE (phi, i)); + return op; +} + /* Mark the beginning of changes to the SSA operands for STMT. */ static inline void start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED) @@ -448,20 +488,6 @@ phi_arg_from_edge (tree phi, edge e) return -1; } - -/* Return the phi argument number for an edge. */ -static inline struct phi_arg_d * -phi_element_for_edge (tree phi, edge e) -{ - int i; - - i = phi_arg_from_edge (phi, e); - if (i != -1) - return &(PHI_ARG_ELT (phi, i)); - else - return (struct phi_arg_d *)NULL; -} - /* ----------------------------------------------------------------------- */ /* Return true if T is an executable statement. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index d9d0b1e3328..12b3b0961de 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -580,14 +580,14 @@ extern void dump_dominator_optimization_stats (FILE *); extern void debug_dominator_optimization_stats (void); /* In tree-ssa-copy.c */ -extern void propagate_value (tree *, tree); -extern void replace_exp (tree *, tree); +extern void propagate_value (use_operand_p, tree); +extern void propagate_tree_value (tree *, tree); +extern void replace_exp (use_operand_p, tree); extern bool cprop_into_stmt (tree, varray_type); extern void cprop_into_successor_phis (basic_block, varray_type, bitmap); /* In tree-flow-inline.h */ static inline int phi_arg_from_edge (tree, edge); -static inline struct phi_arg_d *phi_element_for_edge (tree, edge); static inline bool may_propagate_copy (tree, tree); static inline bool is_call_clobbered (tree); static inline void mark_call_clobbered (tree); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 0f926860427..0a20d2d8a43 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -109,11 +109,12 @@ static void mark_def_sites_initialize_block (struct dom_walk_data *walk_data, static void compute_global_livein (bitmap, bitmap); static void set_def_block (tree, basic_block); static void set_livein_block (tree, basic_block); -static bool prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool); +static bool prepare_use_operand_for_rename (use_operand_p op_p, size_t *uid_p); +static bool prepare_def_operand_for_rename (tree def, size_t *uid_p); static void insert_phi_nodes (bitmap *); static void rewrite_stmt (struct dom_walk_data *, basic_block, block_stmt_iterator); -static inline void rewrite_operand (tree *); +static inline void rewrite_operand (use_operand_p); static void insert_phi_nodes_for (tree, bitmap *, varray_type *); static tree get_reaching_def (tree); static hashval_t def_blocks_hash (const void *); @@ -231,21 +232,21 @@ mark_def_sites (struct dom_walk_data *walk_data, uses = USE_OPS (ann); for (i = 0; i < NUM_USES (uses); i++) { - tree *use_p = USE_OP_PTR (uses, i); + use_operand_p use_p = USE_OP_PTR (uses, i); - if (prepare_operand_for_rename (use_p, &uid, true) + if (prepare_use_operand_for_rename (use_p, &uid) && !TEST_BIT (kills, uid)) - set_livein_block (*use_p, bb); + set_livein_block (USE_FROM_PTR (use_p), bb); } /* Similarly for virtual uses. */ vuses = VUSE_OPS (ann); for (i = 0; i < NUM_VUSES (vuses); i++) { - tree *use_p = VUSE_OP_PTR (vuses, i); + use_operand_p use_p = VUSE_OP_PTR (vuses, i); - if (prepare_operand_for_rename (use_p, &uid, true)) - set_livein_block (*use_p, bb); + if (prepare_use_operand_for_rename (use_p, &uid)) + set_livein_block (USE_FROM_PTR (use_p), bb); } /* Note that virtual definitions are irrelevant for computing KILLS @@ -256,15 +257,15 @@ mark_def_sites (struct dom_walk_data *walk_data, v_may_defs = V_MAY_DEF_OPS (ann); for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - if (prepare_operand_for_rename (V_MAY_DEF_OP_PTR (v_may_defs, i), - &uid, true)) + use_operand_p use_p = V_MAY_DEF_OP_PTR (v_may_defs, i); + if (prepare_use_operand_for_rename (use_p, &uid)) { /* If we do not already have an SSA_NAME for our destination, then set the destination to the source. */ if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME) - V_MAY_DEF_RESULT (v_may_defs, i) = V_MAY_DEF_OP (v_may_defs, i); + SET_V_MAY_DEF_RESULT (v_may_defs, i, USE_FROM_PTR (use_p)); - set_livein_block (V_MAY_DEF_OP (v_may_defs, i), bb); + set_livein_block (USE_FROM_PTR (use_p), bb); set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb); } } @@ -273,11 +274,11 @@ mark_def_sites (struct dom_walk_data *walk_data, v_must_defs = V_MUST_DEF_OPS (ann); for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) { - tree *def_p = V_MUST_DEF_OP_PTR (v_must_defs, i); + tree def = V_MUST_DEF_OP (v_must_defs, i); - if (prepare_operand_for_rename (def_p, &uid, false)) + if (prepare_def_operand_for_rename (def, &uid)) { - set_def_block (*def_p, bb); + set_def_block (def, bb); SET_BIT (kills, uid); } } @@ -287,11 +288,11 @@ mark_def_sites (struct dom_walk_data *walk_data, defs = DEF_OPS (ann); for (i = 0; i < NUM_DEFS (defs); i++) { - tree *def_p = DEF_OP_PTR (defs, i); + tree def = DEF_OP (defs, i); - if (prepare_operand_for_rename (def_p, &uid, false)) + if (prepare_def_operand_for_rename (def, &uid)) { - set_def_block (*def_p, bb); + set_def_block (def, bb); SET_BIT (kills, uid); } } @@ -367,21 +368,16 @@ set_livein_block (tree var, basic_block bb) } -/* If the operand pointed to by OP_P needs to be renamed, then - - 1. If OP_P is used (rather than set), then strip away any SSA_NAME - wrapping the operand. - - 2. Set *UID_P to the underlying variable's uid. - - 3. Return true. - - Otherwise return false. */ +/* If the use operand pointed to by OP_P needs to be renamed, then strip away + any SSA_NAME wrapping the operand, set *UID_P to the underlying variable's + uid, and return true. Otherwise return false. If the operand was an + SSA_NAME, change it to the stipped name. */ static bool -prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool is_use) +prepare_use_operand_for_rename (use_operand_p op_p, size_t *uid_p) { - tree var = (TREE_CODE (*op_p) != SSA_NAME) ? *op_p : SSA_NAME_VAR (*op_p); + tree use = USE_FROM_PTR (op_p); + tree var = (TREE_CODE (use) != SSA_NAME) ? use : SSA_NAME_VAR (use); *uid_p = var_ann (var)->uid; /* Ignore variables that don't need to be renamed. */ @@ -394,12 +390,28 @@ prepare_operand_for_rename (tree *op_p, size_t *uid_p, bool is_use) By not throwing away SSA_NAMEs on assignments, we avoid a lot of useless churn of SSA_NAMEs without having to overly complicate the renamer. */ - if (TREE_CODE (*op_p) == SSA_NAME && is_use) - *op_p = var; + if (TREE_CODE (use) == SSA_NAME) + SET_USE (op_p, var); return true; } +/* If the def variable DEF needs to be renamed, then strip away any SSA_NAME + wrapping the operand, set *UID_P to the underlying variable's uid and return + true. Otherwise return false. */ + +static bool +prepare_def_operand_for_rename (tree def, size_t *uid_p) +{ + tree var = (TREE_CODE (def) != SSA_NAME) ? def : SSA_NAME_VAR (def); + *uid_p = var_ann (var)->uid; + + /* Ignore variables that don't need to be renamed. */ + if (vars_to_rename && !bitmap_bit_p (vars_to_rename, *uid_p)) + return false; + + return true; +} /* Helper for insert_phi_nodes. If VAR needs PHI nodes, insert them at the dominance frontier (DFS) of blocks defining VAR. */ @@ -774,14 +786,14 @@ rewrite_stmt (struct dom_walk_data *walk_data, /* Step 2. Register the statement's DEF and VDEF operands. */ for (i = 0; i < NUM_DEFS (defs); i++) { - tree *def_p = DEF_OP_PTR (defs, i); + def_operand_p def_p = DEF_OP_PTR (defs, i); - if (TREE_CODE (*def_p) != SSA_NAME) - *def_p = make_ssa_name (*def_p, stmt); + if (TREE_CODE (DEF_FROM_PTR (def_p)) != SSA_NAME) + SET_DEF (def_p, make_ssa_name (DEF_FROM_PTR (def_p), stmt)); /* FIXME: We shouldn't be registering new defs if the variable doesn't need to be renamed. */ - register_new_def (*def_p, &bd->block_defs); + register_new_def (DEF_FROM_PTR (def_p), &bd->block_defs); } /* Register new virtual definitions made by the statement. */ @@ -790,8 +802,9 @@ rewrite_stmt (struct dom_walk_data *walk_data, rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i)); if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME) - *V_MAY_DEF_RESULT_PTR (v_may_defs, i) - = make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), stmt); + SET_V_MAY_DEF_RESULT (v_may_defs, i, + make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), + stmt)); /* FIXME: We shouldn't be registering new defs if the variable doesn't need to be renamed. */ @@ -801,27 +814,28 @@ rewrite_stmt (struct dom_walk_data *walk_data, /* Register new virtual mustdefs made by the statement. */ for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) { - tree *v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i); + def_operand_p v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i); - if (TREE_CODE (*v_must_def_p) != SSA_NAME) - *v_must_def_p = make_ssa_name (*v_must_def_p, stmt); + if (TREE_CODE (DEF_FROM_PTR (v_must_def_p)) != SSA_NAME) + SET_DEF (v_must_def_p, + make_ssa_name (DEF_FROM_PTR (v_must_def_p), stmt)); /* FIXME: We shouldn't be registering new mustdefs if the variable doesn't need to be renamed. */ - register_new_def (*v_must_def_p, &bd->block_defs); + register_new_def (DEF_FROM_PTR (v_must_def_p), &bd->block_defs); } } -/* Replace the operand pointed by OP_P with its immediate reaching +/* Replace the use operand pointed by OP_P with its immediate reaching definition. */ static inline void -rewrite_operand (tree *op_p) +rewrite_operand (use_operand_p op_p) { - if (TREE_CODE (*op_p) != SSA_NAME) - *op_p = get_reaching_def (*op_p); + if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME) + SET_USE (op_p, get_reaching_def (USE_FROM_PTR (op_p))); } diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index ec52f6939fb..28c802381d0 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -116,7 +116,8 @@ static void elim_create (elim_graph, int); static void eliminate_phi (edge, int, elim_graph); static tree_live_info_p coalesce_ssa_name (var_map, int); static void assign_vars (var_map); -static bool replace_variable (var_map, tree *, tree *); +static bool replace_use_variable (var_map, use_operand_p, tree *); +static bool replace_def_variable (var_map, def_operand_p, tree *); static void eliminate_virtual_phis (void); static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p); static void print_exprs (FILE *, const char *, tree, const char *, tree, @@ -922,25 +923,25 @@ assign_vars (var_map map) } -/* Replace *P with whatever variable it has been rewritten to based on the - partitions in MAP. EXPR is an optional expression vector over SSA versions - which is used to replace *P with an expression instead of a variable. +/* Replace use operand P with whatever variable it has been rewritten to based + on the partitions in MAP. EXPR is an optional expression vector over SSA + versions which is used to replace P with an expression instead of a variable. If the stmt is changed, return true. */ static inline bool -replace_variable (var_map map, tree *p, tree *expr) +replace_use_variable (var_map map, use_operand_p p, tree *expr) { tree new_var; - tree var = *p; + tree var = USE_FROM_PTR (p); /* Check if we are replacing this variable with an expression. */ if (expr) { - int version = SSA_NAME_VERSION (*p); + int version = SSA_NAME_VERSION (var); if (expr[version]) { tree new_expr = TREE_OPERAND (expr[version], 1); - *p = new_expr; + SET_USE (p, new_expr); /* Clear the stmt's RHS, or GC might bite us. */ TREE_OPERAND (expr[version], 1) = NULL_TREE; return true; @@ -950,7 +951,43 @@ replace_variable (var_map map, tree *p, tree *expr) new_var = var_to_partition_to_var (map, var); if (new_var) { - *p = new_var; + SET_USE (p, new_var); + set_is_used (new_var); + return true; + } + return false; +} + + +/* Replace def operand DEF_P with whatever variable it has been rewritten to + based on the partitions in MAP. EXPR is an optional expression vector over + SSA versions which is used to replace DEF_P with an expression instead of a + variable. If the stmt is changed, return true. */ + +static inline bool +replace_def_variable (var_map map, def_operand_p def_p, tree *expr) +{ + tree new_var; + tree var = DEF_FROM_PTR (def_p); + + /* Check if we are replacing this variable with an expression. */ + if (expr) + { + int version = SSA_NAME_VERSION (var); + if (expr[version]) + { + tree new_expr = TREE_OPERAND (expr[version], 1); + SET_DEF (def_p, new_expr); + /* Clear the stmt's RHS, or GC might bite us. */ + TREE_OPERAND (expr[version], 1) = NULL_TREE; + return true; + } + } + + new_var = var_to_partition_to_var (map, var); + if (new_var) + { + SET_DEF (def_p, new_var); set_is_used (new_var); return true; } @@ -1832,7 +1869,7 @@ rewrite_trees (var_map map, tree *values) use_optype uses; def_optype defs; tree stmt = bsi_stmt (si); - tree *use_p = NULL; + use_operand_p use_p; int remove = 0, is_copy = 0; stmt_ann_t ann; @@ -1850,7 +1887,7 @@ rewrite_trees (var_map map, tree *values) for (i = 0; i < num_uses; i++) { use_p = USE_OP_PTR (uses, i); - if (replace_variable (map, use_p, values)) + if (replace_use_variable (map, use_p, values)) changed = true; } @@ -1871,18 +1908,16 @@ rewrite_trees (var_map map, tree *values) { for (i = 0; i < num_defs; i++) { - tree *def_p = DEF_OP_PTR (defs, i); + def_operand_p def_p = DEF_OP_PTR (defs, i); - if (replace_variable (map, def_p, NULL)) + if (replace_def_variable (map, def_p, NULL)) changed = true; /* If both SSA_NAMEs coalesce to the same variable, mark the now redundant copy for removal. */ if (is_copy && num_uses == 1 - && use_p - && def_p - && (*def_p == *use_p)) + && (DEF_FROM_PTR (def_p) == USE_OP (uses, 0))) remove = 1; } if (changed) @@ -2074,7 +2109,7 @@ rewrite_vars_out_of_ssa (bitmap vars) SSA_NAME_DEF_STMT (new_name) = copy; /* Now make the argument reference our new SSA_NAME. */ - PHI_ARG_DEF (phi, i) = new_name; + SET_PHI_ARG_DEF (phi, i, new_name); /* Queue the statement for insertion. */ bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy); diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 1b98fcd05bc..dc2a2294e7f 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -203,9 +203,9 @@ make_phi_node (tree var, int len) TREE_SET_CODE (phi, PHI_NODE); PHI_ARG_CAPACITY (phi) = len; if (TREE_CODE (var) == SSA_NAME) - PHI_RESULT (phi) = var; + SET_PHI_RESULT (phi, var); else - PHI_RESULT (phi) = make_ssa_name (var, phi); + SET_PHI_RESULT (phi, make_ssa_name (var, phi)); return phi; } @@ -278,7 +278,7 @@ resize_phi_node (tree *phi, int len) for (i = old_len; i < len; i++) { - PHI_ARG_DEF (new_phi, i) = NULL_TREE; + SET_PHI_ARG_DEF (new_phi, i, NULL_TREE); PHI_ARG_EDGE (new_phi, i) = NULL; PHI_ARG_NONZERO (new_phi, i) = false; } @@ -365,7 +365,7 @@ add_phi_arg (tree *phi, tree def, edge e) SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (*phi)) = 1; } - PHI_ARG_DEF (*phi, i) = def; + SET_PHI_ARG_DEF (*phi, i, def); PHI_ARG_EDGE (*phi, i) = e; PHI_ARG_NONZERO (*phi, i) = false; PHI_NUM_ARGS (*phi)++; @@ -408,13 +408,13 @@ remove_phi_arg_num (tree phi, int i) with the element we want to delete. */ if (i != num_elem - 1) { - PHI_ARG_DEF (phi, i) = PHI_ARG_DEF (phi, num_elem - 1); + SET_PHI_ARG_DEF (phi, i, PHI_ARG_DEF (phi, num_elem - 1)); PHI_ARG_EDGE (phi, i) = PHI_ARG_EDGE (phi, num_elem - 1); PHI_ARG_NONZERO (phi, i) = PHI_ARG_NONZERO (phi, num_elem - 1); } /* Shrink the vector and return. */ - PHI_ARG_DEF (phi, num_elem - 1) = NULL_TREE; + SET_PHI_ARG_DEF (phi, num_elem - 1, NULL_TREE); PHI_ARG_EDGE (phi, num_elem - 1) = NULL; PHI_ARG_NONZERO (phi, num_elem - 1) = false; PHI_NUM_ARGS (phi)--; diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 405591fd4aa..53a67a63b85 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -389,15 +389,16 @@ substitute_and_fold (void) for (i = 0; i < PHI_NUM_ARGS (phi); i++) { value *new_val; - tree *orig_p = &PHI_ARG_DEF (phi, i); + use_operand_p orig_p = PHI_ARG_DEF_PTR (phi, i); + tree orig = USE_FROM_PTR (orig_p); - if (! SSA_VAR_P (*orig_p)) + if (! SSA_VAR_P (orig)) break; - new_val = get_value (*orig_p); + new_val = get_value (orig); if (new_val->lattice_val == CONSTANT - && may_propagate_copy (*orig_p, new_val->const_val)) - *orig_p = new_val->const_val; + && may_propagate_copy (orig, new_val->const_val)) + SET_USE (orig_p, new_val->const_val); } } @@ -948,7 +949,7 @@ ccp_fold (tree stmt) /* Restore operands to their original form. */ for (i = 0; i < NUM_USES (uses); i++) - *(USE_OP_PTR (uses, i)) = orig[i]; + SET_USE_OP (uses, i, orig[i]); free (orig); } } @@ -1422,14 +1423,15 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p) uses = STMT_USE_OPS (stmt); for (i = 0; i < NUM_USES (uses); i++) { - tree *use = USE_OP_PTR (uses, i); - value *val = get_value (*use); + use_operand_p use = USE_OP_PTR (uses, i); + value *val = get_value (USE_FROM_PTR (use)); if (val->lattice_val == CONSTANT) { - *use = val->const_val; + SET_USE (use, val->const_val); replaced = true; - if (POINTER_TYPE_P (TREE_TYPE (*use)) && replaced_addresses_p) + if (POINTER_TYPE_P (TREE_TYPE (USE_FROM_PTR (use))) + && replaced_addresses_p) *replaced_addresses_p = true; } } diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 71574d4df00..32db3fa3d86 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -54,31 +54,33 @@ Boston, MA 02111-1307, USA. */ replacements of one SSA_NAME with a different SSA_NAME to use the APIs defined in this file. */ -/* Given two SSA_NAMEs, replace the one pointed to by OP_P with VAR. - If *OP_P is a pointer, copy the memory tag used originally by *OP_P into +/* Given two SSA_NAMEs, replace the annotations for the one referred to by OP + with VAR's annmoptations. + + If OP is a pointer, copy the memory tag used originally by OP into VAR. This is needed in cases where VAR had never been dereferenced in the program. If FOR_PROPAGATION is true, then perform additional checks to ensure - that const/copy propagation of var for *OP_P is valid. */ + that const/copy propagation of var for OP is valid. */ static void -replace_ssa_names (tree *op_p, +replace_ssa_names_ann (tree op, tree var, bool for_propagation ATTRIBUTE_UNUSED) { #if defined ENABLE_CHECKING - if (for_propagation && !may_propagate_copy (*op_p, var)) + if (for_propagation && !may_propagate_copy (op, var)) abort (); #endif /* If VAR doesn't have a memory tag, copy the one from the original operand. Also copy the dereferenced flags. */ - if (POINTER_TYPE_P (TREE_TYPE (*op_p))) + if (POINTER_TYPE_P (TREE_TYPE (op))) { var_ann_t new_ann = var_ann (SSA_NAME_VAR (var)); - var_ann_t orig_ann = var_ann (SSA_NAME_VAR (*op_p)); + var_ann_t orig_ann = var_ann (SSA_NAME_VAR (op)); if (new_ann->type_mem_tag == NULL_TREE) new_ann->type_mem_tag = orig_ann->type_mem_tag; @@ -88,26 +90,25 @@ replace_ssa_names (tree *op_p, abort (); } - *op_p = var; -} +} + /* Common code for propagate_value and replace_exp. - Replace *OP_P with VAL. FOR_PROPAGATION indicates if the replacement - is done to propagate a value or not. */ + Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the + replacement is done to propagate a value or not. */ static void -replace_exp_1 (tree *op_p, tree val, bool for_propagation) +replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation) { if (TREE_CODE (val) == SSA_NAME) { - if (TREE_CODE (*op_p) == SSA_NAME) - replace_ssa_names (op_p, val, for_propagation); - else - *op_p = val; + if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME) + replace_ssa_names_ann (USE_FROM_PTR (op_p), val, for_propagation); + SET_USE (op_p, val); } else - *op_p = lhd_unsave_expr_now (val); + SET_USE (op_p, lhd_unsave_expr_now (val)); } /* Propagate the value VAL (assumed to be a constant or another SSA_NAME) @@ -117,11 +118,32 @@ replace_exp_1 (tree *op_p, tree val, bool for_propagation) checks to ensure validity of the const/copy propagation. */ void -propagate_value (tree *op_p, tree val) +propagate_value (use_operand_p op_p, tree val) { replace_exp_1 (op_p, val, true); } +/* Propagate the value VAL (assumed to be a constant or another SSA_NAME) + into the tree pointed by OP_P. + + Use this version for const/copy propagation when SSA operands are not + available. It will perform the additional checks to ensure validity of + the const/copy propagation, but will not update any operand information. + Be sure to mark the stmt as modified. */ + +void +propagate_tree_value (tree *op_p, tree val) +{ + if (TREE_CODE (val) == SSA_NAME) + { + if (TREE_CODE (*op_p) == SSA_NAME) + replace_ssa_names_ann (*op_p, val, true); + *op_p = val; + } + else + *op_p = lhd_unsave_expr_now (val); +} + /* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME). Use this version when not const/copy propagating values. For example, @@ -129,7 +151,7 @@ propagate_value (tree *op_p, tree val) in specific blocks taking into account actions of PHI nodes. */ void -replace_exp (tree *op_p, tree val) +replace_exp (use_operand_p op_p, tree val) { replace_exp_1 (op_p, val, false); } @@ -138,15 +160,16 @@ replace_exp (tree *op_p, tree val) CONST_AND_COPIES. */ static bool -cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) +cprop_operand (stmt_ann_t ann, use_operand_p op_p, varray_type const_and_copies) { bool may_have_exposed_new_symbols = false; tree val; + tree op = USE_FROM_PTR (op_p); /* If the operand has a known constant value or it is known to be a copy of some other variable, use the value or copy stored in CONST_AND_COPIES. */ - val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (*op_p)); + val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (op)); if (val) { tree op_type, val_type; @@ -156,13 +179,13 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) the renamed virtual operand if we later modify this statement. Also only allow the new value to be an SSA_NAME for propagation into virtual operands. */ - if (!is_gimple_reg (*op_p) - && (get_virtual_var (val) != get_virtual_var (*op_p) + if (!is_gimple_reg (op) + && (get_virtual_var (val) != get_virtual_var (op) || TREE_CODE (val) != SSA_NAME)) return false; /* Get the toplevel type of each operand. */ - op_type = TREE_TYPE (*op_p); + op_type = TREE_TYPE (op); val_type = TREE_TYPE (val); /* While both types are pointers, get the type of the object @@ -180,7 +203,7 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) if (!lang_hooks.types_compatible_p (op_type, val_type) && TREE_CODE (val) != SSA_NAME) { - val = fold_convert (TREE_TYPE (*op_p), val); + val = fold_convert (TREE_TYPE (op), val); if (!is_gimple_min_invariant (val) && TREE_CODE (val) != SSA_NAME) return false; @@ -190,14 +213,14 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) to their interaction with exception handling and some GCC extensions. */ if (TREE_CODE (val) == SSA_NAME - && !may_propagate_copy (*op_p, val)) + && !may_propagate_copy (op, val)) return false; /* Dump details. */ if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " Replaced '"); - print_generic_expr (dump_file, *op_p, dump_flags); + print_generic_expr (dump_file, op, dump_flags); fprintf (dump_file, "' with %s '", (TREE_CODE (val) != SSA_NAME ? "constant" : "variable")); print_generic_expr (dump_file, val, dump_flags); @@ -207,7 +230,7 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) /* If VAL is an ADDR_EXPR or a constant of pointer type, note that we may have exposed a new symbol for SSA renaming. */ if (TREE_CODE (val) == ADDR_EXPR - || (POINTER_TYPE_P (TREE_TYPE (*op_p)) + || (POINTER_TYPE_P (TREE_TYPE (op)) && is_gimple_min_invariant (val))) may_have_exposed_new_symbols = true; @@ -241,8 +264,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies) num_uses = NUM_USES (uses); for (i = 0; i < num_uses; i++) { - tree *op_p = USE_OP_PTR (uses, i); - if (TREE_CODE (*op_p) == SSA_NAME) + use_operand_p op_p = USE_OP_PTR (uses, i); + if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME) may_have_exposed_new_symbols |= cprop_operand (ann, op_p, const_and_copies); } @@ -251,8 +274,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies) num_vuses = NUM_VUSES (vuses); for (i = 0; i < num_vuses; i++) { - tree *op_p = VUSE_OP_PTR (vuses, i); - if (TREE_CODE (*op_p) == SSA_NAME) + use_operand_p op_p = VUSE_OP_PTR (vuses, i); + if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME) may_have_exposed_new_symbols |= cprop_operand (ann, op_p, const_and_copies); } @@ -261,8 +284,8 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies) num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs); for (i = 0; i < num_v_may_defs; i++) { - tree *op_p = V_MAY_DEF_OP_PTR (v_may_defs, i); - if (TREE_CODE (*op_p) == SSA_NAME) + use_operand_p op_p = V_MAY_DEF_OP_PTR (v_may_defs, i); + if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME) may_have_exposed_new_symbols |= cprop_operand (ann, op_p, const_and_copies); } @@ -317,7 +340,8 @@ cprop_into_successor_phis (basic_block bb, { int i; tree new; - tree *orig_p; + use_operand_p orig_p; + tree orig; /* If the hint is valid (!= phi_num_args), see if it points us to the desired phi alternative. */ @@ -343,22 +367,23 @@ cprop_into_successor_phis (basic_block bb, /* The alternative may be associated with a constant, so verify it is an SSA_NAME before doing anything with it. */ - orig_p = &PHI_ARG_DEF (phi, hint); - if (TREE_CODE (*orig_p) != SSA_NAME) + orig_p = PHI_ARG_DEF_PTR (phi, hint); + orig = USE_FROM_PTR (orig_p); + if (TREE_CODE (orig) != SSA_NAME) continue; /* If the alternative is known to have a nonzero value, record that fact in the PHI node itself for future use. */ - if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (*orig_p))) + if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig))) PHI_ARG_NONZERO (phi, hint) = true; /* If we have *ORIG_P in our constant/copy table, then replace ORIG_P with its value in our constant/copy table. */ - new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (*orig_p)); + new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (orig)); if (new && (TREE_CODE (new) == SSA_NAME || is_gimple_min_invariant (new)) - && may_propagate_copy (*orig_p, new)) + && may_propagate_copy (orig, new)) propagate_value (orig_p, new); } } diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 636af8e5834..2be24ae1c8d 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -700,7 +700,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) /* Each PHI creates a temporary equivalence, record them. */ for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi)) { - tree src = PHI_ARG_DEF (phi, phi_arg_from_edge (phi, e)); + tree src = PHI_ARG_DEF_FROM_EDGE (phi, e); tree dst = PHI_RESULT (phi); record_const_or_copy (dst, src, &bd->const_and_copies); register_new_def (dst, &bd->block_defs); @@ -761,7 +761,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME) tmp = get_value_for (USE_OP (uses, i), const_and_copies); if (tmp) - *USE_OP_PTR (uses, i) = tmp; + SET_USE_OP (uses, i, tmp); } /* Similarly for virtual uses. */ @@ -773,7 +773,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME) tmp = get_value_for (VUSE_OP (vuses, i), const_and_copies); if (tmp) - VUSE_OP (vuses, i) = tmp; + SET_VUSE_OP (vuses, i, tmp); } /* Try to lookup the new expression. */ @@ -781,10 +781,10 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) /* Restore the statement's original uses/defs. */ for (i = 0; i < NUM_USES (uses); i++) - *USE_OP_PTR (uses, i) = uses_copy[i]; + SET_USE_OP (uses, i, uses_copy[i]); for (i = 0; i < NUM_VUSES (vuses); i++) - VUSE_OP (vuses, i) = vuses_copy[i]; + SET_VUSE_OP (vuses, i, vuses_copy[i]); free (uses_copy); free (vuses_copy); @@ -2386,7 +2386,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data, && is_gimple_min_invariant (cached_lhs))) retval = true; - propagate_value (expr_p, cached_lhs); + propagate_tree_value (expr_p, cached_lhs); ann->modified = 1; } return retval; diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index e5ba66f56aa..7902e14ff17 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -132,7 +132,7 @@ fix_phi_uses (tree phi, tree stmt) them with the appropriate V_MAY_DEF_OP. */ for (j = 0; j < PHI_NUM_ARGS (phi); j++) if (v_may_def == PHI_ARG_DEF (phi, j)) - PHI_ARG_DEF (phi, j) = V_MAY_DEF_OP (v_may_defs, i); + SET_PHI_ARG_DEF (phi, j, V_MAY_DEF_OP (v_may_defs, i)); } } @@ -164,8 +164,7 @@ fix_stmt_v_may_defs (tree stmt1, tree stmt2) if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j)) { /* Update. */ - *V_MAY_DEF_OP_PTR (v_may_defs1, i) = - V_MAY_DEF_OP (v_may_defs2, j); + SET_V_MAY_DEF_OP (v_may_defs1, i, V_MAY_DEF_OP (v_may_defs2, j)); break; } } diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 2f9288b7114..6daf6557f0d 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -294,7 +294,7 @@ create_ssa_var_map (int flags) { block_stmt_iterator bsi; basic_block bb; - tree *dest, *use; + tree dest, use; tree stmt; stmt_ann_t ann; vuse_optype vuses; @@ -351,22 +351,22 @@ create_ssa_var_map (int flags) uses = USE_OPS (ann); for (x = 0; x < NUM_USES (uses); x++) { - use = USE_OP_PTR (uses, x); - register_ssa_partition (map, *use, true); + use = USE_OP (uses, x); + register_ssa_partition (map, use, true); #if defined ENABLE_CHECKING - SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*use))->uid); + SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (use))->uid); #endif } defs = DEF_OPS (ann); for (x = 0; x < NUM_DEFS (defs); x++) { - dest = DEF_OP_PTR (defs, x); - register_ssa_partition (map, *dest, false); + dest = DEF_OP (defs, x); + register_ssa_partition (map, dest, false); #if defined ENABLE_CHECKING - SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*dest))->uid); + SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (dest))->uid); #endif } @@ -1393,22 +1393,22 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa, if (!is_a_copy) { - tree *var_p; + tree var; defs = DEF_OPS (ann); num = NUM_DEFS (defs); for (x = 0; x < num; x++) { - var_p = DEF_OP_PTR (defs, x); - add_conflicts_if_valid (tpa, graph, map, live, *var_p); + var = DEF_OP (defs, x); + add_conflicts_if_valid (tpa, graph, map, live, var); } uses = USE_OPS (ann); num = NUM_USES (uses); for (x = 0; x < num; x++) { - var_p = USE_OP_PTR (uses, x); - set_if_valid (map, live, *var_p); + var = USE_OP (uses, x); + set_if_valid (map, live, var); } } } diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 89692a27705..e0b3d830b84 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -225,7 +225,7 @@ duplicate_blocks (varray_type bbs_to_duplicate) for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi)) { - tree def = phi_element_for_edge (phi, e)->def; + tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); add_phi_arg (&phi, def, e1); } } diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index f1edfa18e18..9eb0bd12e11 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -88,65 +88,15 @@ static void add_call_clobber_ops (tree, voperands_t); static void add_call_read_ops (tree, voperands_t); static void add_stmt_operand (tree *, tree, int, voperands_t); - -struct freelist_d GTY((chain_next ("%h.next"))) -{ - struct freelist_d *next; -}; - -#define NUM_FREE 5 -static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0}, {0} }; - - -static inline void * -check_optype_freelist (size_t num ATTRIBUTE_UNUSED) -{ - return NULL; -#if 0 - void *vec = NULL; - - if (num <= NUM_FREE && optype_freelist[num - 1].next) - { - vec = (void *)optype_freelist[num - 1].next; - optype_freelist[num - 1].next = optype_freelist[num - 1].next->next; - } - return vec; -#endif -} /* Return a vector of contiguous memory of a specified size. */ - -static inline void -add_optype_freelist (void *vec ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED) -{ -#if 0 - struct freelist_d *ptr; -#ifdef ENABLE_CHECKING - if (size == 0) - abort (); -#endif - - /* if its bigger than one of our lists, simply let it go and let GC - collect it. */ - if (size > NUM_FREE) - return; - - ptr = vec; - ptr->next = optype_freelist[size - 1].next;; - optype_freelist[size - 1].next = ptr; -#endif -} - - static inline def_optype allocate_def_optype (unsigned num) { def_optype def_ops; unsigned size; size = sizeof (struct def_optype_d) + sizeof (tree *) * (num - 1); - def_ops = check_optype_freelist (num); - if (!def_ops) - def_ops = ggc_alloc (size); + def_ops = ggc_alloc (size); def_ops->num_defs = num; return def_ops; } @@ -157,9 +107,7 @@ allocate_use_optype (unsigned num) use_optype use_ops; unsigned size; size = sizeof (struct use_optype_d) + sizeof (tree *) * (num - 1); - use_ops = check_optype_freelist (num); - if (!use_ops) - use_ops = ggc_alloc (size); + use_ops = ggc_alloc (size); use_ops->num_uses = num; return use_ops; } @@ -170,9 +118,7 @@ allocate_v_may_def_optype (unsigned num) v_may_def_optype v_may_def_ops; unsigned size; size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1); - v_may_def_ops = check_optype_freelist (num * 2); - if (!v_may_def_ops) - v_may_def_ops = ggc_alloc (size); + v_may_def_ops = ggc_alloc (size); v_may_def_ops->num_v_may_defs = num; return v_may_def_ops; } @@ -183,9 +129,7 @@ allocate_vuse_optype (unsigned num) vuse_optype vuse_ops; unsigned size; size = sizeof (struct vuse_optype_d) + sizeof (tree) * (num - 1); - vuse_ops = check_optype_freelist (num); - if (!vuse_ops) - vuse_ops = ggc_alloc (size); + vuse_ops = ggc_alloc (size); vuse_ops->num_vuses = num; return vuse_ops; } @@ -196,9 +140,7 @@ allocate_v_must_def_optype (unsigned num) v_must_def_optype v_must_def_ops; unsigned size; size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1); - v_must_def_ops = check_optype_freelist (num); - if (!v_must_def_ops) - v_must_def_ops = ggc_alloc (size); + v_must_def_ops = ggc_alloc (size); v_must_def_ops->num_v_must_defs = num; return v_must_def_ops; } @@ -209,7 +151,7 @@ free_uses (use_optype *uses, bool dealloc) if (*uses) { if (dealloc) - add_optype_freelist (*uses, (*uses)->num_uses); + ggc_free (*uses); *uses = NULL; } } @@ -220,7 +162,7 @@ free_defs (def_optype *defs, bool dealloc) if (*defs) { if (dealloc) - add_optype_freelist (*defs, (*defs)->num_defs); + ggc_free (*defs); *defs = NULL; } } @@ -231,7 +173,7 @@ free_vuses (vuse_optype *vuses, bool dealloc) if (*vuses) { if (dealloc) - add_optype_freelist (*vuses, (*vuses)->num_vuses); + ggc_free (*vuses); *vuses = NULL; } } @@ -242,7 +184,7 @@ free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc) if (*v_may_defs) { if (dealloc) - add_optype_freelist (*v_may_defs, (*v_may_defs)->num_v_may_defs); + ggc_free (*v_may_defs); *v_may_defs = NULL; } } @@ -253,7 +195,7 @@ free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc) if (*v_must_defs) { if (dealloc) - add_optype_freelist (*v_must_defs, (*v_must_defs)->num_v_must_defs); + ggc_free (*v_must_defs); *v_must_defs = NULL; } } @@ -291,24 +233,16 @@ remove_v_must_defs (tree stmt) void init_ssa_operands (void) { - int x; - VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs"); VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses"); VARRAY_TREE_INIT (build_v_may_defs, 10, "build v_may_defs"); VARRAY_TREE_INIT (build_vuses, 10, "build vuses"); VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs"); - - for (x = 0; x < NUM_FREE; x++) - optype_freelist[x].next = NULL; } void fini_ssa_operands (void) { - int x; - for (x = 0; x < NUM_FREE; x++) - optype_freelist[x].next = NULL; } static void @@ -330,7 +264,7 @@ finalize_ssa_defs (tree stmt) def_ops = allocate_def_optype (num); for (x = 0; x < num ; x++) - def_ops->defs[x] = VARRAY_TREE_PTR (build_defs, x); + def_ops->defs[x].def = VARRAY_TREE_PTR (build_defs, x); VARRAY_POP_ALL (build_defs); ann = stmt_ann (stmt); @@ -363,7 +297,7 @@ finalize_ssa_uses (tree stmt) use_ops = allocate_use_optype (num); for (x = 0; x < num ; x++) - use_ops->uses[x] = VARRAY_TREE_PTR (build_uses, x); + use_ops->uses[x].use = VARRAY_TREE_PTR (build_uses, x); VARRAY_POP_ALL (build_uses); ann = stmt_ann (stmt); diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h index e83c776d11f..f34ac162b62 100644 --- a/gcc/tree-ssa-operands.h +++ b/gcc/tree-ssa-operands.h @@ -23,22 +23,39 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* Interface to SSA operands. */ + +/* This represents a pointer to a DEF operand. */ +typedef struct def_operand_ptr GTY(()) +{ + tree * GTY((skip(""))) def; +} def_operand_p; + +/* This represents a pointer to a USE operand. */ +typedef struct use_operand_ptr GTY(()) +{ + tree * GTY((skip(""))) use; +} use_operand_p; + + +/* This represents the DEF operands of a stmt. */ typedef struct def_optype_d GTY(()) { unsigned num_defs; - tree * GTY((length("%h.num_defs"), skip(""))) defs[1]; + struct def_operand_ptr GTY((length("%h.num_defs"))) defs[1]; } def_optype_t; typedef def_optype_t *def_optype; +/* This represents the USE operands of a stmt. */ typedef struct use_optype_d GTY(()) { unsigned num_uses; - tree * GTY((length("%h.num_uses"), skip(""))) uses[1]; + struct use_operand_ptr GTY((length("%h.num_uses"))) uses[1]; } use_optype_t; typedef use_optype_t *use_optype; +/* This represents the MAY_DEFS for a stmt. */ typedef struct v_may_def_optype_d GTY(()) { unsigned num_v_may_defs; @@ -47,6 +64,7 @@ typedef struct v_may_def_optype_d GTY(()) typedef v_may_def_optype_t *v_may_def_optype; +/* This represents the VUSEs for a stmt. */ typedef struct vuse_optype_d GTY(()) { unsigned num_vuses; @@ -55,6 +73,7 @@ typedef struct vuse_optype_d GTY(()) typedef vuse_optype_t *vuse_optype; +/* This represents the V_MUST_DEFS for a stmt. */ typedef struct v_must_def_optype_d GTY(()) { unsigned num_v_must_defs; @@ -63,41 +82,78 @@ typedef struct v_must_def_optype_d GTY(()) typedef v_must_def_optype_t *v_must_def_optype; +#define USE_FROM_PTR(OP) get_use_from_ptr (OP) +#define DEF_FROM_PTR(OP) get_def_from_ptr (OP) +#define SET_USE(OP, V) ((*((OP).use)) = (V)) +#define SET_DEF(OP, V) ((*((OP).def)) = (V)) + + #define USE_OPS(ANN) get_use_ops (ANN) #define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT)) #define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0) #define USE_OP_PTR(OPS, I) get_use_op_ptr ((OPS), (I)) -#define USE_OP(OPS, I) (*(USE_OP_PTR ((OPS), (I)))) +#define USE_OP(OPS, I) (USE_FROM_PTR (USE_OP_PTR ((OPS), (I)))) +#define SET_USE_OP(OPS, I, V) (SET_USE (USE_OP_PTR ((OPS), (I)), (V))) + #define DEF_OPS(ANN) get_def_ops (ANN) #define STMT_DEF_OPS(STMT) get_def_ops (stmt_ann (STMT)) #define NUM_DEFS(OPS) ((OPS) ? (OPS)->num_defs : 0) #define DEF_OP_PTR(OPS, I) get_def_op_ptr ((OPS), (I)) -#define DEF_OP(OPS, I) (*(DEF_OP_PTR ((OPS), (I)))) +#define DEF_OP(OPS, I) (DEF_FROM_PTR (DEF_OP_PTR ((OPS), (I)))) +#define SET_DEF_OP(OPS, I, V) (SET_DEF (DEF_OP_PTR ((OPS), (I)), (V))) + #define V_MAY_DEF_OPS(ANN) get_v_may_def_ops (ANN) #define STMT_V_MAY_DEF_OPS(STMT) get_v_may_def_ops (stmt_ann(STMT)) #define NUM_V_MAY_DEFS(OPS) ((OPS) ? (OPS)->num_v_may_defs : 0) #define V_MAY_DEF_RESULT_PTR(OPS, I) get_v_may_def_result_ptr ((OPS), (I)) -#define V_MAY_DEF_RESULT(OPS, I) (*(V_MAY_DEF_RESULT_PTR ((OPS), (I)))) +#define V_MAY_DEF_RESULT(OPS, I) \ + (DEF_FROM_PTR (V_MAY_DEF_RESULT_PTR ((OPS), (I)))) +#define SET_V_MAY_DEF_RESULT(OPS, I, V) \ + (SET_DEF (V_MAY_DEF_RESULT_PTR ((OPS), (I)), (V))) #define V_MAY_DEF_OP_PTR(OPS, I) get_v_may_def_op_ptr ((OPS), (I)) -#define V_MAY_DEF_OP(OPS, I) (*(V_MAY_DEF_OP_PTR ((OPS), (I)))) +#define V_MAY_DEF_OP(OPS, I) \ + (USE_FROM_PTR (V_MAY_DEF_OP_PTR ((OPS), (I)))) +#define SET_V_MAY_DEF_OP(OPS, I, V) \ + (SET_USE (V_MAY_DEF_OP_PTR ((OPS), (I)), (V))) #define VUSE_OPS(ANN) get_vuse_ops (ANN) #define STMT_VUSE_OPS(STMT) get_vuse_ops (stmt_ann(STMT)) #define NUM_VUSES(OPS) ((OPS) ? (OPS)->num_vuses : 0) #define VUSE_OP_PTR(OPS, I) get_vuse_op_ptr ((OPS), (I)) -#define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I)))) +#define VUSE_OP(OPS, I) (USE_FROM_PTR (VUSE_OP_PTR ((OPS), (I)))) +#define SET_VUSE_OP(OPS, I, V) (SET_USE (VUSE_OP_PTR ((OPS), (I)), (V))) #define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN) #define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT)) #define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0) #define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I)) -#define V_MUST_DEF_OP(OPS, I) (*(V_MUST_DEF_OP_PTR ((OPS), (I)))) +#define V_MUST_DEF_OP(OPS, I) \ + (DEF_FROM_PTR (V_MUST_DEF_OP_PTR ((OPS), (I)))) +#define SET_V_MUST_DEF_OP(OPS, I, V) \ + (SET_DEF (V_MUST_DEF_OP_PTR ((OPS), (I)), (V))) + + +#define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI) +#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI)) +#define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V)) + +#define PHI_ARG_DEF_PTR(PHI, I) get_phi_arg_def_ptr ((PHI), (I)) +#define PHI_ARG_DEF(PHI, I) USE_FROM_PTR (PHI_ARG_DEF_PTR ((PHI), (I))) +#define SET_PHI_ARG_DEF(PHI, I, V) \ + SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V)) +#define PHI_ARG_DEF_FROM_EDGE(PHI, E) \ + PHI_ARG_DEF ((PHI), \ + phi_arg_from_edge ((PHI),(E))) +#define PHI_ARG_DEF_PTR_FROM_EDGE(PHI, E) \ + PHI_ARG_DEF_PTR ((PHI), \ + phi_arg_from_edge ((PHI),(E))) + extern void init_ssa_operands (void); extern void fini_ssa_operands (void); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index e98fbfc6025..5109934c5bc 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1907,7 +1907,7 @@ eliminate (void) print_generic_stmt (dump_file, stmt, 0); } pre_stats.eliminations++; - propagate_value (&TREE_OPERAND (stmt, 1), sprime); + propagate_tree_value (&TREE_OPERAND (stmt, 1), sprime); modify_stmt (stmt); } } diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 7d9e64d338a..5a06cf8e9e1 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -779,7 +779,7 @@ replace_immediate_uses (tree var, tree repl) for (j = 0; j < PHI_NUM_ARGS (stmt); j++) if (PHI_ARG_DEF (stmt, j) == var) { - PHI_ARG_DEF (stmt, j) = repl; + SET_PHI_ARG_DEF (stmt, j, repl); if (TREE_CODE (repl) == SSA_NAME && PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL) SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1; diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 622c4e9ac2b..54597bb7973 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -237,7 +237,7 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi) if (!e) abort (); - expr = phi_element_for_edge (at, e)->def; + expr = PHI_ARG_DEF_FROM_EDGE (at, e); } /* Unmark the blocks. */ @@ -340,7 +340,7 @@ propagate_through_phis (tree var, edge e) tree phi; for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi)) - if (phi_element_for_edge (phi, e)->def == var) + if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var) return PHI_RESULT (phi); return var; diff --git a/gcc/tree.h b/gcc/tree.h index 1a0f8545c13..128b6a5832d 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1206,7 +1206,8 @@ struct tree_ssa_name GTY(()) }; /* In a PHI_NODE node. */ -#define PHI_RESULT(NODE) PHI_NODE_CHECK (NODE)->phi.result +#define PHI_RESULT_TREE(NODE) PHI_NODE_CHECK (NODE)->phi.result +#define PHI_ARG_DEF_TREE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def /* PHI_NODEs for each basic block are chained together in a single linked list. The head of the list is linked from the block annotation, and @@ -1215,13 +1216,12 @@ struct tree_ssa_name GTY(()) /* Nonzero if the PHI node was rewritten by a previous pass through the SSA renamer. */ -#define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten -#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args -#define PHI_ARG_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity -#define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I) -#define PHI_ARG_EDGE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).e -#define PHI_ARG_DEF(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def -#define PHI_ARG_NONZERO(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).nonzero +#define PHI_REWRITTEN(NODE) PHI_NODE_CHECK (NODE)->phi.rewritten +#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args +#define PHI_ARG_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity +#define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I) +#define PHI_ARG_EDGE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).e +#define PHI_ARG_NONZERO(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).nonzero struct edge_def; -- 2.30.2