annotate gcc/ipa-icf-gimple.h @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Interprocedural semantic function equality pass
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
22 /* Gimple identical code folding (class func_checker) is an infrastructure
111
kono
parents:
diff changeset
23 capable of comparing two given functions. The class compares every
kono
parents:
diff changeset
24 gimple statement and uses many dictionaries to map source and target
kono
parents:
diff changeset
25 SSA_NAMEs, declarations and other components.
kono
parents:
diff changeset
26
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
27 To use the infrastructure, create an instance of func_checker and call
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
28 a comparison function based on type of gimple statement. */
111
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 /* Prints string STRING to a FILE with a given number of SPACE_COUNT. */
kono
parents:
diff changeset
31 #define FPUTS_SPACES(file, space_count, string) \
kono
parents:
diff changeset
32 fprintf (file, "%*s" string, space_count, " ");
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 /* fprintf function wrapper that transforms given FORMAT to follow given
kono
parents:
diff changeset
35 number for SPACE_COUNT and call fprintf for a FILE. */
kono
parents:
diff changeset
36 #define FPRINTF_SPACES(file, space_count, format, ...) \
kono
parents:
diff changeset
37 fprintf (file, "%*s" format, space_count, " ", ##__VA_ARGS__);
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 /* Logs a MESSAGE to dump_file if exists and returns false. FUNC is name
kono
parents:
diff changeset
40 of function and LINE is location in the source file. */
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 static inline bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
43 return_false_with_message_1 (const char *message, const char *filename,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
44 const char *func, unsigned int line)
111
kono
parents:
diff changeset
45 {
kono
parents:
diff changeset
46 if (dump_file && (dump_flags & TDF_DETAILS))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
47 fprintf (dump_file, " false returned: '%s' in %s at %s:%u\n", message, func,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
48 filename, line);
111
kono
parents:
diff changeset
49 return false;
kono
parents:
diff changeset
50 }
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 /* Logs a MESSAGE to dump_file if exists and returns false. */
kono
parents:
diff changeset
53 #define return_false_with_msg(message) \
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
54 return_false_with_message_1 (message, __FILE__, __func__, __LINE__)
111
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 /* Return false and log that false value is returned. */
kono
parents:
diff changeset
57 #define return_false() return_false_with_msg ("")
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 /* Logs return value if RESULT is false. FUNC is name of function and LINE
kono
parents:
diff changeset
60 is location in the source file. */
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 static inline bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
63 return_with_result (bool result, const char *filename,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
64 const char *func, unsigned int line)
111
kono
parents:
diff changeset
65 {
kono
parents:
diff changeset
66 if (!result && dump_file && (dump_flags & TDF_DETAILS))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
67 fprintf (dump_file, " false returned: '' in %s at %s:%u\n", func,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
68 filename, line);
111
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 return result;
kono
parents:
diff changeset
71 }
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /* Logs return value if RESULT is false. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
74 #define return_with_debug(result) return_with_result \
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
75 (result, __FILE__, __func__, __LINE__)
111
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 /* Verbose logging function logging statements S1 and S2 of a CODE.
kono
parents:
diff changeset
78 FUNC is name of function and LINE is location in the source file. */
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 static inline bool
kono
parents:
diff changeset
81 return_different_stmts_1 (gimple *s1, gimple *s2, const char *code,
kono
parents:
diff changeset
82 const char *func, unsigned int line)
kono
parents:
diff changeset
83 {
kono
parents:
diff changeset
84 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents:
diff changeset
85 {
kono
parents:
diff changeset
86 fprintf (dump_file, " different statement for code: %s (%s:%u):\n",
kono
parents:
diff changeset
87 code, func, line);
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 print_gimple_stmt (dump_file, s1, 3, TDF_DETAILS);
kono
parents:
diff changeset
90 print_gimple_stmt (dump_file, s2, 3, TDF_DETAILS);
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 return false;
kono
parents:
diff changeset
94 }
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 /* Verbose logging function logging statements S1 and S2 of a CODE. */
kono
parents:
diff changeset
97 #define return_different_stmts(s1, s2, code) \
kono
parents:
diff changeset
98 return_different_stmts_1 (s1, s2, code, __func__, __LINE__)
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 namespace ipa_icf_gimple {
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 /* Basic block struct for semantic equality pass. */
kono
parents:
diff changeset
103 class sem_bb
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 public:
kono
parents:
diff changeset
106 sem_bb (basic_block bb_, unsigned nondbg_stmt_count_, unsigned edge_count_):
kono
parents:
diff changeset
107 bb (bb_), nondbg_stmt_count (nondbg_stmt_count_), edge_count (edge_count_) {}
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 /* Basic block the structure belongs to. */
kono
parents:
diff changeset
110 basic_block bb;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 /* Number of non-debug statements in the basic block. */
kono
parents:
diff changeset
113 unsigned nondbg_stmt_count;
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 /* Number of edges connected to the block. */
kono
parents:
diff changeset
116 unsigned edge_count;
kono
parents:
diff changeset
117 };
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 /* A class aggregating all connections and semantic equivalents
kono
parents:
diff changeset
120 for a given pair of semantic function candidates. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
121 class func_checker : operand_compare
111
kono
parents:
diff changeset
122 {
kono
parents:
diff changeset
123 public:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
124 /* Default constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
125 func_checker ():
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
126 m_source_func_decl (NULL_TREE), m_target_func_decl (NULL_TREE),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
127 m_ignored_source_nodes (NULL), m_ignored_target_nodes (NULL),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
128 m_ignore_labels (false)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
129 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
130 m_source_ssa_names.create (0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
131 m_target_ssa_names.create (0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
132 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
133
111
kono
parents:
diff changeset
134 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
kono
parents:
diff changeset
135 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
kono
parents:
diff changeset
136 an option COMPARE_POLYMORPHIC is true. For special cases, one can
kono
parents:
diff changeset
137 set IGNORE_LABELS to skip label comparison.
kono
parents:
diff changeset
138 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
kono
parents:
diff changeset
139 of declarations that can be skipped. */
kono
parents:
diff changeset
140 func_checker (tree source_func_decl, tree target_func_decl,
kono
parents:
diff changeset
141 bool ignore_labels = false,
kono
parents:
diff changeset
142 hash_set<symtab_node *> *ignored_source_nodes = NULL,
kono
parents:
diff changeset
143 hash_set<symtab_node *> *ignored_target_nodes = NULL);
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 /* Memory release routine. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
146 virtual ~func_checker ();
111
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148 /* Function visits all gimple labels and creates corresponding
kono
parents:
diff changeset
149 mapping between basic blocks and labels. */
kono
parents:
diff changeset
150 void parse_labels (sem_bb *bb);
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 /* Basic block equivalence comparison function that returns true if
kono
parents:
diff changeset
153 basic blocks BB1 and BB2 correspond. */
kono
parents:
diff changeset
154 bool compare_bb (sem_bb *bb1, sem_bb *bb2);
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
157 bool compare_ssa_name (const_tree t1, const_tree t2);
111
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 /* Verification function for edges E1 and E2. */
kono
parents:
diff changeset
160 bool compare_edge (edge e1, edge e2);
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
163 call statements are semantically equivalent. */
kono
parents:
diff changeset
164 bool compare_gimple_call (gcall *s1, gcall *s2);
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
167 assignment statements are semantically equivalent. */
kono
parents:
diff changeset
168 bool compare_gimple_assign (gimple *s1, gimple *s2);
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
171 condition statements are semantically equivalent. */
kono
parents:
diff changeset
172 bool compare_gimple_cond (gimple *s1, gimple *s2);
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
kono
parents:
diff changeset
175 label statements are semantically equivalent. */
kono
parents:
diff changeset
176 bool compare_gimple_label (const glabel *s1, const glabel *s2);
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
kono
parents:
diff changeset
179 switch statements are semantically equivalent. */
kono
parents:
diff changeset
180 bool compare_gimple_switch (const gswitch *s1, const gswitch *s2);
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
kono
parents:
diff changeset
183 return statements are semantically equivalent. */
kono
parents:
diff changeset
184 bool compare_gimple_return (const greturn *s1, const greturn *s2);
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
187 goto statements are semantically equivalent. */
kono
parents:
diff changeset
188 bool compare_gimple_goto (gimple *s1, gimple *s2);
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
kono
parents:
diff changeset
191 resx statements are semantically equivalent. */
kono
parents:
diff changeset
192 bool compare_gimple_resx (const gresx *s1, const gresx *s2);
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 /* Verifies for given GIMPLE_ASM stmts S1 and S2 that ASM statements
kono
parents:
diff changeset
195 are equivalent.
kono
parents:
diff changeset
196 For the beginning, the pass only supports equality for
kono
parents:
diff changeset
197 '__asm__ __volatile__ ("", "", "", "memory")'. */
kono
parents:
diff changeset
198 bool compare_gimple_asm (const gasm *s1, const gasm *s2);
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 /* Verification function for declaration trees T1 and T2. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
201 bool compare_decl (const_tree t1, const_tree t2);
111
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 /* Function responsible for comparison of various operands T1 and T2.
kono
parents:
diff changeset
204 If these components, from functions FUNC1 and FUNC2, are equal, true
kono
parents:
diff changeset
205 is returned. */
kono
parents:
diff changeset
206 bool compare_operand (tree t1, tree t2);
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 /* Compares GIMPLE ASM inputs (or outputs) where we iterate tree chain
kono
parents:
diff changeset
209 and compare both TREE_PURPOSEs and TREE_VALUEs. */
kono
parents:
diff changeset
210 bool compare_asm_inputs_outputs (tree t1, tree t2);
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 /* Verifies that trees T1 and T2, representing function declarations
kono
parents:
diff changeset
213 are equivalent from perspective of ICF. */
kono
parents:
diff changeset
214 bool compare_function_decl (tree t1, tree t2);
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 /* Verifies that trees T1 and T2 do correspond. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
217 bool compare_variable_decl (const_tree t1, const_tree t2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
218
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
219 /* Compare loop information for basic blocks BB1 and BB2. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
220 bool compare_loops (basic_block bb1, basic_block bb2);
111
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 /* Return true if types are compatible for polymorphic call analysis.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
223 COMPARE_PTR indicates if polymorphic type comparison should be
111
kono
parents:
diff changeset
224 done for pointers, too. */
kono
parents:
diff changeset
225 static bool compatible_polymorphic_types_p (tree t1, tree t2,
kono
parents:
diff changeset
226 bool compare_ptr);
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 /* Return true if types are compatible from perspective of ICF.
kono
parents:
diff changeset
229 FIRST_ARGUMENT indicates if the comparison is called for
kono
parents:
diff changeset
230 first parameter of a function. */
kono
parents:
diff changeset
231 static bool compatible_types_p (tree t1, tree t2);
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 private:
kono
parents:
diff changeset
235 /* Vector mapping source SSA names to target ones. */
kono
parents:
diff changeset
236 vec <int> m_source_ssa_names;
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 /* Vector mapping target SSA names to source ones. */
kono
parents:
diff changeset
239 vec <int> m_target_ssa_names;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 /* Source TREE function declaration. */
kono
parents:
diff changeset
242 tree m_source_func_decl;
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 /* Target TREE function declaration. */
kono
parents:
diff changeset
245 tree m_target_func_decl;
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 /* Source symbol nodes that should be skipped by
kono
parents:
diff changeset
248 declaration comparison. */
kono
parents:
diff changeset
249 hash_set<symtab_node *> *m_ignored_source_nodes;
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 /* Target symbol nodes that should be skipped by
kono
parents:
diff changeset
252 declaration comparison. */
kono
parents:
diff changeset
253 hash_set<symtab_node *> *m_ignored_target_nodes;
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 /* Source to target edge map. */
kono
parents:
diff changeset
256 hash_map <edge, edge> m_edge_map;
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 /* Source to target declaration map. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
259 hash_map <const_tree, const_tree> m_decl_map;
111
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 /* Label to basic block index mapping. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
262 hash_map <const_tree, int> m_label_bb_map;
111
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 /* Flag if ignore labels in comparison. */
kono
parents:
diff changeset
265 bool m_ignore_labels;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
266
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
267 public:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
268 /* Return true if two operands are equal. The flags fields can be used
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
269 to specify OEP flags described above. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
270 virtual bool operand_equal_p (const_tree, const_tree, unsigned int flags);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
271
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
272 /* Generate a hash value for an expression. This can be used iteratively
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
273 by passing a previous result as the HSTATE argument. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
274 virtual void hash_operand (const_tree, inchash::hash &, unsigned flags);
111
kono
parents:
diff changeset
275 };
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 } // ipa_icf_gimple namespace