]> gcc.gnu.org Git - gcc.git/blob - gcc/tree-ssa-pre.c
tree-ssa.texi: Remove references to VDEF and add descriptions of V_MAY_DEF and V_MUST...
[gcc.git] / gcc / tree-ssa-pre.c
1 /* SSA-PRE for trees.
2 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin <dan@dberlin.org>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "errors.h"
26 #include "ggc.h"
27 #include "tree.h"
28
29 /* These RTL headers are needed for basic-block.h. */
30 #include "rtl.h"
31 #include "tm_p.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "diagnostic.h"
35 #include "tree-inline.h"
36 #include "tree-flow.h"
37 #include "tree-gimple.h"
38 #include "tree-dump.h"
39 #include "timevar.h"
40 #include "fibheap.h"
41 #include "hashtab.h"
42 #include "tree-iterator.h"
43 #include "real.h"
44 #include "alloc-pool.h"
45 #include "tree-pass.h"
46 #include "flags.h"
47
48
49 /*
50
51 Some of the algorithms are also based on Open64's SSAPRE implementation.
52
53 Since the papers are a bit dense to read, take a while to grasp,
54 and have a few bugs, i'll give a quick rundown:
55
56 Normally, in non-SSA form, one performs PRE on expressions using
57 bit vectors, determining properties for all expressions at once
58 through bitmap operations and iterative dataflow.
59
60 SSAPRE, like most non-SSA->SSA algorithm conversions, operates one
61 expression at a time, and doesn't use bitvectors or iterative
62 dataflow.
63
64 It answers the question "Given a single hypothetical temporary
65 variable, what expressions could we eliminate.
66
67 To be able to do this, we need an SSA form for expressions.
68 If you are already confused, you likely think an expression, as
69 used here, is something like "b_3 = a_2 + 5". It's not. It's "a +
70 5". "a_2 + 5" is an *occurrence* of the expression "a + 5". Just
71 like PRE, it's lexical equivalence that matters.
72 Compilers generally give you an SSA form for variables, and maybe
73 arrays (and/or conditionals). But not for expressions.
74
75 GCC doesn't give you one either, so we have to build it.
76 Thus, the first steps of SSAPRE are to do just these things.
77
78 First we collect lists of occurrences of expressions we are going
79 to operate on.
80 Note that:
81 Unlike the paper, we don't have to ever add newly formed
82 expressions to the list (for normal SSAPRE, anyway), because we
83 don't have expressions with more than two operators, and each
84 operator is either a constant or a variable. Thus, no second
85 order effects.
86
87 Once we have the lists of occurrences, we process one expression
88 at a time, doing the following:
89 1. Using a slightly modified SSA phi placement algorithm, place
90 expression PHI's for expressions.
91 2. Using a two step optimistic SSA renaming algorithm, version the
92 nodes and link phi operands to their real occurrences, if they
93 exist. This creates a factored graph of our expression SSA occurrences.
94 3. Using the factored graph, compute downsafe, avail, and later for
95 EPHIs (which are SSA versions of the same named bitvector PRE
96 problems)
97 4. Using EPHI availability information and versions, compute what
98 occurrences need to have saves, and what occurrences can be
99 reloaded from an already saved value.
100 5. Insert the saves and reloads, and transform EPHIs into regular
101 phis of the temporary we use for insertion/saving.
102
103 See http://citeseer.nj.nec.com/chow97new.html, and
104 http://citeseer.nj.nec.com/kennedy99partial.html for details of the
105 algorithm.
106
107 kennedy99partial is newer, and is what this implementation is based
108 on.
109
110 For strength reduction addition, see
111 http://citeseer.nj.nec.com/kennedy98strength.html.
112
113 There is also a paper on sparse register promotion using PRE that
114 contains the basic algorithm for load PRE. The exact title/url of
115 the paper escapes me.
116
117 Lastly, there is a code hoisting extension that open64 performs
118 (see opt_ehoist.cxx), but we don't. It's not documented in any
119 papers, but not that difficult to understand of implement. */
120
121
122 /* TODOS:
123 Do strength reduction on a +-b and -a, not just a * <constant>.
124 */
125
126 struct expr_info;
127 static void clear_all_eref_arrays (void);
128 static inline bool expr_lexically_eq (const tree, const tree);
129 static void free_expr_info (struct expr_info *);
130 static bitmap compute_idfs (bitmap *, tree);
131 static void set_var_phis (struct expr_info *, tree);
132 static inline bool names_match_p (const tree, const tree);
133 static bool is_strred_cand (const tree);
134 static int pre_expression (struct expr_info *, void *, bitmap);
135 static bool is_injuring_def (struct expr_info *, tree);
136 static inline bool okay_injuring_def (tree, tree);
137 static bool expr_phi_insertion (bitmap *, struct expr_info *);
138 static tree factor_through_injuries (struct expr_info *, tree, tree, bool *);
139 static inline tree maybe_find_rhs_use_for_var (tree, tree, unsigned int);
140 static inline tree find_rhs_use_for_var (tree, tree);
141 static tree create_ephi_node (basic_block, unsigned int);
142 static inline int opnum_of_phi (tree, int);
143 static inline int opnum_of_ephi (const tree, const edge);
144 static tree subst_phis (struct expr_info *, tree, basic_block, basic_block);
145 static void generate_expr_as_of_bb (tree, basic_block, basic_block);
146 static void generate_vops_as_of_bb (tree, basic_block, basic_block);
147 static void rename_1 (struct expr_info *);
148 static void process_delayed_rename (struct expr_info *, tree, tree);
149 static void assign_new_class (tree, varray_type *, varray_type *);
150 static void create_and_insert_occ_in_preorder_dt_order (struct expr_info *);
151 static void insert_euse_in_preorder_dt_order (struct expr_info *);
152 static bool ephi_has_unsafe_arg (tree);
153 static void reset_down_safe (tree, int);
154 static void compute_down_safety (struct expr_info *);
155 static void compute_will_be_avail (struct expr_info *);
156 static void compute_stops (struct expr_info *);
157 static bool finalize_1 (struct expr_info *);
158 static void finalize_2 (struct expr_info *);
159 static tree occ_identical_to (tree);
160 static void require_phi (struct expr_info *, basic_block);
161 static bool really_available_def (tree node);
162
163 /* Functions used for an EPHI based depth first search. */
164 struct ephi_df_search
165 {
166 /* Return true if the ephi has been seen. */
167 bool (*seen) (tree);
168 /* Mark the ephi as seen. */
169 void (*set_seen) (tree);
170 /* Note that the search reaches from one ephi to it's use. */
171 void (*reach_from_to) (tree, int, tree);
172 /* Return true if we should start a search from this PHI. */
173 bool (*start_from) (tree);
174 /* Return true if we should continue the search to this use. */
175 bool (*continue_from_to) (tree, int, tree);
176 };
177 static bool repl_search_seen (tree);
178 static void repl_search_set_seen (tree);
179 static void repl_search_reach_from_to (tree, int, tree);
180 static bool repl_search_start_from (tree);
181 static bool repl_search_continue_from_to (tree, int, tree);
182 static bool stops_search_seen (tree);
183 static void stops_search_set_seen (tree);
184 static void stops_search_reach_from_to (tree, int, tree);
185 static bool stops_search_start_from (tree);
186 static bool stops_search_continue_from_to (tree, int, tree);
187 static bool cba_search_seen (tree);
188 static void cba_search_set_seen (tree);
189 static bool cba_search_start_from (tree);
190 static bool cba_search_continue_from_to (tree, int, tree);
191 struct ephi_df_search cant_be_avail_search = {
192 cba_search_seen,
193 cba_search_set_seen,
194 NULL,
195 cba_search_start_from,
196 cba_search_continue_from_to
197 };
198
199 struct ephi_df_search stops_search = {
200 stops_search_seen,
201 stops_search_set_seen,
202 stops_search_reach_from_to,
203 stops_search_start_from,
204 stops_search_continue_from_to
205 };
206
207
208 /* depth-first replacement search used during temp ESSA minimization. */
209 struct ephi_df_search replacing_search = {
210 repl_search_seen,
211 repl_search_set_seen,
212 repl_search_reach_from_to,
213 repl_search_start_from,
214 repl_search_continue_from_to
215 };
216
217 static void do_ephi_df_search_1 (struct ephi_df_search, tree);
218 static void do_ephi_df_search (struct expr_info *, struct ephi_df_search);
219
220 static inline bool any_operand_injured (tree);
221 static void code_motion (struct expr_info *);
222 static tree pick_ssa_name (tree stmt);
223 #if 0
224 static tree calculate_increment (struct expr_info *, tree);
225 #endif
226 static bool can_insert (tree, int);
227 static void set_save (struct expr_info *, tree);
228 static tree reaching_def (tree, tree, basic_block, tree);
229 static tree do_proper_save (tree , tree, int);
230 static void process_left_occs_and_kills (varray_type, tree);
231 static tree create_expr_ref (struct expr_info *, tree, enum tree_code,
232 basic_block, tree);
233 static inline bool ephi_will_be_avail (tree);
234 static inline tree ephi_at_block (basic_block);
235 static tree get_default_def (tree, htab_t);
236 static inline bool same_e_version_real_occ_real_occ (struct expr_info *,
237 const tree,
238 const tree);
239 static inline bool load_modified_phi_result (basic_block, tree);
240 static inline bool same_e_version_phi_result (struct expr_info *,
241 tree, tree, tree);
242 static inline bool load_modified_real_occ_real_occ (tree, tree);
243 static inline bool same_e_version_real_occ_phi_opnd (struct expr_info *,
244 tree, basic_block,
245 int, tree, bool *);
246 static inline bool injured_real_occ_real_occ (struct expr_info *,
247 tree, tree);
248 static inline bool injured_phi_result_real_occ (struct expr_info *,
249 tree, tree, basic_block);
250 static inline bool injured_real_occ_phi_opnd (struct expr_info *,
251 tree, basic_block, int);
252 static void compute_du_info (struct expr_info *);
253 static void add_ephi_use (tree, tree, int);
254 static void insert_one_operand (struct expr_info *, tree, int, tree, edge,
255 tree **);
256 static void collect_expressions (basic_block, varray_type *);
257 static int build_dfn_array (basic_block, int);
258 static int eref_compare (const void *, const void *);
259
260
261 /* Bitmap of E-PHI predecessor operands have already been created.
262 We only create one phi-pred per block. */
263 static bitmap created_phi_preds;
264
265 /* PRE dominance frontiers. */
266 static bitmap *pre_dfs;
267
268 /* Number of redundancy classes. */
269 static int class_count = 0;
270
271
272 /* Iterated dominance frontiers cache. */
273 static bitmap *idfs_cache;
274
275 /* Partial redundancies statistics. */
276 static struct pre_stats_d
277 {
278 int reloads;
279 int saves;
280 int repairs;
281 int newphis;
282 int ephi_allocated;
283 int ephis_current;
284 int eref_allocated;
285 int exprs_generated;
286 } pre_stats = {0, 0, 0, 0, 0, 0, 0, 0};
287
288
289 /* USE entry in list of uses of ephi's. */
290 struct ephi_use_entry
291 {
292 tree phi;
293 int opnd_indx;
294 };
295
296 /* PRE Expression specific info. */
297 struct expr_info
298 {
299 /* The actual expression. */
300 tree expr;
301 /* The occurrences. */
302 varray_type occurs;
303 /* The kills. */
304 varray_type kills;
305 /* The left occurrences. */
306 varray_type lefts;
307 /* An array of real occurrences. */
308 varray_type reals;
309 /* True if it's a strength reduction candidate. */
310 bool strred_cand;
311 /* True if it's a load PRE candidate. */
312 bool loadpre_cand;
313 /* The euses/ephis in preorder dt order. */
314 varray_type euses_dt_order;
315 /* The name of the temporary for this expression. */
316 tree temp;
317 };
318
319
320 /* Cache of expressions generated for given phi operand, to avoid
321 recomputation and wasting memory. */
322 static tree *phi_pred_cache;
323 static int n_phi_preds;
324
325 /* Trying to lookup ephi pred operand indexes takes forever on graphs
326 that have high connectivity because it's an O(n) linked list
327 traversal. Thus, we set up a hashtable that tells us the operand
328 index for a given edge. */
329
330 typedef struct ephi_pred_index_elt
331 {
332 tree ephi;
333 edge edge;
334 int opnd;
335 } ephi_pindex_t;
336
337 /* Hash an (ephi, edge, opnd) tuple. */
338
339 static hashval_t
340 ephi_pindex_hash (const void *p)
341 {
342 const ephi_pindex_t *ep = (const ephi_pindex_t *)p;
343 return htab_hash_pointer (ep->ephi) + htab_hash_pointer (ep->edge);
344 }
345
346 /* Determine equality of an (ephi, edge, opnd) tuple. */
347
348 static int
349 ephi_pindex_eq (const void *p1, const void *p2)
350 {
351 const ephi_pindex_t *ep1 = (const ephi_pindex_t *)p1;
352 const ephi_pindex_t *ep2 = (const ephi_pindex_t *)p2;
353
354 return ep1->ephi == ep2->ephi && ep1->edge == ep2->edge;
355 }
356
357 /* The (ephi, edge) => opnd mapping hashtable. */
358 static htab_t ephi_pindex_htab;
359
360 /* Add an ephi predecessor to a PHI. */
361
362 static int
363 add_ephi_pred (tree phi, tree def, edge e)
364 {
365 int i = EPHI_NUM_ARGS (phi);
366 void **slot;
367 ephi_pindex_t ep, *epp;
368
369 EPHI_ARG_PRED (phi, i) = def;
370 EPHI_ARG_EDGE (phi, i) = e;
371
372 ep.ephi = phi;
373 ep.edge = e;
374 slot = htab_find_slot (ephi_pindex_htab, (void *)&ep, INSERT);
375 if (*slot == NULL)
376 {
377 epp = xmalloc (sizeof (*epp));
378 epp->ephi = phi;
379 epp->edge = e;
380 epp->opnd = i;
381 *slot = (void *)epp;
382 }
383 else
384 abort ();
385
386 EPHI_NUM_ARGS (phi)++;
387 return i;
388 }
389
390 /* Create a new EPHI node at basic block BB. */
391
392 static tree
393 create_ephi_node (basic_block bb, unsigned int add)
394 {
395 tree phi;
396 int len;
397 edge e;
398 size_t size;
399 bb_ann_t ann;
400
401 for (len = 0, e = bb->pred; e; e = e->pred_next)
402 len++;
403 size = (sizeof (struct tree_ephi_node)
404 + ((len - 1) * sizeof (struct ephi_arg_d)));
405
406 phi = xmalloc (size);
407 memset (phi, 0, size);
408 if (add)
409 {
410 ann = bb_ann (bb);
411 if (ann->ephi_nodes == NULL)
412 ann->ephi_nodes = phi;
413 else
414 chainon (ann->ephi_nodes, phi);
415 }
416 pre_stats.ephi_allocated += size;
417 pre_stats.ephis_current += 1;
418 TREE_SET_CODE (phi, EPHI_NODE);
419 EPHI_NUM_ARGS (phi) = 0;
420 EPHI_ARG_CAPACITY (phi) = len;
421
422 /* Associate BB to the PHI node. */
423 set_bb_for_stmt (phi, bb);
424
425 return phi;
426 }
427
428 /* Given DEF (which can be an SSA_NAME or entire statement), and VAR,
429 find a use of VAR on the RHS of DEF, if one exists. Abort if we
430 can't find one. */
431
432 static inline tree
433 find_rhs_use_for_var (tree def, tree var)
434 {
435 tree ret = maybe_find_rhs_use_for_var (def, var, 0);
436 if (!ret)
437 abort ();
438 return ret;
439 }
440
441 /* Determine if two trees are referring to the same variable.
442 Handles SSA_NAME vs non SSA_NAME, etc. Uses operand_equal_p for
443 non-trivial cases (INDIRECT_REF and friends). */
444
445 static inline bool
446 names_match_p (const tree t1, const tree t2)
447 {
448 tree name1, name2;
449
450 if (t1 == t2)
451 return true;
452
453 if (TREE_CODE (t1) == INDIRECT_REF)
454 return names_match_p (TREE_OPERAND (t1, 0), t2);
455
456 if (TREE_CODE (t2) == INDIRECT_REF)
457 return names_match_p (t1, TREE_OPERAND (t2, 0));
458
459 if (TREE_CODE (t1) == SSA_NAME)
460 name1 = SSA_NAME_VAR (t1);
461 else if (DECL_P (t1))
462 name1 = t1;
463 else
464 name1 = NULL_TREE;
465
466 if (TREE_CODE (t2) == SSA_NAME)
467 name2 = SSA_NAME_VAR (t2);
468 else if (DECL_P (t2))
469 name2 = t2;
470 else
471 name2 = NULL_TREE;
472
473 if (name1 == NULL_TREE && name2 != NULL_TREE)
474 return false;
475 if (name2 == NULL_TREE && name1 != NULL_TREE)
476 return false;
477 if (name1 == NULL_TREE && name2 == NULL_TREE)
478 return operand_equal_p (t1, t2, 0);
479
480 return name1 == name2;
481 }
482
483 /* Given DEF (which can be an SSA_NAME or entire statement), and VAR,
484 find a use of VAR on the RHS of DEF, if one exists. Return NULL if
485 we cannot find one. */
486
487 static inline tree
488 maybe_find_rhs_use_for_var (tree def, tree var, unsigned int startpos)
489 {
490 use_optype uses;
491 size_t i;
492
493 if (SSA_VAR_P (def))
494 {
495 if (names_match_p (var, def))
496 return def;
497 return NULL_TREE;
498 }
499 get_stmt_operands (def);
500 uses = STMT_USE_OPS (def);
501
502 for (i = startpos; i < NUM_USES (uses); i++)
503 {
504 tree use = USE_OP (uses, i);
505 if (names_match_p (use, var))
506 return use;
507 }
508 return NULL_TREE;
509 }
510
511 /* Determine if an injuring def is one which we can repair, and thus,
512 ignore for purposes of determining the version of a variable. */
513
514 static inline bool
515 okay_injuring_def (tree inj, tree var)
516 {
517 /* Acceptable injuries are those which
518 1. aren't empty statements.
519 2. aren't phi nodes.
520 3. contain a use of VAR on the RHS. */
521 if (!inj || IS_EMPTY_STMT (inj)
522 || TREE_CODE (inj) == PHI_NODE
523 || !maybe_find_rhs_use_for_var (inj, var, 0))
524 return false;
525 return true;
526 }
527
528 /* Return true if INJ is an injuring definition */
529
530 static bool
531 is_injuring_def (struct expr_info *ei, tree inj)
532 {
533 /* Things that are never injuring definitions. */
534 if (!inj || IS_EMPTY_STMT (inj) || TREE_CODE (inj) == PHI_NODE)
535 return false;
536
537 /* Things we can't handle. */
538 if (TREE_CODE (TREE_OPERAND (inj, 1)) != PLUS_EXPR
539 && TREE_CODE (TREE_OPERAND (inj, 1)) != MINUS_EXPR)
540 return false;
541
542 /* given inj: a1 = a2 + 5
543 expr: a3 * c
544 we are testing:
545 if (a1 != a3
546 || ! (a2 exists)
547 || a2 != a3)
548 return false
549
550 Or, in English, if either the assigned-to variable in
551 the injury is different from the first variable in the
552 expression, or the incremented variable is different from the
553 first variable in the expression, punt.
554
555 This makes sure we have something of the form
556
557 a = a {+,-} {expr}
558 for an expression like "a * 5".
559
560 This limitation only exists because we don't know how to repair
561 other forms of increments/decrements. */
562 if (!names_match_p (TREE_OPERAND (inj, 0), TREE_OPERAND (ei->expr, 0))
563 || !TREE_OPERAND (TREE_OPERAND (inj, 1), 0)
564 || !names_match_p (TREE_OPERAND (TREE_OPERAND (inj, 1), 0),
565 TREE_OPERAND (ei->expr, 0)))
566 return false;
567
568 /* If we are strength reducing a multiply, we have the additional
569 constraints that
570 1. {expr} is 1
571 2. {expr} and the RHS of the expression are constants. */
572 if (TREE_CODE (ei->expr) == MULT_EXPR)
573 {
574 tree irhs1;
575 tree irhs2;
576 tree irhs;
577 irhs = TREE_OPERAND (inj, 1);
578 irhs1 = TREE_OPERAND (irhs, 0);
579 irhs2 = TREE_OPERAND (irhs, 1);
580
581 if (TREE_CODE (irhs2) != INTEGER_CST)
582 return false;
583 if (tree_low_cst (irhs2, 0) == 1)
584 return true;
585 if (really_constant_p (irhs2)
586 && really_constant_p (TREE_OPERAND (ei->expr, 1)))
587 return true;
588 /* We don't currently support "the injury is inside a loop,expr is
589 loop-invariant, and b is either loop-invariant or is
590 another induction variable with respect to the loop." */
591 return false;
592 }
593 return true;
594 }
595
596 /* Find the statement defining VAR, ignoring injuries we can repair.
597 START is the first potential injuring def. */
598
599 static tree
600 factor_through_injuries (struct expr_info *ei, tree start, tree var,
601 bool *injured)
602 {
603 tree end = start;
604
605 while (is_injuring_def (ei, SSA_NAME_DEF_STMT (end)))
606 {
607 if (injured)
608 *injured = true;
609 end = find_rhs_use_for_var (SSA_NAME_DEF_STMT (end), var);
610 if (!okay_injuring_def (SSA_NAME_DEF_STMT (end), var))
611 break;
612 if (dump_file)
613 {
614 fprintf (dump_file, "Found a real injury:");
615 print_generic_stmt (dump_file, SSA_NAME_DEF_STMT (end), dump_flags);
616 fprintf (dump_file, "\n");
617 }
618 if (injured)
619 *injured = true;
620 end = find_rhs_use_for_var (SSA_NAME_DEF_STMT (end), var);
621 }
622 return end;
623 }
624
625 /* Return true if the result of the EPHI, when transformed into a phi,
626 will be available. */
627
628 static inline bool
629 ephi_will_be_avail (tree ephi)
630 {
631 if (!EPHI_CANT_BE_AVAIL (ephi))
632 if (EPHI_STOPS (ephi))
633 return true;
634
635 return false;
636 }
637
638 /* EUSE node pool. We allocate EUSE nodes out of this*/
639 static alloc_pool euse_node_pool;
640
641 /* EREF node pool. We allocate regular EREF nodes (like EEXIT_NODE)
642 out of this. */
643 static alloc_pool eref_node_pool;
644
645
646 /* To order EREF's in a given block, we assign them each an ID based
647 on when we see them. */
648 static int eref_id_counter = 0;
649
650 /* Creation an expression reference of TYPE. */
651
652 static tree
653 create_expr_ref (struct expr_info *ei, tree expr, enum tree_code type,
654 basic_block bb, tree parent)
655 {
656 tree ret;
657 if (type == EPHI_NODE)
658 {
659 int len;
660 edge e;
661
662 ret = create_ephi_node (bb, 1);
663 for (len = 0, e = bb->pred; e; e = e->pred_next)
664 len++;
665
666 EREF_TEMP (ret) = make_phi_node (ei->temp, len);
667 }
668 else
669 {
670 if (type == EUSE_NODE)
671 ret = (tree) pool_alloc (euse_node_pool);
672 else
673 ret = (tree) pool_alloc (eref_node_pool);
674 TREE_SET_CODE (ret, type);
675 memset (ret, 0, tree_size (ret));
676 TREE_SET_CODE (ret, type);
677 pre_stats.eref_allocated += tree_size (ret);
678 }
679
680 EREF_NAME (ret) = expr;
681 set_bb_for_stmt (ret, bb);
682 EREF_STMT (ret) = parent;
683 EREF_SAVE (ret) = false;
684 EREF_ID (ret) = eref_id_counter++;
685
686 return ret;
687 }
688
689
690 /* dfphis is a bitmap of where we need to insert ephis due to the
691 iterated dominance frontier of an expression. */
692
693 static bitmap dfphis;
694
695 /* varphis is a bitmap of where we need to insert ephis due to the
696 presence of phis for a variable. */
697
698 static bitmap varphis;
699
700
701 /* Function to recursively figure out where EPHI's need to be placed
702 because of PHI's.
703 We always place EPHI's where we place PHI's because they are also
704 partially anticipated expression points (because some expression
705 alteration reaches that merge point).
706
707 We do this recursively, because we have to figure out
708 EPHI's for the variables in the PHI as well. */
709
710 static void
711 set_var_phis (struct expr_info *ei, tree phi)
712 {
713 basic_block bb = bb_for_stmt (phi);
714 /* If we've already got an EPHI set to be placed in PHI's BB, we
715 don't need to do this again. */
716 if (!bitmap_bit_p (varphis, bb->index)
717 && !bitmap_bit_p (dfphis, bb->index))
718 {
719 tree phi_operand;
720 int curr_phi_operand;
721 bitmap_set_bit (varphis, bb->index);
722 for (curr_phi_operand = 0;
723 curr_phi_operand < PHI_NUM_ARGS (phi);
724 curr_phi_operand++)
725 {
726 phi_operand = PHI_ARG_DEF (phi, curr_phi_operand);
727 /* For strength reduction, factor through injuries we can
728 repair. */
729 if (ei->strred_cand && TREE_CODE (phi_operand) != PHI_NODE)
730 {
731 phi_operand = factor_through_injuries (ei, phi_operand,
732 SSA_NAME_VAR (phi_operand),
733 NULL);
734 phi_operand = SSA_NAME_DEF_STMT (phi_operand);
735 if (dump_file)
736 {
737 fprintf (dump_file, "After factoring through injuries:");
738 print_generic_stmt (dump_file, phi_operand, dump_flags);
739 fprintf (dump_file, "\n");
740 }
741 }
742
743 /* If our phi operand is defined by a phi, we need to
744 record where the phi operands alter the expression as
745 well, and place EPHI's at each point. */
746 if (TREE_CODE (phi_operand) == PHI_NODE)
747 set_var_phis (ei, phi_operand);
748 }
749 }
750 }
751
752
753 /* Clear all the expression reference arrays. */
754
755 static void
756 clear_all_eref_arrays (void)
757 {
758 basic_block bb;
759 bb_ann_t ann;
760
761 FOR_ALL_BB (bb)
762 {
763 ann = bb_ann (bb);
764 if (ann->ephi_nodes)
765 {
766 free (ann->ephi_nodes);
767 pre_stats.ephis_current -= 1;
768 }
769 ann->ephi_nodes = NULL;
770 }
771 }
772
773 /* EPHI insertion algorithm. */
774
775 static bool
776 expr_phi_insertion (bitmap *dfs, struct expr_info *ei)
777 {
778 size_t i, j;
779 vuse_optype vuses;
780 use_optype uses;
781 bool retval = true;
782
783 dfphis = BITMAP_XMALLOC ();
784 bitmap_zero (dfphis);
785 varphis = BITMAP_XMALLOC ();
786 bitmap_zero (varphis);
787
788 /* Compute where we need to place EPHIS. There are two types of
789 places we need EPHI's: Those places we would normally place a
790 PHI for the occurrence (calculated by determining the IDF+ of
791 the statement), and those places we need an EPHI due to partial
792 anticipation. */
793 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->occurs); i++)
794 {
795 tree occurp = VARRAY_TREE (ei->occurs, i);
796 tree occur = occurp ? occurp : NULL;
797 tree killp = VARRAY_TREE (ei->kills, i);
798 tree kill = killp ? killp : NULL;
799 tree leftp = VARRAY_TREE (ei->lefts, i);
800 tree left = leftp ? leftp : NULL;
801 bitmap temp;
802 stmt_ann_t ann;
803
804 #ifdef ENABLE_CHECKING
805 if ((kill && occur) || (left && occur) || (kill && left))
806 abort();
807 #endif
808 occurp = occur ? occurp : kill ? killp : leftp;
809 occur = occur ? occur : kill ? kill : left;
810 temp = compute_idfs (dfs, occur);
811 bitmap_a_or_b (dfphis, dfphis, temp);
812 if (kill != NULL)
813 continue;
814 get_stmt_operands (occurp);
815 ann = stmt_ann (occurp);
816 uses = USE_OPS (ann);
817 for (j = 0; j < NUM_USES (uses); j ++)
818 {
819 tree use = USE_OP (uses, j);
820 if (ei->strred_cand)
821 use = factor_through_injuries (ei, use, SSA_NAME_VAR (use),
822 NULL);
823 if (TREE_CODE (SSA_NAME_DEF_STMT (use)) != PHI_NODE)
824 continue;
825 set_var_phis (ei, SSA_NAME_DEF_STMT (use));
826 }
827 if (ei->loadpre_cand && TREE_CODE (ei->expr) == INDIRECT_REF)
828 {
829 vuses = VUSE_OPS (ann);
830 for (j = 0; j < NUM_VUSES (vuses); j ++)
831 {
832 tree use = VUSE_OP (vuses, j);
833 if (ei->strred_cand)
834 use = factor_through_injuries (ei, use, SSA_NAME_VAR (use),
835 NULL);
836 if (TREE_CODE (SSA_NAME_DEF_STMT (use)) != PHI_NODE)
837 continue;
838 set_var_phis (ei, SSA_NAME_DEF_STMT (use));
839 }
840 }
841 }
842 /* Union the results of the dfphis and the varphis to get the
843 answer to everywhere we need EPHIS. */
844 bitmap_a_or_b (dfphis, dfphis, varphis);
845
846 /* Now create the EPHI's in each of these blocks. */
847 EXECUTE_IF_SET_IN_BITMAP(dfphis, 0, i,
848 {
849 tree ref = create_expr_ref (ei, ei->expr, EPHI_NODE, BASIC_BLOCK (i),
850 NULL);
851 EREF_PROCESSED (ref) = false;
852 EPHI_DOWNSAFE (ref) = true;
853 EPHI_DEAD (ref) = true;
854 });
855 #if 0
856 /* If there are no phis, we don't have anything to optimize,
857 assuming the dominator optimizer took care of it all. */
858 if (bitmap_first_set_bit (dfphis) == -1)
859 retval = false;
860 #endif
861 BITMAP_XFREE (dfphis);
862 BITMAP_XFREE (varphis);
863 return retval;
864
865 }
866
867 /* Return the EPHI at block BB, if one exists. */
868
869 static inline tree
870 ephi_at_block (basic_block bb)
871 {
872 bb_ann_t ann = bb_ann (bb);
873 if (ann->ephi_nodes)
874 return ann->ephi_nodes;
875 else
876 return NULL_TREE;
877 }
878
879 /* Depth first numbering array. */
880 static int *dfn;
881
882 /* Build a depth first numbering array to be used in sorting in
883 dominator order. */
884
885 static int
886 build_dfn_array (basic_block bb, int num)
887 {
888 basic_block son;
889
890 if (bb->index >= 0)
891 dfn[bb->index] = num;
892
893 for (son = first_dom_son (CDI_DOMINATORS, bb);
894 son;
895 son = next_dom_son (CDI_DOMINATORS, son))
896 num = build_dfn_array (son, ++num);
897 return num;
898 }
899
900
901 /* Compare two EREF's in terms of dominator preorder. Return -1 if
902 ELEM1 goes before ELEM2, 1 if ELEM1 goes after ELEM2, and 0 if they
903 are equal. */
904
905 static int
906 eref_compare (const void *elem1, const void *elem2)
907 {
908 tree t1 = *(tree *)elem1;
909 tree t2 = *(tree *)elem2;
910 basic_block bb1, bb2;
911 if (t1 == t2)
912 return 0;
913 bb1 = bb_for_stmt (t1);
914 bb2 = bb_for_stmt (t2);
915 if (bb1 == bb2)
916 {
917 if (TREE_CODE (t1) == EEXIT_NODE)
918 return 1;
919 if (TREE_CODE (t2) == EEXIT_NODE)
920 return -1;
921 if (TREE_CODE (t1) == EPHI_NODE)
922 return -1;
923 if (TREE_CODE (t2) == EPHI_NODE)
924 return 1;
925 if ((TREE_CODE (t1) == EUSE_NODE && EUSE_PHIOP (t1))
926 && (TREE_CODE (t2) == EUSE_NODE && !EUSE_PHIOP (t2)))
927 return 1;
928 if ((TREE_CODE (t1) == EUSE_NODE && !EUSE_PHIOP (t1))
929 && (TREE_CODE (t2) == EUSE_NODE && EUSE_PHIOP (t2)))
930 return -1;
931 if (TREE_CODE (t1) == EUSE_NODE && TREE_CODE (t2) == EUSE_NODE)
932 return EREF_ID (t1) - EREF_ID (t2);
933 if (TREE_CODE (t1) == EPHI_NODE && TREE_CODE (t2) == EPHI_NODE)
934 abort ();
935
936 }
937 else
938 {
939 if (dfn[bb1->index] == dfn[bb2->index])
940 {
941 if (dominated_by_p (CDI_DOMINATORS, bb1, bb2))
942 return 1;
943 else
944 return -1;
945 }
946 else
947 return (dfn[bb1->index] < dfn[bb2->index]) ? -1 : 1;
948 }
949
950 abort ();
951 }
952
953 /* Create expression references for occurrences, kills, phi operands,
954 and the like. At the same time, insert the occurrences into the
955 ei->euses_dt_order array in the proper order. If this function had
956 any use outside of rename_1, you could split it into two
957 functions, one creating, one inserting. */
958
959 static void
960 create_and_insert_occ_in_preorder_dt_order (struct expr_info *ei)
961 {
962 size_t i;
963 edge succ;
964 tree curr_phi_pred = NULL_TREE;
965 basic_block block;
966
967 /* The ephis references were already created, so just push them into
968 the euses_dt_order list. */
969 FOR_EACH_BB (block)
970 {
971 tree ephi = ephi_at_block (block);
972 /* The ordering for a given BB is EPHI's, real/left/kill
973 occurrences, phi preds, exit occurrences. */
974 if (ephi != NULL_TREE)
975 VARRAY_PUSH_TREE (ei->euses_dt_order, ephi);
976 }
977
978 /* The non-ephis have to actually be created, so do that, then push
979 them into the list. */
980
981 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->occurs); i++)
982 {
983 tree newref;
984 tree current;
985 current = VARRAY_TREE (ei->occurs, i);
986 current = current ? current : VARRAY_TREE (ei->kills, i);
987 current = current ? current : VARRAY_TREE (ei->lefts, i);
988 block = bb_for_stmt (current);
989 if (VARRAY_TREE (ei->kills, i) != NULL)
990 {
991 tree killexpr = VARRAY_TREE (ei->kills, i);
992 tree killname = ei->expr;
993 newref = create_expr_ref (ei, killname, EKILL_NODE, block, killexpr);
994 VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
995 }
996 else if (VARRAY_TREE (ei->lefts, i) != NULL)
997 {
998 tree occurexpr = VARRAY_TREE (ei->lefts, i);
999 tree occurname;
1000 occurname = ei->expr;
1001 newref = create_expr_ref (ei, occurname, EUSE_NODE, block,
1002 occurexpr);
1003 EUSE_DEF (newref) = NULL_TREE;
1004 EUSE_LVAL (newref) = true;
1005 EREF_CLASS (newref) = -1;
1006 EUSE_PHIOP (newref) = false;
1007 EREF_PROCESSED (newref) = false;
1008 VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
1009 }
1010 else
1011 {
1012 tree occurexpr = VARRAY_TREE (ei->occurs, i);
1013 tree occurname;
1014 occurname = ei->expr;
1015 newref = create_expr_ref (ei, occurname, EUSE_NODE, block,
1016 occurexpr);
1017 EUSE_DEF (newref) = NULL_TREE;
1018 EREF_CLASS (newref) = -1;
1019 EUSE_PHIOP (newref) = false;
1020 EREF_PROCESSED (newref) = false;
1021 VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
1022 }
1023 }
1024
1025 /* Lastly, we need to create and insert the ephi operand occurrences
1026 into the list. */
1027 FOR_ALL_BB (block)
1028 {
1029 /* Insert the phi operand occurrences into the list at the
1030 successors.*/
1031 for (succ = block->succ; succ; succ = succ->succ_next)
1032 {
1033 if (succ->dest != EXIT_BLOCK_PTR)
1034 {
1035 tree ephi = ephi_at_block (succ->dest);
1036 if (ephi != NULL
1037 && !bitmap_bit_p (created_phi_preds, block->index))
1038 {
1039 tree newref = create_expr_ref (ei, 0, EUSE_NODE, block, NULL);
1040 curr_phi_pred = newref;
1041 VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
1042 EUSE_DEF (newref) = NULL_TREE;
1043 EREF_CLASS (newref) = -1;
1044 EUSE_PHIOP (newref) = true;
1045 EREF_SAVE (newref) = false;
1046 EREF_RELOAD (newref) = false;
1047 EUSE_INSERTED (newref) = false;
1048 EREF_PROCESSED (newref) = false;
1049 bitmap_set_bit (created_phi_preds, block->index);
1050 add_ephi_pred (ephi, newref, succ);
1051 }
1052 else if (ephi != NULL)
1053 {
1054 #ifdef ENABLE_CHECKING
1055 if (curr_phi_pred == NULL_TREE)
1056 abort();
1057 #endif
1058 add_ephi_pred (ephi, curr_phi_pred, succ);
1059 }
1060 }
1061 else if (succ->dest == EXIT_BLOCK_PTR && !(succ->flags & EDGE_FAKE))
1062 {
1063 /* No point in inserting exit blocks into heap first, since
1064 they'll never be anything on the stack. */
1065 tree newref;
1066 newref = create_expr_ref (ei, ei->expr, EEXIT_NODE,
1067 block,
1068 NULL);
1069 VARRAY_PUSH_TREE (ei->euses_dt_order, newref);
1070 }
1071 }
1072 }
1073 qsort (ei->euses_dt_order->data.tree,
1074 VARRAY_ACTIVE_SIZE (ei->euses_dt_order),
1075 sizeof (tree),
1076 eref_compare);
1077 }
1078
1079
1080 /* Assign a new redundancy class to the occurrence, and push it on the
1081 renaming stack. */
1082
1083 static void
1084 assign_new_class (tree occ, varray_type * stack, varray_type * stack2)
1085 {
1086 /* class(occ) <- count
1087 Push(occ, stack)
1088 count <- count + 1
1089 */
1090 EREF_CLASS (occ) = class_count;
1091 VARRAY_PUSH_TREE (*stack, occ);
1092 if (stack2)
1093 VARRAY_PUSH_TREE (*stack2, occ);
1094 class_count++;
1095 }
1096
1097 /* Determine if two real occurrences have the same ESSA version.
1098 We do this by hashing the expressions and comparing the hash
1099 values. Even if they don't match, we then see if this is a
1100 strength reduction candidate, and if so, if the use is simply
1101 injured. */
1102
1103 static inline bool
1104 same_e_version_real_occ_real_occ (struct expr_info *ei,
1105 const tree def, const tree use)
1106 {
1107 hashval_t expr1val;
1108 hashval_t expr2val;
1109 vuse_optype vuses;
1110 size_t i;
1111 const tree t1 = EREF_STMT (def);
1112 const tree t2 = EREF_STMT (use);
1113
1114 expr1val = iterative_hash_expr (TREE_OPERAND (t1, 1), 0);
1115 expr2val = iterative_hash_expr (TREE_OPERAND (t2, 1), 0);
1116
1117 if (expr1val == expr2val)
1118 {
1119 vuses = STMT_VUSE_OPS (t1);
1120 for (i = 0; i < NUM_VUSES (vuses); i++)
1121 expr1val = iterative_hash_expr (VUSE_OP (vuses, i), expr1val);
1122 vuses = STMT_VUSE_OPS (t2);
1123 for (i = 0; i < NUM_VUSES (vuses); i++)
1124 expr2val = iterative_hash_expr (VUSE_OP (vuses, i), expr2val);
1125 if (expr1val != expr2val)
1126 return false;
1127 }
1128
1129 /* If the def is injured, and the expressions have the same value,
1130 then the use is injured. */
1131 if (expr1val == expr2val)
1132 {
1133 if (EREF_INJURED (def))
1134 EREF_INJURED (use) = true;
1135 return true;
1136 }
1137
1138 /* Even if the expressions don't have the same value, it might be
1139 the case that the use is simply injured, in which case, it's
1140 still okay. */
1141 if (expr1val != expr2val && ei->strred_cand)
1142 {
1143 if (injured_real_occ_real_occ (ei, def, use))
1144 {
1145 EREF_INJURED (use) = true;
1146 return true;
1147 }
1148 }
1149 return false;
1150 }
1151
1152 /* Determine if the use occurrence is injured.
1153 TODO: Finish actually implementing this. */
1154
1155 static inline bool
1156 injured_real_occ_real_occ (struct expr_info *ei ATTRIBUTE_UNUSED,
1157 tree def ATTRIBUTE_UNUSED,
1158 tree use ATTRIBUTE_UNUSED)
1159 {
1160 tree defstmt;
1161 tree defvar;
1162
1163 defstmt = EREF_STMT (def);
1164 if (TREE_CODE (TREE_OPERAND (defstmt, 0)) != SSA_NAME)
1165 return false;
1166
1167 defvar = TREE_OPERAND (defstmt, 0);
1168 /* XXX: Implement. */
1169 return false;
1170
1171 }
1172
1173 /* Determine the operand number of edge E in EPHI. */
1174
1175 static inline int
1176 opnum_of_ephi (const tree ephi, const edge e)
1177 {
1178 ephi_pindex_t ep, *epp;
1179
1180 ep.ephi = ephi;
1181 ep.edge = e;
1182 epp = htab_find (ephi_pindex_htab, &ep);
1183 if (epp == NULL)
1184 abort ();
1185 return epp->opnd;
1186 }
1187
1188 /* Determine the phi operand index for J in PHI. */
1189
1190 static inline int
1191 opnum_of_phi (tree phi, int j)
1192 {
1193 int i;
1194 /* We can't just count predecessors, since tree-ssa.c generates them
1195 when it sees a phi in the successor during it's traversal. So the
1196 order is dependent on the traversal order. */
1197 for (i = 0 ; i < PHI_NUM_ARGS (phi); i++)
1198 if (PHI_ARG_EDGE (phi, i)->src->index == j)
1199 return i;
1200
1201 abort();
1202 }
1203
1204 /* Generate EXPR as it would look in basic block PRED (using the phi in
1205 block BB). We do this by replacing the variables with the phi
1206 argument definitions for block J if they are defined by a phi in
1207 block BB. */
1208
1209 static void
1210 generate_expr_as_of_bb (tree expr, basic_block pred, basic_block bb)
1211 {
1212 use_optype uses = STMT_USE_OPS (expr);
1213 bool replaced_constants = false;
1214 size_t k;
1215
1216 for (k = 0; k < NUM_USES (uses); k++)
1217 {
1218 tree *vp = USE_OP_PTR (uses, k);
1219 tree v = *vp;
1220 tree phi;
1221
1222 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
1223 {
1224 if (PHI_RESULT (phi) == v)
1225 {
1226 int opnum = opnum_of_phi (phi, pred->index);
1227 tree p = PHI_ARG_DEF (phi, opnum);
1228 replace_exp (vp, p);
1229 if (!phi_ssa_name_p (p))
1230 replaced_constants = true;
1231 break;
1232 }
1233 }
1234 }
1235
1236 /* If we've substituted in new constants, we must be sure to
1237 simplify the result lest we crash in get_expr_operands. */
1238 if (replaced_constants)
1239 fold_stmt (&expr);
1240 }
1241
1242 /* Generate VUSE ops as they would look in basic block PRED (using the
1243 phi in block BB). Done the same way as we do generation of regular
1244 ops for the bb. */
1245
1246 static void
1247 generate_vops_as_of_bb (tree expr, basic_block pred, basic_block bb)
1248 {
1249 vuse_optype vuses = STMT_VUSE_OPS (expr);
1250 size_t i;
1251
1252 for (i = 0; i < NUM_VUSES (vuses); i++)
1253 {
1254 tree v = VUSE_OP (vuses, i);
1255 tree phi;
1256
1257 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
1258 {
1259 if (PHI_RESULT (phi) == v)
1260 {
1261 int opnum = opnum_of_phi (phi, pred->index);
1262 tree p = PHI_ARG_DEF (phi, opnum);
1263 replace_exp (VUSE_OP_PTR (vuses, i), p);
1264 break;
1265 }
1266 }
1267 }
1268 }
1269
1270 /* Make a copy of Z as it would look in basic block PRED, using the PHIs
1271 in BB. */
1272
1273 static tree
1274 subst_phis (struct expr_info *ei, tree Z, basic_block pred, basic_block bb)
1275 {
1276 tree stmt_copy;
1277 size_t i;
1278
1279 /* Return the cached version, if we have one. */
1280 if (pred->index < n_phi_preds
1281 && phi_pred_cache[pred->index] != NULL_TREE)
1282 return phi_pred_cache[pred->index];
1283
1284 /* Otherwise, generate a new expression. */
1285 pre_stats.exprs_generated++;
1286 stmt_copy = unshare_expr (Z);
1287 create_stmt_ann (stmt_copy);
1288 modify_stmt (stmt_copy);
1289 get_stmt_operands (stmt_copy);
1290 generate_expr_as_of_bb (stmt_copy, pred, bb);
1291 set_bb_for_stmt (stmt_copy, bb);
1292 modify_stmt (stmt_copy);
1293 get_stmt_operands (stmt_copy);
1294
1295 /* If we have vuses on the original statement, and we still have
1296 use_ops on the generated expr, we need to copy the vuses. */
1297
1298 if (ei->loadpre_cand
1299 && NUM_VUSES (STMT_VUSE_OPS (Z)) != 0
1300 && NUM_USES (STMT_USE_OPS (stmt_copy)) != 0)
1301 {
1302 vuse_optype vuses = STMT_VUSE_OPS (Z);
1303 remove_vuses (stmt_copy);
1304
1305 start_ssa_stmt_operands (stmt_copy);
1306 for (i = 0; i < NUM_VUSES (vuses); i++)
1307 add_vuse (VUSE_OP (vuses, i), stmt_copy);
1308 finalize_ssa_stmt_operands (stmt_copy);
1309
1310 generate_vops_as_of_bb (stmt_copy, pred, bb);
1311 }
1312 else
1313 {
1314 remove_vuses (stmt_copy);
1315 remove_v_may_defs (stmt_copy);
1316 remove_v_must_defs (stmt_copy);
1317 }
1318
1319 if (pred->index < n_phi_preds)
1320 phi_pred_cache[pred->index] = stmt_copy;
1321 return stmt_copy;
1322 }
1323
1324 /* Determine if def and use_tree should have the same e-version. We do
1325 this by simply determining if something modifies the expression
1326 between DEF and USE_TREE. USE_TREE was generated from the OPND_NUM'th
1327 operand of the EPHI in USE_BB. If it is modified, we determine if
1328 it is simply injured, and thus, okay. */
1329
1330 static inline bool
1331 same_e_version_real_occ_phi_opnd (struct expr_info *ei, tree def,
1332 basic_block use_bb, int opnd_num,
1333 tree use_tree, bool *injured)
1334 {
1335 bool not_mod = true;
1336 *injured = false;
1337
1338 if (load_modified_real_occ_real_occ (EREF_STMT (def),
1339 use_tree))
1340 not_mod = false;
1341
1342 if (not_mod)
1343 return true;
1344 else if (ei->strred_cand)
1345 {
1346 if (injured_real_occ_phi_opnd (ei, def, use_bb, opnd_num))
1347 return true;
1348 }
1349 return false;
1350 }
1351
1352 /* Determine whether the OPND_NUM'th operand of USE_BB's EPHI is an
1353 injured version of DEF. */
1354 static inline bool
1355 injured_real_occ_phi_opnd (struct expr_info *ei ATTRIBUTE_UNUSED,
1356 tree def ATTRIBUTE_UNUSED,
1357 basic_block use_bb ATTRIBUTE_UNUSED,
1358 int opnd_num ATTRIBUTE_UNUSED)
1359 {
1360 /* XXX: Implement. */
1361 return false;
1362 }
1363
1364 /* Determine whether the expression is modified between DEF and USE,
1365 by comparing the hash values of the two expressions. */
1366 static inline bool
1367 load_modified_real_occ_real_occ (tree def, tree use)
1368 {
1369 hashval_t expr1val;
1370 hashval_t expr2val;
1371 vuse_optype vuses;
1372 size_t i;
1373
1374 if (TREE_CODE (def) == VA_ARG_EXPR)
1375 expr1val = iterative_hash_expr (def, 0);
1376 else
1377 expr1val = iterative_hash_expr (TREE_OPERAND (def, 1), 0);
1378
1379 if (TREE_CODE (use) == VA_ARG_EXPR)
1380 expr2val = iterative_hash_expr (use, 0);
1381 else
1382 expr2val = iterative_hash_expr (TREE_OPERAND (use, 1), 0);
1383
1384 if (expr1val == expr2val)
1385 {
1386 vuses = STMT_VUSE_OPS (def);
1387 for (i = 0; i < NUM_VUSES (vuses); i++)
1388 expr1val = iterative_hash_expr (VUSE_OP (vuses, i), expr1val);
1389 vuses = STMT_VUSE_OPS (use);
1390 for (i = 0; i < NUM_VUSES (vuses); i++)
1391 expr2val = iterative_hash_expr (VUSE_OP (vuses, i), expr2val);
1392 if (expr1val != expr2val)
1393 return false;
1394 }
1395 return expr1val != expr2val;
1396 }
1397
1398 /* Determine if the expression is modified between the start of BB,
1399 and the use at USE, ignoring phis. We do this by simple
1400 domination, because of the properties of SSA. */
1401 static bool
1402 load_modified_phi_result (basic_block bb, tree use)
1403 {
1404 basic_block defbb = bb_for_stmt (SSA_NAME_DEF_STMT (use));
1405 if (defbb != bb)
1406 {
1407 /* This guards against moving around undefined variables.
1408 However, PARM_DECL is special because it *IS* live on entry,
1409 so it's not really undefined. */
1410 if (!defbb && TREE_CODE (SSA_NAME_VAR (use)) != PARM_DECL)
1411 return true;
1412 else if (!defbb && TREE_CODE (SSA_NAME_VAR (use)) == PARM_DECL)
1413 return false;
1414 if (dominated_by_p (CDI_DOMINATORS, bb, defbb))
1415 return false;
1416 }
1417 else
1418 {
1419 if (TREE_CODE (SSA_NAME_DEF_STMT (use)) == PHI_NODE)
1420 return false;
1421 }
1422 return true;
1423 }
1424
1425 /* Determine if the variables in EXP are modified between DEF and
1426 USE. If they are, we have to give a new e-version to the result.
1427 For load PRE, we have to check the vuses too. For strength
1428 reduction, we need to check whether the modification is a simple
1429 injury. */
1430
1431 static bool
1432 same_e_version_phi_result (struct expr_info *ei, tree def, tree exp,
1433 tree use)
1434 {
1435 stmt_ann_t ann = stmt_ann (exp);
1436 bool not_mod = true;
1437 size_t i;
1438 use_optype real_expuses = USE_OPS (ann);
1439 vuse_optype expuses;
1440
1441
1442 if (NUM_USES (real_expuses) == 0)
1443 return false;
1444
1445 for (i = 0; i < NUM_USES (real_expuses) && not_mod; i++)
1446 {
1447 tree *use1p = USE_OP_PTR (real_expuses, i);
1448 tree use1;
1449 if (!use1p)
1450 continue;
1451 use1 = *use1p;
1452 if (load_modified_phi_result (bb_for_stmt (def), use1))
1453 not_mod = false;
1454 }
1455
1456 if (not_mod && ei->loadpre_cand)
1457 {
1458 expuses = VUSE_OPS (ann);
1459
1460 for (i = 0; i < NUM_VUSES (expuses) && not_mod; i++)
1461 {
1462 tree use1 = VUSE_OP (expuses, i);
1463 if (load_modified_phi_result (bb_for_stmt (def), use1))
1464 not_mod = false;
1465 }
1466 }
1467
1468 if (not_mod)
1469 return true;
1470 else if (ei->strred_cand)
1471 {
1472 if (injured_phi_result_real_occ (ei, def, exp, bb_for_stmt (use)))
1473 {
1474 EREF_INJURED (use) = true;
1475 return true;
1476 }
1477 }
1478
1479 return false;
1480 }
1481
1482 /* Determine whether USE_TREE is an injured version of DEF. */
1483
1484 static inline bool
1485 injured_phi_result_real_occ (struct expr_info *ei ATTRIBUTE_UNUSED,
1486 tree def ATTRIBUTE_UNUSED,
1487 tree use_tree ATTRIBUTE_UNUSED,
1488 basic_block use_bb ATTRIBUTE_UNUSED)
1489 {
1490 /* XXX: Implement. */
1491 return false;
1492 }
1493
1494 /* Delayed renaming checks to make sure the optimistic assumptions
1495 about ephi operand versions in rename_1 actually turned out to be
1496 true. This requires generating the expressions for each ephi
1497 operand, and comparing them to the versions of the occurrence it is
1498 defined by.
1499 Delayed rename handling is done like open64 does it. Basically,
1500 like the delayed renaming is described in the paper, with
1501 extensions for strength reduction. */
1502
1503 static void
1504 process_delayed_rename (struct expr_info *ei, tree use, tree real_occ)
1505 {
1506 tree exp_phi = use;
1507 int opnd_num = 0;
1508
1509 /* We only care about operands we actually have DELAYED_RENAME set
1510 on. */
1511 for (opnd_num = 0; opnd_num < EPHI_NUM_ARGS (exp_phi); opnd_num++)
1512 {
1513 tree opnd = EPHI_ARG_DEF (exp_phi, opnd_num);
1514 if (EPHI_ARG_DELAYED_RENAME (exp_phi, opnd_num))
1515 {
1516 tree def;
1517 tree newexp;
1518
1519 /* Mark it as being processed, then generate the ephi
1520 operand expression. */
1521 EPHI_ARG_DELAYED_RENAME (exp_phi, opnd_num) = false;
1522 def = opnd;
1523 newexp = subst_phis (ei, real_occ,
1524 EPHI_ARG_EDGE (exp_phi, opnd_num)->src,
1525 bb_for_stmt (exp_phi));
1526
1527 /* For operands defined by EPHIs, we need to compare the
1528 generated expression and the phi result.
1529 For operands defined by real occurrences, we simply compare
1530 the phi operand and the real occurrence. */
1531 if (TREE_CODE (def) == EPHI_NODE)
1532 {
1533 tree tmp_use = EPHI_ARG_PRED (exp_phi, opnd_num);
1534 EREF_STMT (tmp_use) = newexp;
1535 if (same_e_version_phi_result (ei, def, newexp,
1536 tmp_use))
1537 {
1538
1539 if (EREF_INJURED (tmp_use))
1540 {
1541 EREF_INJURED (tmp_use) = false;
1542 EPHI_ARG_INJURED (exp_phi, opnd_num) = true;
1543 }
1544 if (EREF_STMT (def) == NULL)
1545 {
1546 /* If it was injured, we need to make up a new
1547 phi result with the actually injured
1548 version. */
1549 if (EPHI_ARG_INJURED (exp_phi, opnd_num))
1550 {
1551 /* XXX: Allocate phi result with correct version. */
1552
1553 }
1554 EREF_STMT (def) = newexp;
1555 process_delayed_rename (ei, def, newexp);
1556 }
1557 }
1558 /* If it's not the same version, the defining ephi can't
1559 be downsafe, and the operand is not really defined by
1560 anything. */
1561 else
1562 {
1563 EPHI_DOWNSAFE (def) = false;
1564 EPHI_ARG_DEF (exp_phi, opnd_num) = NULL;
1565 }
1566 }
1567 else if (TREE_CODE (def) == EUSE_NODE && !EUSE_PHIOP (def))
1568 {
1569 bool injured = false;
1570 if (same_e_version_real_occ_phi_opnd (ei, def,
1571 bb_for_stmt (use),
1572 opnd_num, newexp, &injured))
1573 {
1574 tree tmp_use = EPHI_ARG_PRED (exp_phi, opnd_num);
1575 EPHI_ARG_HAS_REAL_USE (exp_phi, opnd_num) = true;
1576 /* EREF_STMT (opnd) = EREF_STMT (def); */
1577 if (injured || EREF_INJURED (def))
1578 EREF_INJURED (def) = true;
1579 if (injured || EREF_INJURED (def))
1580 EREF_INJURED (opnd) = true;
1581 else
1582 EREF_STMT (tmp_use) = EREF_STMT (def);
1583 if (EUSE_DEF (def) != NULL)
1584 EPHI_ARG_DEF (exp_phi, opnd_num) = EUSE_DEF (def);
1585 else
1586 EPHI_ARG_DEF (exp_phi, opnd_num) = def;
1587 }
1588 else
1589 {
1590 EPHI_ARG_DEF (exp_phi, opnd_num) = NULL;
1591 }
1592 }
1593 }
1594 }
1595 }
1596
1597 /* For the uninitiated, the algorithm is a modified SSA renaming
1598 algorithm (working on expressions rather than variables) . We
1599 attempt to determine which expression occurrences have the same
1600 ESSA version (we call it class, for equivalence/redundancy class,
1601 which is what the papers call it. Open64 calls it e-version), and
1602 which occurrences are actually operands for an EPHI (since this has
1603 to be discovered from the program).
1604
1605 Renaming is done like Open64 does it. Basically as the paper says,
1606 except that we try to use earlier defined occurrences if they are
1607 available in order to keep the number of saves down. */
1608
1609 static void
1610 rename_1 (struct expr_info *ei)
1611 {
1612 tree occur;
1613 basic_block phi_bb;
1614 size_t i;
1615 varray_type stack;
1616
1617 VARRAY_GENERIC_PTR_NOGC_INIT (stack, 1, "Stack for renaming");
1618
1619 /* Start by creating and inserting the occurrences in preorder,
1620 dominator tree into a list. */
1621 create_and_insert_occ_in_preorder_dt_order (ei);
1622
1623 /* Walk the occurrences. */
1624 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
1625 {
1626 occur = VARRAY_TREE (ei->euses_dt_order, i);
1627
1628 /* The current occurrence can't have the same version as
1629 something on the top of the stack unless it is in a basic
1630 block dominated by the basic block of the occurrence on the
1631 top of the stack. */
1632 while (VARRAY_ACTIVE_SIZE (stack) > 0
1633 && !dominated_by_p (CDI_DOMINATORS,
1634 bb_for_stmt (occur),
1635 bb_for_stmt (VARRAY_TOP_TREE (stack))))
1636
1637 VARRAY_POP (stack);
1638
1639 /* If the stack is empty, we assign a new version since it isn't
1640 dominated by any other version. */
1641 if (VARRAY_ACTIVE_SIZE (stack) == 0 || VARRAY_TOP_TREE (stack) == NULL)
1642 {
1643 if (TREE_CODE (occur) == EPHI_NODE)
1644 assign_new_class (occur, &stack, NULL);
1645 else if (TREE_CODE (occur) == EUSE_NODE && !EUSE_PHIOP (occur))
1646 assign_new_class (occur, &stack, NULL);
1647 }
1648 else
1649 {
1650 if (TREE_CODE (occur) == EUSE_NODE && !EUSE_PHIOP (occur))
1651 {
1652 tree tos = VARRAY_TOP_TREE (stack);
1653
1654 if (TREE_CODE (tos) == EUSE_NODE && !EUSE_PHIOP (tos))
1655 {
1656 /* If two real occurrences have the same
1657 e-version/class, then this occurrence can be
1658 defined by the prior occurrence (or whatever
1659 the prior occurrence is defined by, if
1660 anything).
1661 Otherwise, we have to assign a new version.
1662 lvalue occurrences always need a new version,
1663 since they are definitions. */
1664 if (!EUSE_LVAL (occur)
1665 && same_e_version_real_occ_real_occ (ei, tos, occur))
1666 {
1667
1668
1669 tree newdef;
1670 EREF_CLASS (occur) = EREF_CLASS (tos);
1671 newdef = EUSE_DEF (tos) != NULL ? EUSE_DEF (tos) : tos;
1672 EUSE_DEF (occur) = newdef;
1673 }
1674 else
1675 assign_new_class (occur, &stack, NULL);
1676 }
1677 else if (TREE_CODE (tos) == EPHI_NODE)
1678 {
1679 /* Here we have an ephi occurrence at the top of the
1680 stack, and the current occurrence is a real
1681 occurrence. So determine if the real occurrence
1682 has the same version as the result of the phi.
1683 If so, then this real occurrence is defined by the
1684 EPHI at the top of the stack.
1685 If not, the EPHI isn't downsafe (because something
1686 must change in between the ephi result and the next
1687 occurrence), and we need a new version for the real
1688 occurrence.
1689 lvalues always need a new version. */
1690 if (!EUSE_LVAL (occur)
1691 && same_e_version_phi_result (ei, tos, EREF_STMT (occur),
1692 occur))
1693 {
1694 EREF_CLASS (occur) = EREF_CLASS (tos);
1695 EUSE_DEF (occur) = tos;
1696 EREF_STMT (tos) = EREF_STMT (occur);
1697
1698 VARRAY_PUSH_TREE (stack, occur);
1699 }
1700 else
1701 {
1702 EPHI_DOWNSAFE (tos) = false;
1703 assign_new_class (occur, &stack, NULL);
1704 }
1705 }
1706 }
1707 /* EPHI occurrences always get new versions. */
1708 else if (TREE_CODE (occur) == EPHI_NODE)
1709 {
1710 assign_new_class (occur, &stack, NULL);
1711 }
1712 /* EPHI operands are optimistcally assumed to be whatever is
1713 at the top of the stack at the time we hit the ephi
1714 operand occurrence. The delayed renaming checks this
1715 optimistic assumption for validity. */
1716 else if (TREE_CODE (occur) == EUSE_NODE && EUSE_PHIOP (occur))
1717 {
1718 basic_block pred_bb = bb_for_stmt (occur);
1719 edge e;
1720 tree tos = VARRAY_TOP_TREE (stack);
1721 for (e = pred_bb->succ; e; e = e->succ_next)
1722 {
1723 tree ephi = ephi_at_block (e->dest);
1724 if (ephi != NULL_TREE)
1725 {
1726 int opnum = opnum_of_ephi (ephi, e);
1727
1728 EPHI_ARG_DELAYED_RENAME (ephi, opnum) = true;
1729 EPHI_ARG_DEF (ephi, opnum) = tos;
1730 }
1731 }
1732 }
1733 /* No EPHI can be downsafe past an exit node. */
1734 else if (TREE_CODE (occur) == EEXIT_NODE)
1735 {
1736 if (VARRAY_ACTIVE_SIZE (stack) > 0
1737 && TREE_CODE (VARRAY_TOP_TREE (stack)) == EPHI_NODE)
1738 EPHI_DOWNSAFE (VARRAY_TOP_TREE (stack)) = false;
1739 }
1740 }
1741 }
1742 if (dump_file && (dump_flags & TDF_DETAILS))
1743 {
1744 size_t i;
1745 fprintf (dump_file, "Occurrences for expression ");
1746 print_generic_expr (dump_file, ei->expr, dump_flags);
1747 fprintf (dump_file, " after Rename 1\n");
1748 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
1749 {
1750 print_generic_expr (dump_file,
1751 VARRAY_TREE (ei->euses_dt_order, i), 1);
1752 fprintf (dump_file, "\n");
1753 }
1754 }
1755
1756 /* Now process the renames for EPHI's that actually have the result
1757 valid and used. These will be the EPHI's that have the statement
1758 set above. */
1759 FOR_EACH_BB (phi_bb)
1760 {
1761 tree ephi = ephi_at_block (phi_bb);
1762 if (ephi != NULL && EREF_STMT (ephi) != NULL)
1763 process_delayed_rename (ei, ephi, EREF_STMT (ephi));
1764 }
1765
1766 /* If we didn't process the delayed rename for an ephi argument,
1767 but thought we needed to, mark the operand as NULL. Also, if the
1768 operand was defined by an EPHI, we can mark it not downsafe
1769 because there can't have been a real occurrence (or else we would
1770 have processed a rename for it). */
1771 FOR_EACH_BB (phi_bb)
1772 {
1773 tree ephi = ephi_at_block (phi_bb);
1774 if (ephi != NULL)
1775 {
1776 int j;
1777 for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
1778 {
1779 if (EPHI_ARG_DELAYED_RENAME (ephi, j))
1780 {
1781 tree def = EPHI_ARG_DEF (ephi, j);
1782 if (def && TREE_CODE (def) == EPHI_NODE)
1783 EPHI_DOWNSAFE (def) = false;
1784 EPHI_ARG_DEF (ephi, j) = NULL;
1785 }
1786 }
1787 }
1788 }
1789 VARRAY_FREE (stack);
1790 }
1791
1792 /* Determine if the EPHI has an argument we could never insert
1793 or extend the lifetime of, such as an argument occurring on
1794 an abnormal edge. */
1795
1796 static bool
1797 ephi_has_unsafe_arg (tree ephi)
1798 {
1799 int i;
1800 for (i = 0; i < EPHI_NUM_ARGS (ephi); i++)
1801 if (EPHI_ARG_EDGE (ephi, i)->flags & EDGE_ABNORMAL)
1802 return true;
1803 return false;
1804 }
1805
1806 /* Reset down safety flags for non-downsafe ephis. Uses depth first
1807 search. */
1808
1809 static void
1810 reset_down_safe (tree currphi, int opnum)
1811 {
1812 tree ephi;
1813 int i;
1814
1815 if (EPHI_ARG_HAS_REAL_USE (currphi, opnum))
1816 return;
1817 ephi = EPHI_ARG_DEF (currphi, opnum);
1818 if (!ephi || TREE_CODE (ephi) != EPHI_NODE)
1819 return;
1820 if (!EPHI_DOWNSAFE (ephi))
1821 return;
1822 EPHI_DOWNSAFE (ephi) = false;
1823 for (i = 0; i < EPHI_NUM_ARGS (ephi); i++)
1824 reset_down_safe (ephi, i);
1825 }
1826
1827 /* Compute down_safety using a depth first search.
1828 This propagates not fully anticipated phi assignments upwards. */
1829
1830 static void
1831 compute_down_safety (struct expr_info *ei)
1832 {
1833 size_t i;
1834 basic_block bb;
1835 FOR_EACH_BB (bb)
1836 {
1837 tree ephi = ephi_at_block (bb);
1838 if (ephi == NULL_TREE)
1839 continue;
1840 if (ephi_has_unsafe_arg (ephi))
1841 EPHI_DOWNSAFE (ephi) = false;
1842 }
1843 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
1844 {
1845 int j;
1846 tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
1847 if (TREE_CODE (ephi) != EPHI_NODE)
1848 continue;
1849
1850 if (!EPHI_DOWNSAFE (ephi))
1851 for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
1852 reset_down_safe (ephi, j);
1853
1854 }
1855 }
1856
1857 /* EPHI use node pool. We allocate ephi_use_node's out of this. */
1858 static alloc_pool ephi_use_pool;
1859
1860 /* Add a use of DEF to it's use list. The use is at operand OPND_INDX
1861 of USE. */
1862
1863 static void
1864 add_ephi_use (tree def, tree use, int opnd_indx)
1865 {
1866 struct ephi_use_entry *entry;
1867 if (EPHI_USES (def) == NULL)
1868 VARRAY_GENERIC_PTR_INIT (EPHI_USES (def), 1, "EPHI uses");
1869 entry = (struct ephi_use_entry *) pool_alloc (ephi_use_pool);
1870 entry->phi = use;
1871 entry->opnd_indx = opnd_indx;
1872 VARRAY_PUSH_GENERIC_PTR (EPHI_USES (def), entry);
1873 }
1874
1875 /* Compute def-uses of ephis. */
1876
1877 static void
1878 compute_du_info (struct expr_info *ei)
1879 {
1880 size_t i;
1881 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
1882 {
1883 int j;
1884 tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
1885 if (TREE_CODE (ephi) != EPHI_NODE)
1886 continue;
1887 for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
1888 {
1889 tree def = EPHI_ARG_DEF (ephi, j);
1890 if (def != NULL_TREE)
1891 {
1892 if (TREE_CODE (def) == EPHI_NODE)
1893 add_ephi_use (def, ephi, j);
1894 #ifdef ENABLE_CHECKING
1895 else
1896 if (! (TREE_CODE (def) == EUSE_NODE && !EUSE_PHIOP (def)))
1897 abort();
1898 #endif
1899 }
1900 }
1901 }
1902 }
1903
1904 /* STOPS marks what EPHI's/operands stop forward movement. (IE where
1905 we can't insert past). */
1906
1907 static void
1908 compute_stops (struct expr_info *ei)
1909 {
1910 size_t i;
1911
1912 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
1913 {
1914 tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
1915 int j;
1916
1917 if (TREE_CODE (ephi) != EPHI_NODE)
1918 continue;
1919 if (EPHI_CANT_BE_AVAIL (ephi))
1920 EPHI_STOPS (ephi) = true;
1921 for (j = 0; j < EPHI_NUM_ARGS (ephi); j++)
1922 if (EPHI_ARG_HAS_REAL_USE (ephi, j))
1923 EPHI_ARG_STOPS (ephi, j) = true;
1924 }
1925 do_ephi_df_search (ei, stops_search);
1926 }
1927
1928 /* Compute will_be_avail property, which consists of cant_be_avail and
1929 stops properties. */
1930
1931 static void
1932 compute_will_be_avail (struct expr_info *ei)
1933 {
1934 do_ephi_df_search (ei, cant_be_avail_search);
1935 compute_stops (ei);
1936 }
1937
1938 /* Insert the expressions into ei->euses_dt_order in preorder dt order. */
1939
1940 static void
1941 insert_euse_in_preorder_dt_order (struct expr_info *ei)
1942 {
1943 varray_type new_euses_dt_order;
1944 size_t i;
1945 VARRAY_GENERIC_PTR_NOGC_INIT (new_euses_dt_order, 1, "EUSEs");
1946
1947 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
1948 {
1949 tree ref = VARRAY_TREE (ei->euses_dt_order, i);
1950 if (TREE_CODE (ref) == EUSE_NODE || TREE_CODE (ref) == EPHI_NODE)
1951 VARRAY_PUSH_TREE (new_euses_dt_order, ref);
1952 }
1953 VARRAY_FREE (ei->euses_dt_order);
1954 ei->euses_dt_order = new_euses_dt_order;
1955 qsort (ei->euses_dt_order->data.tree,
1956 VARRAY_ACTIVE_SIZE (ei->euses_dt_order),
1957 sizeof (tree),
1958 eref_compare);
1959
1960 }
1961
1962 /* Determine if we can insert operand OPND_INDX of EPHI. */
1963
1964 static bool
1965 can_insert (tree ephi, int opnd_indx)
1966 {
1967 tree def;
1968
1969 if (EPHI_ARG_DEF (ephi, opnd_indx) == NULL_TREE)
1970 return true;
1971 def = EPHI_ARG_DEF (ephi, opnd_indx);
1972 if (!EPHI_ARG_HAS_REAL_USE (ephi, opnd_indx))
1973 if (TREE_CODE (def) == EPHI_NODE && !(ephi_will_be_avail (def)))
1974 return true;
1975 return false;
1976 }
1977
1978 /* Find the default definition of VAR.
1979 This is incredibly ugly, since we have to walk back through all
1980 the definitions to find the one defined by the empty statement. */
1981
1982 static tree
1983 get_default_def (tree var, htab_t seen)
1984 {
1985 def_optype defs;
1986 size_t i;
1987 tree defstmt = SSA_NAME_DEF_STMT (var);
1988
1989 if (IS_EMPTY_STMT (defstmt))
1990 return var;
1991 *(htab_find_slot (seen, var, INSERT)) = var;
1992 if (TREE_CODE (defstmt) == PHI_NODE)
1993 {
1994 int j;
1995 for (j = 0; j < PHI_NUM_ARGS (defstmt); j++)
1996 if (htab_find (seen, PHI_ARG_DEF (defstmt, j)) == NULL)
1997 {
1998 if (TREE_CODE (PHI_ARG_DEF (defstmt, j)) == SSA_NAME)
1999 {
2000 tree temp = get_default_def (PHI_ARG_DEF (defstmt, j), seen);
2001 if (temp != NULL_TREE)
2002 return temp;
2003 }
2004 }
2005 }
2006
2007
2008 defs = STMT_DEF_OPS (defstmt);
2009 for (i = 0; i < NUM_DEFS (defs); i++)
2010 {
2011 tree def = DEF_OP (defs, i);
2012 if (SSA_NAME_VAR (def) == SSA_NAME_VAR (var))
2013 {
2014 if (htab_find (seen, def) != NULL)
2015 return NULL;
2016 return get_default_def (def, seen);
2017 }
2018 }
2019
2020 /* We should never get here. */
2021 abort ();
2022 }
2023
2024 /* Hunt down the right reaching def for VAR, starting with BB. Ignore
2025 defs in statement IGNORE, and stop if we hit CURRSTMT. */
2026
2027 static tree
2028 reaching_def (tree var, tree currstmt, basic_block bb, tree ignore)
2029 {
2030 tree curruse = NULL_TREE;
2031 block_stmt_iterator bsi;
2032 basic_block dom;
2033 tree phi;
2034
2035 /* Check phis first. */
2036 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
2037 {
2038 if (phi == currstmt)
2039 break;
2040 if (phi == ignore)
2041 continue;
2042 if (names_match_p (var, PHI_RESULT (phi)))
2043 curruse = PHI_RESULT (phi);
2044 }
2045
2046 /* We can't walk BB's backwards right now, so we have to walk *all*
2047 the statements, and choose the last name we find. */
2048 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2049 {
2050 tree stmt = bsi_stmt (bsi);
2051 tree *def;
2052 def_optype defs;
2053 size_t i;
2054
2055 if (stmt == currstmt)
2056 break;
2057
2058 get_stmt_operands (stmt);
2059 defs = STMT_DEF_OPS (stmt);
2060 for (i = 0; i < NUM_DEFS (defs); i++)
2061 {
2062 def = DEF_OP_PTR (defs, i);
2063 if (def && *def != ignore && names_match_p (var, *def))
2064 {
2065 curruse = *def;
2066 break;
2067 }
2068 }
2069 }
2070 if (curruse != NULL_TREE)
2071 return curruse;
2072 dom = get_immediate_dominator (CDI_DOMINATORS, bb);
2073 if (bb == ENTRY_BLOCK_PTR)
2074 {
2075 htab_t temp;
2076 temp = htab_create (7, htab_hash_pointer, htab_eq_pointer, NULL);
2077 curruse = get_default_def (var, temp);
2078 htab_delete (temp);
2079 }
2080 if (!dom)
2081 return curruse;
2082 return reaching_def (var, currstmt, dom, ignore);
2083 }
2084
2085 /* Insert one ephi operand that doesn't currently exist as a use. */
2086
2087 static void
2088 insert_one_operand (struct expr_info *ei, tree ephi, int opnd_indx,
2089 tree x, edge succ, tree **avdefsp)
2090 {
2091 /* FIXME. pre_insert_on_edge should probably disappear. */
2092 extern void pre_insert_on_edge (edge, tree);
2093 tree expr;
2094 tree temp = ei->temp;
2095 tree copy;
2096 tree newtemp;
2097 basic_block bb = bb_for_stmt (x);
2098
2099 /* Insert definition of expr at end of BB containing x. */
2100 copy = TREE_OPERAND (EREF_STMT (ephi), 1);
2101 copy = unshare_expr (copy);
2102 expr = build (MODIFY_EXPR, TREE_TYPE (ei->expr),
2103 temp, copy);
2104 expr = subst_phis (ei, expr, bb, bb_for_stmt (ephi));
2105 newtemp = make_ssa_name (temp, expr);
2106 TREE_OPERAND (expr, 0) = newtemp;
2107 copy = TREE_OPERAND (expr, 1);
2108 if (dump_file)
2109 {
2110 fprintf (dump_file, "In BB %d, insert save of ", bb->index);
2111 print_generic_expr (dump_file, expr, dump_flags);
2112 fprintf (dump_file, " to ");
2113 print_generic_expr (dump_file, newtemp, dump_flags);
2114 fprintf (dump_file, " after ");
2115 print_generic_stmt (dump_file, last_stmt (bb), dump_flags);
2116 fprintf (dump_file, " (on edge), because of EPHI");
2117 fprintf (dump_file, " in BB %d\n", bb_for_stmt (ephi)->index);
2118 }
2119
2120 /* Do the insertion. */
2121 /* ??? Previously we did bizarre searching, presumably to get
2122 around bugs elsewhere in the infrastructure. I'm not sure
2123 if we really should be using pre_insert_on_edge
2124 or just bsi_insert_after at the end of BB. */
2125 pre_insert_on_edge (succ, expr);
2126
2127 EPHI_ARG_DEF (ephi, opnd_indx)
2128 = create_expr_ref (ei, ei->expr, EUSE_NODE, bb, 0);
2129 EUSE_DEF (x) = EPHI_ARG_DEF (ephi, opnd_indx);
2130 VARRAY_PUSH_TREE (ei->euses_dt_order, EPHI_ARG_DEF (ephi, opnd_indx));
2131 qsort (ei->euses_dt_order->data.tree,
2132 VARRAY_ACTIVE_SIZE (ei->euses_dt_order),
2133 sizeof (tree),
2134 eref_compare);
2135 EREF_TEMP (EUSE_DEF (x)) = newtemp;
2136 EREF_RELOAD (EUSE_DEF (x)) = false;
2137 EREF_SAVE (EUSE_DEF (x)) = false;
2138 EUSE_INSERTED (EUSE_DEF (x)) = true;
2139 EUSE_PHIOP (EUSE_DEF (x)) = false;
2140 EREF_SAVE (x) = false;
2141 EREF_RELOAD (x) = false;
2142 EUSE_INSERTED (x) = true;
2143 EREF_CLASS (x) = class_count++;
2144 EREF_CLASS (EUSE_DEF (x)) = class_count++;
2145 *avdefsp = xrealloc (*avdefsp, sizeof (tree) * (class_count + 1));
2146 (*avdefsp)[class_count - 2] = x;
2147 (*avdefsp)[class_count - 1] = EUSE_DEF (x);
2148 pre_stats.saves++;
2149 }
2150
2151 /* First step of finalization. Determine which expressions are being
2152 saved and which are being deleted.
2153 This is done as a simple dominator based availability calculation,
2154 using the e-versions/redundancy classes. */
2155
2156 static bool
2157 finalize_1 (struct expr_info *ei)
2158 {
2159 tree x;
2160 int nx;
2161 bool made_a_reload = false;
2162 size_t i;
2163 tree *avdefs;
2164
2165 avdefs = xcalloc (class_count + 1, sizeof (tree));
2166
2167 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
2168 {
2169 x = VARRAY_TREE (ei->euses_dt_order, i);
2170 nx = EREF_CLASS (x);
2171
2172 if (TREE_CODE (x) == EPHI_NODE)
2173 {
2174 if (ephi_will_be_avail (x))
2175 avdefs[nx] = x;
2176 }
2177 else if (TREE_CODE (x) == EUSE_NODE && EUSE_LVAL (x))
2178 {
2179 avdefs[nx] = x;
2180 }
2181 else if (TREE_CODE (x) == EUSE_NODE && !EUSE_PHIOP (x))
2182 {
2183 if (avdefs[nx] == NULL
2184 || !dominated_by_p (CDI_DOMINATORS, bb_for_stmt (x),
2185 bb_for_stmt (avdefs[nx])))
2186 {
2187 EREF_RELOAD (x) = false;
2188 avdefs[nx] = x;
2189 EUSE_DEF (x) = NULL;
2190 }
2191 else
2192 {
2193 EREF_RELOAD (x) = true;
2194 made_a_reload = true;
2195 EUSE_DEF (x) = avdefs[nx];
2196 #ifdef ENABLE_CHECKING
2197 if (EREF_CLASS (x) != EREF_CLASS (avdefs[nx]))
2198 abort ();
2199 #endif
2200 }
2201 }
2202 else
2203 {
2204 edge succ;
2205 basic_block bb = bb_for_stmt (x);
2206 /* For each ephi in the successor blocks. */
2207 for (succ = bb->succ; succ; succ = succ->succ_next)
2208 {
2209 tree ephi = ephi_at_block (succ->dest);
2210 if (ephi == NULL_TREE)
2211 continue;
2212 if (ephi_will_be_avail (ephi))
2213 {
2214 int opnd_indx = opnum_of_ephi (ephi, succ);
2215 #ifdef ENABLE_CHECKING
2216 if (EPHI_ARG_PRED (ephi, opnd_indx) != x)
2217 abort ();
2218 #endif
2219 if (can_insert (ephi, opnd_indx))
2220 {
2221 insert_one_operand (ei, ephi, opnd_indx, x, succ,
2222 &avdefs);
2223 }
2224 else
2225 {
2226 nx = EREF_CLASS (EPHI_ARG_DEF (ephi,opnd_indx));
2227 EPHI_ARG_DEF (ephi, opnd_indx) = avdefs[nx];
2228 }
2229 }
2230 }
2231 }
2232 }
2233 free (avdefs);
2234 return made_a_reload;
2235 }
2236
2237 /* Mark the necessary SAVE bits on X. */
2238
2239 static void
2240 set_save (struct expr_info *ei, tree X)
2241 {
2242 if (TREE_CODE (X) == EUSE_NODE && !EUSE_PHIOP (X))
2243 EREF_SAVE (X) = true;
2244 else if (TREE_CODE (X) == EPHI_NODE)
2245 {
2246 int curr_phiop;
2247 for (curr_phiop = 0; curr_phiop < EPHI_NUM_ARGS (X); curr_phiop++)
2248 {
2249 tree w = EPHI_ARG_DEF (X, curr_phiop);
2250 if (!EPHI_ARG_PROCESSED2 (X, curr_phiop))
2251 {
2252 EPHI_ARG_PROCESSED2 (X, curr_phiop) = true;
2253 if (w)
2254 set_save (ei, w);
2255 }
2256 }
2257 }
2258 }
2259
2260 /* DFS Search function: Return true if PHI is can't be available. */
2261
2262 static bool
2263 cba_search_seen (tree phi)
2264 {
2265 return EPHI_CANT_BE_AVAIL (phi);
2266 }
2267
2268 /* DFS Search function: Mark PHI as can't be available when seen. */
2269
2270 static void
2271 cba_search_set_seen (tree phi)
2272 {
2273 EPHI_CANT_BE_AVAIL (phi) = true;
2274 }
2275
2276 /* DFS Search function: Return true if PHI should be marked can't be
2277 available due to a NULL operand. */
2278
2279 static bool
2280 cba_search_start_from (tree phi)
2281 {
2282 if (!EPHI_DOWNSAFE (phi))
2283 {
2284 int i;
2285 for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
2286 if (EPHI_ARG_DEF (phi, i) == NULL_TREE
2287 || EPHI_ARG_EDGE (phi, i)->flags & EDGE_ABNORMAL)
2288 return true;
2289 }
2290 return false;
2291 }
2292
2293 /* DFS Search function: Return true if the used PHI is not downsafe,
2294 unless we have a real use for the operand. */
2295
2296 static bool
2297 cba_search_continue_from_to (tree def_phi ATTRIBUTE_UNUSED,
2298 int opnd_indx,
2299 tree use_phi)
2300 {
2301 if (EPHI_ARG_HAS_REAL_USE (use_phi, opnd_indx) &&
2302 !(EPHI_ARG_EDGE (use_phi, opnd_indx)->flags & EDGE_ABNORMAL))
2303 return false;
2304 if (!EPHI_DOWNSAFE (use_phi))
2305 return true;
2306 return false;
2307 }
2308
2309 /* DFS Search function: Return true if this PHI stops forward
2310 movement. */
2311
2312 static bool
2313 stops_search_seen (tree phi)
2314 {
2315 return EPHI_STOPS (phi);
2316 }
2317
2318 /* DFS Search function: Mark the PHI as stopping forward movement. */
2319
2320 static void
2321 stops_search_set_seen (tree phi)
2322 {
2323 EPHI_STOPS (phi) = true;
2324 }
2325
2326 /* DFS Search function: Note that the used phi argument stops forward
2327 movement. */
2328
2329 static void
2330 stops_search_reach_from_to (tree def_phi ATTRIBUTE_UNUSED,
2331 int opnd_indx,
2332 tree use_phi)
2333 {
2334 EPHI_ARG_STOPS (use_phi, opnd_indx) = true;
2335 }
2336
2337 /* DFS Search function: Return true if the PHI has any arguments
2338 stopping forward movement. */
2339
2340 static bool
2341 stops_search_start_from (tree phi)
2342 {
2343 int i;
2344 for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
2345 if (EPHI_ARG_STOPS (phi, i))
2346 return true;
2347 return false;
2348 }
2349
2350 /* DFS Search function: Return true if the PHI has any arguments
2351 stopping forward movement. */
2352
2353 static bool
2354 stops_search_continue_from_to (tree def_phi ATTRIBUTE_UNUSED,
2355 int opnd_indx ATTRIBUTE_UNUSED,
2356 tree use_phi)
2357 {
2358 return stops_search_start_from (use_phi);
2359 }
2360
2361 /* DFS Search function: Return true if the replacing occurrence is
2362 known. */
2363
2364 static bool
2365 repl_search_seen (tree phi)
2366 {
2367 return EPHI_REP_OCCUR_KNOWN (phi);
2368 }
2369
2370 /* DFS Search function: Set the identical_to field and note the
2371 replacing occurrence is now known. */
2372
2373 static void
2374 repl_search_set_seen (tree phi)
2375 {
2376 int i;
2377
2378 #ifdef ENABLE_CHECKING
2379 if (!ephi_will_be_avail (phi))
2380 abort ();
2381 #endif
2382
2383 if (EPHI_IDENTICAL_TO (phi) == NULL_TREE)
2384 {
2385 for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
2386 {
2387 tree identical_to = occ_identical_to (EPHI_ARG_DEF (phi, i));
2388 if (identical_to != NULL_TREE)
2389 {
2390 if (EPHI_IDENTICAL_TO (phi) == NULL)
2391 EPHI_IDENTICAL_TO (phi) = identical_to;
2392 if (EPHI_ARG_INJURED (phi, i))
2393 EPHI_IDENT_INJURED (phi) = true;
2394 }
2395 }
2396 }
2397 EPHI_REP_OCCUR_KNOWN (phi) = true;
2398 }
2399
2400 /* Helper function. Return true if any argument in the PHI is
2401 injured. */
2402
2403 static inline bool
2404 any_operand_injured (tree ephi)
2405 {
2406 int i;
2407 for (i = 0; i < EPHI_NUM_ARGS (ephi); i++)
2408 if (EPHI_ARG_INJURED (ephi, i))
2409 return true;
2410 return false;
2411
2412 }
2413
2414 /* DFS Search function: Note the identity of the used phi operand is
2415 the same as it's defining phi operand, if that phi will be
2416 available, and it's known. */
2417
2418 static void
2419 repl_search_reach_from_to (tree def_phi, int opnd_indx ATTRIBUTE_UNUSED,
2420 tree use_phi)
2421 {
2422 if (ephi_will_be_avail (use_phi)
2423 && EPHI_IDENTITY (use_phi)
2424 && EPHI_IDENTICAL_TO (use_phi) == NULL_TREE)
2425 {
2426 EPHI_IDENTICAL_TO (use_phi) = EPHI_IDENTICAL_TO (def_phi);
2427
2428 if (EPHI_IDENT_INJURED (def_phi)
2429 || any_operand_injured (use_phi))
2430 EPHI_IDENT_INJURED (use_phi) = true;
2431 }
2432 }
2433
2434 /* DFS Search function: Return true if the PHI will be available,
2435 it's an identity PHI, and it's arguments are identical to
2436 something. */
2437
2438 static bool
2439 repl_search_start_from (tree phi)
2440 {
2441 if (ephi_will_be_avail (phi) && EPHI_IDENTITY (phi))
2442 {
2443 int i;
2444 for (i = 0; i < EPHI_NUM_ARGS (phi); i++)
2445 if (occ_identical_to (EPHI_ARG_DEF (phi, i)) != NULL_TREE)
2446 return true;
2447 }
2448 return false;
2449 }
2450
2451 /* DFS Search function: Return true if the using PHI is will be available,
2452 and identity. */
2453
2454 static bool
2455 repl_search_continue_from_to (tree def_phi ATTRIBUTE_UNUSED,
2456 int opnd_indx ATTRIBUTE_UNUSED,
2457 tree use_phi)
2458 {
2459 return ephi_will_be_avail (use_phi) && EPHI_IDENTITY (use_phi);
2460 }
2461
2462 /* Mark all will-be-avail ephi's in the dominance frontier of BB as
2463 required. */
2464
2465 static void
2466 require_phi (struct expr_info *ei, basic_block bb)
2467 {
2468 size_t i;
2469 EXECUTE_IF_SET_IN_BITMAP (pre_dfs[bb->index], 0, i,
2470 {
2471 tree ephi;
2472 ephi = ephi_at_block (BASIC_BLOCK (i));
2473 if (ephi != NULL_TREE
2474 && ephi_will_be_avail (ephi)
2475 && EPHI_IDENTITY (ephi))
2476 {
2477 EPHI_IDENTITY (ephi) = false;
2478 require_phi (ei, BASIC_BLOCK (i));
2479 }
2480 });
2481 }
2482
2483 /* Return the occurrence this occurrence is identical to, if one exists. */
2484
2485 static tree
2486 occ_identical_to (tree t)
2487 {
2488 if (TREE_CODE (t) == EUSE_NODE && !EUSE_PHIOP (t))
2489 return t;
2490 else if (TREE_CODE (t) == EUSE_NODE && EUSE_PHIOP (t))
2491 return t;
2492 else if (TREE_CODE (t) == EPHI_NODE)
2493 {
2494 if (EPHI_IDENTITY (t) && EPHI_REP_OCCUR_KNOWN (t))
2495 return EPHI_IDENTICAL_TO (t);
2496 else if (!EPHI_IDENTITY (t))
2497 return t;
2498 }
2499 return NULL_TREE;
2500 }
2501
2502 /* Return true if NODE was or is going to be saved. */
2503 static bool
2504 really_available_def (tree node)
2505 {
2506 if (TREE_CODE (node) == EUSE_NODE
2507 && EUSE_PHIOP (node)
2508 && EUSE_INSERTED (node))
2509 return true;
2510 if (TREE_CODE (node) == EUSE_NODE
2511 && EUSE_DEF (node) == NULL_TREE)
2512 return true;
2513 return false;
2514 }
2515
2516
2517 /* Second part of the finalize step. Performs save bit setting, and
2518 ESSA minimization. */
2519
2520 static void
2521 finalize_2 (struct expr_info *ei)
2522 {
2523 size_t i;
2524
2525 insert_euse_in_preorder_dt_order (ei);
2526 /* Note which uses need to be saved to a temporary. */
2527 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
2528 {
2529 tree ref = VARRAY_TREE (ei->euses_dt_order, i);
2530 if (TREE_CODE (ref) == EUSE_NODE
2531 && !EUSE_PHIOP (ref)
2532 && EREF_RELOAD (ref))
2533 {
2534 set_save (ei, EUSE_DEF (ref));
2535 }
2536 }
2537
2538 /* ESSA Minimization. Determines which phis are identical to other
2539 phis, and not strictly necessary. */
2540
2541 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
2542 {
2543 tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
2544 if (TREE_CODE (ephi) != EPHI_NODE)
2545 continue;
2546 EPHI_IDENTITY (ephi) = true;
2547 EPHI_IDENTICAL_TO (ephi) = NULL;
2548 }
2549
2550 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
2551 {
2552 tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
2553 if (!ephi || TREE_CODE (ephi) != EPHI_NODE)
2554 continue;
2555 if (ephi_will_be_avail (ephi))
2556 {
2557 int k;
2558 for (k = 0; k < EPHI_NUM_ARGS (ephi); k++)
2559 {
2560 if (EPHI_ARG_INJURED (ephi, k))
2561 require_phi (ei, EPHI_ARG_EDGE (ephi, k)->src);
2562 else if (EPHI_ARG_DEF (ephi, k)
2563 && TREE_CODE (EPHI_ARG_DEF (ephi, k)) == EUSE_NODE
2564 && really_available_def (EPHI_ARG_DEF (ephi, k)))
2565 require_phi (ei, bb_for_stmt (EPHI_ARG_DEF (ephi, k)));
2566 }
2567 }
2568 }
2569 do_ephi_df_search (ei, replacing_search);
2570 }
2571
2572 /* Perform a DFS on EPHI using the functions in SEARCH. */
2573
2574 static void
2575 do_ephi_df_search_1 (struct ephi_df_search search, tree ephi)
2576 {
2577 varray_type uses;
2578 size_t i;
2579 search.set_seen (ephi);
2580
2581 uses = EPHI_USES (ephi);
2582 if (!uses)
2583 return;
2584 for (i = 0; i < VARRAY_ACTIVE_SIZE (uses); i++)
2585 {
2586 struct ephi_use_entry *use = VARRAY_GENERIC_PTR (uses, i);
2587 if (search.reach_from_to)
2588 search.reach_from_to (ephi, use->opnd_indx, use->phi);
2589 if (!search.seen (use->phi) &&
2590 search.continue_from_to (ephi, use->opnd_indx, use->phi))
2591 {
2592 do_ephi_df_search_1 (search, use->phi);
2593 }
2594 }
2595 }
2596
2597 /* Perform a DFS on the EPHI's, using the functions in SEARCH. */
2598
2599 static void
2600 do_ephi_df_search (struct expr_info *ei, struct ephi_df_search search)
2601 {
2602 size_t i;
2603 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
2604 {
2605 tree ephi = VARRAY_TREE (ei->euses_dt_order, i);
2606 if (!ephi || TREE_CODE (ephi) != EPHI_NODE)
2607 continue;
2608 if (!search.seen (ephi)
2609 && search.start_from (ephi))
2610 do_ephi_df_search_1 (search, ephi);
2611 }
2612 }
2613
2614 #if 0
2615 /* Calculate the increment necessary due to EXPR for the temporary. */
2616 static tree
2617 calculate_increment (struct expr_info *ei, tree expr)
2618 {
2619 tree incr;
2620
2621 /*XXX: Currently assume it's like a = a + 5, thus, this will give us the 5.
2622 */
2623 incr = TREE_OPERAND (TREE_OPERAND (expr, 1), 1);
2624 if (TREE_CODE (incr) != INTEGER_CST)
2625 abort();
2626 if (TREE_CODE (ei->expr) == MULT_EXPR)
2627 incr = fold (build (MULT_EXPR, TREE_TYPE (ei->expr),
2628 incr, TREE_OPERAND (ei->expr, 1)));
2629 #if DEBUGGING_STRRED
2630 if (dump_file)
2631 {
2632 fprintf (dump_file, "Increment calculated to be: ");
2633 print_generic_expr (dump_file, incr, 0);
2634 fprintf (dump_file, "\n");
2635 }
2636 #endif
2637 return incr;
2638 }
2639 #endif
2640
2641
2642 /* Perform an insertion of EXPR before/after USE, depending on the
2643 value of BEFORE. */
2644
2645 static tree
2646 do_proper_save (tree use, tree expr, int before)
2647 {
2648 basic_block bb = bb_for_stmt (use);
2649 block_stmt_iterator bsi;
2650
2651 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
2652 {
2653 if (bsi_stmt (bsi) == use)
2654 {
2655 if (before)
2656 bsi_insert_before (&bsi, expr, BSI_SAME_STMT);
2657 else
2658 bsi_insert_after (&bsi, expr, BSI_SAME_STMT);
2659 return use;
2660 }
2661 }
2662 abort ();
2663 }
2664
2665 /* Get the temporary for ESSA node USE.
2666 Takes into account minimized ESSA. */
2667 static tree
2668 get_temp (tree use)
2669 {
2670 tree newtemp;
2671 if (TREE_CODE (use) == EPHI_NODE && EPHI_IDENTITY (use))
2672 {
2673 tree newuse = use;
2674 while (TREE_CODE (newuse) == EPHI_NODE
2675 && EPHI_IDENTITY (newuse))
2676 {
2677 #ifdef ENABLE_CHECKING
2678 if (!EPHI_IDENTICAL_TO (newuse))
2679 abort ();
2680 #endif
2681 newuse = EPHI_IDENTICAL_TO (newuse);
2682 if (TREE_CODE (newuse) != EPHI_NODE)
2683 break;
2684 }
2685 if (TREE_CODE (EREF_TEMP (newuse)) == PHI_NODE)
2686 newtemp = PHI_RESULT (EREF_TEMP (newuse));
2687 else
2688 newtemp = EREF_TEMP (newuse);
2689 }
2690 else
2691 {
2692 if (TREE_CODE (EREF_TEMP (use)) == PHI_NODE)
2693 newtemp = PHI_RESULT (EREF_TEMP (use));
2694 else
2695 newtemp = EREF_TEMP (use);
2696 }
2697 return newtemp;
2698 }
2699
2700 /* Return the side of the statement that contains an SSA name. */
2701
2702 static tree
2703 pick_ssa_name (tree stmt)
2704 {
2705 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
2706 return TREE_OPERAND (stmt, 0);
2707 else if (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)
2708 return TREE_OPERAND (stmt, 1);
2709 else
2710 abort ();
2711 }
2712
2713 /* Code motion step of SSAPRE. Take the save bits, and reload bits,
2714 and perform the saves and reloads. Also insert new phis where
2715 necessary. */
2716
2717 static void
2718 code_motion (struct expr_info *ei)
2719 {
2720 tree use;
2721 tree newtemp;
2722 size_t euse_iter;
2723 tree temp = ei->temp;
2724 basic_block bb;
2725
2726 /* First, add the phi node temporaries so the reaching defs are
2727 always right. */
2728 for (euse_iter = 0;
2729 euse_iter < VARRAY_ACTIVE_SIZE (ei->euses_dt_order);
2730 euse_iter++)
2731 {
2732
2733 use = VARRAY_TREE (ei->euses_dt_order, euse_iter);
2734 if (TREE_CODE (use) != EPHI_NODE)
2735 continue;
2736 if (ephi_will_be_avail (use) && !EPHI_IDENTITY (use))
2737 {
2738 bb = bb_for_stmt (use);
2739 /* Add the new PHI node to the list of PHI nodes for block BB. */
2740 bb_ann (bb)->phi_nodes = chainon (phi_nodes (bb), EREF_TEMP (use));
2741 }
2742 else if (EPHI_IDENTITY (use))
2743 {
2744 if (dump_file && (dump_flags & TDF_DETAILS))
2745 {
2746 fprintf (dump_file, "Pointless EPHI in block %d\n",
2747 bb_for_stmt (use)->index);
2748 }
2749 }
2750 }
2751 /* Now do the actual saves and reloads, plus repairs. */
2752 for (euse_iter = 0;
2753 euse_iter < VARRAY_ACTIVE_SIZE (ei->euses_dt_order);
2754 euse_iter++)
2755 {
2756 use = VARRAY_TREE (ei->euses_dt_order, euse_iter);
2757 #ifdef ENABLE_CHECKING
2758 if (TREE_CODE (use) == EUSE_NODE && EUSE_PHIOP (use)
2759 && (EREF_RELOAD (use) || EREF_SAVE (use)))
2760 abort ();
2761 #endif
2762 if (EREF_SAVE (use) && !EUSE_INSERTED (use))
2763 {
2764 tree newexpr;
2765 tree use_stmt;
2766 tree copy;
2767 basic_block usebb = bb_for_stmt (use);
2768 use_stmt = EREF_STMT (use);
2769
2770 copy = TREE_OPERAND (use_stmt, 1);
2771 copy = unshare_expr (copy);
2772 newexpr = build (MODIFY_EXPR, TREE_TYPE (temp), temp, copy);
2773 newtemp = make_ssa_name (temp, newexpr);
2774 EREF_TEMP (use) = newtemp;
2775 TREE_OPERAND (newexpr, 0) = newtemp;
2776 TREE_OPERAND (use_stmt, 1) = newtemp;
2777
2778 if (dump_file)
2779 {
2780 fprintf (dump_file, "In BB %d, insert save of ",
2781 usebb->index);
2782 print_generic_expr (dump_file, copy, dump_flags);
2783 fprintf (dump_file, " to ");
2784 print_generic_expr (dump_file, newtemp, dump_flags);
2785 fprintf (dump_file, " before statement ");
2786 print_generic_expr (dump_file, use_stmt, dump_flags);
2787 fprintf (dump_file, "\n");
2788 if (EXPR_HAS_LOCATION (use_stmt))
2789 fprintf (dump_file, " on line %d\n",
2790 EXPR_LINENO (use_stmt));
2791 }
2792 modify_stmt (newexpr);
2793 modify_stmt (use_stmt);
2794 set_bb_for_stmt (newexpr, usebb);
2795 EREF_STMT (use) = do_proper_save (use_stmt, newexpr, true);
2796 pre_stats.saves++;
2797 }
2798 else if (EREF_RELOAD (use))
2799 {
2800 tree use_stmt;
2801 tree newtemp;
2802
2803 use_stmt = EREF_STMT (use);
2804 bb = bb_for_stmt (use_stmt);
2805
2806 newtemp = get_temp (EUSE_DEF (use));
2807 if (!newtemp)
2808 abort ();
2809 if (dump_file)
2810 {
2811 fprintf (dump_file, "In BB %d, insert reload of ",
2812 bb->index);
2813 print_generic_expr (dump_file,
2814 TREE_OPERAND (use_stmt, 1), 0);
2815 fprintf (dump_file, " from ");
2816 print_generic_expr (dump_file, newtemp, dump_flags);
2817 fprintf (dump_file, " in statement ");
2818 print_generic_stmt (dump_file, use_stmt, dump_flags);
2819 fprintf (dump_file, "\n");
2820 if (EXPR_HAS_LOCATION (use_stmt))
2821 fprintf (dump_file, " on line %d\n",
2822 EXPR_LINENO (use_stmt));
2823 }
2824 TREE_OPERAND (use_stmt, 1) = newtemp;
2825 EREF_TEMP (use) = newtemp;
2826 modify_stmt (use_stmt);
2827 pre_stats.reloads++;
2828 }
2829 }
2830
2831 /* Now do the phi nodes. */
2832 for (euse_iter = 0;
2833 euse_iter < VARRAY_ACTIVE_SIZE (ei->euses_dt_order);
2834 euse_iter++)
2835 {
2836 use = VARRAY_TREE (ei->euses_dt_order, euse_iter);
2837 if (TREE_CODE (use) == EPHI_NODE
2838 && ephi_will_be_avail (use)
2839 && !EPHI_IDENTITY (use))
2840 {
2841 int i;
2842 tree argdef;
2843 bb = bb_for_stmt (use);
2844 if (dump_file)
2845 {
2846 fprintf (dump_file,
2847 "In BB %d, insert PHI to replace EPHI\n", bb->index);
2848 }
2849 newtemp = EREF_TEMP (use);
2850 for (i = 0; i < EPHI_NUM_ARGS (use); i++)
2851 {
2852 tree rdef;
2853 argdef = EPHI_ARG_DEF (use, i);
2854 if (argdef == use)
2855 rdef = get_temp (use);
2856 else if (EREF_RELOAD (argdef) || EREF_SAVE (argdef))
2857 rdef = get_temp (argdef);
2858 else if (TREE_CODE (argdef) == EPHI_NODE)
2859 rdef = get_temp (argdef);
2860 else if (argdef
2861 && EPHI_ARG_HAS_REAL_USE (use, i)
2862 && EREF_STMT (argdef)
2863 && !EPHI_ARG_INJURED (use, i))
2864 rdef = pick_ssa_name (EREF_STMT (argdef));
2865 else
2866 abort ();
2867
2868 if (!rdef)
2869 abort();
2870 add_phi_arg (&newtemp, rdef, EPHI_ARG_EDGE (use, i));
2871 }
2872
2873 /* Associate BB to the PHI node. */
2874 set_bb_for_stmt (EREF_TEMP (use), bb);
2875 pre_stats.newphis++;
2876
2877 }
2878 }
2879 }
2880
2881 /* Compute the iterated dominance frontier of a statement. */
2882
2883 static bitmap
2884 compute_idfs (bitmap * dfs, tree stmt)
2885 {
2886 fibheap_t worklist;
2887 sbitmap inworklist, done;
2888 bitmap idf;
2889 size_t i;
2890 basic_block block;
2891
2892 block = bb_for_stmt (stmt);
2893 if (idfs_cache[block->index] != NULL)
2894 return idfs_cache[block->index];
2895
2896 inworklist = sbitmap_alloc (last_basic_block);
2897 done = sbitmap_alloc (last_basic_block);
2898 worklist = fibheap_new ();
2899 sbitmap_zero (inworklist);
2900 sbitmap_zero (done);
2901
2902 idf = BITMAP_XMALLOC ();
2903 bitmap_zero (idf);
2904
2905 block = bb_for_stmt (stmt);
2906 fibheap_insert (worklist, block->index, (void *)(size_t)block->index);
2907 SET_BIT (inworklist, block->index);
2908
2909 while (!fibheap_empty (worklist))
2910 {
2911 int a = (size_t) fibheap_extract_min (worklist);
2912 if (TEST_BIT (done, a))
2913 continue;
2914 SET_BIT (done, a);
2915 if (idfs_cache[a])
2916 {
2917 bitmap_a_or_b (idf, idf, idfs_cache[a]);
2918 EXECUTE_IF_SET_IN_BITMAP (idfs_cache[a], 0, i,
2919 {
2920 SET_BIT (inworklist, i);
2921 SET_BIT (done, i);
2922 });
2923 }
2924 else
2925 {
2926 bitmap_a_or_b (idf, idf, dfs[a]);
2927 EXECUTE_IF_SET_IN_BITMAP (dfs[a], 0, i,
2928 {
2929 if (!TEST_BIT (inworklist, i))
2930 {
2931 SET_BIT (inworklist, i);
2932 fibheap_insert (worklist, i, (void *)i);
2933 }
2934 });
2935 }
2936
2937 }
2938 fibheap_delete (worklist);
2939 sbitmap_free (inworklist);
2940 sbitmap_free (done);
2941 idfs_cache[block->index] = idf;
2942 return idf;
2943
2944 }
2945
2946 /* Return true if EXPR is a strength reduction candidate. */
2947 static bool
2948 is_strred_cand (const tree expr ATTRIBUTE_UNUSED)
2949 {
2950 #if 0
2951 if (TREE_CODE (TREE_OPERAND (expr, 1)) != MULT_EXPR
2952 && TREE_CODE (TREE_OPERAND (expr, 1)) != MINUS_EXPR
2953 && TREE_CODE (TREE_OPERAND (expr, 1)) != NEGATE_EXPR
2954 && TREE_CODE (TREE_OPERAND (expr, 1)) != PLUS_EXPR)
2955 return false;
2956 return true;
2957 #endif
2958 return false;
2959 }
2960
2961
2962
2963 /* Determine if two expressions are lexically equivalent. */
2964
2965 static inline bool
2966 expr_lexically_eq (const tree v1, const tree v2)
2967 {
2968 if (TREE_CODE_CLASS (TREE_CODE (v1)) != TREE_CODE_CLASS (TREE_CODE (v2)))
2969 return false;
2970 if (TREE_CODE (v1) != TREE_CODE (v2))
2971 return false;
2972 switch (TREE_CODE_CLASS (TREE_CODE (v1)))
2973 {
2974 case 'r':
2975 case '1':
2976 return names_match_p (TREE_OPERAND (v1, 0), TREE_OPERAND (v2, 0));
2977 case 'x':
2978 case 'd':
2979 return names_match_p (v1, v2);
2980 case '2':
2981 {
2982 bool match;
2983 match = names_match_p (TREE_OPERAND (v1, 0), TREE_OPERAND (v2, 0));
2984 if (!match)
2985 return false;
2986 match = names_match_p (TREE_OPERAND (v1, 1), TREE_OPERAND (v2, 1));
2987 if (!match)
2988 return false;
2989 return true;
2990 }
2991 default:
2992 return false;
2993 }
2994
2995 }
2996
2997 /* Free an expression info structure. */
2998
2999 static void
3000 free_expr_info (struct expr_info *v1)
3001 {
3002 struct expr_info *e1 = (struct expr_info *)v1;
3003 VARRAY_FREE (e1->occurs);
3004 VARRAY_FREE (e1->kills);
3005 VARRAY_FREE (e1->lefts);
3006 VARRAY_FREE (e1->reals);
3007 VARRAY_FREE (e1->euses_dt_order);
3008 }
3009
3010 /* Process left occurrences and kills due to EXPR.
3011 A left occurrence occurs wherever a variable in an expression we
3012 are PRE'ing is stored to directly in a def, or indirectly because
3013 of a VDEF of an expression that we VUSE. */
3014
3015 static void
3016 process_left_occs_and_kills (varray_type bexprs, tree expr)
3017 {
3018 size_t i, j, k;
3019
3020 v_may_def_optype v_may_defs;
3021 v_must_def_optype v_must_defs;
3022 vuse_optype vuses;
3023 def_optype defs;
3024 defs = STMT_DEF_OPS (expr);
3025 v_may_defs = STMT_V_MAY_DEF_OPS (expr);
3026 v_must_defs = STMT_V_MUST_DEF_OPS (expr);
3027 if (NUM_DEFS (defs) == 0
3028 && NUM_V_MAY_DEFS (v_may_defs) == 0
3029 && NUM_V_MUST_DEFS (v_must_defs) == 0)
3030 return;
3031
3032 for (j = 0; j < VARRAY_ACTIVE_SIZE (bexprs); j++)
3033 {
3034 struct expr_info *ei = VARRAY_GENERIC_PTR (bexprs, j);
3035 tree vuse_name;
3036 tree random_occur;
3037 stmt_ann_t ann;
3038
3039 if (!ei->loadpre_cand)
3040 continue;
3041
3042 /* If we define the variable itself (IE a in *a, or a in a),
3043 it's a left occurrence. */
3044 for (i = 0; i < NUM_DEFS (defs); i++)
3045 {
3046 if (names_match_p (DEF_OP (defs, i), ei->expr))
3047 {
3048 if (TREE_CODE (expr) == ASM_EXPR)
3049 {
3050 ei->loadpre_cand = false;
3051 continue;
3052 }
3053 VARRAY_PUSH_TREE (ei->lefts, expr);
3054 VARRAY_PUSH_TREE (ei->occurs, NULL);
3055 VARRAY_PUSH_TREE (ei->kills, NULL);
3056 }
3057 }
3058
3059 /* If we virtually define the variable itself,
3060 it's a left occurrence. */
3061 for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
3062 {
3063 if (names_match_p (V_MUST_DEF_OP (v_must_defs, i), ei->expr))
3064 {
3065 if (TREE_CODE (expr) == ASM_EXPR)
3066 {
3067 ei->loadpre_cand = false;
3068 continue;
3069 }
3070 VARRAY_PUSH_TREE (ei->lefts, expr);
3071 VARRAY_PUSH_TREE (ei->occurs, NULL);
3072 VARRAY_PUSH_TREE (ei->kills, NULL);
3073 }
3074 }
3075
3076 /* If we V_MAY_DEF the VUSE of the expression, it's also a left
3077 occurrence. */
3078 random_occur = VARRAY_TREE (ei->occurs, 0);
3079 ann = stmt_ann (random_occur);
3080 vuses = VUSE_OPS (ann);
3081 if (NUM_V_MAY_DEFS (v_may_defs) != 0)
3082 {
3083 for (k = 0; k < NUM_VUSES (vuses); k++)
3084 {
3085 vuse_name = VUSE_OP (vuses, k);
3086 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
3087 {
3088 if (names_match_p (V_MAY_DEF_OP (v_may_defs, i), vuse_name))
3089 {
3090 VARRAY_PUSH_TREE (ei->lefts, expr);
3091 VARRAY_PUSH_TREE (ei->occurs, NULL);
3092 VARRAY_PUSH_TREE (ei->kills, NULL);
3093 }
3094 }
3095 }
3096 }
3097 }
3098 }
3099
3100 /* Perform SSAPRE on an expression. */
3101
3102 static int
3103 pre_expression (struct expr_info *slot, void *data, bitmap vars_to_rename)
3104 {
3105 struct expr_info *ei = (struct expr_info *) slot;
3106 basic_block bb;
3107
3108 class_count = 0;
3109 eref_id_counter = 0;
3110
3111 /* If we don't have two occurrences along any dominated path, and
3112 it's not load PRE, this is a waste of time. */
3113
3114 if (VARRAY_ACTIVE_SIZE (ei->reals) < 2)
3115 return 1;
3116
3117 memset (&pre_stats, 0, sizeof (struct pre_stats_d));
3118
3119 ei->temp = create_tmp_var (TREE_TYPE (ei->expr), "pretmp");
3120 add_referenced_tmp_var (ei->temp);
3121
3122 bitmap_clear (created_phi_preds);
3123 ephi_pindex_htab = htab_create (500, ephi_pindex_hash, ephi_pindex_eq, free);
3124 phi_pred_cache = xcalloc (last_basic_block, sizeof (tree));
3125 n_phi_preds = last_basic_block;
3126
3127 if (!expr_phi_insertion ((bitmap *)data, ei))
3128 goto cleanup;
3129 rename_1 (ei);
3130 if (dump_file && (dump_flags & TDF_DETAILS))
3131 {
3132 size_t i;
3133 fprintf (dump_file, "Occurrences for expression ");
3134 print_generic_expr (dump_file, ei->expr, dump_flags);
3135 fprintf (dump_file, " after Rename 2\n");
3136 for (i = 0; i < VARRAY_ACTIVE_SIZE (ei->euses_dt_order); i++)
3137 {
3138 print_generic_expr (dump_file,
3139 VARRAY_TREE (ei->euses_dt_order, i), 1);
3140 fprintf (dump_file, "\n");
3141 }
3142 }
3143 compute_down_safety (ei);
3144 compute_du_info (ei);
3145 compute_will_be_avail (ei);
3146
3147 if (dump_file && (dump_flags & TDF_DETAILS))
3148 {
3149 fprintf (dump_file, "EPHI's for expression ");
3150 print_generic_expr (dump_file, ei->expr, dump_flags);
3151 fprintf (dump_file,
3152 " after down safety and will_be_avail computation\n");
3153 FOR_EACH_BB (bb)
3154 {
3155 tree ephi = ephi_at_block (bb);
3156 if (ephi != NULL)
3157 {
3158 print_generic_expr (dump_file, ephi, 1);
3159 fprintf (dump_file, "\n");
3160 }
3161 }
3162 }
3163
3164 if (finalize_1 (ei))
3165 {
3166 finalize_2 (ei);
3167 code_motion (ei);
3168 if (ei->loadpre_cand)
3169 bitmap_set_bit (vars_to_rename, var_ann (ei->temp)->uid);
3170 }
3171
3172 clear_all_eref_arrays ();
3173 if (dump_file)
3174 if (dump_flags & TDF_STATS)
3175 {
3176 fprintf (dump_file, "PRE stats:\n");
3177 fprintf (dump_file, "Reloads:%d\n", pre_stats.reloads);
3178 fprintf (dump_file, "Saves:%d\n", pre_stats.saves);
3179 fprintf (dump_file, "Repairs:%d\n", pre_stats.repairs);
3180 fprintf (dump_file, "New phis:%d\n", pre_stats.newphis);
3181 fprintf (dump_file, "EPHI memory allocated:%d\n",
3182 pre_stats.ephi_allocated);
3183 fprintf (dump_file, "EREF memory allocated:%d\n",
3184 pre_stats.eref_allocated);
3185 fprintf (dump_file, "Expressions generated for rename2:%d\n",
3186 pre_stats.exprs_generated);
3187 }
3188 cleanup:
3189 free (phi_pred_cache);
3190 if (ephi_pindex_htab)
3191 {
3192 htab_delete (ephi_pindex_htab);
3193 ephi_pindex_htab = NULL;
3194 }
3195
3196
3197 return 0;
3198 }
3199
3200
3201 /* Step 1 - Collect the expressions to perform PRE on. */
3202
3203 static void
3204 collect_expressions (basic_block block, varray_type *bexprsp)
3205 {
3206 size_t k;
3207 block_stmt_iterator j;
3208 basic_block son;
3209
3210 varray_type bexprs = *bexprsp;
3211
3212 for (j = bsi_start (block); !bsi_end_p (j); bsi_next (&j))
3213 {
3214 tree stmt = bsi_stmt (j);
3215 tree expr = stmt;
3216 tree orig_expr = expr;
3217 stmt_ann_t ann;
3218 struct expr_info *slot = NULL;
3219
3220 get_stmt_operands (expr);
3221 ann = stmt_ann (expr);
3222
3223 if (NUM_USES (USE_OPS (ann)) == 0)
3224 {
3225 process_left_occs_and_kills (bexprs, expr);
3226 continue;
3227 }
3228
3229 if (TREE_CODE (expr) == MODIFY_EXPR)
3230 expr = TREE_OPERAND (expr, 1);
3231 if ((TREE_CODE_CLASS (TREE_CODE (expr)) == '2'
3232 || TREE_CODE_CLASS (TREE_CODE (expr)) == '<'
3233 /*|| TREE_CODE_CLASS (TREE_CODE (expr)) == '1'*/
3234 || TREE_CODE (expr) == SSA_NAME
3235 || TREE_CODE (expr) == INDIRECT_REF)
3236 && !ann->makes_aliased_stores
3237 && !ann->has_volatile_ops)
3238 {
3239 bool is_scalar = true;
3240 tree origop0 = TREE_OPERAND (orig_expr, 0);
3241
3242 if (AGGREGATE_TYPE_P (TREE_TYPE (origop0))
3243 || TREE_CODE (TREE_TYPE (origop0)) == COMPLEX_TYPE)
3244 is_scalar = false;
3245
3246 if (is_scalar
3247 && (TREE_CODE (expr) == SSA_NAME
3248 || (TREE_CODE (expr) == INDIRECT_REF
3249 && !DECL_P (TREE_OPERAND (expr, 0)))
3250 ||(!DECL_P (TREE_OPERAND (expr, 0))
3251 && (!TREE_OPERAND (expr, 1)
3252 || !DECL_P (TREE_OPERAND (expr, 1))))))
3253 {
3254 for (k = 0; k < VARRAY_ACTIVE_SIZE (bexprs); k++)
3255 {
3256 slot = VARRAY_GENERIC_PTR (bexprs, k);
3257 if (expr_lexically_eq (slot->expr, expr))
3258 break;
3259 }
3260 if (k >= VARRAY_ACTIVE_SIZE (bexprs))
3261 slot = NULL;
3262 if (slot)
3263 {
3264 VARRAY_PUSH_TREE (slot->occurs, orig_expr);
3265 VARRAY_PUSH_TREE (slot->kills, NULL);
3266 VARRAY_PUSH_TREE (slot->lefts, NULL);
3267 VARRAY_PUSH_TREE (slot->reals, stmt);
3268 slot->strred_cand &= is_strred_cand (orig_expr);
3269 }
3270 else
3271 {
3272 slot = ggc_alloc (sizeof (struct expr_info));
3273 slot->expr = expr;
3274 VARRAY_GENERIC_PTR_NOGC_INIT (slot->occurs, 1, "Occurrence");
3275 VARRAY_GENERIC_PTR_NOGC_INIT (slot->kills, 1, "Kills");
3276 VARRAY_GENERIC_PTR_NOGC_INIT (slot->lefts, 1, "Left occurrences");
3277 VARRAY_GENERIC_PTR_NOGC_INIT (slot->reals, 1, "Real occurrences");
3278 VARRAY_GENERIC_PTR_NOGC_INIT (slot->euses_dt_order, 1, "EUSEs");
3279
3280 VARRAY_PUSH_TREE (slot->occurs, orig_expr);
3281 VARRAY_PUSH_TREE (slot->kills, NULL);
3282 VARRAY_PUSH_TREE (slot->lefts, NULL);
3283 VARRAY_PUSH_TREE (slot->reals, stmt);
3284 VARRAY_PUSH_GENERIC_PTR (bexprs, slot);
3285 slot->strred_cand = is_strred_cand (orig_expr);
3286 slot->loadpre_cand = false;
3287 if (TREE_CODE (expr) == SSA_NAME
3288 || TREE_CODE (expr) == INDIRECT_REF)
3289 slot->loadpre_cand = true;
3290 }
3291 }
3292 }
3293 process_left_occs_and_kills (bexprs, orig_expr);
3294 }
3295 *bexprsp = bexprs;
3296
3297 for (son = first_dom_son (CDI_DOMINATORS, block);
3298 son;
3299 son = next_dom_son (CDI_DOMINATORS, son))
3300 collect_expressions (son, bexprsp);
3301 }
3302
3303 /* Main entry point to the SSA-PRE pass.
3304
3305 PHASE indicates which dump file from the DUMP_FILES array to use when
3306 dumping debugging information. */
3307
3308 static void
3309 execute_pre (void)
3310 {
3311 int currbbs;
3312 varray_type bexprs;
3313 size_t k;
3314 int i;
3315
3316 if (ENTRY_BLOCK_PTR->succ->dest->pred->pred_next)
3317 if (!(ENTRY_BLOCK_PTR->succ->flags & EDGE_ABNORMAL))
3318 split_edge (ENTRY_BLOCK_PTR->succ);
3319
3320 euse_node_pool = create_alloc_pool ("EUSE node pool",
3321 sizeof (struct tree_euse_node), 30);
3322 eref_node_pool = create_alloc_pool ("EREF node pool",
3323 sizeof (struct tree_eref_common), 30);
3324 ephi_use_pool = create_alloc_pool ("EPHI use node pool",
3325 sizeof (struct ephi_use_entry), 30);
3326 VARRAY_GENERIC_PTR_INIT (bexprs, 1, "bexprs");
3327 /* Compute immediate dominators. */
3328 calculate_dominance_info (CDI_DOMINATORS);
3329
3330 /* DCE screws the dom_children up, without bothering to fix it. So fix it. */
3331 currbbs = n_basic_blocks;
3332 dfn = xcalloc (last_basic_block + 1, sizeof (int));
3333 build_dfn_array (ENTRY_BLOCK_PTR, 0);
3334
3335 /* Initialize IDFS cache. */
3336 idfs_cache = xcalloc (currbbs, sizeof (bitmap));
3337
3338 /* Compute dominance frontiers. */
3339 pre_dfs = (bitmap *) xmalloc (sizeof (bitmap) * currbbs);
3340 for (i = 0; i < currbbs; i++)
3341 pre_dfs[i] = BITMAP_XMALLOC ();
3342 compute_dominance_frontiers (pre_dfs);
3343
3344 created_phi_preds = BITMAP_XMALLOC ();
3345
3346 collect_expressions (ENTRY_BLOCK_PTR, &bexprs);
3347
3348 ggc_push_context ();
3349
3350 for (k = 0; k < VARRAY_ACTIVE_SIZE (bexprs); k++)
3351 {
3352 pre_expression (VARRAY_GENERIC_PTR (bexprs, k), pre_dfs, vars_to_rename);
3353 free_alloc_pool (euse_node_pool);
3354 free_alloc_pool (eref_node_pool);
3355 free_alloc_pool (ephi_use_pool);
3356 euse_node_pool = create_alloc_pool ("EUSE node pool",
3357 sizeof (struct tree_euse_node), 30);
3358 eref_node_pool = create_alloc_pool ("EREF node pool",
3359 sizeof (struct tree_eref_common), 30);
3360 ephi_use_pool = create_alloc_pool ("EPHI use node pool",
3361 sizeof (struct ephi_use_entry), 30);
3362 free_expr_info (VARRAY_GENERIC_PTR (bexprs, k));
3363 #ifdef ENABLE_CHECKING
3364 if (pre_stats.ephis_current != 0)
3365 abort ();
3366 #endif
3367 ggc_collect ();
3368 }
3369
3370 ggc_pop_context ();
3371
3372 /* Clean up after PRE. */
3373 memset (&pre_stats, 0, sizeof (struct pre_stats_d));
3374 free_alloc_pool (euse_node_pool);
3375 free_alloc_pool (eref_node_pool);
3376 free_alloc_pool (ephi_use_pool);
3377 VARRAY_CLEAR (bexprs);
3378 for (i = 0; i < currbbs; i++)
3379 BITMAP_XFREE (pre_dfs[i]);
3380 free (pre_dfs);
3381 BITMAP_XFREE (created_phi_preds);
3382 for (i = 0; i < currbbs; i++)
3383 if (idfs_cache[i] != NULL)
3384 BITMAP_XFREE (idfs_cache[i]);
3385
3386 free (dfn);
3387 free (idfs_cache);
3388 }
3389
3390 static bool
3391 gate_pre (void)
3392 {
3393 return flag_tree_pre != 0;
3394 }
3395
3396 struct tree_opt_pass pass_pre =
3397 {
3398 "pre", /* name */
3399 gate_pre, /* gate */
3400 execute_pre, /* execute */
3401 NULL, /* sub */
3402 NULL, /* next */
3403 0, /* static_pass_number */
3404 TV_TREE_PRE, /* tv_id */
3405 PROP_no_crit_edges | PROP_cfg | PROP_ssa,/* properties_required */
3406 0, /* properties_provided */
3407 0, /* properties_destroyed */
3408 0, /* todo_flags_start */
3409 TODO_dump_func | TODO_rename_vars
3410 | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
3411 };
This page took 0.179565 seconds and 5 git commands to generate.