diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-01 17:25:56 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-01 17:25:56 +0000 |
commit | cffc1a1a1999ee3428d0ef9f34c60c7901a47d8a (patch) | |
tree | d232b12d9096969f32c887b0016fe2cc6b46faf4 /gcc/tree-sra.c | |
parent | 8c2dfae616d6ef30a50b40dee5ac1af3d6ae3162 (diff) | |
download | gcc-cffc1a1a1999ee3428d0ef9f34c60c7901a47d8a.tar.gz |
2012-08-01 Richard Guenther <rguenther@suse.de>
* tree-flow-inline.h (referenced_var): Remove.
* tree-ssa-coalesce.c (create_outofssa_var_map): Remove duplicate
checking code.
* tree-sra.c (candidates): New global hashtable.
(candidate): New function.
(sra_initialize): Initialize candidates.
(sra_deinitialize): Free candidates.
(disqualify_candidate): Remove candidate from candidates.
(maybe_add_sra_candidate): New function.
(find_var_candidates): Walk over all local decls and parameters,
add candidates to candidates hashtable.
(find_param_candidates): Add candidates to candidates hashtable.
(analyze_all_variable_accesses): Use candidate instead of
referenced_var.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190047 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 174 |
1 files changed, 106 insertions, 68 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 45d9f023502..2ae9346b8b4 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -224,9 +224,7 @@ struct access BIT_FIELD_REF? */ unsigned grp_partial_lhs : 1; - /* Set when a scalar replacement should be created for this variable. We do - the decision and creation at different places because create_tmp_var - cannot be called from within FOR_EACH_REFERENCED_VAR. */ + /* Set when a scalar replacement should be created for this variable. */ unsigned grp_to_be_replaced : 1; /* Should TREE_NO_WARNING of a replacement be set? */ @@ -269,8 +267,19 @@ static alloc_pool link_pool; /* Base (tree) -> Vector (VEC(access_p,heap) *) map. */ static struct pointer_map_t *base_access_vec; -/* Bitmap of candidates. */ +/* Set of candidates. */ static bitmap candidate_bitmap; +static htab_t candidates; + +/* For a candidate UID return the candidates decl. */ + +static inline tree +candidate (unsigned uid) +{ + struct tree_decl_minimal t; + t.uid = uid; + return (tree) htab_find_with_hash (candidates, &t, uid); +} /* Bitmap of candidates which we should try to entirely scalarize away and those which cannot be (because they are and need be used as a whole). */ @@ -600,6 +609,8 @@ static void sra_initialize (void) { candidate_bitmap = BITMAP_ALLOC (NULL); + candidates = htab_create (VEC_length (tree, cfun->local_decls) / 2, + uid_decl_map_hash, uid_decl_map_eq, NULL); should_scalarize_away_bitmap = BITMAP_ALLOC (NULL); cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL); gcc_obstack_init (&name_obstack); @@ -631,6 +642,7 @@ static void sra_deinitialize (void) { BITMAP_FREE (candidate_bitmap); + htab_delete (candidates); BITMAP_FREE (should_scalarize_away_bitmap); BITMAP_FREE (cannot_scalarize_away_bitmap); free_alloc_pool (access_pool); @@ -646,7 +658,10 @@ sra_deinitialize (void) static void disqualify_candidate (tree decl, const char *reason) { - bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)); + if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl))) + htab_clear_slot (candidates, + htab_find_slot_with_hash (candidates, decl, + DECL_UID (decl), NO_INSERT)); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1632,77 +1647,95 @@ reject (tree var, const char *msg) } } +/* Return true if VAR is a candidate for SRA. */ + +static bool +maybe_add_sra_candidate (tree var) +{ + tree type = TREE_TYPE (var); + const char *msg; + void **slot; + + if (!AGGREGATE_TYPE_P (type)) + { + reject (var, "not aggregate"); + return false; + } + if (needs_to_live_in_memory (var)) + { + reject (var, "needs to live in memory"); + return false; + } + if (TREE_THIS_VOLATILE (var)) + { + reject (var, "is volatile"); + return false; + } + if (!COMPLETE_TYPE_P (type)) + { + reject (var, "has incomplete type"); + return false; + } + if (!host_integerp (TYPE_SIZE (type), 1)) + { + reject (var, "type size not fixed"); + return false; + } + if (tree_low_cst (TYPE_SIZE (type), 1) == 0) + { + reject (var, "type size is zero"); + return false; + } + if (type_internals_preclude_sra_p (type, &msg)) + { + reject (var, msg); + return false; + } + if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but + we also want to schedule it rather late. Thus we ignore it in + the early pass. */ + (sra_mode == SRA_MODE_EARLY_INTRA + && is_va_list_type (type))) + { + reject (var, "is va_list"); + return false; + } + + bitmap_set_bit (candidate_bitmap, DECL_UID (var)); + slot = htab_find_slot_with_hash (candidates, var, DECL_UID (var), INSERT); + *slot = (void *) var; + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Candidate (%d): ", DECL_UID (var)); + print_generic_expr (dump_file, var, 0); + fprintf (dump_file, "\n"); + } + + return true; +} + /* The very first phase of intraprocedural SRA. It marks in candidate_bitmap those with type which is suitable for scalarization. */ static bool find_var_candidates (void) { - tree var, type; - referenced_var_iterator rvi; + tree var, parm; + unsigned int i; bool ret = false; - const char *msg; - FOR_EACH_REFERENCED_VAR (cfun, var, rvi) + for (parm = DECL_ARGUMENTS (current_function_decl); + parm; + parm = DECL_CHAIN (parm)) + ret |= maybe_add_sra_candidate (parm); + + FOR_EACH_LOCAL_DECL (cfun, i, var) { - if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL) + if (TREE_CODE (var) != VAR_DECL) continue; - type = TREE_TYPE (var); - if (!AGGREGATE_TYPE_P (type)) - { - reject (var, "not aggregate"); - continue; - } - if (needs_to_live_in_memory (var)) - { - reject (var, "needs to live in memory"); - continue; - } - if (TREE_THIS_VOLATILE (var)) - { - reject (var, "is volatile"); - continue; - } - if (!COMPLETE_TYPE_P (type)) - { - reject (var, "has incomplete type"); - continue; - } - if (!host_integerp (TYPE_SIZE (type), 1)) - { - reject (var, "type size not fixed"); - continue; - } - if (tree_low_cst (TYPE_SIZE (type), 1) == 0) - { - reject (var, "type size is zero"); - continue; - } - if (type_internals_preclude_sra_p (type, &msg)) - { - reject (var, msg); - continue; - } - if (/* Fix for PR 41089. tree-stdarg.c needs to have va_lists intact but - we also want to schedule it rather late. Thus we ignore it in - the early pass. */ - (sra_mode == SRA_MODE_EARLY_INTRA - && is_va_list_type (type))) - { - reject (var, "is va_list"); - continue; - } - - bitmap_set_bit (candidate_bitmap, DECL_UID (var)); - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Candidate (%d): ", DECL_UID (var)); - print_generic_expr (dump_file, var, 0); - fprintf (dump_file, "\n"); - } - ret = true; + ret |= maybe_add_sra_candidate (var); } return ret; @@ -2335,7 +2368,7 @@ analyze_all_variable_accesses (void) if (bitmap_bit_p (should_scalarize_away_bitmap, i) && !bitmap_bit_p (cannot_scalarize_away_bitmap, i)) { - tree var = referenced_var (i); + tree var = candidate (i); if (TREE_CODE (var) == VAR_DECL && type_consists_of_records_p (TREE_TYPE (var))) @@ -2363,7 +2396,7 @@ analyze_all_variable_accesses (void) bitmap_copy (tmp, candidate_bitmap); EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi) { - tree var = referenced_var (i); + tree var = candidate (i); struct access *access; access = sort_and_splice_var_accesses (var); @@ -2377,7 +2410,7 @@ analyze_all_variable_accesses (void) bitmap_copy (tmp, candidate_bitmap); EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi) { - tree var = referenced_var (i); + tree var = candidate (i); struct access *access = get_first_repr_for_decl (var); if (analyze_access_trees (access)) @@ -3424,6 +3457,7 @@ find_param_candidates (void) parm = DECL_CHAIN (parm)) { tree type = TREE_TYPE (parm); + void **slot; count++; @@ -3462,6 +3496,10 @@ find_param_candidates (void) continue; bitmap_set_bit (candidate_bitmap, DECL_UID (parm)); + slot = htab_find_slot_with_hash (candidates, parm, + DECL_UID (parm), INSERT); + *slot = (void *) parm; + ret = true; if (dump_file && (dump_flags & TDF_DETAILS)) { |