1 /* Classes for purging state at function_points.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_ANALYZER_STATE_PURGE_H
22 #define GCC_ANALYZER_STATE_PURGE_H
24 /* Hash traits for function_point. */
26 template <> struct default_hash_traits
<function_point
>
27 : public pod_hash_traits
<function_point
>
29 static const bool empty_zero_p
= false;
34 pod_hash_traits
<function_point
>::hash (value_type v
)
41 pod_hash_traits
<function_point
>::equal (const value_type
&existing
,
42 const value_type
&candidate
)
44 return existing
== candidate
;
48 pod_hash_traits
<function_point
>::mark_deleted (value_type
&v
)
50 v
= function_point::deleted ();
54 pod_hash_traits
<function_point
>::mark_empty (value_type
&v
)
56 v
= function_point::empty ();
60 pod_hash_traits
<function_point
>::is_deleted (value_type v
)
62 return v
.get_kind () == PK_DELETED
;
66 pod_hash_traits
<function_point
>::is_empty (value_type v
)
68 return v
.get_kind () == PK_EMPTY
;
73 /* The result of analyzing which decls and SSA names can be purged from state at
74 different points in the program, so that we can simplify program_state
75 objects, in the hope of reducing state-blowup. */
77 class state_purge_map
: public log_user
80 typedef ordered_hash_map
<tree
, state_purge_per_ssa_name
*> ssa_map_t
;
81 typedef ssa_map_t::iterator ssa_iterator
;
83 typedef ordered_hash_map
<tree
, state_purge_per_decl
*> decl_map_t
;
84 typedef decl_map_t::iterator decl_iterator
;
86 state_purge_map (const supergraph
&sg
,
87 region_model_manager
*mgr
,
91 const state_purge_per_ssa_name
&get_data_for_ssa_name (tree name
) const
93 gcc_assert (TREE_CODE (name
) == SSA_NAME
);
94 if (tree var
= SSA_NAME_VAR (name
))
95 if (TREE_CODE (var
) == VAR_DECL
)
96 gcc_assert (!VAR_DECL_IS_VIRTUAL_OPERAND (var
));
98 state_purge_per_ssa_name
**slot
99 = const_cast <ssa_map_t
&> (m_ssa_map
).get (name
);
103 const state_purge_per_decl
*get_any_data_for_decl (tree decl
) const
105 gcc_assert (TREE_CODE (decl
) == VAR_DECL
106 || TREE_CODE (decl
) == PARM_DECL
107 || TREE_CODE (decl
) == RESULT_DECL
);
108 if (state_purge_per_decl
**slot
109 = const_cast <decl_map_t
&> (m_decl_map
).get (decl
))
115 state_purge_per_decl
&
116 get_or_create_data_for_decl (const function
&fun
, tree decl
);
118 const supergraph
&get_sg () const { return m_sg
; }
120 ssa_iterator
begin_ssas () const { return m_ssa_map
.begin (); }
121 ssa_iterator
end_ssas () const { return m_ssa_map
.end (); }
123 decl_iterator
begin_decls () const { return m_decl_map
.begin (); }
124 decl_iterator
end_decls () const { return m_decl_map
.end (); }
127 DISABLE_COPY_AND_ASSIGN (state_purge_map
);
129 const supergraph
&m_sg
;
131 decl_map_t m_decl_map
;
134 /* Base class for state_purge_per_ssa_name and state_purge_per_decl. */
136 class state_purge_per_tree
139 const function
&get_function () const { return m_fun
; }
140 tree
get_fndecl () const { return m_fun
.decl
; }
143 typedef hash_set
<function_point
> point_set_t
;
145 state_purge_per_tree (const function
&fun
)
151 const function
&m_fun
;
154 /* The part of a state_purge_map relating to a specific SSA name.
156 The result of analyzing a given SSA name, recording which
157 function_points need to retain state information about it to handle
158 their successor states, so that we can simplify program_state objects,
159 in the hope of reducing state-blowup. */
161 class state_purge_per_ssa_name
: public state_purge_per_tree
164 state_purge_per_ssa_name (const state_purge_map
&map
,
166 const function
&fun
);
168 bool needed_at_point_p (const function_point
&point
) const;
171 static function_point
before_use_stmt (const state_purge_map
&map
,
172 const gimple
*use_stmt
);
174 void add_to_worklist (const function_point
&point
,
175 auto_vec
<function_point
> *worklist
,
178 void process_point (const function_point
&point
,
179 auto_vec
<function_point
> *worklist
,
180 const state_purge_map
&map
);
182 point_set_t m_points_needing_name
;
186 /* The part of a state_purge_map relating to a specific decl.
188 Analogous to state_purge_per_ssa_name, but for local decls.
190 This is more involved than the SSA name case, because we also need
191 to handle pointers and components. */
193 class state_purge_per_decl
: public state_purge_per_tree
196 state_purge_per_decl (const state_purge_map
&map
,
198 const function
&fun
);
200 bool needed_at_point_p (const function_point
&point
) const;
202 void add_needed_at (const function_point
&point
);
203 void add_pointed_to_at (const function_point
&point
);
204 void process_worklists (const state_purge_map
&map
,
205 region_model_manager
*mgr
);
208 static function_point
before_use_stmt (const state_purge_map
&map
,
209 const gimple
*use_stmt
);
211 void add_to_worklist (const function_point
&point
,
212 auto_vec
<function_point
> *worklist
,
216 void process_point_backwards (const function_point
&point
,
217 auto_vec
<function_point
> *worklist
,
219 const state_purge_map
&map
,
220 const region_model
&model
);
221 void process_point_forwards (const function_point
&point
,
222 auto_vec
<function_point
> *worklist
,
224 const state_purge_map
&map
);
226 point_set_t m_points_needing_decl
;
227 point_set_t m_points_taking_address
;
231 /* Subclass of dot_annotator for use by -fdump-analyzer-state-purge.
232 Annotate the .dot output with state-purge information. */
234 class state_purge_annotator
: public dot_annotator
237 state_purge_annotator (const state_purge_map
*map
) : m_map (map
) {}
239 bool add_node_annotations (graphviz_out
*gv
, const supernode
&n
, bool)
240 const final override
;
242 void add_stmt_annotations (graphviz_out
*gv
, const gimple
*stmt
,
244 const final override
;
247 void print_needed (graphviz_out
*gv
,
248 const function_point
&point
,
249 bool within_table
) const;
251 const state_purge_map
*m_map
;
256 #endif /* GCC_ANALYZER_STATE_PURGE_H */