]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-dse.c
2015-06-17 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / tree-ssa-dse.c
CommitLineData
4ee9c684 1/* Dead store elimination
d353bf18 2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
4ee9c684 3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8c4c00c1 8the Free Software Foundation; either version 3, or (at your option)
4ee9c684 9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
4ee9c684 19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tm.h"
b20a8bb4 24#include "alias.h"
25#include "symtab.h"
4ee9c684 26#include "tree.h"
b20a8bb4 27#include "fold-const.h"
4ee9c684 28#include "tm_p.h"
94ea8568 29#include "predict.h"
94ea8568 30#include "hard-reg-set.h"
94ea8568 31#include "function.h"
32#include "dominance.h"
33#include "cfg.h"
4ee9c684 34#include "basic-block.h"
ce084dfc 35#include "gimple-pretty-print.h"
073c1fd5 36#include "bitmap.h"
bc61cadb 37#include "tree-ssa-alias.h"
38#include "internal-fn.h"
39#include "gimple-expr.h"
073c1fd5 40#include "gimple.h"
dcf1a1ec 41#include "gimple-iterator.h"
073c1fd5 42#include "gimple-ssa.h"
43#include "tree-cfg.h"
44#include "tree-phinodes.h"
45#include "ssa-iterators.h"
9ed99284 46#include "stringpool.h"
073c1fd5 47#include "tree-ssanames.h"
d53441c8 48#include "rtl.h"
49#include "flags.h"
d53441c8 50#include "insn-config.h"
51#include "expmed.h"
52#include "dojump.h"
53#include "explow.h"
54#include "calls.h"
55#include "emit-rtl.h"
56#include "varasm.h"
57#include "stmt.h"
9ed99284 58#include "expr.h"
073c1fd5 59#include "tree-dfa.h"
4ee9c684 60#include "tree-pass.h"
4ee9c684 61#include "domwalk.h"
f0e4d727 62#include "langhooks.h"
424a4a92 63#include "tree-cfgcleanup.h"
4ee9c684 64
65/* This file implements dead store elimination.
66
67 A dead store is a store into a memory location which will later be
68 overwritten by another store without any intervening loads. In this
69 case the earlier store can be deleted.
70
71 In our SSA + virtual operand world we use immediate uses of virtual
72 operands to detect dead stores. If a store's virtual definition
73 is used precisely once by a later store to the same location which
48e1416a 74 post dominates the first store, then the first store is dead.
4ee9c684 75
76 The single use of the store's virtual definition ensures that
77 there are no intervening aliased loads and the requirement that
78 the second load post dominate the first ensures that if the earlier
79 store executes, then the later stores will execute before the function
80 exits.
81
82 It may help to think of this as first moving the earlier store to
83 the point immediately before the later store. Again, the single
2c763ed4 84 use of the virtual definition and the post-dominance relationship
48e1416a 85 ensure that such movement would be safe. Clearly if there are
4ee9c684 86 back to back stores, then the second is redundant.
87
88 Reviewing section 10.7.2 in Morgan's "Building an Optimizing Compiler"
89 may also help in understanding this code since it discusses the
90 relationship between dead store and redundant load elimination. In
91 fact, they are the same transformation applied to different views of
92 the CFG. */
75a70cf9 93
4ee9c684 94
d02c8339 95/* Bitmap of blocks that have had EH statements cleaned. We should
96 remove their dead edges eventually. */
97static bitmap need_eh_cleanup;
98
4ee9c684 99
4fb5e5ca 100/* A helper of dse_optimize_stmt.
258bd648 101 Given a GIMPLE_ASSIGN in STMT that writes to REF, find a candidate
102 statement *USE_STMT that may prove STMT to be dead.
4fb5e5ca 103 Return TRUE if the above conditions are met, otherwise FALSE. */
104
105static bool
258bd648 106dse_possible_dead_store_p (ao_ref *ref, gimple stmt, gimple *use_stmt)
4fb5e5ca 107{
75a70cf9 108 gimple temp;
dd277d48 109 unsigned cnt = 0;
4fb5e5ca 110
4fb5e5ca 111 *use_stmt = NULL;
4fb5e5ca 112
dd277d48 113 /* Find the first dominated statement that clobbers (part of) the
114 memory stmt stores to with no intermediate statement that may use
115 part of the memory stmt stores. That is, find a store that may
116 prove stmt to be a dead store. */
117 temp = stmt;
118 do
119 {
48089971 120 gimple use_stmt, defvar_def;
dd277d48 121 imm_use_iterator ui;
122 bool fail = false;
123 tree defvar;
124
125 /* Limit stmt walking to be linear in the number of possibly
126 dead stores. */
127 if (++cnt > 256)
128 return false;
4fb5e5ca 129
75a70cf9 130 if (gimple_code (temp) == GIMPLE_PHI)
dd277d48 131 defvar = PHI_RESULT (temp);
132 else
133 defvar = gimple_vdef (temp);
48089971 134 defvar_def = temp;
dd277d48 135 temp = NULL;
136 FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
77ad2905 137 {
dd277d48 138 cnt++;
161fe168 139
43e2b34d 140 /* If we ever reach our DSE candidate stmt again fail. We
141 cannot handle dead stores in loops. */
142 if (use_stmt == stmt)
143 {
144 fail = true;
145 BREAK_FROM_IMM_USE_STMT (ui);
146 }
dd277d48 147 /* In simple cases we can look through PHI nodes, but we
148 have to be careful with loops and with memory references
149 containing operands that are also operands of PHI nodes.
150 See gcc.c-torture/execute/20051110-*.c. */
43e2b34d 151 else if (gimple_code (use_stmt) == GIMPLE_PHI)
dd277d48 152 {
153 if (temp
43e2b34d 154 /* Make sure we are not in a loop latch block. */
155 || gimple_bb (stmt) == gimple_bb (use_stmt)
dd277d48 156 || dominated_by_p (CDI_DOMINATORS,
43e2b34d 157 gimple_bb (stmt), gimple_bb (use_stmt))
158 /* We can look through PHIs to regions post-dominating
159 the DSE candidate stmt. */
160 || !dominated_by_p (CDI_POST_DOMINATORS,
161 gimple_bb (stmt), gimple_bb (use_stmt)))
dd277d48 162 {
163 fail = true;
164 BREAK_FROM_IMM_USE_STMT (ui);
165 }
48089971 166 /* Do not consider the PHI as use if it dominates the
167 stmt defining the virtual operand we are processing,
168 we have processed it already in this case. */
169 if (gimple_bb (defvar_def) != gimple_bb (use_stmt)
170 && !dominated_by_p (CDI_DOMINATORS,
171 gimple_bb (defvar_def),
172 gimple_bb (use_stmt)))
173 temp = use_stmt;
dd277d48 174 }
175 /* If the statement is a use the store is not dead. */
258bd648 176 else if (ref_maybe_used_by_stmt_p (use_stmt, ref))
161fe168 177 {
178 fail = true;
dd277d48 179 BREAK_FROM_IMM_USE_STMT (ui);
180 }
181 /* If this is a store, remember it or bail out if we have
182 multiple ones (the will be in different CFG parts then). */
183 else if (gimple_vdef (use_stmt))
184 {
185 if (temp)
186 {
187 fail = true;
188 BREAK_FROM_IMM_USE_STMT (ui);
189 }
190 temp = use_stmt;
161fe168 191 }
192 }
193
dd277d48 194 if (fail)
195 return false;
196
197 /* If we didn't find any definition this means the store is dead
198 if it isn't a store to global reachable memory. In this case
199 just pretend the stmt makes itself dead. Otherwise fail. */
200 if (!temp)
4fb5e5ca 201 {
258bd648 202 if (ref_may_alias_global_p (ref))
dd277d48 203 return false;
204
205 temp = stmt;
789aa951 206 break;
4fb5e5ca 207 }
208 }
88114c9f 209 /* Continue walking until we reach a kill. */
258bd648 210 while (!stmt_kills_ref_p (temp, ref));
4fb5e5ca 211
dd277d48 212 *use_stmt = temp;
4fb5e5ca 213
4fb5e5ca 214 return true;
215}
216
217
4ee9c684 218/* Attempt to eliminate dead stores in the statement referenced by BSI.
219
220 A dead store is a store into a memory location which will later be
221 overwritten by another store without any intervening loads. In this
222 case the earlier store can be deleted.
223
224 In our SSA + virtual operand world we use immediate uses of virtual
225 operands to detect dead stores. If a store's virtual definition
226 is used precisely once by a later store to the same location which
227 post dominates the first store, then the first store is dead. */
228
229static void
3222e348 230dse_optimize_stmt (gimple_stmt_iterator *gsi)
4ee9c684 231{
3222e348 232 gimple stmt = gsi_stmt (*gsi);
4ee9c684 233
e920115e 234 /* If this statement has no virtual defs, then there is nothing
4ee9c684 235 to do. */
dd277d48 236 if (!gimple_vdef (stmt))
4ee9c684 237 return;
238
9f559b20 239 /* Don't return early on *this_2(D) ={v} {CLOBBER}. */
240 if (gimple_has_volatile_ops (stmt)
241 && (!gimple_clobber_p (stmt)
242 || TREE_CODE (gimple_assign_lhs (stmt)) != MEM_REF))
52c2a307 243 return;
244
258bd648 245 /* We know we have virtual definitions. We can handle assignments and
246 some builtin calls. */
247 if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
248 {
249 switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
250 {
251 case BUILT_IN_MEMCPY:
252 case BUILT_IN_MEMMOVE:
253 case BUILT_IN_MEMSET:
254 {
255 gimple use_stmt;
256 ao_ref ref;
257 tree size = NULL_TREE;
258 if (gimple_call_num_args (stmt) == 3)
259 size = gimple_call_arg (stmt, 2);
260 tree ptr = gimple_call_arg (stmt, 0);
261 ao_ref_init_from_ptr_and_size (&ref, ptr, size);
262 if (!dse_possible_dead_store_p (&ref, stmt, &use_stmt))
263 return;
264
265 if (dump_file && (dump_flags & TDF_DETAILS))
266 {
267 fprintf (dump_file, " Deleted dead call '");
268 print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0);
269 fprintf (dump_file, "'\n");
270 }
271
272 tree lhs = gimple_call_lhs (stmt);
273 if (lhs)
274 {
275 gimple new_stmt = gimple_build_assign (lhs, ptr);
276 unlink_stmt_vdef (stmt);
277 if (gsi_replace (gsi, new_stmt, true))
278 bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
279 }
280 else
281 {
282 /* Then we need to fix the operand of the consuming stmt. */
283 unlink_stmt_vdef (stmt);
284
285 /* Remove the dead store. */
286 if (gsi_remove (gsi, true))
287 bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index);
288 }
289 break;
290 }
291 default:
292 return;
293 }
294 }
295
75a70cf9 296 if (is_gimple_assign (stmt))
4ee9c684 297 {
75a70cf9 298 gimple use_stmt;
4ee9c684 299
258bd648 300 /* Self-assignments are zombies. */
301 if (operand_equal_p (gimple_assign_rhs1 (stmt),
302 gimple_assign_lhs (stmt), 0))
303 use_stmt = stmt;
304 else
305 {
306 ao_ref ref;
307 ao_ref_init (&ref, gimple_assign_lhs (stmt));
308 if (!dse_possible_dead_store_p (&ref, stmt, &use_stmt))
309 return;
310 }
2bf1fefd 311
88114c9f 312 /* Now we know that use_stmt kills the LHS of stmt. */
313
9f559b20 314 /* But only remove *this_2(D) ={v} {CLOBBER} if killed by
315 another clobber stmt. */
316 if (gimple_clobber_p (stmt)
317 && !gimple_clobber_p (use_stmt))
318 return;
319
88114c9f 320 if (dump_file && (dump_flags & TDF_DETAILS))
4ee9c684 321 {
88114c9f 322 fprintf (dump_file, " Deleted dead store '");
323 print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0);
324 fprintf (dump_file, "'\n");
4ee9c684 325 }
88114c9f 326
327 /* Then we need to fix the operand of the consuming stmt. */
328 unlink_stmt_vdef (stmt);
329
330 /* Remove the dead store. */
258bd648 331 basic_block bb = gimple_bb (stmt);
88114c9f 332 if (gsi_remove (gsi, true))
333 bitmap_set_bit (need_eh_cleanup, bb->index);
334
335 /* And release any SSA_NAMEs set in this statement back to the
336 SSA_NAME manager. */
337 release_defs (stmt);
4ee9c684 338 }
339}
340
54c91640 341class dse_dom_walker : public dom_walker
342{
343public:
344 dse_dom_walker (cdi_direction direction) : dom_walker (direction) {}
345
346 virtual void before_dom_children (basic_block);
347};
348
349void
350dse_dom_walker::before_dom_children (basic_block bb)
4ee9c684 351{
75a70cf9 352 gimple_stmt_iterator gsi;
4ee9c684 353
3222e348 354 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
355 {
356 dse_optimize_stmt (&gsi);
357 if (gsi_end_p (gsi))
358 gsi = gsi_last_bb (bb);
359 else
360 gsi_prev (&gsi);
361 }
4ee9c684 362}
363
65b0537f 364namespace {
365
366const pass_data pass_data_dse =
367{
368 GIMPLE_PASS, /* type */
369 "dse", /* name */
370 OPTGROUP_NONE, /* optinfo_flags */
65b0537f 371 TV_TREE_DSE, /* tv_id */
372 ( PROP_cfg | PROP_ssa ), /* properties_required */
373 0, /* properties_provided */
374 0, /* properties_destroyed */
375 0, /* todo_flags_start */
8b88439e 376 0, /* todo_flags_finish */
65b0537f 377};
378
379class pass_dse : public gimple_opt_pass
380{
381public:
382 pass_dse (gcc::context *ctxt)
383 : gimple_opt_pass (pass_data_dse, ctxt)
384 {}
385
386 /* opt_pass methods: */
387 opt_pass * clone () { return new pass_dse (m_ctxt); }
388 virtual bool gate (function *) { return flag_tree_dse != 0; }
389 virtual unsigned int execute (function *);
390
391}; // class pass_dse
4fb5e5ca 392
65b0537f 393unsigned int
394pass_dse::execute (function *fun)
4ee9c684 395{
d02c8339 396 need_eh_cleanup = BITMAP_ALLOC (NULL);
397
ec415c45 398 renumber_gimple_stmt_uids ();
4ee9c684 399
400 /* We might consider making this a property of each pass so that it
401 can be [re]computed on an as-needed basis. Particularly since
402 this pass could be seen as an extension of DCE which needs post
403 dominators. */
404 calculate_dominance_info (CDI_POST_DOMINATORS);
dd277d48 405 calculate_dominance_info (CDI_DOMINATORS);
4ee9c684 406
4ee9c684 407 /* Dead store elimination is fundamentally a walk of the post-dominator
408 tree and a backwards walk of statements within each block. */
65b0537f 409 dse_dom_walker (CDI_POST_DOMINATORS).walk (fun->cfg->x_exit_block_ptr);
4ee9c684 410
d02c8339 411 /* Removal of stores may make some EH edges dead. Purge such edges from
412 the CFG as needed. */
413 if (!bitmap_empty_p (need_eh_cleanup))
414 {
415 gimple_purge_all_dead_eh_edges (need_eh_cleanup);
416 cleanup_tree_cfg ();
417 }
418
419 BITMAP_FREE (need_eh_cleanup);
420
4ee9c684 421 /* For now, just wipe the post-dominator information. */
422 free_dominance_info (CDI_POST_DOMINATORS);
2a1990e9 423 return 0;
4ee9c684 424}
425
cbe8bda8 426} // anon namespace
427
428gimple_opt_pass *
429make_pass_dse (gcc::context *ctxt)
430{
431 return new pass_dse (ctxt);
432}