diff options
author | Andrew Pinski <apinski@marvell.com> | 2023-07-14 15:14:59 -0700 |
---|---|---|
committer | Andrew Pinski <apinski@marvell.com> | 2023-07-19 09:17:02 -0700 |
commit | a86d5eca6a11c25da4aff436f53589950641675f (patch) | |
tree | d7f649c59afcca23e5fe2b6e6c66c2b6a6527586 /gcc | |
parent | bf20b770d9aabb15faf2644b5e3106249cb175f3 (diff) | |
download | gcc-a86d5eca6a11c25da4aff436f53589950641675f.zip gcc-a86d5eca6a11c25da4aff436f53589950641675f.tar.gz gcc-a86d5eca6a11c25da4aff436f53589950641675f.tar.bz2 |
Add flow_sensitive_info_storage and use it in gimple-fold.
This adds flow_sensitive_info_storage and uses it in
maybe_fold_comparisons_from_match_pd as mentioned in
https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621817.html .
Since using it in maybe_fold_comparisons_from_match_pd was easy
and allowed me to test the storage earlier, I did it.
This also hides better how the flow sensitive information is
stored and only a single place needs to be updated if that
ever changes (again).
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
gcc/ChangeLog:
* gimple-fold.cc (fosa_unwind): Replace `vrange_storage *`
with flow_sensitive_info_storage.
(follow_outer_ssa_edges): Update how to save off the flow
sensitive info.
(maybe_fold_comparisons_from_match_pd): Update restoring
of flow sensitive info.
* tree-ssanames.cc (flow_sensitive_info_storage::save): New method.
(flow_sensitive_info_storage::restore): New method.
(flow_sensitive_info_storage::save_and_clear): New method.
(flow_sensitive_info_storage::clear_storage): New method.
* tree-ssanames.h (class flow_sensitive_info_storage): New class.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-fold.cc | 17 | ||||
-rw-r--r-- | gcc/tree-ssanames.cc | 72 | ||||
-rw-r--r-- | gcc/tree-ssanames.h | 21 |
3 files changed, 100 insertions, 10 deletions
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 4027ff7..de94efb 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -6947,7 +6947,7 @@ and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, } static basic_block fosa_bb; -static vec<std::pair<tree, vrange_storage *> > *fosa_unwind; +static vec<std::pair<tree, flow_sensitive_info_storage> > *fosa_unwind; static tree follow_outer_ssa_edges (tree val) { @@ -6967,14 +6967,11 @@ follow_outer_ssa_edges (tree val) || POINTER_TYPE_P (TREE_TYPE (val))) && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (val))) return NULL_TREE; + flow_sensitive_info_storage storage; + storage.save_and_clear (val); /* If the definition does not dominate fosa_bb temporarily reset flow-sensitive info. */ - if (val->ssa_name.info.range_info) - { - fosa_unwind->safe_push (std::make_pair - (val, val->ssa_name.info.range_info)); - val->ssa_name.info.range_info = NULL; - } + fosa_unwind->safe_push (std::make_pair (val, storage)); return val; } return val; @@ -7034,14 +7031,14 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, type, gimple_assign_lhs (stmt1), gimple_assign_lhs (stmt2)); fosa_bb = outer_cond_bb; - auto_vec<std::pair<tree, vrange_storage *>, 8> unwind_stack; + auto_vec<std::pair<tree, flow_sensitive_info_storage>, 8> unwind_stack; fosa_unwind = &unwind_stack; if (op.resimplify (NULL, (!outer_cond_bb ? follow_all_ssa_edges : follow_outer_ssa_edges))) { fosa_unwind = NULL; for (auto p : unwind_stack) - p.first->ssa_name.info.range_info = p.second; + p.second.restore (p.first); if (gimple_simplified_result_is_gimple_val (&op)) { tree res = op.ops[0]; @@ -7065,7 +7062,7 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, } fosa_unwind = NULL; for (auto p : unwind_stack) - p.first->ssa_name.info.range_info = p.second; + p.second.restore (p.first); return NULL_TREE; } diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index f543943..23387b9 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -931,3 +931,75 @@ make_pass_release_ssa_names (gcc::context *ctxt) { return new pass_release_ssa_names (ctxt); } + +/* Save and restore of flow sensitive information. */ + +/* Save off the flow sensitive info from NAME. */ + +void +flow_sensitive_info_storage::save (tree name) +{ + gcc_assert (state == 0); + if (!POINTER_TYPE_P (TREE_TYPE (name))) + { + range_info = SSA_NAME_RANGE_INFO (name); + state = 1; + return; + } + state = -1; + auto ptr_info = SSA_NAME_PTR_INFO (name); + if (ptr_info) + { + align = ptr_info->align; + misalign = ptr_info->misalign; + null = SSA_NAME_PTR_INFO (name)->pt.null; + } + else + { + align = 0; + misalign = 0; + null = true; + } +} + +/* Restore the flow sensitive info from NAME. */ + +void +flow_sensitive_info_storage::restore (tree name) +{ + gcc_assert (state != 0); + if (!POINTER_TYPE_P (TREE_TYPE (name))) + { + gcc_assert (state == 1); + SSA_NAME_RANGE_INFO (name) = range_info; + return; + } + gcc_assert (state == -1); + auto ptr_info = SSA_NAME_PTR_INFO (name); + /* If there was no flow sensitive info on the pointer + just return, there is nothing to restore to. */ + if (!ptr_info) + return; + if (align != 0) + set_ptr_info_alignment (ptr_info, align, misalign); + else + mark_ptr_info_alignment_unknown (ptr_info); + SSA_NAME_PTR_INFO (name)->pt.null = null; +} + +/* Save off the flow sensitive info from NAME. + And reset the flow sensitive info of NAME. */ + +void +flow_sensitive_info_storage::save_and_clear (tree name) +{ + save (name); + reset_flow_sensitive_info (name); +} + +/* Clear the storage. */ +void +flow_sensitive_info_storage::clear_storage (void) +{ + state = 0; +} diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index b5e3f22..35e4255 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -137,5 +137,26 @@ make_temp_ssa_name (tree type, gimple *stmt, const char *name) return ssa_name; } +/* A class which is used to save/restore the flow sensitive information. */ +class flow_sensitive_info_storage +{ +public: + void save (tree); + void save_and_clear (tree); + void restore (tree); + void clear_storage (); +private: + /* 0 means there is nothing saved. + 1 means non pointer is saved. + -1 means a pointer type is saved. + -2 means a pointer type is saved but no information was saved. */ + int state = 0; + /* The range info for non pointers */ + vrange_storage *range_info = nullptr; + /* Flow sensitive pointer information. */ + unsigned int align = 0; + unsigned int misalign = 0; + bool null = true; +}; #endif /* GCC_TREE_SSANAMES_H */ |