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
&get_or_create_data_for_decl (function
*fun
, tree decl
);
117 const supergraph
&get_sg () const { return m_sg
; }
119 ssa_iterator
begin_ssas () const { return m_ssa_map
.begin (); }
120 ssa_iterator
end_ssas () const { return m_ssa_map
.end (); }
122 decl_iterator
begin_decls () const { return m_decl_map
.begin (); }
123 decl_iterator
end_decls () const { return m_decl_map
.end (); }
126 DISABLE_COPY_AND_ASSIGN (state_purge_map
);
128 const supergraph
&m_sg
;
130 decl_map_t m_decl_map
;
133 /* Base class for state_purge_per_ssa_name and state_purge_per_decl. */
135 class state_purge_per_tree
138 function
*get_function () const { return m_fun
; }
139 tree
get_fndecl () const { return m_fun
->decl
; }
142 typedef hash_set
<function_point
> point_set_t
;
144 state_purge_per_tree (function
*fun
)
153 /* The part of a state_purge_map relating to a specific SSA name.
155 The result of analyzing a given SSA name, recording which
156 function_points need to retain state information about it to handle
157 their successor states, so that we can simplify program_state objects,
158 in the hope of reducing state-blowup. */
160 class state_purge_per_ssa_name
: public state_purge_per_tree
163 state_purge_per_ssa_name (const state_purge_map
&map
,
167 bool needed_at_point_p (const function_point
&point
) const;
170 static function_point
before_use_stmt (const state_purge_map
&map
,
171 const gimple
*use_stmt
);
173 void add_to_worklist (const function_point
&point
,
174 auto_vec
<function_point
> *worklist
,
177 void process_point (const function_point
&point
,
178 auto_vec
<function_point
> *worklist
,
179 const state_purge_map
&map
);
181 point_set_t m_points_needing_name
;
185 /* The part of a state_purge_map relating to a specific decl.
187 Analogous to state_purge_per_ssa_name, but for local decls.
189 This is more involved than the SSA name case, because we also need
190 to handle pointers and components. */
192 class state_purge_per_decl
: public state_purge_per_tree
195 state_purge_per_decl (const state_purge_map
&map
,
199 bool needed_at_point_p (const function_point
&point
) const;
201 void add_needed_at (const function_point
&point
);
202 void add_pointed_to_at (const function_point
&point
);
203 void process_worklists (const state_purge_map
&map
,
204 region_model_manager
*mgr
);
207 static function_point
before_use_stmt (const state_purge_map
&map
,
208 const gimple
*use_stmt
);
210 void add_to_worklist (const function_point
&point
,
211 auto_vec
<function_point
> *worklist
,
215 void process_point_backwards (const function_point
&point
,
216 auto_vec
<function_point
> *worklist
,
218 const state_purge_map
&map
,
219 const region_model
&model
);
220 void process_point_forwards (const function_point
&point
,
221 auto_vec
<function_point
> *worklist
,
223 const state_purge_map
&map
);
225 point_set_t m_points_needing_decl
;
226 point_set_t m_points_taking_address
;
230 /* Subclass of dot_annotator for use by -fdump-analyzer-state-purge.
231 Annotate the .dot output with state-purge information. */
233 class state_purge_annotator
: public dot_annotator
236 state_purge_annotator (const state_purge_map
*map
) : m_map (map
) {}
238 bool add_node_annotations (graphviz_out
*gv
, const supernode
&n
, bool)
239 const final override
;
241 void add_stmt_annotations (graphviz_out
*gv
, const gimple
*stmt
,
243 const final override
;
246 void print_needed (graphviz_out
*gv
,
247 const function_point
&point
,
248 bool within_table
) const;
250 const state_purge_map
*m_map
;
255 #endif /* GCC_ANALYZER_STATE_PURGE_H */