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