xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa-uncprop.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* Routines for discovering and unpropagating edge equivalences.
2    Copyright (C) 2005-2013 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 3, 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 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 "tree.h"
25 #include "flags.h"
26 #include "tm_p.h"
27 #include "basic-block.h"
28 #include "function.h"
29 #include "tree-flow.h"
30 #include "domwalk.h"
31 #include "tree-pass.h"
32 #include "tree-ssa-propagate.h"
33 
34 /* The basic structure describing an equivalency created by traversing
35    an edge.  Traversing the edge effectively means that we can assume
36    that we've seen an assignment LHS = RHS.  */
37 struct edge_equivalency
38 {
39   tree rhs;
40   tree lhs;
41 };
42 
43 /* This routine finds and records edge equivalences for every edge
44    in the CFG.
45 
46    When complete, each edge that creates an equivalency will have an
47    EDGE_EQUIVALENCY structure hanging off the edge's AUX field.
48    The caller is responsible for freeing the AUX fields.  */
49 
50 static void
51 associate_equivalences_with_edges (void)
52 {
53   basic_block bb;
54 
55   /* Walk over each block.  If the block ends with a control statement,
56      then it might create a useful equivalence.  */
57   FOR_EACH_BB (bb)
58     {
59       gimple_stmt_iterator gsi = gsi_last_bb (bb);
60       gimple stmt;
61 
62       /* If the block does not end with a COND_EXPR or SWITCH_EXPR
63 	 then there is nothing to do.  */
64       if (gsi_end_p (gsi))
65 	continue;
66 
67       stmt = gsi_stmt (gsi);
68 
69       if (!stmt)
70 	continue;
71 
72       /* A COND_EXPR may create an equivalency in a variety of different
73 	 ways.  */
74       if (gimple_code (stmt) == GIMPLE_COND)
75 	{
76 	  edge true_edge;
77 	  edge false_edge;
78 	  struct edge_equivalency *equivalency;
79 	  enum tree_code code = gimple_cond_code (stmt);
80 
81 	  extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
82 
83 	  /* Equality tests may create one or two equivalences.  */
84 	  if (code == EQ_EXPR || code == NE_EXPR)
85 	    {
86 	      tree op0 = gimple_cond_lhs (stmt);
87 	      tree op1 = gimple_cond_rhs (stmt);
88 
89 	      /* Special case comparing booleans against a constant as we
90 		 know the value of OP0 on both arms of the branch.  i.e., we
91 		 can record an equivalence for OP0 rather than COND.  */
92 	      if (TREE_CODE (op0) == SSA_NAME
93 		  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
94 		  && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
95 		  && is_gimple_min_invariant (op1))
96 		{
97 		  if (code == EQ_EXPR)
98 		    {
99 		      equivalency = XNEW (struct edge_equivalency);
100 		      equivalency->lhs = op0;
101 		      equivalency->rhs = (integer_zerop (op1)
102 					  ? boolean_false_node
103 					  : boolean_true_node);
104 		      true_edge->aux = equivalency;
105 
106 		      equivalency = XNEW (struct edge_equivalency);
107 		      equivalency->lhs = op0;
108 		      equivalency->rhs = (integer_zerop (op1)
109 					  ? boolean_true_node
110 					  : boolean_false_node);
111 		      false_edge->aux = equivalency;
112 		    }
113 		  else
114 		    {
115 		      equivalency = XNEW (struct edge_equivalency);
116 		      equivalency->lhs = op0;
117 		      equivalency->rhs = (integer_zerop (op1)
118 					  ? boolean_true_node
119 					  : boolean_false_node);
120 		      true_edge->aux = equivalency;
121 
122 		      equivalency = XNEW (struct edge_equivalency);
123 		      equivalency->lhs = op0;
124 		      equivalency->rhs = (integer_zerop (op1)
125 					  ? boolean_false_node
126 					  : boolean_true_node);
127 		      false_edge->aux = equivalency;
128 		    }
129 		}
130 
131 	      else if (TREE_CODE (op0) == SSA_NAME
132 		       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
133 		       && (is_gimple_min_invariant (op1)
134 			   || (TREE_CODE (op1) == SSA_NAME
135 			       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))))
136 		{
137 		  /* For IEEE, -0.0 == 0.0, so we don't necessarily know
138 		     the sign of a variable compared against zero.  If
139 		     we're honoring signed zeros, then we cannot record
140 		     this value unless we know that the value is nonzero.  */
141 		  if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
142 		      && (TREE_CODE (op1) != REAL_CST
143 			  || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (op1))))
144 		    continue;
145 
146 		  equivalency = XNEW (struct edge_equivalency);
147 		  equivalency->lhs = op0;
148 		  equivalency->rhs = op1;
149 		  if (code == EQ_EXPR)
150 		    true_edge->aux = equivalency;
151 		  else
152 		    false_edge->aux = equivalency;
153 
154 		}
155 	    }
156 
157 	  /* ??? TRUTH_NOT_EXPR can create an equivalence too.  */
158 	}
159 
160       /* For a SWITCH_EXPR, a case label which represents a single
161 	 value and which is the only case label which reaches the
162 	 target block creates an equivalence.  */
163       else if (gimple_code (stmt) == GIMPLE_SWITCH)
164 	{
165 	  tree cond = gimple_switch_index (stmt);
166 
167 	  if (TREE_CODE (cond) == SSA_NAME
168 	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond))
169 	    {
170 	      int i, n_labels = gimple_switch_num_labels (stmt);
171 	      tree *info = XCNEWVEC (tree, last_basic_block);
172 
173 	      /* Walk over the case label vector.  Record blocks
174 		 which are reached by a single case label which represents
175 		 a single value.  */
176 	      for (i = 0; i < n_labels; i++)
177 		{
178 		  tree label = gimple_switch_label (stmt, i);
179 		  basic_block bb = label_to_block (CASE_LABEL (label));
180 
181 		  if (CASE_HIGH (label)
182 		      || !CASE_LOW (label)
183 		      || info[bb->index])
184 		    info[bb->index] = error_mark_node;
185 		  else
186 		    info[bb->index] = label;
187 		}
188 
189 	      /* Now walk over the blocks to determine which ones were
190 		 marked as being reached by a useful case label.  */
191 	      for (i = 0; i < n_basic_blocks; i++)
192 		{
193 		  tree node = info[i];
194 
195 		  if (node != NULL
196 		      && node != error_mark_node)
197 		    {
198 		      tree x = fold_convert (TREE_TYPE (cond), CASE_LOW (node));
199 		      struct edge_equivalency *equivalency;
200 
201 		      /* Record an equivalency on the edge from BB to basic
202 			 block I.  */
203 		      equivalency = XNEW (struct edge_equivalency);
204 		      equivalency->rhs = x;
205 		      equivalency->lhs = cond;
206 		      find_edge (bb, BASIC_BLOCK (i))->aux = equivalency;
207 		    }
208 		}
209 	      free (info);
210 	    }
211 	}
212 
213     }
214 }
215 
216 
217 /* Translating out of SSA sometimes requires inserting copies and
218    constant initializations on edges to eliminate PHI nodes.
219 
220    In some cases those copies and constant initializations are
221    redundant because the target already has the value on the
222    RHS of the assignment.
223 
224    We previously tried to catch these cases after translating
225    out of SSA form.  However, that code often missed cases.  Worse
226    yet, the cases it missed were also often missed by the RTL
227    optimizers.  Thus the resulting code had redundant instructions.
228 
229    This pass attempts to detect these situations before translating
230    out of SSA form.
231 
232    The key concept that this pass is built upon is that these
233    redundant copies and constant initializations often occur
234    due to constant/copy propagating equivalences resulting from
235    COND_EXPRs and SWITCH_EXPRs.
236 
237    We want to do those propagations as they can sometimes allow
238    the SSA optimizers to do a better job.  However, in the cases
239    where such propagations do not result in further optimization,
240    we would like to "undo" the propagation to avoid the redundant
241    copies and constant initializations.
242 
243    This pass works by first associating equivalences with edges in
244    the CFG.  For example, the edge leading from a SWITCH_EXPR to
245    its associated CASE_LABEL will have an equivalency between
246    SWITCH_COND and the value in the case label.
247 
248    Once we have found the edge equivalences, we proceed to walk
249    the CFG in dominator order.  As we traverse edges we record
250    equivalences associated with those edges we traverse.
251 
252    When we encounter a PHI node, we walk its arguments to see if we
253    have an equivalence for the PHI argument.  If so, then we replace
254    the argument.
255 
256    Equivalences are looked up based on their value (think of it as
257    the RHS of an assignment).   A value may be an SSA_NAME or an
258    invariant.  We may have several SSA_NAMEs with the same value,
259    so with each value we have a list of SSA_NAMEs that have the
260    same value.  */
261 
262 /* As we enter each block we record the value for any edge equivalency
263    leading to this block.  If no such edge equivalency exists, then we
264    record NULL.  These equivalences are live until we leave the dominator
265    subtree rooted at the block where we record the equivalency.  */
266 static vec<tree> equiv_stack;
267 
268 /* Global hash table implementing a mapping from invariant values
269    to a list of SSA_NAMEs which have the same value.  We might be
270    able to reuse tree-vn for this code.  */
271 static htab_t equiv;
272 
273 /* Main structure for recording equivalences into our hash table.  */
274 struct equiv_hash_elt
275 {
276   /* The value/key of this entry.  */
277   tree value;
278 
279   /* List of SSA_NAMEs which have the same value/key.  */
280   vec<tree> equivalences;
281 };
282 
283 static void uncprop_enter_block (struct dom_walk_data *, basic_block);
284 static void uncprop_leave_block (struct dom_walk_data *, basic_block);
285 static void uncprop_into_successor_phis (basic_block);
286 
287 /* Hashing and equality routines for the hash table.  */
288 
289 static hashval_t
290 equiv_hash (const void *p)
291 {
292   tree const value = ((const struct equiv_hash_elt *)p)->value;
293   return iterative_hash_expr (value, 0);
294 }
295 
296 static int
297 equiv_eq (const void *p1, const void *p2)
298 {
299   tree value1 = ((const struct equiv_hash_elt *)p1)->value;
300   tree value2 = ((const struct equiv_hash_elt *)p2)->value;
301 
302   return operand_equal_p (value1, value2, 0);
303 }
304 
305 /* Free an instance of equiv_hash_elt.  */
306 
307 static void
308 equiv_free (void *p)
309 {
310   struct equiv_hash_elt *elt = (struct equiv_hash_elt *) p;
311   elt->equivalences.release ();
312   free (elt);
313 }
314 
315 /* Remove the most recently recorded equivalency for VALUE.  */
316 
317 static void
318 remove_equivalence (tree value)
319 {
320   struct equiv_hash_elt equiv_hash_elt, *equiv_hash_elt_p;
321   void **slot;
322 
323   equiv_hash_elt.value = value;
324   equiv_hash_elt.equivalences.create (0);
325 
326   slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
327 
328   equiv_hash_elt_p = (struct equiv_hash_elt *) *slot;
329   equiv_hash_elt_p->equivalences.pop ();
330 }
331 
332 /* Record EQUIVALENCE = VALUE into our hash table.  */
333 
334 static void
335 record_equiv (tree value, tree equivalence)
336 {
337   struct equiv_hash_elt *equiv_hash_elt;
338   void **slot;
339 
340   equiv_hash_elt = XNEW (struct equiv_hash_elt);
341   equiv_hash_elt->value = value;
342   equiv_hash_elt->equivalences.create (0);
343 
344   slot = htab_find_slot (equiv, equiv_hash_elt, INSERT);
345 
346   if (*slot == NULL)
347     *slot = (void *) equiv_hash_elt;
348   else
349      free (equiv_hash_elt);
350 
351   equiv_hash_elt = (struct equiv_hash_elt *) *slot;
352 
353   equiv_hash_elt->equivalences.safe_push (equivalence);
354 }
355 
356 /* Main driver for un-cprop.  */
357 
358 static unsigned int
359 tree_ssa_uncprop (void)
360 {
361   struct dom_walk_data walk_data;
362   basic_block bb;
363 
364   associate_equivalences_with_edges ();
365 
366   /* Create our global data structures.  */
367   equiv = htab_create (1024, equiv_hash, equiv_eq, equiv_free);
368   equiv_stack.create (2);
369 
370   /* We're going to do a dominator walk, so ensure that we have
371      dominance information.  */
372   calculate_dominance_info (CDI_DOMINATORS);
373 
374   /* Setup callbacks for the generic dominator tree walker.  */
375   walk_data.dom_direction = CDI_DOMINATORS;
376   walk_data.initialize_block_local_data = NULL;
377   walk_data.before_dom_children = uncprop_enter_block;
378   walk_data.after_dom_children = uncprop_leave_block;
379   walk_data.global_data = NULL;
380   walk_data.block_local_data_size = 0;
381 
382   /* Now initialize the dominator walker.  */
383   init_walk_dominator_tree (&walk_data);
384 
385   /* Recursively walk the dominator tree undoing unprofitable
386      constant/copy propagations.  */
387   walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
388 
389   /* Finalize and clean up.  */
390   fini_walk_dominator_tree (&walk_data);
391 
392   /* EQUIV_STACK should already be empty at this point, so we just
393      need to empty elements out of the hash table, free EQUIV_STACK,
394      and cleanup the AUX field on the edges.  */
395   htab_delete (equiv);
396   equiv_stack.release ();
397   FOR_EACH_BB (bb)
398     {
399       edge e;
400       edge_iterator ei;
401 
402       FOR_EACH_EDGE (e, ei, bb->succs)
403 	{
404 	  if (e->aux)
405 	    {
406 	      free (e->aux);
407 	      e->aux = NULL;
408 	    }
409 	}
410     }
411   return 0;
412 }
413 
414 
415 /* We have finished processing the dominator children of BB, perform
416    any finalization actions in preparation for leaving this node in
417    the dominator tree.  */
418 
419 static void
420 uncprop_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
421 		     basic_block bb ATTRIBUTE_UNUSED)
422 {
423   /* Pop the topmost value off the equiv stack.  */
424   tree value = equiv_stack.pop ();
425 
426   /* If that value was non-null, then pop the topmost equivalency off
427      its equivalency stack.  */
428   if (value != NULL)
429     remove_equivalence (value);
430 }
431 
432 /* Unpropagate values from PHI nodes in successor blocks of BB.  */
433 
434 static void
435 uncprop_into_successor_phis (basic_block bb)
436 {
437   edge e;
438   edge_iterator ei;
439 
440   /* For each successor edge, first temporarily record any equivalence
441      on that edge.  Then unpropagate values in any PHI nodes at the
442      destination of the edge.  Then remove the temporary equivalence.  */
443   FOR_EACH_EDGE (e, ei, bb->succs)
444     {
445       gimple_seq phis = phi_nodes (e->dest);
446       gimple_stmt_iterator gsi;
447 
448       /* If there are no PHI nodes in this destination, then there is
449 	 no sense in recording any equivalences.  */
450       if (gimple_seq_empty_p (phis))
451 	continue;
452 
453       /* Record any equivalency associated with E.  */
454       if (e->aux)
455 	{
456 	  struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
457 	  record_equiv (equiv->rhs, equiv->lhs);
458 	}
459 
460       /* Walk over the PHI nodes, unpropagating values.  */
461       for (gsi = gsi_start (phis) ; !gsi_end_p (gsi); gsi_next (&gsi))
462 	{
463 	  gimple phi = gsi_stmt (gsi);
464 	  tree arg = PHI_ARG_DEF (phi, e->dest_idx);
465 	  tree res = PHI_RESULT (phi);
466 	  struct equiv_hash_elt equiv_hash_elt;
467 	  void **slot;
468 
469 	  /* If the argument is not an invariant, and refers to the same
470 	     underlying variable as the PHI result, then there's no
471 	     point in un-propagating the argument.  */
472 	  if (!is_gimple_min_invariant (arg)
473 	      && (SSA_NAME_VAR (arg) == SSA_NAME_VAR (res)
474 		  && TREE_TYPE (arg) == TREE_TYPE (res)))
475 	    continue;
476 
477 	  /* Lookup this argument's value in the hash table.  */
478 	  equiv_hash_elt.value = arg;
479 	  equiv_hash_elt.equivalences.create (0);
480 	  slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
481 
482 	  if (slot)
483 	    {
484 	      struct equiv_hash_elt *elt = (struct equiv_hash_elt *) *slot;
485 	      int j;
486 
487 	      /* Walk every equivalence with the same value.  If we find
488 		 one with the same underlying variable as the PHI result,
489 		 then replace the value in the argument with its equivalent
490 		 SSA_NAME.  Use the most recent equivalence as hopefully
491 		 that results in shortest lifetimes.  */
492 	      for (j = elt->equivalences.length () - 1; j >= 0; j--)
493 		{
494 		  tree equiv = elt->equivalences[j];
495 
496 		  if (SSA_NAME_VAR (equiv) == SSA_NAME_VAR (res)
497 		      && TREE_TYPE (equiv) == TREE_TYPE (res))
498 		    {
499 		      SET_PHI_ARG_DEF (phi, e->dest_idx, equiv);
500 		      break;
501 		    }
502 		}
503 	    }
504 	}
505 
506       /* If we had an equivalence associated with this edge, remove it.  */
507       if (e->aux)
508 	{
509 	  struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
510 	  remove_equivalence (equiv->rhs);
511 	}
512     }
513 }
514 
515 /* Ignoring loop backedges, if BB has precisely one incoming edge then
516    return that edge.  Otherwise return NULL.  */
517 static edge
518 single_incoming_edge_ignoring_loop_edges (basic_block bb)
519 {
520   edge retval = NULL;
521   edge e;
522   edge_iterator ei;
523 
524   FOR_EACH_EDGE (e, ei, bb->preds)
525     {
526       /* A loop back edge can be identified by the destination of
527 	 the edge dominating the source of the edge.  */
528       if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
529 	continue;
530 
531       /* If we have already seen a non-loop edge, then we must have
532 	 multiple incoming non-loop edges and thus we return NULL.  */
533       if (retval)
534 	return NULL;
535 
536       /* This is the first non-loop incoming edge we have found.  Record
537 	 it.  */
538       retval = e;
539     }
540 
541   return retval;
542 }
543 
544 static void
545 uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
546 		     basic_block bb)
547 {
548   basic_block parent;
549   edge e;
550   bool recorded = false;
551 
552   /* If this block is dominated by a single incoming edge and that edge
553      has an equivalency, then record the equivalency and push the
554      VALUE onto EQUIV_STACK.  Else push a NULL entry on EQUIV_STACK.  */
555   parent = get_immediate_dominator (CDI_DOMINATORS, bb);
556   if (parent)
557     {
558       e = single_incoming_edge_ignoring_loop_edges (bb);
559 
560       if (e && e->src == parent && e->aux)
561 	{
562 	  struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
563 
564 	  record_equiv (equiv->rhs, equiv->lhs);
565 	  equiv_stack.safe_push (equiv->rhs);
566 	  recorded = true;
567 	}
568     }
569 
570   if (!recorded)
571     equiv_stack.safe_push (NULL_TREE);
572 
573   uncprop_into_successor_phis (bb);
574 }
575 
576 static bool
577 gate_uncprop (void)
578 {
579   return flag_tree_dom != 0;
580 }
581 
582 struct gimple_opt_pass pass_uncprop =
583 {
584  {
585   GIMPLE_PASS,
586   "uncprop",				/* name */
587   OPTGROUP_NONE,                        /* optinfo_flags */
588   gate_uncprop,				/* gate */
589   tree_ssa_uncprop,			/* execute */
590   NULL,					/* sub */
591   NULL,					/* next */
592   0,					/* static_pass_number */
593   TV_TREE_SSA_UNCPROP,			/* tv_id */
594   PROP_cfg | PROP_ssa,			/* properties_required */
595   0,					/* properties_provided */
596   0,					/* properties_destroyed */
597   0,					/* todo_flags_start */
598   TODO_verify_ssa	                /* todo_flags_finish */
599  }
600 };
601