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