2015-05-18 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / tree-ssa-uncprop.c
blobf75a7f1b8e068db508a4bbcd80533685a78c665a
1 /* Routines for discovering and unpropagating edge equivalences.
2 Copyright (C) 2005-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)
9 any later version.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "wide-int.h"
32 #include "inchash.h"
33 #include "real.h"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "stor-layout.h"
37 #include "flags.h"
38 #include "tm_p.h"
39 #include "predict.h"
40 #include "hard-reg-set.h"
41 #include "input.h"
42 #include "function.h"
43 #include "dominance.h"
44 #include "cfg.h"
45 #include "cfganal.h"
46 #include "basic-block.h"
47 #include "hash-table.h"
48 #include "hash-map.h"
49 #include "tree-ssa-alias.h"
50 #include "internal-fn.h"
51 #include "gimple-expr.h"
52 #include "is-a.h"
53 #include "gimple.h"
54 #include "gimple-iterator.h"
55 #include "gimple-ssa.h"
56 #include "tree-cfg.h"
57 #include "tree-phinodes.h"
58 #include "ssa-iterators.h"
59 #include "domwalk.h"
60 #include "tree-pass.h"
61 #include "tree-ssa-propagate.h"
63 /* The basic structure describing an equivalency created by traversing
64 an edge. Traversing the edge effectively means that we can assume
65 that we've seen an assignment LHS = RHS. */
66 struct edge_equivalency
68 tree rhs;
69 tree lhs;
72 /* This routine finds and records edge equivalences for every edge
73 in the CFG.
75 When complete, each edge that creates an equivalency will have an
76 EDGE_EQUIVALENCY structure hanging off the edge's AUX field.
77 The caller is responsible for freeing the AUX fields. */
79 static void
80 associate_equivalences_with_edges (void)
82 basic_block bb;
84 /* Walk over each block. If the block ends with a control statement,
85 then it might create a useful equivalence. */
86 FOR_EACH_BB_FN (bb, cfun)
88 gimple_stmt_iterator gsi = gsi_last_bb (bb);
89 gimple stmt;
91 /* If the block does not end with a COND_EXPR or SWITCH_EXPR
92 then there is nothing to do. */
93 if (gsi_end_p (gsi))
94 continue;
96 stmt = gsi_stmt (gsi);
98 if (!stmt)
99 continue;
101 /* A COND_EXPR may create an equivalency in a variety of different
102 ways. */
103 if (gimple_code (stmt) == GIMPLE_COND)
105 edge true_edge;
106 edge false_edge;
107 struct edge_equivalency *equivalency;
108 enum tree_code code = gimple_cond_code (stmt);
110 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
112 /* Equality tests may create one or two equivalences. */
113 if (code == EQ_EXPR || code == NE_EXPR)
115 tree op0 = gimple_cond_lhs (stmt);
116 tree op1 = gimple_cond_rhs (stmt);
118 /* Special case comparing booleans against a constant as we
119 know the value of OP0 on both arms of the branch. i.e., we
120 can record an equivalence for OP0 rather than COND. */
121 if (TREE_CODE (op0) == SSA_NAME
122 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
123 && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
124 && is_gimple_min_invariant (op1))
126 if (code == EQ_EXPR)
128 equivalency = XNEW (struct edge_equivalency);
129 equivalency->lhs = op0;
130 equivalency->rhs = (integer_zerop (op1)
131 ? boolean_false_node
132 : boolean_true_node);
133 true_edge->aux = equivalency;
135 equivalency = XNEW (struct edge_equivalency);
136 equivalency->lhs = op0;
137 equivalency->rhs = (integer_zerop (op1)
138 ? boolean_true_node
139 : boolean_false_node);
140 false_edge->aux = equivalency;
142 else
144 equivalency = XNEW (struct edge_equivalency);
145 equivalency->lhs = op0;
146 equivalency->rhs = (integer_zerop (op1)
147 ? boolean_true_node
148 : boolean_false_node);
149 true_edge->aux = equivalency;
151 equivalency = XNEW (struct edge_equivalency);
152 equivalency->lhs = op0;
153 equivalency->rhs = (integer_zerop (op1)
154 ? boolean_false_node
155 : boolean_true_node);
156 false_edge->aux = equivalency;
160 else if (TREE_CODE (op0) == SSA_NAME
161 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
162 && (is_gimple_min_invariant (op1)
163 || (TREE_CODE (op1) == SSA_NAME
164 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op1))))
166 /* For IEEE, -0.0 == 0.0, so we don't necessarily know
167 the sign of a variable compared against zero. If
168 we're honoring signed zeros, then we cannot record
169 this value unless we know that the value is nonzero. */
170 if (HONOR_SIGNED_ZEROS (op0)
171 && (TREE_CODE (op1) != REAL_CST
172 || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (op1))))
173 continue;
175 equivalency = XNEW (struct edge_equivalency);
176 equivalency->lhs = op0;
177 equivalency->rhs = op1;
178 if (code == EQ_EXPR)
179 true_edge->aux = equivalency;
180 else
181 false_edge->aux = equivalency;
186 /* ??? TRUTH_NOT_EXPR can create an equivalence too. */
189 /* For a SWITCH_EXPR, a case label which represents a single
190 value and which is the only case label which reaches the
191 target block creates an equivalence. */
192 else if (gimple_code (stmt) == GIMPLE_SWITCH)
194 gswitch *switch_stmt = as_a <gswitch *> (stmt);
195 tree cond = gimple_switch_index (switch_stmt);
197 if (TREE_CODE (cond) == SSA_NAME
198 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond))
200 int i, n_labels = gimple_switch_num_labels (switch_stmt);
201 tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun));
203 /* Walk over the case label vector. Record blocks
204 which are reached by a single case label which represents
205 a single value. */
206 for (i = 0; i < n_labels; i++)
208 tree label = gimple_switch_label (switch_stmt, i);
209 basic_block bb = label_to_block (CASE_LABEL (label));
211 if (CASE_HIGH (label)
212 || !CASE_LOW (label)
213 || info[bb->index])
214 info[bb->index] = error_mark_node;
215 else
216 info[bb->index] = label;
219 /* Now walk over the blocks to determine which ones were
220 marked as being reached by a useful case label. */
221 for (i = 0; i < n_basic_blocks_for_fn (cfun); i++)
223 tree node = info[i];
225 if (node != NULL
226 && node != error_mark_node)
228 tree x = fold_convert (TREE_TYPE (cond), CASE_LOW (node));
229 struct edge_equivalency *equivalency;
231 /* Record an equivalency on the edge from BB to basic
232 block I. */
233 equivalency = XNEW (struct edge_equivalency);
234 equivalency->rhs = x;
235 equivalency->lhs = cond;
236 find_edge (bb, BASIC_BLOCK_FOR_FN (cfun, i))->aux =
237 equivalency;
240 free (info);
248 /* Translating out of SSA sometimes requires inserting copies and
249 constant initializations on edges to eliminate PHI nodes.
251 In some cases those copies and constant initializations are
252 redundant because the target already has the value on the
253 RHS of the assignment.
255 We previously tried to catch these cases after translating
256 out of SSA form. However, that code often missed cases. Worse
257 yet, the cases it missed were also often missed by the RTL
258 optimizers. Thus the resulting code had redundant instructions.
260 This pass attempts to detect these situations before translating
261 out of SSA form.
263 The key concept that this pass is built upon is that these
264 redundant copies and constant initializations often occur
265 due to constant/copy propagating equivalences resulting from
266 COND_EXPRs and SWITCH_EXPRs.
268 We want to do those propagations as they can sometimes allow
269 the SSA optimizers to do a better job. However, in the cases
270 where such propagations do not result in further optimization,
271 we would like to "undo" the propagation to avoid the redundant
272 copies and constant initializations.
274 This pass works by first associating equivalences with edges in
275 the CFG. For example, the edge leading from a SWITCH_EXPR to
276 its associated CASE_LABEL will have an equivalency between
277 SWITCH_COND and the value in the case label.
279 Once we have found the edge equivalences, we proceed to walk
280 the CFG in dominator order. As we traverse edges we record
281 equivalences associated with those edges we traverse.
283 When we encounter a PHI node, we walk its arguments to see if we
284 have an equivalence for the PHI argument. If so, then we replace
285 the argument.
287 Equivalences are looked up based on their value (think of it as
288 the RHS of an assignment). A value may be an SSA_NAME or an
289 invariant. We may have several SSA_NAMEs with the same value,
290 so with each value we have a list of SSA_NAMEs that have the
291 same value. */
294 /* Main structure for recording equivalences into our hash table. */
295 struct equiv_hash_elt
297 /* The value/key of this entry. */
298 tree value;
300 /* List of SSA_NAMEs which have the same value/key. */
301 vec<tree> equivalences;
304 /* Value to ssa name equivalence hashtable helpers. */
306 struct val_ssa_equiv_hash_traits : default_hashmap_traits
308 static inline hashval_t hash (tree);
309 static inline bool equal_keys (tree, tree);
310 template<typename T> static inline void remove (T &);
313 inline hashval_t
314 val_ssa_equiv_hash_traits::hash (tree value)
316 return iterative_hash_expr (value, 0);
319 inline bool
320 val_ssa_equiv_hash_traits::equal_keys (tree value1, tree value2)
322 return operand_equal_p (value1, value2, 0);
325 /* Free an instance of equiv_hash_elt. */
327 template<typename T>
328 inline void
329 val_ssa_equiv_hash_traits::remove (T &elt)
331 elt.m_value.release ();
334 /* Global hash table implementing a mapping from invariant values
335 to a list of SSA_NAMEs which have the same value. We might be
336 able to reuse tree-vn for this code. */
337 static hash_map<tree, vec<tree>, val_ssa_equiv_hash_traits> *val_ssa_equiv;
339 static void uncprop_into_successor_phis (basic_block);
341 /* Remove the most recently recorded equivalency for VALUE. */
343 static void
344 remove_equivalence (tree value)
346 val_ssa_equiv->get (value)->pop ();
349 /* Record EQUIVALENCE = VALUE into our hash table. */
351 static void
352 record_equiv (tree value, tree equivalence)
354 val_ssa_equiv->get_or_insert (value).safe_push (equivalence);
357 class uncprop_dom_walker : public dom_walker
359 public:
360 uncprop_dom_walker (cdi_direction direction) : dom_walker (direction) {}
362 virtual void before_dom_children (basic_block);
363 virtual void after_dom_children (basic_block);
365 private:
367 /* As we enter each block we record the value for any edge equivalency
368 leading to this block. If no such edge equivalency exists, then we
369 record NULL. These equivalences are live until we leave the dominator
370 subtree rooted at the block where we record the equivalency. */
371 auto_vec<tree, 2> m_equiv_stack;
374 /* We have finished processing the dominator children of BB, perform
375 any finalization actions in preparation for leaving this node in
376 the dominator tree. */
378 void
379 uncprop_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
381 /* Pop the topmost value off the equiv stack. */
382 tree value = m_equiv_stack.pop ();
384 /* If that value was non-null, then pop the topmost equivalency off
385 its equivalency stack. */
386 if (value != NULL)
387 remove_equivalence (value);
390 /* Unpropagate values from PHI nodes in successor blocks of BB. */
392 static void
393 uncprop_into_successor_phis (basic_block bb)
395 edge e;
396 edge_iterator ei;
398 /* For each successor edge, first temporarily record any equivalence
399 on that edge. Then unpropagate values in any PHI nodes at the
400 destination of the edge. Then remove the temporary equivalence. */
401 FOR_EACH_EDGE (e, ei, bb->succs)
403 gimple_seq phis = phi_nodes (e->dest);
404 gimple_stmt_iterator gsi;
406 /* If there are no PHI nodes in this destination, then there is
407 no sense in recording any equivalences. */
408 if (gimple_seq_empty_p (phis))
409 continue;
411 /* Record any equivalency associated with E. */
412 if (e->aux)
414 struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
415 record_equiv (equiv->rhs, equiv->lhs);
418 /* Walk over the PHI nodes, unpropagating values. */
419 for (gsi = gsi_start (phis) ; !gsi_end_p (gsi); gsi_next (&gsi))
421 gimple phi = gsi_stmt (gsi);
422 tree arg = PHI_ARG_DEF (phi, e->dest_idx);
423 tree res = PHI_RESULT (phi);
425 /* If the argument is not an invariant and can be potentially
426 coalesced with the result, then there's no point in
427 un-propagating the argument. */
428 if (!is_gimple_min_invariant (arg)
429 && gimple_can_coalesce_p (arg, res))
430 continue;
432 /* Lookup this argument's value in the hash table. */
433 vec<tree> *equivalences = val_ssa_equiv->get (arg);
434 if (equivalences)
436 /* Walk every equivalence with the same value. If we find
437 one that can potentially coalesce with the PHI rsult,
438 then replace the value in the argument with its equivalent
439 SSA_NAME. Use the most recent equivalence as hopefully
440 that results in shortest lifetimes. */
441 for (int j = equivalences->length () - 1; j >= 0; j--)
443 tree equiv = (*equivalences)[j];
445 if (gimple_can_coalesce_p (equiv, res))
447 SET_PHI_ARG_DEF (phi, e->dest_idx, equiv);
448 break;
454 /* If we had an equivalence associated with this edge, remove it. */
455 if (e->aux)
457 struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
458 remove_equivalence (equiv->rhs);
463 /* Ignoring loop backedges, if BB has precisely one incoming edge then
464 return that edge. Otherwise return NULL. */
465 static edge
466 single_incoming_edge_ignoring_loop_edges (basic_block bb)
468 edge retval = NULL;
469 edge e;
470 edge_iterator ei;
472 FOR_EACH_EDGE (e, ei, bb->preds)
474 /* A loop back edge can be identified by the destination of
475 the edge dominating the source of the edge. */
476 if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
477 continue;
479 /* If we have already seen a non-loop edge, then we must have
480 multiple incoming non-loop edges and thus we return NULL. */
481 if (retval)
482 return NULL;
484 /* This is the first non-loop incoming edge we have found. Record
485 it. */
486 retval = e;
489 return retval;
492 void
493 uncprop_dom_walker::before_dom_children (basic_block bb)
495 basic_block parent;
496 edge e;
497 bool recorded = false;
499 /* If this block is dominated by a single incoming edge and that edge
500 has an equivalency, then record the equivalency and push the
501 VALUE onto EQUIV_STACK. Else push a NULL entry on EQUIV_STACK. */
502 parent = get_immediate_dominator (CDI_DOMINATORS, bb);
503 if (parent)
505 e = single_incoming_edge_ignoring_loop_edges (bb);
507 if (e && e->src == parent && e->aux)
509 struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
511 record_equiv (equiv->rhs, equiv->lhs);
512 m_equiv_stack.safe_push (equiv->rhs);
513 recorded = true;
517 if (!recorded)
518 m_equiv_stack.safe_push (NULL_TREE);
520 uncprop_into_successor_phis (bb);
523 namespace {
525 const pass_data pass_data_uncprop =
527 GIMPLE_PASS, /* type */
528 "uncprop", /* name */
529 OPTGROUP_NONE, /* optinfo_flags */
530 TV_TREE_SSA_UNCPROP, /* tv_id */
531 ( PROP_cfg | PROP_ssa ), /* properties_required */
532 0, /* properties_provided */
533 0, /* properties_destroyed */
534 0, /* todo_flags_start */
535 0, /* todo_flags_finish */
538 class pass_uncprop : public gimple_opt_pass
540 public:
541 pass_uncprop (gcc::context *ctxt)
542 : gimple_opt_pass (pass_data_uncprop, ctxt)
545 /* opt_pass methods: */
546 opt_pass * clone () { return new pass_uncprop (m_ctxt); }
547 virtual bool gate (function *) { return flag_tree_dom != 0; }
548 virtual unsigned int execute (function *);
550 }; // class pass_uncprop
552 unsigned int
553 pass_uncprop::execute (function *fun)
555 basic_block bb;
557 associate_equivalences_with_edges ();
559 /* Create our global data structures. */
560 val_ssa_equiv
561 = new hash_map<tree, vec<tree>, val_ssa_equiv_hash_traits> (1024);
563 /* We're going to do a dominator walk, so ensure that we have
564 dominance information. */
565 calculate_dominance_info (CDI_DOMINATORS);
567 /* Recursively walk the dominator tree undoing unprofitable
568 constant/copy propagations. */
569 uncprop_dom_walker (CDI_DOMINATORS).walk (fun->cfg->x_entry_block_ptr);
571 /* we just need to empty elements out of the hash table, and cleanup the
572 AUX field on the edges. */
573 delete val_ssa_equiv;
574 val_ssa_equiv = NULL;
575 FOR_EACH_BB_FN (bb, fun)
577 edge e;
578 edge_iterator ei;
580 FOR_EACH_EDGE (e, ei, bb->succs)
582 if (e->aux)
584 free (e->aux);
585 e->aux = NULL;
589 return 0;
592 } // anon namespace
594 gimple_opt_pass *
595 make_pass_uncprop (gcc::context *ctxt)
597 return new pass_uncprop (ctxt);