diff options
author | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-24 23:36:04 +0000 |
---|---|---|
committer | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-24 23:36:04 +0000 |
commit | 9cabbd009655c6d3a4691f84f17a43c8d5d3a176 (patch) | |
tree | 81847459ed3a48b0e2fb27223e2a7c6cbd045dca /gcc/tree-if-conv.c | |
parent | e1cc68bd3e4621c0829b59365aeb11fc4c132e5f (diff) | |
download | gcc-9cabbd009655c6d3a4691f84f17a43c8d5d3a176.tar.gz |
Speed-up ifcvt_memrefs_wont_trap caching previous results.
This patch speeds up the ifcvt_memrefs_wont_trap computation by
caching the results of the computations in the data references ->aux
fields.
* tree-if-conv.c (struct ifc_dr): New.
(IFC_DR): New.
(DR_WRITTEN_AT_LEAST_ONCE): New.
(DR_RW_UNCONDITIONALLY): New.
(memref_read_or_written_unconditionally): Use the cached values
when possible.
(write_memref_written_at_least_once): Same.
(if_convertible_loop_p): Initialize and free DR->aux fields.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163532 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r-- | gcc/tree-if-conv.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 55e2a11a2b1..86b8f2686e4 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -446,6 +446,21 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi) return true; } +/* Records the status of a data reference. This struct is attached to + each DR->aux field. */ + +struct ifc_dr { + /* -1 when not initialized, 0 when false, 1 when true. */ + int written_at_least_once; + + /* -1 when not initialized, 0 when false, 1 when true. */ + int rw_unconditionally; +}; + +#define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux) +#define DR_WRITTEN_AT_LEAST_ONCE(DR) (IFC_DR (DR)->written_at_least_once) +#define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally) + /* Returns true when the memory references of STMT are read or written unconditionally. In other words, this function returns true when for every data reference A in STMT there exist other accesses to @@ -465,6 +480,13 @@ memrefs_read_or_written_unconditionally (gimple stmt, if (DR_STMT (a) == stmt) { bool found = false; + int x = DR_RW_UNCONDITIONALLY (a); + + if (x == 0) + return false; + + if (x == 1) + continue; for (j = 0; VEC_iterate (data_reference_p, drs, j, b); j++) if (DR_STMT (b) != stmt @@ -472,17 +494,23 @@ memrefs_read_or_written_unconditionally (gimple stmt, { tree cb = bb_predicate (gimple_bb (DR_STMT (b))); - if (is_true_predicate (cb) + if (DR_RW_UNCONDITIONALLY (b) == 1 + || is_true_predicate (cb) || is_true_predicate (ca = fold_or_predicates (EXPR_LOCATION (cb), ca, cb))) { + DR_RW_UNCONDITIONALLY (a) = 1; + DR_RW_UNCONDITIONALLY (b) = 1; found = true; break; } } if (!found) - return false; + { + DR_RW_UNCONDITIONALLY (a) = 0; + return false; + } } return true; @@ -508,6 +536,13 @@ write_memrefs_written_at_least_once (gimple stmt, && !DR_IS_READ (a)) { bool found = false; + int x = DR_WRITTEN_AT_LEAST_ONCE (a); + + if (x == 0) + return false; + + if (x == 1) + continue; for (j = 0; VEC_iterate (data_reference_p, drs, j, b); j++) if (DR_STMT (b) != stmt @@ -516,17 +551,23 @@ write_memrefs_written_at_least_once (gimple stmt, { tree cb = bb_predicate (gimple_bb (DR_STMT (b))); - if (is_true_predicate (cb) + if (DR_WRITTEN_AT_LEAST_ONCE (b) == 1 + || is_true_predicate (cb) || is_true_predicate (ca = fold_or_predicates (EXPR_LOCATION (cb), ca, cb))) { + DR_WRITTEN_AT_LEAST_ONCE (a) = 1; + DR_WRITTEN_AT_LEAST_ONCE (b) = 1; found = true; break; } } if (!found) - return false; + { + DR_WRITTEN_AT_LEAST_ONCE (a) = 0; + return false; + } } return true; @@ -972,6 +1013,18 @@ if_convertible_loop_p_1 (struct loop *loop, if (!res) return false; + if (flag_tree_loop_if_convert_stores) + { + data_reference_p dr; + + for (i = 0; VEC_iterate (data_reference_p, *refs, i, dr); i++) + { + dr->aux = XNEW (struct ifc_dr); + DR_WRITTEN_AT_LEAST_ONCE (dr) = -1; + DR_RW_UNCONDITIONALLY (dr) = -1; + } + } + for (i = 0; i < loop->num_nodes; i++) { basic_block bb = ifc_bbs[i]; @@ -1045,6 +1098,15 @@ if_convertible_loop_p (struct loop *loop) ddrs = VEC_alloc (ddr_p, heap, 25); res = if_convertible_loop_p_1 (loop, &refs, &ddrs); + if (flag_tree_loop_if_convert_stores) + { + data_reference_p dr; + unsigned int i; + + for (i = 0; VEC_iterate (data_reference_p, refs, i, dr); i++) + free (dr->aux); + } + free_data_refs (refs); free_dependence_relations (ddrs); return res; |