OSDN Git Service

PR testsuite/23611, PR testsuite/23615
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dse.c
1 /* Dead store elimination
2    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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 2, or (at your option)
9 any later version.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "basic-block.h"
30 #include "timevar.h"
31 #include "diagnostic.h"
32 #include "tree-flow.h"
33 #include "tree-pass.h"
34 #include "tree-dump.h"
35 #include "domwalk.h"
36 #include "flags.h"
37
38 /* This file implements dead store elimination.
39
40    A dead store is a store into a memory location which will later be
41    overwritten by another store without any intervening loads.  In this
42    case the earlier store can be deleted.
43
44    In our SSA + virtual operand world we use immediate uses of virtual
45    operands to detect dead stores.  If a store's virtual definition
46    is used precisely once by a later store to the same location which
47    post dominates the first store, then the first store is dead. 
48
49    The single use of the store's virtual definition ensures that
50    there are no intervening aliased loads and the requirement that
51    the second load post dominate the first ensures that if the earlier
52    store executes, then the later stores will execute before the function
53    exits.
54
55    It may help to think of this as first moving the earlier store to
56    the point immediately before the later store.  Again, the single
57    use of the virtual definition and the post-dominance relationship
58    ensure that such movement would be safe.  Clearly if there are 
59    back to back stores, then the second is redundant.
60
61    Reviewing section 10.7.2 in Morgan's "Building an Optimizing Compiler"
62    may also help in understanding this code since it discusses the
63    relationship between dead store and redundant load elimination.  In
64    fact, they are the same transformation applied to different views of
65    the CFG.  */
66    
67
68 struct dse_global_data
69 {
70   /* This is the global bitmap for store statements.
71
72      Each statement has a unique ID.  When we encounter a store statement
73      that we want to record, set the bit corresponding to the statement's
74      unique ID in this bitmap.  */
75   bitmap stores;
76 };
77
78 /* We allocate a bitmap-per-block for stores which are encountered
79    during the scan of that block.  This allows us to restore the 
80    global bitmap of stores when we finish processing a block.  */
81 struct dse_block_local_data
82 {
83   bitmap stores;
84 };
85
86 static bool gate_dse (void);
87 static void tree_ssa_dse (void);
88 static void dse_initialize_block_local_data (struct dom_walk_data *,
89                                              basic_block,
90                                              bool);
91 static void dse_optimize_stmt (struct dom_walk_data *,
92                                basic_block,
93                                block_stmt_iterator);
94 static void dse_record_phis (struct dom_walk_data *, basic_block);
95 static void dse_finalize_block (struct dom_walk_data *, basic_block);
96 static void record_voperand_set (bitmap, bitmap *, unsigned int);
97
98 static unsigned max_stmt_uid;   /* Maximal uid of a statement.  Uids to phi
99                                    nodes are assigned using the versions of
100                                    ssa names they define.  */
101
102 /* Returns uid of statement STMT.  */
103
104 static unsigned
105 get_stmt_uid (tree stmt)
106 {
107   if (TREE_CODE (stmt) == PHI_NODE)
108     return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid;
109
110   return stmt_ann (stmt)->uid;
111 }
112
113 /* Set bit UID in bitmaps GLOBAL and *LOCAL, creating *LOCAL as needed.  */
114
115 static void
116 record_voperand_set (bitmap global, bitmap *local, unsigned int uid)
117 {
118   /* Lazily allocate the bitmap.  Note that we do not get a notification
119      when the block local data structures die, so we allocate the local
120      bitmap backed by the GC system.  */
121   if (*local == NULL)
122     *local = BITMAP_GGC_ALLOC ();
123
124   /* Set the bit in the local and global bitmaps.  */
125   bitmap_set_bit (*local, uid);
126   bitmap_set_bit (global, uid);
127 }
128
129 /* Initialize block local data structures.  */
130
131 static void
132 dse_initialize_block_local_data (struct dom_walk_data *walk_data,
133                                  basic_block bb ATTRIBUTE_UNUSED,
134                                  bool recycled)
135 {
136   struct dse_block_local_data *bd
137     = VEC_last (void_p, walk_data->block_data_stack);
138
139   /* If we are given a recycled block local data structure, ensure any
140      bitmap associated with the block is cleared.  */
141   if (recycled)
142     {
143       if (bd->stores)
144         bitmap_clear (bd->stores);
145     }
146 }
147
148 /* Attempt to eliminate dead stores in the statement referenced by BSI.
149
150    A dead store is a store into a memory location which will later be
151    overwritten by another store without any intervening loads.  In this
152    case the earlier store can be deleted.
153
154    In our SSA + virtual operand world we use immediate uses of virtual
155    operands to detect dead stores.  If a store's virtual definition
156    is used precisely once by a later store to the same location which
157    post dominates the first store, then the first store is dead.  */
158
159 static void
160 dse_optimize_stmt (struct dom_walk_data *walk_data,
161                    basic_block bb ATTRIBUTE_UNUSED,
162                    block_stmt_iterator bsi)
163 {
164   struct dse_block_local_data *bd
165     = VEC_last (void_p, walk_data->block_data_stack);
166   struct dse_global_data *dse_gd = walk_data->global_data;
167   tree stmt = bsi_stmt (bsi);
168   stmt_ann_t ann = stmt_ann (stmt);
169
170   /* If this statement has no virtual defs, then there is nothing
171      to do.  */
172   if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF)))
173     return;
174
175   /* We know we have virtual definitions.  If this is a MODIFY_EXPR that's
176      not also a function call, then record it into our table.  */
177   if (get_call_expr_in (stmt))
178     return;
179
180   if (ann->has_volatile_ops)
181     return;
182
183   if (TREE_CODE (stmt) == MODIFY_EXPR)
184     {
185       use_operand_p first_use_p = NULL_USE_OPERAND_P;
186       use_operand_p use_p = NULL;
187       tree use, use_stmt, temp;
188       tree defvar = NULL_TREE, usevar = NULL_TREE;
189       bool fail = false;
190       use_operand_p var2;
191       def_operand_p var1;
192       ssa_op_iter op_iter;
193
194       /* We want to verify that each virtual definition in STMT has
195          precisely one use and that all the virtual definitions are
196          used by the same single statement.  When complete, we
197          want USE_STMT to refer to the one statement which uses
198          all of the virtual definitions from STMT.  */
199       use_stmt = NULL;
200       FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND (var1, var2, stmt, op_iter)
201         {
202           defvar = DEF_FROM_PTR (var1);
203           usevar = USE_FROM_PTR (var2);
204
205           /* If this virtual def does not have precisely one use, then
206              we will not be able to eliminate STMT.  */
207           if (num_imm_uses (defvar) != 1)
208             {
209               fail = true;
210               break;
211             }
212
213           /* Get the one and only immediate use of DEFVAR.  */
214           single_imm_use (defvar, &use_p, &temp);
215           gcc_assert (use_p != NULL_USE_OPERAND_P);
216           first_use_p = use_p;
217           use = USE_FROM_PTR (use_p);
218
219           /* If the immediate use of DEF_VAR is not the same as the
220              previously find immediate uses, then we will not be able
221              to eliminate STMT.  */
222           if (use_stmt == NULL)
223             use_stmt = temp;
224           else if (temp != use_stmt)
225             {
226               fail = true;
227               break;
228             }
229         }
230
231       if (fail)
232         {
233           record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
234           return;
235         }
236
237       /* Skip through any PHI nodes we have already seen if the PHI
238          represents the only use of this store.
239
240          Note this does not handle the case where the store has
241          multiple V_{MAY,MUST}_DEFs which all reach a set of PHI nodes in the
242          same block.  */
243       while (use_p != NULL_USE_OPERAND_P
244              && TREE_CODE (use_stmt) == PHI_NODE
245              && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt)))
246         {
247           /* Skip past this PHI and loop again in case we had a PHI
248              chain.  */
249           if (single_imm_use (PHI_RESULT (use_stmt), &use_p, &use_stmt))
250             use = USE_FROM_PTR (use_p);
251         }
252
253       /* If we have precisely one immediate use at this point, then we may
254          have found redundant store.  */
255       if (use_p != NULL_USE_OPERAND_P
256           && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
257           && operand_equal_p (TREE_OPERAND (stmt, 0),
258                               TREE_OPERAND (use_stmt, 0), 0))
259         {
260           /* Make sure we propagate the ABNORMAL bit setting.  */
261           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (first_use_p)))
262             SSA_NAME_OCCURS_IN_ABNORMAL_PHI (usevar) = 1;
263
264           if (dump_file && (dump_flags & TDF_DETAILS))
265             {
266               fprintf (dump_file, "  Deleted dead store '");
267               print_generic_expr (dump_file, bsi_stmt (bsi), dump_flags);
268               fprintf (dump_file, "'\n");
269             }
270           /* Then we need to fix the operand of the consuming stmt.  */
271           FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND (var1, var2, stmt, op_iter)
272             {
273               single_imm_use (DEF_FROM_PTR (var1), &use_p, &temp);
274               SET_USE (use_p, USE_FROM_PTR (var2));
275             }
276           /* Remove the dead store.  */
277           bsi_remove (&bsi);
278
279           /* And release any SSA_NAMEs set in this statement back to the
280              SSA_NAME manager.  */
281           release_defs (stmt);
282         }
283
284       record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
285     }
286 }
287
288 /* Record that we have seen the PHIs at the start of BB which correspond
289    to virtual operands.  */
290 static void
291 dse_record_phis (struct dom_walk_data *walk_data, basic_block bb)
292 {
293   struct dse_block_local_data *bd
294     = VEC_last (void_p, walk_data->block_data_stack);
295   struct dse_global_data *dse_gd = walk_data->global_data;
296   tree phi;
297
298   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
299     if (!is_gimple_reg (PHI_RESULT (phi)))
300       record_voperand_set (dse_gd->stores,
301                            &bd->stores,
302                            get_stmt_uid (phi));
303 }
304
305 static void
306 dse_finalize_block (struct dom_walk_data *walk_data,
307                     basic_block bb ATTRIBUTE_UNUSED)
308 {
309   struct dse_block_local_data *bd
310     = VEC_last (void_p, walk_data->block_data_stack);
311   struct dse_global_data *dse_gd = walk_data->global_data;
312   bitmap stores = dse_gd->stores;
313   unsigned int i;
314   bitmap_iterator bi;
315
316   /* Unwind the stores noted in this basic block.  */
317   if (bd->stores)
318     EXECUTE_IF_SET_IN_BITMAP (bd->stores, 0, i, bi)
319       {
320         bitmap_clear_bit (stores, i);
321       }
322 }
323
324 static void
325 tree_ssa_dse (void)
326 {
327   struct dom_walk_data walk_data;
328   struct dse_global_data dse_gd;
329   basic_block bb;
330
331   /* Create a UID for each statement in the function.  Ordering of the
332      UIDs is not important for this pass.  */
333   max_stmt_uid = 0;
334   FOR_EACH_BB (bb)
335     {
336       block_stmt_iterator bsi;
337
338       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
339         stmt_ann (bsi_stmt (bsi))->uid = max_stmt_uid++;
340     }
341
342   /* We might consider making this a property of each pass so that it
343      can be [re]computed on an as-needed basis.  Particularly since
344      this pass could be seen as an extension of DCE which needs post
345      dominators.  */
346   calculate_dominance_info (CDI_POST_DOMINATORS);
347
348   /* Dead store elimination is fundamentally a walk of the post-dominator
349      tree and a backwards walk of statements within each block.  */
350   walk_data.walk_stmts_backward = true;
351   walk_data.dom_direction = CDI_POST_DOMINATORS;
352   walk_data.initialize_block_local_data = dse_initialize_block_local_data;
353   walk_data.before_dom_children_before_stmts = NULL;
354   walk_data.before_dom_children_walk_stmts = dse_optimize_stmt;
355   walk_data.before_dom_children_after_stmts = dse_record_phis;
356   walk_data.after_dom_children_before_stmts = NULL;
357   walk_data.after_dom_children_walk_stmts = NULL;
358   walk_data.after_dom_children_after_stmts = dse_finalize_block;
359   walk_data.interesting_blocks = NULL;
360
361   walk_data.block_local_data_size = sizeof (struct dse_block_local_data);
362
363   /* This is the main hash table for the dead store elimination pass.  */
364   dse_gd.stores = BITMAP_ALLOC (NULL);
365   walk_data.global_data = &dse_gd;
366
367   /* Initialize the dominator walker.  */
368   init_walk_dominator_tree (&walk_data);
369
370   /* Recursively walk the dominator tree.  */
371   walk_dominator_tree (&walk_data, EXIT_BLOCK_PTR);
372
373   /* Finalize the dominator walker.  */
374   fini_walk_dominator_tree (&walk_data);
375
376   /* Release the main bitmap.  */
377   BITMAP_FREE (dse_gd.stores);
378
379   /* For now, just wipe the post-dominator information.  */
380   free_dominance_info (CDI_POST_DOMINATORS);
381 }
382
383 static bool
384 gate_dse (void)
385 {
386   return flag_tree_dse != 0;
387 }
388
389 struct tree_opt_pass pass_dse = {
390   "dse",                        /* name */
391   gate_dse,                     /* gate */
392   tree_ssa_dse,                 /* execute */
393   NULL,                         /* sub */
394   NULL,                         /* next */
395   0,                            /* static_pass_number */
396   TV_TREE_DSE,                  /* tv_id */
397   PROP_cfg
398     | PROP_ssa
399     | PROP_alias,               /* properties_required */
400   0,                            /* properties_provided */
401   0,                            /* properties_destroyed */
402   0,                            /* todo_flags_start */
403   TODO_dump_func
404     | TODO_ggc_collect
405     | TODO_verify_ssa,          /* todo_flags_finish */
406   0                             /* letter */
407 };