1 /* Dead store elimination
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
27 #include "fold-const.h"
30 #include "hard-reg-set.h"
32 #include "dominance.h"
34 #include "basic-block.h"
35 #include "gimple-pretty-print.h"
37 #include "tree-ssa-alias.h"
38 #include "internal-fn.h"
39 #include "gimple-expr.h"
41 #include "gimple-iterator.h"
42 #include "gimple-ssa.h"
44 #include "tree-phinodes.h"
45 #include "ssa-iterators.h"
46 #include "stringpool.h"
47 #include "tree-ssanames.h"
50 #include "insn-config.h"
60 #include "tree-pass.h"
62 #include "langhooks.h"
63 #include "tree-cfgcleanup.h"
65 /* This file implements dead store elimination.
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.
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
74 post dominates the first store, then the first store is dead.
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
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
84 use of the virtual definition and the post-dominance relationship
85 ensure that such movement would be safe. Clearly if there are
86 back to back stores, then the second is redundant.
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
95 /* Bitmap of blocks that have had EH statements cleaned. We should
96 remove their dead edges eventually. */
97 static bitmap need_eh_cleanup
;
100 /* A helper of dse_optimize_stmt.
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.
103 Return TRUE if the above conditions are met, otherwise FALSE. */
106 dse_possible_dead_store_p (ao_ref
*ref
, gimple stmt
, gimple
*use_stmt
)
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. */
120 gimple use_stmt
, defvar_def
;
125 /* Limit stmt walking to be linear in the number of possibly
130 if (gimple_code (temp
) == GIMPLE_PHI
)
131 defvar
= PHI_RESULT (temp
);
133 defvar
= gimple_vdef (temp
);
136 FOR_EACH_IMM_USE_STMT (use_stmt
, ui
, defvar
)
140 /* If we ever reach our DSE candidate stmt again fail. We
141 cannot handle dead stores in loops. */
142 if (use_stmt
== stmt
)
145 BREAK_FROM_IMM_USE_STMT (ui
);
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. */
151 else if (gimple_code (use_stmt
) == GIMPLE_PHI
)
154 /* Make sure we are not in a loop latch block. */
155 || gimple_bb (stmt
) == gimple_bb (use_stmt
)
156 || dominated_by_p (CDI_DOMINATORS
,
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
)))
164 BREAK_FROM_IMM_USE_STMT (ui
);
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
)))
175 /* If the statement is a use the store is not dead. */
176 else if (ref_maybe_used_by_stmt_p (use_stmt
, ref
))
179 BREAK_FROM_IMM_USE_STMT (ui
);
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
))
188 BREAK_FROM_IMM_USE_STMT (ui
);
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. */
202 if (ref_may_alias_global_p (ref
))
209 /* Continue walking until we reach a kill. */
210 while (!stmt_kills_ref_p (temp
, ref
));
218 /* Attempt to eliminate dead stores in the statement referenced by BSI.
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.
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. */
230 dse_optimize_stmt (gimple_stmt_iterator
*gsi
)
232 gimple stmt
= gsi_stmt (*gsi
);
234 /* If this statement has no virtual defs, then there is nothing
236 if (!gimple_vdef (stmt
))
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
))
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
))
249 switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
)))
251 case BUILT_IN_MEMCPY
:
252 case BUILT_IN_MEMMOVE
:
253 case BUILT_IN_MEMSET
:
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
))
265 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
267 fprintf (dump_file
, " Deleted dead call '");
268 print_gimple_stmt (dump_file
, gsi_stmt (*gsi
), dump_flags
, 0);
269 fprintf (dump_file
, "'\n");
272 tree lhs
= gimple_call_lhs (stmt
);
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
);
282 /* Then we need to fix the operand of the consuming stmt. */
283 unlink_stmt_vdef (stmt
);
285 /* Remove the dead store. */
286 if (gsi_remove (gsi
, true))
287 bitmap_set_bit (need_eh_cleanup
, gimple_bb (stmt
)->index
);
296 if (is_gimple_assign (stmt
))
300 /* Self-assignments are zombies. */
301 if (operand_equal_p (gimple_assign_rhs1 (stmt
),
302 gimple_assign_lhs (stmt
), 0))
307 ao_ref_init (&ref
, gimple_assign_lhs (stmt
));
308 if (!dse_possible_dead_store_p (&ref
, stmt
, &use_stmt
))
312 /* Now we know that use_stmt kills the LHS of stmt. */
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
))
320 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
322 fprintf (dump_file
, " Deleted dead store '");
323 print_gimple_stmt (dump_file
, gsi_stmt (*gsi
), dump_flags
, 0);
324 fprintf (dump_file
, "'\n");
327 /* Then we need to fix the operand of the consuming stmt. */
328 unlink_stmt_vdef (stmt
);
330 /* Remove the dead store. */
331 basic_block bb
= gimple_bb (stmt
);
332 if (gsi_remove (gsi
, true))
333 bitmap_set_bit (need_eh_cleanup
, bb
->index
);
335 /* And release any SSA_NAMEs set in this statement back to the
341 class dse_dom_walker
: public dom_walker
344 dse_dom_walker (cdi_direction direction
) : dom_walker (direction
) {}
346 virtual void before_dom_children (basic_block
);
350 dse_dom_walker::before_dom_children (basic_block bb
)
352 gimple_stmt_iterator gsi
;
354 for (gsi
= gsi_last_bb (bb
); !gsi_end_p (gsi
);)
356 dse_optimize_stmt (&gsi
);
358 gsi
= gsi_last_bb (bb
);
366 const pass_data pass_data_dse
=
368 GIMPLE_PASS
, /* type */
370 OPTGROUP_NONE
, /* optinfo_flags */
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 */
376 0, /* todo_flags_finish */
379 class pass_dse
: public gimple_opt_pass
382 pass_dse (gcc::context
*ctxt
)
383 : gimple_opt_pass (pass_data_dse
, ctxt
)
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
*);
394 pass_dse::execute (function
*fun
)
396 need_eh_cleanup
= BITMAP_ALLOC (NULL
);
398 renumber_gimple_stmt_uids ();
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
404 calculate_dominance_info (CDI_POST_DOMINATORS
);
405 calculate_dominance_info (CDI_DOMINATORS
);
407 /* Dead store elimination is fundamentally a walk of the post-dominator
408 tree and a backwards walk of statements within each block. */
409 dse_dom_walker (CDI_POST_DOMINATORS
).walk (fun
->cfg
->x_exit_block_ptr
);
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
))
415 gimple_purge_all_dead_eh_edges (need_eh_cleanup
);
419 BITMAP_FREE (need_eh_cleanup
);
421 /* For now, just wipe the post-dominator information. */
422 free_dominance_info (CDI_POST_DOMINATORS
);
429 make_pass_dse (gcc::context
*ctxt
)
431 return new pass_dse (ctxt
);