tree-ssa-dse.c revision 1.3
1/* Dead store elimination
2   Copyright (C) 2004-2013 Free Software Foundation, Inc.
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
8the Free Software Foundation; either version 3, or (at your option)
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
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tm.h"
24#include "ggc.h"
25#include "tree.h"
26#include "tm_p.h"
27#include "basic-block.h"
28#include "gimple-pretty-print.h"
29#include "tree-flow.h"
30#include "tree-pass.h"
31#include "domwalk.h"
32#include "flags.h"
33#include "langhooks.h"
34
35/* This file implements dead store elimination.
36
37   A dead store is a store into a memory location which will later be
38   overwritten by another store without any intervening loads.  In this
39   case the earlier store can be deleted.
40
41   In our SSA + virtual operand world we use immediate uses of virtual
42   operands to detect dead stores.  If a store's virtual definition
43   is used precisely once by a later store to the same location which
44   post dominates the first store, then the first store is dead.
45
46   The single use of the store's virtual definition ensures that
47   there are no intervening aliased loads and the requirement that
48   the second load post dominate the first ensures that if the earlier
49   store executes, then the later stores will execute before the function
50   exits.
51
52   It may help to think of this as first moving the earlier store to
53   the point immediately before the later store.  Again, the single
54   use of the virtual definition and the post-dominance relationship
55   ensure that such movement would be safe.  Clearly if there are
56   back to back stores, then the second is redundant.
57
58   Reviewing section 10.7.2 in Morgan's "Building an Optimizing Compiler"
59   may also help in understanding this code since it discusses the
60   relationship between dead store and redundant load elimination.  In
61   fact, they are the same transformation applied to different views of
62   the CFG.  */
63
64
65/* Bitmap of blocks that have had EH statements cleaned.  We should
66   remove their dead edges eventually.  */
67static bitmap need_eh_cleanup;
68
69static bool gate_dse (void);
70static unsigned int tree_ssa_dse (void);
71static void dse_enter_block (struct dom_walk_data *, basic_block);
72
73
74/* A helper of dse_optimize_stmt.
75   Given a GIMPLE_ASSIGN in STMT, find a candidate statement *USE_STMT that
76   may prove STMT to be dead.
77   Return TRUE if the above conditions are met, otherwise FALSE.  */
78
79static bool
80dse_possible_dead_store_p (gimple stmt, gimple *use_stmt)
81{
82  gimple temp;
83  unsigned cnt = 0;
84
85  *use_stmt = NULL;
86
87  /* Find the first dominated statement that clobbers (part of) the
88     memory stmt stores to with no intermediate statement that may use
89     part of the memory stmt stores.  That is, find a store that may
90     prove stmt to be a dead store.  */
91  temp = stmt;
92  do
93    {
94      gimple use_stmt, defvar_def;
95      imm_use_iterator ui;
96      bool fail = false;
97      tree defvar;
98
99      /* Limit stmt walking to be linear in the number of possibly
100         dead stores.  */
101      if (++cnt > 256)
102	return false;
103
104      if (gimple_code (temp) == GIMPLE_PHI)
105	defvar = PHI_RESULT (temp);
106      else
107	defvar = gimple_vdef (temp);
108      defvar_def = temp;
109      temp = NULL;
110      FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
111	{
112	  cnt++;
113
114	  /* If we ever reach our DSE candidate stmt again fail.  We
115	     cannot handle dead stores in loops.  */
116	  if (use_stmt == stmt)
117	    {
118	      fail = true;
119	      BREAK_FROM_IMM_USE_STMT (ui);
120	    }
121	  /* In simple cases we can look through PHI nodes, but we
122	     have to be careful with loops and with memory references
123	     containing operands that are also operands of PHI nodes.
124	     See gcc.c-torture/execute/20051110-*.c.  */
125	  else if (gimple_code (use_stmt) == GIMPLE_PHI)
126	    {
127	      if (temp
128		  /* Make sure we are not in a loop latch block.  */
129		  || gimple_bb (stmt) == gimple_bb (use_stmt)
130		  || dominated_by_p (CDI_DOMINATORS,
131				     gimple_bb (stmt), gimple_bb (use_stmt))
132		  /* We can look through PHIs to regions post-dominating
133		     the DSE candidate stmt.  */
134		  || !dominated_by_p (CDI_POST_DOMINATORS,
135				      gimple_bb (stmt), gimple_bb (use_stmt)))
136		{
137		  fail = true;
138		  BREAK_FROM_IMM_USE_STMT (ui);
139		}
140	      /* Do not consider the PHI as use if it dominates the
141	         stmt defining the virtual operand we are processing,
142		 we have processed it already in this case.  */
143	      if (gimple_bb (defvar_def) != gimple_bb (use_stmt)
144		  && !dominated_by_p (CDI_DOMINATORS,
145				      gimple_bb (defvar_def),
146				      gimple_bb (use_stmt)))
147		temp = use_stmt;
148	    }
149	  /* If the statement is a use the store is not dead.  */
150	  else if (ref_maybe_used_by_stmt_p (use_stmt,
151					     gimple_assign_lhs (stmt)))
152	    {
153	      fail = true;
154	      BREAK_FROM_IMM_USE_STMT (ui);
155	    }
156	  /* If this is a store, remember it or bail out if we have
157	     multiple ones (the will be in different CFG parts then).  */
158	  else if (gimple_vdef (use_stmt))
159	    {
160	      if (temp)
161		{
162		  fail = true;
163		  BREAK_FROM_IMM_USE_STMT (ui);
164		}
165	      temp = use_stmt;
166	    }
167	}
168
169      if (fail)
170	return false;
171
172      /* If we didn't find any definition this means the store is dead
173         if it isn't a store to global reachable memory.  In this case
174	 just pretend the stmt makes itself dead.  Otherwise fail.  */
175      if (!temp)
176	{
177	  if (stmt_may_clobber_global_p (stmt))
178	    return false;
179
180	  temp = stmt;
181	  break;
182	}
183    }
184  /* We deliberately stop on clobbering statements and not only on
185     killing ones to make walking cheaper.  Otherwise we can just
186     continue walking until both stores have equal reference trees.  */
187  while (!stmt_may_clobber_ref_p (temp, gimple_assign_lhs (stmt)));
188
189  *use_stmt = temp;
190
191  return true;
192}
193
194
195/* Attempt to eliminate dead stores in the statement referenced by BSI.
196
197   A dead store is a store into a memory location which will later be
198   overwritten by another store without any intervening loads.  In this
199   case the earlier store can be deleted.
200
201   In our SSA + virtual operand world we use immediate uses of virtual
202   operands to detect dead stores.  If a store's virtual definition
203   is used precisely once by a later store to the same location which
204   post dominates the first store, then the first store is dead.  */
205
206static void
207dse_optimize_stmt (gimple_stmt_iterator *gsi)
208{
209  gimple stmt = gsi_stmt (*gsi);
210
211  /* If this statement has no virtual defs, then there is nothing
212     to do.  */
213  if (!gimple_vdef (stmt))
214    return;
215
216  /* We know we have virtual definitions.  If this is a GIMPLE_ASSIGN
217     that's not also a function call, then record it into our table.  */
218  if (is_gimple_call (stmt) && gimple_call_fndecl (stmt))
219    return;
220
221  if (gimple_has_volatile_ops (stmt))
222    return;
223
224  if (is_gimple_assign (stmt))
225    {
226      gimple use_stmt;
227
228      if (!dse_possible_dead_store_p (stmt, &use_stmt))
229	return;
230
231      /* If we have precisely one immediate use at this point and the
232	 stores are to the same memory location or there is a chain of
233	 virtual uses from stmt and the stmt which stores to that same
234	 memory location, then we may have found redundant store.  */
235      if ((gimple_has_lhs (use_stmt)
236	   && (operand_equal_p (gimple_assign_lhs (stmt),
237				gimple_get_lhs (use_stmt), 0)))
238	  || stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt)))
239	{
240	  basic_block bb;
241
242	  /* If use_stmt is or might be a nop assignment, e.g. for
243	     struct { ... } S a, b, *p; ...
244	     b = a; b = b;
245	     or
246	     b = a; b = *p; where p might be &b,
247	     or
248	     *p = a; *p = b; where p might be &b,
249	     or
250	     *p = *u; *p = *v; where p might be v, then USE_STMT
251	     acts as a use as well as definition, so store in STMT
252	     is not dead.  */
253	  if (stmt != use_stmt
254	      && ref_maybe_used_by_stmt_p (use_stmt, gimple_assign_lhs (stmt)))
255	    return;
256
257	  if (dump_file && (dump_flags & TDF_DETAILS))
258            {
259              fprintf (dump_file, "  Deleted dead store '");
260              print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0);
261              fprintf (dump_file, "'\n");
262            }
263
264	  /* Then we need to fix the operand of the consuming stmt.  */
265	  unlink_stmt_vdef (stmt);
266
267	  /* Remove the dead store.  */
268	  bb = gimple_bb (stmt);
269	  if (gsi_remove (gsi, true))
270	    bitmap_set_bit (need_eh_cleanup, bb->index);
271
272	  /* And release any SSA_NAMEs set in this statement back to the
273	     SSA_NAME manager.  */
274	  release_defs (stmt);
275	}
276    }
277}
278
279static void
280dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
281		 basic_block bb)
282{
283  gimple_stmt_iterator gsi;
284
285  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
286    {
287      dse_optimize_stmt (&gsi);
288      if (gsi_end_p (gsi))
289	gsi = gsi_last_bb (bb);
290      else
291	gsi_prev (&gsi);
292    }
293}
294
295/* Main entry point.  */
296
297static unsigned int
298tree_ssa_dse (void)
299{
300  struct dom_walk_data walk_data;
301
302  need_eh_cleanup = BITMAP_ALLOC (NULL);
303
304  renumber_gimple_stmt_uids ();
305
306  /* We might consider making this a property of each pass so that it
307     can be [re]computed on an as-needed basis.  Particularly since
308     this pass could be seen as an extension of DCE which needs post
309     dominators.  */
310  calculate_dominance_info (CDI_POST_DOMINATORS);
311  calculate_dominance_info (CDI_DOMINATORS);
312
313  /* Dead store elimination is fundamentally a walk of the post-dominator
314     tree and a backwards walk of statements within each block.  */
315  walk_data.dom_direction = CDI_POST_DOMINATORS;
316  walk_data.initialize_block_local_data = NULL;
317  walk_data.before_dom_children = dse_enter_block;
318  walk_data.after_dom_children = NULL;
319
320  walk_data.block_local_data_size = 0;
321  walk_data.global_data = NULL;
322
323  /* Initialize the dominator walker.  */
324  init_walk_dominator_tree (&walk_data);
325
326  /* Recursively walk the dominator tree.  */
327  walk_dominator_tree (&walk_data, EXIT_BLOCK_PTR);
328
329  /* Finalize the dominator walker.  */
330  fini_walk_dominator_tree (&walk_data);
331
332  /* Removal of stores may make some EH edges dead.  Purge such edges from
333     the CFG as needed.  */
334  if (!bitmap_empty_p (need_eh_cleanup))
335    {
336      gimple_purge_all_dead_eh_edges (need_eh_cleanup);
337      cleanup_tree_cfg ();
338    }
339
340  BITMAP_FREE (need_eh_cleanup);
341
342  /* For now, just wipe the post-dominator information.  */
343  free_dominance_info (CDI_POST_DOMINATORS);
344  return 0;
345}
346
347static bool
348gate_dse (void)
349{
350  return flag_tree_dse != 0;
351}
352
353struct gimple_opt_pass pass_dse =
354{
355 {
356  GIMPLE_PASS,
357  "dse",			/* name */
358  OPTGROUP_NONE,                /* optinfo_flags */
359  gate_dse,			/* gate */
360  tree_ssa_dse,			/* execute */
361  NULL,				/* sub */
362  NULL,				/* next */
363  0,				/* static_pass_number */
364  TV_TREE_DSE,			/* tv_id */
365  PROP_cfg | PROP_ssa,		/* properties_required */
366  0,				/* properties_provided */
367  0,				/* properties_destroyed */
368  0,				/* todo_flags_start */
369  TODO_ggc_collect
370    | TODO_verify_ssa		/* todo_flags_finish */
371 }
372};
373