1e4b17023SJohn Marino /* SSA-PRE for trees.
2e4b17023SJohn Marino    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3e4b17023SJohn Marino    Free Software Foundation, Inc.
4e4b17023SJohn Marino    Contributed by Daniel Berlin <dan@dberlin.org> and Steven Bosscher
5e4b17023SJohn Marino    <stevenb@suse.de>
6e4b17023SJohn Marino 
7e4b17023SJohn Marino This file is part of GCC.
8e4b17023SJohn Marino 
9e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
10e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
11e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
12e4b17023SJohn Marino any later version.
13e4b17023SJohn Marino 
14e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
15e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
16e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17e4b17023SJohn Marino GNU General Public License for more details.
18e4b17023SJohn Marino 
19e4b17023SJohn Marino You should have received a copy of the GNU General Public License
20e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
21e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
22e4b17023SJohn Marino 
23e4b17023SJohn Marino #include "config.h"
24e4b17023SJohn Marino #include "system.h"
25e4b17023SJohn Marino #include "coretypes.h"
26e4b17023SJohn Marino #include "tm.h"
27e4b17023SJohn Marino #include "tree.h"
28e4b17023SJohn Marino #include "basic-block.h"
29e4b17023SJohn Marino #include "tree-pretty-print.h"
30e4b17023SJohn Marino #include "gimple-pretty-print.h"
31e4b17023SJohn Marino #include "tree-inline.h"
32e4b17023SJohn Marino #include "tree-flow.h"
33e4b17023SJohn Marino #include "gimple.h"
34e4b17023SJohn Marino #include "tree-dump.h"
35e4b17023SJohn Marino #include "timevar.h"
36e4b17023SJohn Marino #include "fibheap.h"
37e4b17023SJohn Marino #include "hashtab.h"
38e4b17023SJohn Marino #include "tree-iterator.h"
39e4b17023SJohn Marino #include "alloc-pool.h"
40e4b17023SJohn Marino #include "obstack.h"
41e4b17023SJohn Marino #include "tree-pass.h"
42e4b17023SJohn Marino #include "flags.h"
43e4b17023SJohn Marino #include "bitmap.h"
44e4b17023SJohn Marino #include "langhooks.h"
45e4b17023SJohn Marino #include "cfgloop.h"
46e4b17023SJohn Marino #include "tree-ssa-sccvn.h"
47e4b17023SJohn Marino #include "tree-scalar-evolution.h"
48e4b17023SJohn Marino #include "params.h"
49e4b17023SJohn Marino #include "dbgcnt.h"
50e4b17023SJohn Marino 
51e4b17023SJohn Marino /* TODO:
52e4b17023SJohn Marino 
53e4b17023SJohn Marino    1. Avail sets can be shared by making an avail_find_leader that
54e4b17023SJohn Marino       walks up the dominator tree and looks in those avail sets.
55e4b17023SJohn Marino       This might affect code optimality, it's unclear right now.
56e4b17023SJohn Marino    2. Strength reduction can be performed by anticipating expressions
57e4b17023SJohn Marino       we can repair later on.
58e4b17023SJohn Marino    3. We can do back-substitution or smarter value numbering to catch
59e4b17023SJohn Marino       commutative expressions split up over multiple statements.
60e4b17023SJohn Marino */
61e4b17023SJohn Marino 
62e4b17023SJohn Marino /* For ease of terminology, "expression node" in the below refers to
63e4b17023SJohn Marino    every expression node but GIMPLE_ASSIGN, because GIMPLE_ASSIGNs
64e4b17023SJohn Marino    represent the actual statement containing the expressions we care about,
65e4b17023SJohn Marino    and we cache the value number by putting it in the expression.  */
66e4b17023SJohn Marino 
67e4b17023SJohn Marino /* Basic algorithm
68e4b17023SJohn Marino 
69e4b17023SJohn Marino    First we walk the statements to generate the AVAIL sets, the
70e4b17023SJohn Marino    EXP_GEN sets, and the tmp_gen sets.  EXP_GEN sets represent the
71e4b17023SJohn Marino    generation of values/expressions by a given block.  We use them
72e4b17023SJohn Marino    when computing the ANTIC sets.  The AVAIL sets consist of
73e4b17023SJohn Marino    SSA_NAME's that represent values, so we know what values are
74e4b17023SJohn Marino    available in what blocks.  AVAIL is a forward dataflow problem.  In
75e4b17023SJohn Marino    SSA, values are never killed, so we don't need a kill set, or a
76e4b17023SJohn Marino    fixpoint iteration, in order to calculate the AVAIL sets.  In
77e4b17023SJohn Marino    traditional parlance, AVAIL sets tell us the downsafety of the
78e4b17023SJohn Marino    expressions/values.
79e4b17023SJohn Marino 
80e4b17023SJohn Marino    Next, we generate the ANTIC sets.  These sets represent the
81e4b17023SJohn Marino    anticipatable expressions.  ANTIC is a backwards dataflow
82e4b17023SJohn Marino    problem.  An expression is anticipatable in a given block if it could
83e4b17023SJohn Marino    be generated in that block.  This means that if we had to perform
84e4b17023SJohn Marino    an insertion in that block, of the value of that expression, we
85e4b17023SJohn Marino    could.  Calculating the ANTIC sets requires phi translation of
86e4b17023SJohn Marino    expressions, because the flow goes backwards through phis.  We must
87e4b17023SJohn Marino    iterate to a fixpoint of the ANTIC sets, because we have a kill
88e4b17023SJohn Marino    set.  Even in SSA form, values are not live over the entire
89e4b17023SJohn Marino    function, only from their definition point onwards.  So we have to
90e4b17023SJohn Marino    remove values from the ANTIC set once we go past the definition
91e4b17023SJohn Marino    point of the leaders that make them up.
92e4b17023SJohn Marino    compute_antic/compute_antic_aux performs this computation.
93e4b17023SJohn Marino 
94e4b17023SJohn Marino    Third, we perform insertions to make partially redundant
95e4b17023SJohn Marino    expressions fully redundant.
96e4b17023SJohn Marino 
97e4b17023SJohn Marino    An expression is partially redundant (excluding partial
98e4b17023SJohn Marino    anticipation) if:
99e4b17023SJohn Marino 
100e4b17023SJohn Marino    1. It is AVAIL in some, but not all, of the predecessors of a
101e4b17023SJohn Marino       given block.
102e4b17023SJohn Marino    2. It is ANTIC in all the predecessors.
103e4b17023SJohn Marino 
104e4b17023SJohn Marino    In order to make it fully redundant, we insert the expression into
105e4b17023SJohn Marino    the predecessors where it is not available, but is ANTIC.
106e4b17023SJohn Marino 
107e4b17023SJohn Marino    For the partial anticipation case, we only perform insertion if it
108e4b17023SJohn Marino    is partially anticipated in some block, and fully available in all
109e4b17023SJohn Marino    of the predecessors.
110e4b17023SJohn Marino 
111e4b17023SJohn Marino    insert/insert_aux/do_regular_insertion/do_partial_partial_insertion
112e4b17023SJohn Marino    performs these steps.
113e4b17023SJohn Marino 
114e4b17023SJohn Marino    Fourth, we eliminate fully redundant expressions.
115e4b17023SJohn Marino    This is a simple statement walk that replaces redundant
116e4b17023SJohn Marino    calculations with the now available values.  */
117e4b17023SJohn Marino 
118e4b17023SJohn Marino /* Representations of value numbers:
119e4b17023SJohn Marino 
120e4b17023SJohn Marino    Value numbers are represented by a representative SSA_NAME.  We
121e4b17023SJohn Marino    will create fake SSA_NAME's in situations where we need a
122e4b17023SJohn Marino    representative but do not have one (because it is a complex
123e4b17023SJohn Marino    expression).  In order to facilitate storing the value numbers in
124e4b17023SJohn Marino    bitmaps, and keep the number of wasted SSA_NAME's down, we also
125e4b17023SJohn Marino    associate a value_id with each value number, and create full blown
126e4b17023SJohn Marino    ssa_name's only where we actually need them (IE in operands of
127e4b17023SJohn Marino    existing expressions).
128e4b17023SJohn Marino 
129e4b17023SJohn Marino    Theoretically you could replace all the value_id's with
130e4b17023SJohn Marino    SSA_NAME_VERSION, but this would allocate a large number of
131e4b17023SJohn Marino    SSA_NAME's (which are each > 30 bytes) just to get a 4 byte number.
132e4b17023SJohn Marino    It would also require an additional indirection at each point we
133e4b17023SJohn Marino    use the value id.  */
134e4b17023SJohn Marino 
135e4b17023SJohn Marino /* Representation of expressions on value numbers:
136e4b17023SJohn Marino 
137e4b17023SJohn Marino    Expressions consisting of value numbers are represented the same
138e4b17023SJohn Marino    way as our VN internally represents them, with an additional
139e4b17023SJohn Marino    "pre_expr" wrapping around them in order to facilitate storing all
140e4b17023SJohn Marino    of the expressions in the same sets.  */
141e4b17023SJohn Marino 
142e4b17023SJohn Marino /* Representation of sets:
143e4b17023SJohn Marino 
144e4b17023SJohn Marino    The dataflow sets do not need to be sorted in any particular order
145e4b17023SJohn Marino    for the majority of their lifetime, are simply represented as two
146e4b17023SJohn Marino    bitmaps, one that keeps track of values present in the set, and one
147e4b17023SJohn Marino    that keeps track of expressions present in the set.
148e4b17023SJohn Marino 
149e4b17023SJohn Marino    When we need them in topological order, we produce it on demand by
150e4b17023SJohn Marino    transforming the bitmap into an array and sorting it into topo
151e4b17023SJohn Marino    order.  */
152e4b17023SJohn Marino 
153e4b17023SJohn Marino /* Type of expression, used to know which member of the PRE_EXPR union
154e4b17023SJohn Marino    is valid.  */
155e4b17023SJohn Marino 
156e4b17023SJohn Marino enum pre_expr_kind
157e4b17023SJohn Marino {
158e4b17023SJohn Marino     NAME,
159e4b17023SJohn Marino     NARY,
160e4b17023SJohn Marino     REFERENCE,
161e4b17023SJohn Marino     CONSTANT
162e4b17023SJohn Marino };
163e4b17023SJohn Marino 
164e4b17023SJohn Marino typedef union pre_expr_union_d
165e4b17023SJohn Marino {
166e4b17023SJohn Marino   tree name;
167e4b17023SJohn Marino   tree constant;
168e4b17023SJohn Marino   vn_nary_op_t nary;
169e4b17023SJohn Marino   vn_reference_t reference;
170e4b17023SJohn Marino } pre_expr_union;
171e4b17023SJohn Marino 
172e4b17023SJohn Marino typedef struct pre_expr_d
173e4b17023SJohn Marino {
174e4b17023SJohn Marino   enum pre_expr_kind kind;
175e4b17023SJohn Marino   unsigned int id;
176e4b17023SJohn Marino   pre_expr_union u;
177e4b17023SJohn Marino } *pre_expr;
178e4b17023SJohn Marino 
179e4b17023SJohn Marino #define PRE_EXPR_NAME(e) (e)->u.name
180e4b17023SJohn Marino #define PRE_EXPR_NARY(e) (e)->u.nary
181e4b17023SJohn Marino #define PRE_EXPR_REFERENCE(e) (e)->u.reference
182e4b17023SJohn Marino #define PRE_EXPR_CONSTANT(e) (e)->u.constant
183e4b17023SJohn Marino 
184e4b17023SJohn Marino static int
pre_expr_eq(const void * p1,const void * p2)185e4b17023SJohn Marino pre_expr_eq (const void *p1, const void *p2)
186e4b17023SJohn Marino {
187e4b17023SJohn Marino   const struct pre_expr_d *e1 = (const struct pre_expr_d *) p1;
188e4b17023SJohn Marino   const struct pre_expr_d *e2 = (const struct pre_expr_d *) p2;
189e4b17023SJohn Marino 
190e4b17023SJohn Marino   if (e1->kind != e2->kind)
191e4b17023SJohn Marino     return false;
192e4b17023SJohn Marino 
193e4b17023SJohn Marino   switch (e1->kind)
194e4b17023SJohn Marino     {
195e4b17023SJohn Marino     case CONSTANT:
196e4b17023SJohn Marino       return vn_constant_eq_with_type (PRE_EXPR_CONSTANT (e1),
197e4b17023SJohn Marino 				       PRE_EXPR_CONSTANT (e2));
198e4b17023SJohn Marino     case NAME:
199e4b17023SJohn Marino       return PRE_EXPR_NAME (e1) == PRE_EXPR_NAME (e2);
200e4b17023SJohn Marino     case NARY:
201e4b17023SJohn Marino       return vn_nary_op_eq (PRE_EXPR_NARY (e1), PRE_EXPR_NARY (e2));
202e4b17023SJohn Marino     case REFERENCE:
203e4b17023SJohn Marino       return vn_reference_eq (PRE_EXPR_REFERENCE (e1),
204e4b17023SJohn Marino 			      PRE_EXPR_REFERENCE (e2));
205e4b17023SJohn Marino     default:
206e4b17023SJohn Marino       gcc_unreachable ();
207e4b17023SJohn Marino     }
208e4b17023SJohn Marino }
209e4b17023SJohn Marino 
210e4b17023SJohn Marino static hashval_t
pre_expr_hash(const void * p1)211e4b17023SJohn Marino pre_expr_hash (const void *p1)
212e4b17023SJohn Marino {
213e4b17023SJohn Marino   const struct pre_expr_d *e = (const struct pre_expr_d *) p1;
214e4b17023SJohn Marino   switch (e->kind)
215e4b17023SJohn Marino     {
216e4b17023SJohn Marino     case CONSTANT:
217e4b17023SJohn Marino       return vn_hash_constant_with_type (PRE_EXPR_CONSTANT (e));
218e4b17023SJohn Marino     case NAME:
219e4b17023SJohn Marino       return SSA_NAME_VERSION (PRE_EXPR_NAME (e));
220e4b17023SJohn Marino     case NARY:
221e4b17023SJohn Marino       return PRE_EXPR_NARY (e)->hashcode;
222e4b17023SJohn Marino     case REFERENCE:
223e4b17023SJohn Marino       return PRE_EXPR_REFERENCE (e)->hashcode;
224e4b17023SJohn Marino     default:
225e4b17023SJohn Marino       gcc_unreachable ();
226e4b17023SJohn Marino     }
227e4b17023SJohn Marino }
228e4b17023SJohn Marino 
229e4b17023SJohn Marino 
230e4b17023SJohn Marino /* Next global expression id number.  */
231e4b17023SJohn Marino static unsigned int next_expression_id;
232e4b17023SJohn Marino 
233e4b17023SJohn Marino /* Mapping from expression to id number we can use in bitmap sets.  */
234e4b17023SJohn Marino DEF_VEC_P (pre_expr);
235e4b17023SJohn Marino DEF_VEC_ALLOC_P (pre_expr, heap);
236e4b17023SJohn Marino static VEC(pre_expr, heap) *expressions;
237e4b17023SJohn Marino static htab_t expression_to_id;
238e4b17023SJohn Marino static VEC(unsigned, heap) *name_to_id;
239e4b17023SJohn Marino 
240e4b17023SJohn Marino /* Allocate an expression id for EXPR.  */
241e4b17023SJohn Marino 
242e4b17023SJohn Marino static inline unsigned int
alloc_expression_id(pre_expr expr)243e4b17023SJohn Marino alloc_expression_id (pre_expr expr)
244e4b17023SJohn Marino {
245e4b17023SJohn Marino   void **slot;
246e4b17023SJohn Marino   /* Make sure we won't overflow. */
247e4b17023SJohn Marino   gcc_assert (next_expression_id + 1 > next_expression_id);
248e4b17023SJohn Marino   expr->id = next_expression_id++;
249e4b17023SJohn Marino   VEC_safe_push (pre_expr, heap, expressions, expr);
250e4b17023SJohn Marino   if (expr->kind == NAME)
251e4b17023SJohn Marino     {
252e4b17023SJohn Marino       unsigned version = SSA_NAME_VERSION (PRE_EXPR_NAME (expr));
253e4b17023SJohn Marino       /* VEC_safe_grow_cleared allocates no headroom.  Avoid frequent
254e4b17023SJohn Marino 	 re-allocations by using VEC_reserve upfront.  There is no
255e4b17023SJohn Marino 	 VEC_quick_grow_cleared unfortunately.  */
256e4b17023SJohn Marino       VEC_reserve (unsigned, heap, name_to_id, num_ssa_names);
257e4b17023SJohn Marino       VEC_safe_grow_cleared (unsigned, heap, name_to_id, num_ssa_names);
258e4b17023SJohn Marino       gcc_assert (VEC_index (unsigned, name_to_id, version) == 0);
259e4b17023SJohn Marino       VEC_replace (unsigned, name_to_id, version, expr->id);
260e4b17023SJohn Marino     }
261e4b17023SJohn Marino   else
262e4b17023SJohn Marino     {
263e4b17023SJohn Marino       slot = htab_find_slot (expression_to_id, expr, INSERT);
264e4b17023SJohn Marino       gcc_assert (!*slot);
265e4b17023SJohn Marino       *slot = expr;
266e4b17023SJohn Marino     }
267e4b17023SJohn Marino   return next_expression_id - 1;
268e4b17023SJohn Marino }
269e4b17023SJohn Marino 
270e4b17023SJohn Marino /* Return the expression id for tree EXPR.  */
271e4b17023SJohn Marino 
272e4b17023SJohn Marino static inline unsigned int
get_expression_id(const pre_expr expr)273e4b17023SJohn Marino get_expression_id (const pre_expr expr)
274e4b17023SJohn Marino {
275e4b17023SJohn Marino   return expr->id;
276e4b17023SJohn Marino }
277e4b17023SJohn Marino 
278e4b17023SJohn Marino static inline unsigned int
lookup_expression_id(const pre_expr expr)279e4b17023SJohn Marino lookup_expression_id (const pre_expr expr)
280e4b17023SJohn Marino {
281e4b17023SJohn Marino   void **slot;
282e4b17023SJohn Marino 
283e4b17023SJohn Marino   if (expr->kind == NAME)
284e4b17023SJohn Marino     {
285e4b17023SJohn Marino       unsigned version = SSA_NAME_VERSION (PRE_EXPR_NAME (expr));
286e4b17023SJohn Marino       if (VEC_length (unsigned, name_to_id) <= version)
287e4b17023SJohn Marino 	return 0;
288e4b17023SJohn Marino       return VEC_index (unsigned, name_to_id, version);
289e4b17023SJohn Marino     }
290e4b17023SJohn Marino   else
291e4b17023SJohn Marino     {
292e4b17023SJohn Marino       slot = htab_find_slot (expression_to_id, expr, NO_INSERT);
293e4b17023SJohn Marino       if (!slot)
294e4b17023SJohn Marino 	return 0;
295e4b17023SJohn Marino       return ((pre_expr)*slot)->id;
296e4b17023SJohn Marino     }
297e4b17023SJohn Marino }
298e4b17023SJohn Marino 
299e4b17023SJohn Marino /* Return the existing expression id for EXPR, or create one if one
300e4b17023SJohn Marino    does not exist yet.  */
301e4b17023SJohn Marino 
302e4b17023SJohn Marino static inline unsigned int
get_or_alloc_expression_id(pre_expr expr)303e4b17023SJohn Marino get_or_alloc_expression_id (pre_expr expr)
304e4b17023SJohn Marino {
305e4b17023SJohn Marino   unsigned int id = lookup_expression_id (expr);
306e4b17023SJohn Marino   if (id == 0)
307e4b17023SJohn Marino     return alloc_expression_id (expr);
308e4b17023SJohn Marino   return expr->id = id;
309e4b17023SJohn Marino }
310e4b17023SJohn Marino 
311e4b17023SJohn Marino /* Return the expression that has expression id ID */
312e4b17023SJohn Marino 
313e4b17023SJohn Marino static inline pre_expr
expression_for_id(unsigned int id)314e4b17023SJohn Marino expression_for_id (unsigned int id)
315e4b17023SJohn Marino {
316e4b17023SJohn Marino   return VEC_index (pre_expr, expressions, id);
317e4b17023SJohn Marino }
318e4b17023SJohn Marino 
319e4b17023SJohn Marino /* Free the expression id field in all of our expressions,
320e4b17023SJohn Marino    and then destroy the expressions array.  */
321e4b17023SJohn Marino 
322e4b17023SJohn Marino static void
clear_expression_ids(void)323e4b17023SJohn Marino clear_expression_ids (void)
324e4b17023SJohn Marino {
325e4b17023SJohn Marino   VEC_free (pre_expr, heap, expressions);
326e4b17023SJohn Marino }
327e4b17023SJohn Marino 
328e4b17023SJohn Marino static alloc_pool pre_expr_pool;
329e4b17023SJohn Marino 
330e4b17023SJohn Marino /* Given an SSA_NAME NAME, get or create a pre_expr to represent it.  */
331e4b17023SJohn Marino 
332e4b17023SJohn Marino static pre_expr
get_or_alloc_expr_for_name(tree name)333e4b17023SJohn Marino get_or_alloc_expr_for_name (tree name)
334e4b17023SJohn Marino {
335e4b17023SJohn Marino   struct pre_expr_d expr;
336e4b17023SJohn Marino   pre_expr result;
337e4b17023SJohn Marino   unsigned int result_id;
338e4b17023SJohn Marino 
339e4b17023SJohn Marino   expr.kind = NAME;
340e4b17023SJohn Marino   expr.id = 0;
341e4b17023SJohn Marino   PRE_EXPR_NAME (&expr) = name;
342e4b17023SJohn Marino   result_id = lookup_expression_id (&expr);
343e4b17023SJohn Marino   if (result_id != 0)
344e4b17023SJohn Marino     return expression_for_id (result_id);
345e4b17023SJohn Marino 
346e4b17023SJohn Marino   result = (pre_expr) pool_alloc (pre_expr_pool);
347e4b17023SJohn Marino   result->kind = NAME;
348e4b17023SJohn Marino   PRE_EXPR_NAME (result) = name;
349e4b17023SJohn Marino   alloc_expression_id (result);
350e4b17023SJohn Marino   return result;
351e4b17023SJohn Marino }
352e4b17023SJohn Marino 
353e4b17023SJohn Marino static bool in_fre = false;
354e4b17023SJohn Marino 
355e4b17023SJohn Marino /* An unordered bitmap set.  One bitmap tracks values, the other,
356e4b17023SJohn Marino    expressions.  */
357e4b17023SJohn Marino typedef struct bitmap_set
358e4b17023SJohn Marino {
359e4b17023SJohn Marino   bitmap_head expressions;
360e4b17023SJohn Marino   bitmap_head values;
361e4b17023SJohn Marino } *bitmap_set_t;
362e4b17023SJohn Marino 
363e4b17023SJohn Marino #define FOR_EACH_EXPR_ID_IN_SET(set, id, bi)		\
364e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP(&(set)->expressions, 0, (id), (bi))
365e4b17023SJohn Marino 
366e4b17023SJohn Marino #define FOR_EACH_VALUE_ID_IN_SET(set, id, bi)		\
367e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP(&(set)->values, 0, (id), (bi))
368e4b17023SJohn Marino 
369e4b17023SJohn Marino /* Mapping from value id to expressions with that value_id.  */
370e4b17023SJohn Marino DEF_VEC_P (bitmap_set_t);
371e4b17023SJohn Marino DEF_VEC_ALLOC_P (bitmap_set_t, heap);
VEC(bitmap_set_t,heap)372e4b17023SJohn Marino static VEC(bitmap_set_t, heap) *value_expressions;
373e4b17023SJohn Marino 
374e4b17023SJohn Marino /* Sets that we need to keep track of.  */
375e4b17023SJohn Marino typedef struct bb_bitmap_sets
376e4b17023SJohn Marino {
377e4b17023SJohn Marino   /* The EXP_GEN set, which represents expressions/values generated in
378e4b17023SJohn Marino      a basic block.  */
379e4b17023SJohn Marino   bitmap_set_t exp_gen;
380e4b17023SJohn Marino 
381e4b17023SJohn Marino   /* The PHI_GEN set, which represents PHI results generated in a
382e4b17023SJohn Marino      basic block.  */
383e4b17023SJohn Marino   bitmap_set_t phi_gen;
384e4b17023SJohn Marino 
385e4b17023SJohn Marino   /* The TMP_GEN set, which represents results/temporaries generated
386e4b17023SJohn Marino      in a basic block. IE the LHS of an expression.  */
387e4b17023SJohn Marino   bitmap_set_t tmp_gen;
388e4b17023SJohn Marino 
389e4b17023SJohn Marino   /* The AVAIL_OUT set, which represents which values are available in
390e4b17023SJohn Marino      a given basic block.  */
391e4b17023SJohn Marino   bitmap_set_t avail_out;
392e4b17023SJohn Marino 
393e4b17023SJohn Marino   /* The ANTIC_IN set, which represents which values are anticipatable
394e4b17023SJohn Marino      in a given basic block.  */
395e4b17023SJohn Marino   bitmap_set_t antic_in;
396e4b17023SJohn Marino 
397e4b17023SJohn Marino   /* The PA_IN set, which represents which values are
398e4b17023SJohn Marino      partially anticipatable in a given basic block.  */
399e4b17023SJohn Marino   bitmap_set_t pa_in;
400e4b17023SJohn Marino 
401e4b17023SJohn Marino   /* The NEW_SETS set, which is used during insertion to augment the
402e4b17023SJohn Marino      AVAIL_OUT set of blocks with the new insertions performed during
403e4b17023SJohn Marino      the current iteration.  */
404e4b17023SJohn Marino   bitmap_set_t new_sets;
405e4b17023SJohn Marino 
406e4b17023SJohn Marino   /* A cache for value_dies_in_block_x.  */
407e4b17023SJohn Marino   bitmap expr_dies;
408e4b17023SJohn Marino 
409e4b17023SJohn Marino   /* True if we have visited this block during ANTIC calculation.  */
410e4b17023SJohn Marino   unsigned int visited : 1;
411e4b17023SJohn Marino 
412e4b17023SJohn Marino   /* True we have deferred processing this block during ANTIC
413e4b17023SJohn Marino      calculation until its successor is processed.  */
414e4b17023SJohn Marino   unsigned int deferred : 1;
415e4b17023SJohn Marino 
416e4b17023SJohn Marino   /* True when the block contains a call that might not return.  */
417e4b17023SJohn Marino   unsigned int contains_may_not_return_call : 1;
418e4b17023SJohn Marino } *bb_value_sets_t;
419e4b17023SJohn Marino 
420e4b17023SJohn Marino #define EXP_GEN(BB)	((bb_value_sets_t) ((BB)->aux))->exp_gen
421e4b17023SJohn Marino #define PHI_GEN(BB)	((bb_value_sets_t) ((BB)->aux))->phi_gen
422e4b17023SJohn Marino #define TMP_GEN(BB)	((bb_value_sets_t) ((BB)->aux))->tmp_gen
423e4b17023SJohn Marino #define AVAIL_OUT(BB)	((bb_value_sets_t) ((BB)->aux))->avail_out
424e4b17023SJohn Marino #define ANTIC_IN(BB)	((bb_value_sets_t) ((BB)->aux))->antic_in
425e4b17023SJohn Marino #define PA_IN(BB)	((bb_value_sets_t) ((BB)->aux))->pa_in
426e4b17023SJohn Marino #define NEW_SETS(BB)	((bb_value_sets_t) ((BB)->aux))->new_sets
427e4b17023SJohn Marino #define EXPR_DIES(BB)	((bb_value_sets_t) ((BB)->aux))->expr_dies
428e4b17023SJohn Marino #define BB_VISITED(BB)	((bb_value_sets_t) ((BB)->aux))->visited
429e4b17023SJohn Marino #define BB_DEFERRED(BB) ((bb_value_sets_t) ((BB)->aux))->deferred
430e4b17023SJohn Marino #define BB_MAY_NOTRETURN(BB) ((bb_value_sets_t) ((BB)->aux))->contains_may_not_return_call
431e4b17023SJohn Marino 
432e4b17023SJohn Marino 
433e4b17023SJohn Marino /* Basic block list in postorder.  */
434e4b17023SJohn Marino static int *postorder;
435e4b17023SJohn Marino 
436e4b17023SJohn Marino /* This structure is used to keep track of statistics on what
437e4b17023SJohn Marino    optimization PRE was able to perform.  */
438e4b17023SJohn Marino static struct
439e4b17023SJohn Marino {
440e4b17023SJohn Marino   /* The number of RHS computations eliminated by PRE.  */
441e4b17023SJohn Marino   int eliminations;
442e4b17023SJohn Marino 
443e4b17023SJohn Marino   /* The number of new expressions/temporaries generated by PRE.  */
444e4b17023SJohn Marino   int insertions;
445e4b17023SJohn Marino 
446e4b17023SJohn Marino   /* The number of inserts found due to partial anticipation  */
447e4b17023SJohn Marino   int pa_insert;
448e4b17023SJohn Marino 
449e4b17023SJohn Marino   /* The number of new PHI nodes added by PRE.  */
450e4b17023SJohn Marino   int phis;
451e4b17023SJohn Marino } pre_stats;
452e4b17023SJohn Marino 
453e4b17023SJohn Marino static bool do_partial_partial;
454e4b17023SJohn Marino static pre_expr bitmap_find_leader (bitmap_set_t, unsigned int, gimple);
455e4b17023SJohn Marino static void bitmap_value_insert_into_set (bitmap_set_t, pre_expr);
456e4b17023SJohn Marino static void bitmap_value_replace_in_set (bitmap_set_t, pre_expr);
457e4b17023SJohn Marino static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
458e4b17023SJohn Marino static bool bitmap_set_contains_value (bitmap_set_t, unsigned int);
459e4b17023SJohn Marino static void bitmap_insert_into_set (bitmap_set_t, pre_expr);
460e4b17023SJohn Marino static void bitmap_insert_into_set_1 (bitmap_set_t, pre_expr,
461e4b17023SJohn Marino 				      unsigned int, bool);
462e4b17023SJohn Marino static bitmap_set_t bitmap_set_new (void);
463e4b17023SJohn Marino static tree create_expression_by_pieces (basic_block, pre_expr, gimple_seq *,
464e4b17023SJohn Marino 					 gimple, tree);
465e4b17023SJohn Marino static tree find_or_generate_expression (basic_block, pre_expr, gimple_seq *,
466e4b17023SJohn Marino 					 gimple);
467e4b17023SJohn Marino static unsigned int get_expr_value_id (pre_expr);
468e4b17023SJohn Marino 
469e4b17023SJohn Marino /* We can add and remove elements and entries to and from sets
470e4b17023SJohn Marino    and hash tables, so we use alloc pools for them.  */
471e4b17023SJohn Marino 
472e4b17023SJohn Marino static alloc_pool bitmap_set_pool;
473e4b17023SJohn Marino static bitmap_obstack grand_bitmap_obstack;
474e4b17023SJohn Marino 
475e4b17023SJohn Marino /* To avoid adding 300 temporary variables when we only need one, we
476e4b17023SJohn Marino    only create one temporary variable, on demand, and build ssa names
477e4b17023SJohn Marino    off that.  We do have to change the variable if the types don't
478e4b17023SJohn Marino    match the current variable's type.  */
479e4b17023SJohn Marino static tree pretemp;
480e4b17023SJohn Marino static tree storetemp;
481e4b17023SJohn Marino static tree prephitemp;
482e4b17023SJohn Marino 
483e4b17023SJohn Marino /* Set of blocks with statements that have had their EH properties changed.  */
484e4b17023SJohn Marino static bitmap need_eh_cleanup;
485e4b17023SJohn Marino 
486e4b17023SJohn Marino /* Set of blocks with statements that have had their AB properties changed.  */
487e4b17023SJohn Marino static bitmap need_ab_cleanup;
488e4b17023SJohn Marino 
489e4b17023SJohn Marino /* The phi_translate_table caches phi translations for a given
490e4b17023SJohn Marino    expression and predecessor.  */
491e4b17023SJohn Marino 
492e4b17023SJohn Marino static htab_t phi_translate_table;
493e4b17023SJohn Marino 
494e4b17023SJohn Marino /* A three tuple {e, pred, v} used to cache phi translations in the
495e4b17023SJohn Marino    phi_translate_table.  */
496e4b17023SJohn Marino 
497e4b17023SJohn Marino typedef struct expr_pred_trans_d
498e4b17023SJohn Marino {
499e4b17023SJohn Marino   /* The expression.  */
500e4b17023SJohn Marino   pre_expr e;
501e4b17023SJohn Marino 
502e4b17023SJohn Marino   /* The predecessor block along which we translated the expression.  */
503e4b17023SJohn Marino   basic_block pred;
504e4b17023SJohn Marino 
505e4b17023SJohn Marino   /* The value that resulted from the translation.  */
506e4b17023SJohn Marino   pre_expr v;
507e4b17023SJohn Marino 
508e4b17023SJohn Marino   /* The hashcode for the expression, pred pair. This is cached for
509e4b17023SJohn Marino      speed reasons.  */
510e4b17023SJohn Marino   hashval_t hashcode;
511e4b17023SJohn Marino } *expr_pred_trans_t;
512e4b17023SJohn Marino typedef const struct expr_pred_trans_d *const_expr_pred_trans_t;
513e4b17023SJohn Marino 
514e4b17023SJohn Marino /* Return the hash value for a phi translation table entry.  */
515e4b17023SJohn Marino 
516e4b17023SJohn Marino static hashval_t
expr_pred_trans_hash(const void * p)517e4b17023SJohn Marino expr_pred_trans_hash (const void *p)
518e4b17023SJohn Marino {
519e4b17023SJohn Marino   const_expr_pred_trans_t const ve = (const_expr_pred_trans_t) p;
520e4b17023SJohn Marino   return ve->hashcode;
521e4b17023SJohn Marino }
522e4b17023SJohn Marino 
523e4b17023SJohn Marino /* Return true if two phi translation table entries are the same.
524e4b17023SJohn Marino    P1 and P2 should point to the expr_pred_trans_t's to be compared.*/
525e4b17023SJohn Marino 
526e4b17023SJohn Marino static int
expr_pred_trans_eq(const void * p1,const void * p2)527e4b17023SJohn Marino expr_pred_trans_eq (const void *p1, const void *p2)
528e4b17023SJohn Marino {
529e4b17023SJohn Marino   const_expr_pred_trans_t const ve1 = (const_expr_pred_trans_t) p1;
530e4b17023SJohn Marino   const_expr_pred_trans_t const ve2 = (const_expr_pred_trans_t) p2;
531e4b17023SJohn Marino   basic_block b1 = ve1->pred;
532e4b17023SJohn Marino   basic_block b2 = ve2->pred;
533e4b17023SJohn Marino 
534e4b17023SJohn Marino   /* If they are not translations for the same basic block, they can't
535e4b17023SJohn Marino      be equal.  */
536e4b17023SJohn Marino   if (b1 != b2)
537e4b17023SJohn Marino     return false;
538e4b17023SJohn Marino   return pre_expr_eq (ve1->e, ve2->e);
539e4b17023SJohn Marino }
540e4b17023SJohn Marino 
541e4b17023SJohn Marino /* Search in the phi translation table for the translation of
542e4b17023SJohn Marino    expression E in basic block PRED.
543e4b17023SJohn Marino    Return the translated value, if found, NULL otherwise.  */
544e4b17023SJohn Marino 
545e4b17023SJohn Marino static inline pre_expr
phi_trans_lookup(pre_expr e,basic_block pred)546e4b17023SJohn Marino phi_trans_lookup (pre_expr e, basic_block pred)
547e4b17023SJohn Marino {
548e4b17023SJohn Marino   void **slot;
549e4b17023SJohn Marino   struct expr_pred_trans_d ept;
550e4b17023SJohn Marino 
551e4b17023SJohn Marino   ept.e = e;
552e4b17023SJohn Marino   ept.pred = pred;
553e4b17023SJohn Marino   ept.hashcode = iterative_hash_hashval_t (pre_expr_hash (e), pred->index);
554e4b17023SJohn Marino   slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
555e4b17023SJohn Marino 				   NO_INSERT);
556e4b17023SJohn Marino   if (!slot)
557e4b17023SJohn Marino     return NULL;
558e4b17023SJohn Marino   else
559e4b17023SJohn Marino     return ((expr_pred_trans_t) *slot)->v;
560e4b17023SJohn Marino }
561e4b17023SJohn Marino 
562e4b17023SJohn Marino 
563e4b17023SJohn Marino /* Add the tuple mapping from {expression E, basic block PRED} to
564e4b17023SJohn Marino    value V, to the phi translation table.  */
565e4b17023SJohn Marino 
566e4b17023SJohn Marino static inline void
phi_trans_add(pre_expr e,pre_expr v,basic_block pred)567e4b17023SJohn Marino phi_trans_add (pre_expr e, pre_expr v, basic_block pred)
568e4b17023SJohn Marino {
569e4b17023SJohn Marino   void **slot;
570e4b17023SJohn Marino   expr_pred_trans_t new_pair = XNEW (struct expr_pred_trans_d);
571e4b17023SJohn Marino   new_pair->e = e;
572e4b17023SJohn Marino   new_pair->pred = pred;
573e4b17023SJohn Marino   new_pair->v = v;
574e4b17023SJohn Marino   new_pair->hashcode = iterative_hash_hashval_t (pre_expr_hash (e),
575e4b17023SJohn Marino 						 pred->index);
576e4b17023SJohn Marino 
577e4b17023SJohn Marino   slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
578e4b17023SJohn Marino 				   new_pair->hashcode, INSERT);
579e4b17023SJohn Marino   free (*slot);
580e4b17023SJohn Marino   *slot = (void *) new_pair;
581e4b17023SJohn Marino }
582e4b17023SJohn Marino 
583e4b17023SJohn Marino 
584e4b17023SJohn Marino /* Add expression E to the expression set of value id V.  */
585e4b17023SJohn Marino 
586e4b17023SJohn Marino void
add_to_value(unsigned int v,pre_expr e)587e4b17023SJohn Marino add_to_value (unsigned int v, pre_expr e)
588e4b17023SJohn Marino {
589e4b17023SJohn Marino   bitmap_set_t set;
590e4b17023SJohn Marino 
591e4b17023SJohn Marino   gcc_assert (get_expr_value_id (e) == v);
592e4b17023SJohn Marino 
593e4b17023SJohn Marino   if (v >= VEC_length (bitmap_set_t, value_expressions))
594e4b17023SJohn Marino     {
595e4b17023SJohn Marino       VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
596e4b17023SJohn Marino 			     v + 1);
597e4b17023SJohn Marino     }
598e4b17023SJohn Marino 
599e4b17023SJohn Marino   set = VEC_index (bitmap_set_t, value_expressions, v);
600e4b17023SJohn Marino   if (!set)
601e4b17023SJohn Marino     {
602e4b17023SJohn Marino       set = bitmap_set_new ();
603e4b17023SJohn Marino       VEC_replace (bitmap_set_t, value_expressions, v, set);
604e4b17023SJohn Marino     }
605e4b17023SJohn Marino 
606e4b17023SJohn Marino   bitmap_insert_into_set_1 (set, e, v, true);
607e4b17023SJohn Marino }
608e4b17023SJohn Marino 
609e4b17023SJohn Marino /* Create a new bitmap set and return it.  */
610e4b17023SJohn Marino 
611e4b17023SJohn Marino static bitmap_set_t
bitmap_set_new(void)612e4b17023SJohn Marino bitmap_set_new (void)
613e4b17023SJohn Marino {
614e4b17023SJohn Marino   bitmap_set_t ret = (bitmap_set_t) pool_alloc (bitmap_set_pool);
615e4b17023SJohn Marino   bitmap_initialize (&ret->expressions, &grand_bitmap_obstack);
616e4b17023SJohn Marino   bitmap_initialize (&ret->values, &grand_bitmap_obstack);
617e4b17023SJohn Marino   return ret;
618e4b17023SJohn Marino }
619e4b17023SJohn Marino 
620e4b17023SJohn Marino /* Return the value id for a PRE expression EXPR.  */
621e4b17023SJohn Marino 
622e4b17023SJohn Marino static unsigned int
get_expr_value_id(pre_expr expr)623e4b17023SJohn Marino get_expr_value_id (pre_expr expr)
624e4b17023SJohn Marino {
625e4b17023SJohn Marino   switch (expr->kind)
626e4b17023SJohn Marino     {
627e4b17023SJohn Marino     case CONSTANT:
628e4b17023SJohn Marino       {
629e4b17023SJohn Marino 	unsigned int id;
630e4b17023SJohn Marino 	id = get_constant_value_id (PRE_EXPR_CONSTANT (expr));
631e4b17023SJohn Marino 	if (id == 0)
632e4b17023SJohn Marino 	  {
633e4b17023SJohn Marino 	    id = get_or_alloc_constant_value_id (PRE_EXPR_CONSTANT (expr));
634e4b17023SJohn Marino 	    add_to_value (id, expr);
635e4b17023SJohn Marino 	  }
636e4b17023SJohn Marino 	return id;
637e4b17023SJohn Marino       }
638e4b17023SJohn Marino     case NAME:
639e4b17023SJohn Marino       return VN_INFO (PRE_EXPR_NAME (expr))->value_id;
640e4b17023SJohn Marino     case NARY:
641e4b17023SJohn Marino       return PRE_EXPR_NARY (expr)->value_id;
642e4b17023SJohn Marino     case REFERENCE:
643e4b17023SJohn Marino       return PRE_EXPR_REFERENCE (expr)->value_id;
644e4b17023SJohn Marino     default:
645e4b17023SJohn Marino       gcc_unreachable ();
646e4b17023SJohn Marino     }
647e4b17023SJohn Marino }
648e4b17023SJohn Marino 
649e4b17023SJohn Marino /* Remove an expression EXPR from a bitmapped set.  */
650e4b17023SJohn Marino 
651e4b17023SJohn Marino static void
bitmap_remove_from_set(bitmap_set_t set,pre_expr expr)652e4b17023SJohn Marino bitmap_remove_from_set (bitmap_set_t set, pre_expr expr)
653e4b17023SJohn Marino {
654e4b17023SJohn Marino   unsigned int val  = get_expr_value_id (expr);
655e4b17023SJohn Marino   if (!value_id_constant_p (val))
656e4b17023SJohn Marino     {
657e4b17023SJohn Marino       bitmap_clear_bit (&set->values, val);
658e4b17023SJohn Marino       bitmap_clear_bit (&set->expressions, get_expression_id (expr));
659e4b17023SJohn Marino     }
660e4b17023SJohn Marino }
661e4b17023SJohn Marino 
662e4b17023SJohn Marino static void
bitmap_insert_into_set_1(bitmap_set_t set,pre_expr expr,unsigned int val,bool allow_constants)663e4b17023SJohn Marino bitmap_insert_into_set_1 (bitmap_set_t set, pre_expr expr,
664e4b17023SJohn Marino 			  unsigned int val, bool allow_constants)
665e4b17023SJohn Marino {
666e4b17023SJohn Marino   if (allow_constants || !value_id_constant_p (val))
667e4b17023SJohn Marino     {
668e4b17023SJohn Marino       /* We specifically expect this and only this function to be able to
669e4b17023SJohn Marino 	 insert constants into a set.  */
670e4b17023SJohn Marino       bitmap_set_bit (&set->values, val);
671e4b17023SJohn Marino       bitmap_set_bit (&set->expressions, get_or_alloc_expression_id (expr));
672e4b17023SJohn Marino     }
673e4b17023SJohn Marino }
674e4b17023SJohn Marino 
675e4b17023SJohn Marino /* Insert an expression EXPR into a bitmapped set.  */
676e4b17023SJohn Marino 
677e4b17023SJohn Marino static void
bitmap_insert_into_set(bitmap_set_t set,pre_expr expr)678e4b17023SJohn Marino bitmap_insert_into_set (bitmap_set_t set, pre_expr expr)
679e4b17023SJohn Marino {
680e4b17023SJohn Marino   bitmap_insert_into_set_1 (set, expr, get_expr_value_id (expr), false);
681e4b17023SJohn Marino }
682e4b17023SJohn Marino 
683e4b17023SJohn Marino /* Copy a bitmapped set ORIG, into bitmapped set DEST.  */
684e4b17023SJohn Marino 
685e4b17023SJohn Marino static void
bitmap_set_copy(bitmap_set_t dest,bitmap_set_t orig)686e4b17023SJohn Marino bitmap_set_copy (bitmap_set_t dest, bitmap_set_t orig)
687e4b17023SJohn Marino {
688e4b17023SJohn Marino   bitmap_copy (&dest->expressions, &orig->expressions);
689e4b17023SJohn Marino   bitmap_copy (&dest->values, &orig->values);
690e4b17023SJohn Marino }
691e4b17023SJohn Marino 
692e4b17023SJohn Marino 
693e4b17023SJohn Marino /* Free memory used up by SET.  */
694e4b17023SJohn Marino static void
bitmap_set_free(bitmap_set_t set)695e4b17023SJohn Marino bitmap_set_free (bitmap_set_t set)
696e4b17023SJohn Marino {
697e4b17023SJohn Marino   bitmap_clear (&set->expressions);
698e4b17023SJohn Marino   bitmap_clear (&set->values);
699e4b17023SJohn Marino }
700e4b17023SJohn Marino 
701e4b17023SJohn Marino 
702e4b17023SJohn Marino /* Generate an topological-ordered array of bitmap set SET.  */
703e4b17023SJohn Marino 
VEC(pre_expr,heap)704e4b17023SJohn Marino static VEC(pre_expr, heap) *
705e4b17023SJohn Marino sorted_array_from_bitmap_set (bitmap_set_t set)
706e4b17023SJohn Marino {
707e4b17023SJohn Marino   unsigned int i, j;
708e4b17023SJohn Marino   bitmap_iterator bi, bj;
709e4b17023SJohn Marino   VEC(pre_expr, heap) *result;
710e4b17023SJohn Marino 
711e4b17023SJohn Marino   /* Pre-allocate roughly enough space for the array.  */
712e4b17023SJohn Marino   result = VEC_alloc (pre_expr, heap, bitmap_count_bits (&set->values));
713e4b17023SJohn Marino 
714e4b17023SJohn Marino   FOR_EACH_VALUE_ID_IN_SET (set, i, bi)
715e4b17023SJohn Marino     {
716e4b17023SJohn Marino       /* The number of expressions having a given value is usually
717e4b17023SJohn Marino 	 relatively small.  Thus, rather than making a vector of all
718e4b17023SJohn Marino 	 the expressions and sorting it by value-id, we walk the values
719e4b17023SJohn Marino 	 and check in the reverse mapping that tells us what expressions
720e4b17023SJohn Marino 	 have a given value, to filter those in our set.  As a result,
721e4b17023SJohn Marino 	 the expressions are inserted in value-id order, which means
722e4b17023SJohn Marino 	 topological order.
723e4b17023SJohn Marino 
724e4b17023SJohn Marino 	 If this is somehow a significant lose for some cases, we can
725e4b17023SJohn Marino 	 choose which set to walk based on the set size.  */
726e4b17023SJohn Marino       bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, i);
727e4b17023SJohn Marino       FOR_EACH_EXPR_ID_IN_SET (exprset, j, bj)
728e4b17023SJohn Marino 	{
729e4b17023SJohn Marino 	  if (bitmap_bit_p (&set->expressions, j))
730e4b17023SJohn Marino 	    VEC_safe_push (pre_expr, heap, result, expression_for_id (j));
731e4b17023SJohn Marino         }
732e4b17023SJohn Marino     }
733e4b17023SJohn Marino 
734e4b17023SJohn Marino   return result;
735e4b17023SJohn Marino }
736e4b17023SJohn Marino 
737e4b17023SJohn Marino /* Perform bitmapped set operation DEST &= ORIG.  */
738e4b17023SJohn Marino 
739e4b17023SJohn Marino static void
bitmap_set_and(bitmap_set_t dest,bitmap_set_t orig)740e4b17023SJohn Marino bitmap_set_and (bitmap_set_t dest, bitmap_set_t orig)
741e4b17023SJohn Marino {
742e4b17023SJohn Marino   bitmap_iterator bi;
743e4b17023SJohn Marino   unsigned int i;
744e4b17023SJohn Marino 
745e4b17023SJohn Marino   if (dest != orig)
746e4b17023SJohn Marino     {
747e4b17023SJohn Marino       bitmap_head temp;
748e4b17023SJohn Marino       bitmap_initialize (&temp, &grand_bitmap_obstack);
749e4b17023SJohn Marino 
750e4b17023SJohn Marino       bitmap_and_into (&dest->values, &orig->values);
751e4b17023SJohn Marino       bitmap_copy (&temp, &dest->expressions);
752e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (&temp, 0, i, bi)
753e4b17023SJohn Marino 	{
754e4b17023SJohn Marino 	  pre_expr expr = expression_for_id (i);
755e4b17023SJohn Marino 	  unsigned int value_id = get_expr_value_id (expr);
756e4b17023SJohn Marino 	  if (!bitmap_bit_p (&dest->values, value_id))
757e4b17023SJohn Marino 	    bitmap_clear_bit (&dest->expressions, i);
758e4b17023SJohn Marino 	}
759e4b17023SJohn Marino       bitmap_clear (&temp);
760e4b17023SJohn Marino     }
761e4b17023SJohn Marino }
762e4b17023SJohn Marino 
763e4b17023SJohn Marino /* Subtract all values and expressions contained in ORIG from DEST.  */
764e4b17023SJohn Marino 
765e4b17023SJohn Marino static bitmap_set_t
bitmap_set_subtract(bitmap_set_t dest,bitmap_set_t orig)766e4b17023SJohn Marino bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig)
767e4b17023SJohn Marino {
768e4b17023SJohn Marino   bitmap_set_t result = bitmap_set_new ();
769e4b17023SJohn Marino   bitmap_iterator bi;
770e4b17023SJohn Marino   unsigned int i;
771e4b17023SJohn Marino 
772e4b17023SJohn Marino   bitmap_and_compl (&result->expressions, &dest->expressions,
773e4b17023SJohn Marino 		    &orig->expressions);
774e4b17023SJohn Marino 
775e4b17023SJohn Marino   FOR_EACH_EXPR_ID_IN_SET (result, i, bi)
776e4b17023SJohn Marino     {
777e4b17023SJohn Marino       pre_expr expr = expression_for_id (i);
778e4b17023SJohn Marino       unsigned int value_id = get_expr_value_id (expr);
779e4b17023SJohn Marino       bitmap_set_bit (&result->values, value_id);
780e4b17023SJohn Marino     }
781e4b17023SJohn Marino 
782e4b17023SJohn Marino   return result;
783e4b17023SJohn Marino }
784e4b17023SJohn Marino 
785e4b17023SJohn Marino /* Subtract all the values in bitmap set B from bitmap set A.  */
786e4b17023SJohn Marino 
787e4b17023SJohn Marino static void
bitmap_set_subtract_values(bitmap_set_t a,bitmap_set_t b)788e4b17023SJohn Marino bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b)
789e4b17023SJohn Marino {
790e4b17023SJohn Marino   unsigned int i;
791e4b17023SJohn Marino   bitmap_iterator bi;
792e4b17023SJohn Marino   bitmap_head temp;
793e4b17023SJohn Marino 
794e4b17023SJohn Marino   bitmap_initialize (&temp, &grand_bitmap_obstack);
795e4b17023SJohn Marino 
796e4b17023SJohn Marino   bitmap_copy (&temp, &a->expressions);
797e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (&temp, 0, i, bi)
798e4b17023SJohn Marino     {
799e4b17023SJohn Marino       pre_expr expr = expression_for_id (i);
800e4b17023SJohn Marino       if (bitmap_set_contains_value (b, get_expr_value_id (expr)))
801e4b17023SJohn Marino 	bitmap_remove_from_set (a, expr);
802e4b17023SJohn Marino     }
803e4b17023SJohn Marino   bitmap_clear (&temp);
804e4b17023SJohn Marino }
805e4b17023SJohn Marino 
806e4b17023SJohn Marino 
807e4b17023SJohn Marino /* Return true if bitmapped set SET contains the value VALUE_ID.  */
808e4b17023SJohn Marino 
809e4b17023SJohn Marino static bool
bitmap_set_contains_value(bitmap_set_t set,unsigned int value_id)810e4b17023SJohn Marino bitmap_set_contains_value (bitmap_set_t set, unsigned int value_id)
811e4b17023SJohn Marino {
812e4b17023SJohn Marino   if (value_id_constant_p (value_id))
813e4b17023SJohn Marino     return true;
814e4b17023SJohn Marino 
815e4b17023SJohn Marino   if (!set || bitmap_empty_p (&set->expressions))
816e4b17023SJohn Marino     return false;
817e4b17023SJohn Marino 
818e4b17023SJohn Marino   return bitmap_bit_p (&set->values, value_id);
819e4b17023SJohn Marino }
820e4b17023SJohn Marino 
821e4b17023SJohn Marino static inline bool
bitmap_set_contains_expr(bitmap_set_t set,const pre_expr expr)822e4b17023SJohn Marino bitmap_set_contains_expr (bitmap_set_t set, const pre_expr expr)
823e4b17023SJohn Marino {
824e4b17023SJohn Marino   return bitmap_bit_p (&set->expressions, get_expression_id (expr));
825e4b17023SJohn Marino }
826e4b17023SJohn Marino 
827e4b17023SJohn Marino /* Replace an instance of value LOOKFOR with expression EXPR in SET.  */
828e4b17023SJohn Marino 
829e4b17023SJohn Marino static void
bitmap_set_replace_value(bitmap_set_t set,unsigned int lookfor,const pre_expr expr)830e4b17023SJohn Marino bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
831e4b17023SJohn Marino 			  const pre_expr expr)
832e4b17023SJohn Marino {
833e4b17023SJohn Marino   bitmap_set_t exprset;
834e4b17023SJohn Marino   unsigned int i;
835e4b17023SJohn Marino   bitmap_iterator bi;
836e4b17023SJohn Marino 
837e4b17023SJohn Marino   if (value_id_constant_p (lookfor))
838e4b17023SJohn Marino     return;
839e4b17023SJohn Marino 
840e4b17023SJohn Marino   if (!bitmap_set_contains_value (set, lookfor))
841e4b17023SJohn Marino     return;
842e4b17023SJohn Marino 
843e4b17023SJohn Marino   /* The number of expressions having a given value is usually
844e4b17023SJohn Marino      significantly less than the total number of expressions in SET.
845e4b17023SJohn Marino      Thus, rather than check, for each expression in SET, whether it
846e4b17023SJohn Marino      has the value LOOKFOR, we walk the reverse mapping that tells us
847e4b17023SJohn Marino      what expressions have a given value, and see if any of those
848e4b17023SJohn Marino      expressions are in our set.  For large testcases, this is about
849e4b17023SJohn Marino      5-10x faster than walking the bitmap.  If this is somehow a
850e4b17023SJohn Marino      significant lose for some cases, we can choose which set to walk
851e4b17023SJohn Marino      based on the set size.  */
852e4b17023SJohn Marino   exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
853e4b17023SJohn Marino   FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
854e4b17023SJohn Marino     {
855e4b17023SJohn Marino       if (bitmap_clear_bit (&set->expressions, i))
856e4b17023SJohn Marino 	{
857e4b17023SJohn Marino 	  bitmap_set_bit (&set->expressions, get_expression_id (expr));
858e4b17023SJohn Marino 	  return;
859e4b17023SJohn Marino 	}
860e4b17023SJohn Marino     }
8615ce9237cSJohn Marino 
8625ce9237cSJohn Marino   gcc_unreachable ();
863e4b17023SJohn Marino }
864e4b17023SJohn Marino 
865e4b17023SJohn Marino /* Return true if two bitmap sets are equal.  */
866e4b17023SJohn Marino 
867e4b17023SJohn Marino static bool
bitmap_set_equal(bitmap_set_t a,bitmap_set_t b)868e4b17023SJohn Marino bitmap_set_equal (bitmap_set_t a, bitmap_set_t b)
869e4b17023SJohn Marino {
870e4b17023SJohn Marino   return bitmap_equal_p (&a->values, &b->values);
871e4b17023SJohn Marino }
872e4b17023SJohn Marino 
873e4b17023SJohn Marino /* Replace an instance of EXPR's VALUE with EXPR in SET if it exists,
874e4b17023SJohn Marino    and add it otherwise.  */
875e4b17023SJohn Marino 
876e4b17023SJohn Marino static void
bitmap_value_replace_in_set(bitmap_set_t set,pre_expr expr)877e4b17023SJohn Marino bitmap_value_replace_in_set (bitmap_set_t set, pre_expr expr)
878e4b17023SJohn Marino {
879e4b17023SJohn Marino   unsigned int val = get_expr_value_id (expr);
880e4b17023SJohn Marino 
881e4b17023SJohn Marino   if (bitmap_set_contains_value (set, val))
882e4b17023SJohn Marino     bitmap_set_replace_value (set, val, expr);
883e4b17023SJohn Marino   else
884e4b17023SJohn Marino     bitmap_insert_into_set (set, expr);
885e4b17023SJohn Marino }
886e4b17023SJohn Marino 
887e4b17023SJohn Marino /* Insert EXPR into SET if EXPR's value is not already present in
888e4b17023SJohn Marino    SET.  */
889e4b17023SJohn Marino 
890e4b17023SJohn Marino static void
bitmap_value_insert_into_set(bitmap_set_t set,pre_expr expr)891e4b17023SJohn Marino bitmap_value_insert_into_set (bitmap_set_t set, pre_expr expr)
892e4b17023SJohn Marino {
893e4b17023SJohn Marino   unsigned int val = get_expr_value_id (expr);
894e4b17023SJohn Marino 
895e4b17023SJohn Marino   gcc_checking_assert (expr->id == get_or_alloc_expression_id (expr));
896e4b17023SJohn Marino 
897e4b17023SJohn Marino   /* Constant values are always considered to be part of the set.  */
898e4b17023SJohn Marino   if (value_id_constant_p (val))
899e4b17023SJohn Marino     return;
900e4b17023SJohn Marino 
901e4b17023SJohn Marino   /* If the value membership changed, add the expression.  */
902e4b17023SJohn Marino   if (bitmap_set_bit (&set->values, val))
903e4b17023SJohn Marino     bitmap_set_bit (&set->expressions, expr->id);
904e4b17023SJohn Marino }
905e4b17023SJohn Marino 
906e4b17023SJohn Marino /* Print out EXPR to outfile.  */
907e4b17023SJohn Marino 
908e4b17023SJohn Marino static void
print_pre_expr(FILE * outfile,const pre_expr expr)909e4b17023SJohn Marino print_pre_expr (FILE *outfile, const pre_expr expr)
910e4b17023SJohn Marino {
911e4b17023SJohn Marino   switch (expr->kind)
912e4b17023SJohn Marino     {
913e4b17023SJohn Marino     case CONSTANT:
914e4b17023SJohn Marino       print_generic_expr (outfile, PRE_EXPR_CONSTANT (expr), 0);
915e4b17023SJohn Marino       break;
916e4b17023SJohn Marino     case NAME:
917e4b17023SJohn Marino       print_generic_expr (outfile, PRE_EXPR_NAME (expr), 0);
918e4b17023SJohn Marino       break;
919e4b17023SJohn Marino     case NARY:
920e4b17023SJohn Marino       {
921e4b17023SJohn Marino 	unsigned int i;
922e4b17023SJohn Marino 	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
923e4b17023SJohn Marino 	fprintf (outfile, "{%s,", tree_code_name [nary->opcode]);
924e4b17023SJohn Marino 	for (i = 0; i < nary->length; i++)
925e4b17023SJohn Marino 	  {
926e4b17023SJohn Marino 	    print_generic_expr (outfile, nary->op[i], 0);
927e4b17023SJohn Marino 	    if (i != (unsigned) nary->length - 1)
928e4b17023SJohn Marino 	      fprintf (outfile, ",");
929e4b17023SJohn Marino 	  }
930e4b17023SJohn Marino 	fprintf (outfile, "}");
931e4b17023SJohn Marino       }
932e4b17023SJohn Marino       break;
933e4b17023SJohn Marino 
934e4b17023SJohn Marino     case REFERENCE:
935e4b17023SJohn Marino       {
936e4b17023SJohn Marino 	vn_reference_op_t vro;
937e4b17023SJohn Marino 	unsigned int i;
938e4b17023SJohn Marino 	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
939e4b17023SJohn Marino 	fprintf (outfile, "{");
940e4b17023SJohn Marino 	for (i = 0;
941e4b17023SJohn Marino 	     VEC_iterate (vn_reference_op_s, ref->operands, i, vro);
942e4b17023SJohn Marino 	     i++)
943e4b17023SJohn Marino 	  {
944e4b17023SJohn Marino 	    bool closebrace = false;
945e4b17023SJohn Marino 	    if (vro->opcode != SSA_NAME
946e4b17023SJohn Marino 		&& TREE_CODE_CLASS (vro->opcode) != tcc_declaration)
947e4b17023SJohn Marino 	      {
948e4b17023SJohn Marino 		fprintf (outfile, "%s", tree_code_name [vro->opcode]);
949e4b17023SJohn Marino 		if (vro->op0)
950e4b17023SJohn Marino 		  {
951e4b17023SJohn Marino 		    fprintf (outfile, "<");
952e4b17023SJohn Marino 		    closebrace = true;
953e4b17023SJohn Marino 		  }
954e4b17023SJohn Marino 	      }
955e4b17023SJohn Marino 	    if (vro->op0)
956e4b17023SJohn Marino 	      {
957e4b17023SJohn Marino 		print_generic_expr (outfile, vro->op0, 0);
958e4b17023SJohn Marino 		if (vro->op1)
959e4b17023SJohn Marino 		  {
960e4b17023SJohn Marino 		    fprintf (outfile, ",");
961e4b17023SJohn Marino 		    print_generic_expr (outfile, vro->op1, 0);
962e4b17023SJohn Marino 		  }
963e4b17023SJohn Marino 		if (vro->op2)
964e4b17023SJohn Marino 		  {
965e4b17023SJohn Marino 		    fprintf (outfile, ",");
966e4b17023SJohn Marino 		    print_generic_expr (outfile, vro->op2, 0);
967e4b17023SJohn Marino 		  }
968e4b17023SJohn Marino 	      }
969e4b17023SJohn Marino 	    if (closebrace)
970e4b17023SJohn Marino 		fprintf (outfile, ">");
971e4b17023SJohn Marino 	    if (i != VEC_length (vn_reference_op_s, ref->operands) - 1)
972e4b17023SJohn Marino 	      fprintf (outfile, ",");
973e4b17023SJohn Marino 	  }
974e4b17023SJohn Marino 	fprintf (outfile, "}");
975e4b17023SJohn Marino 	if (ref->vuse)
976e4b17023SJohn Marino 	  {
977e4b17023SJohn Marino 	    fprintf (outfile, "@");
978e4b17023SJohn Marino 	    print_generic_expr (outfile, ref->vuse, 0);
979e4b17023SJohn Marino 	  }
980e4b17023SJohn Marino       }
981e4b17023SJohn Marino       break;
982e4b17023SJohn Marino     }
983e4b17023SJohn Marino }
984e4b17023SJohn Marino void debug_pre_expr (pre_expr);
985e4b17023SJohn Marino 
986e4b17023SJohn Marino /* Like print_pre_expr but always prints to stderr.  */
987e4b17023SJohn Marino DEBUG_FUNCTION void
debug_pre_expr(pre_expr e)988e4b17023SJohn Marino debug_pre_expr (pre_expr e)
989e4b17023SJohn Marino {
990e4b17023SJohn Marino   print_pre_expr (stderr, e);
991e4b17023SJohn Marino   fprintf (stderr, "\n");
992e4b17023SJohn Marino }
993e4b17023SJohn Marino 
994e4b17023SJohn Marino /* Print out SET to OUTFILE.  */
995e4b17023SJohn Marino 
996e4b17023SJohn Marino static void
print_bitmap_set(FILE * outfile,bitmap_set_t set,const char * setname,int blockindex)997e4b17023SJohn Marino print_bitmap_set (FILE *outfile, bitmap_set_t set,
998e4b17023SJohn Marino 		  const char *setname, int blockindex)
999e4b17023SJohn Marino {
1000e4b17023SJohn Marino   fprintf (outfile, "%s[%d] := { ", setname, blockindex);
1001e4b17023SJohn Marino   if (set)
1002e4b17023SJohn Marino     {
1003e4b17023SJohn Marino       bool first = true;
1004e4b17023SJohn Marino       unsigned i;
1005e4b17023SJohn Marino       bitmap_iterator bi;
1006e4b17023SJohn Marino 
1007e4b17023SJohn Marino       FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
1008e4b17023SJohn Marino 	{
1009e4b17023SJohn Marino 	  const pre_expr expr = expression_for_id (i);
1010e4b17023SJohn Marino 
1011e4b17023SJohn Marino 	  if (!first)
1012e4b17023SJohn Marino 	    fprintf (outfile, ", ");
1013e4b17023SJohn Marino 	  first = false;
1014e4b17023SJohn Marino 	  print_pre_expr (outfile, expr);
1015e4b17023SJohn Marino 
1016e4b17023SJohn Marino 	  fprintf (outfile, " (%04d)", get_expr_value_id (expr));
1017e4b17023SJohn Marino 	}
1018e4b17023SJohn Marino     }
1019e4b17023SJohn Marino   fprintf (outfile, " }\n");
1020e4b17023SJohn Marino }
1021e4b17023SJohn Marino 
1022e4b17023SJohn Marino void debug_bitmap_set (bitmap_set_t);
1023e4b17023SJohn Marino 
1024e4b17023SJohn Marino DEBUG_FUNCTION void
debug_bitmap_set(bitmap_set_t set)1025e4b17023SJohn Marino debug_bitmap_set (bitmap_set_t set)
1026e4b17023SJohn Marino {
1027e4b17023SJohn Marino   print_bitmap_set (stderr, set, "debug", 0);
1028e4b17023SJohn Marino }
1029e4b17023SJohn Marino 
1030e4b17023SJohn Marino /* Print out the expressions that have VAL to OUTFILE.  */
1031e4b17023SJohn Marino 
1032e4b17023SJohn Marino void
print_value_expressions(FILE * outfile,unsigned int val)1033e4b17023SJohn Marino print_value_expressions (FILE *outfile, unsigned int val)
1034e4b17023SJohn Marino {
1035e4b17023SJohn Marino   bitmap_set_t set = VEC_index (bitmap_set_t, value_expressions, val);
1036e4b17023SJohn Marino   if (set)
1037e4b17023SJohn Marino     {
1038e4b17023SJohn Marino       char s[10];
1039e4b17023SJohn Marino       sprintf (s, "%04d", val);
1040e4b17023SJohn Marino       print_bitmap_set (outfile, set, s, 0);
1041e4b17023SJohn Marino     }
1042e4b17023SJohn Marino }
1043e4b17023SJohn Marino 
1044e4b17023SJohn Marino 
1045e4b17023SJohn Marino DEBUG_FUNCTION void
debug_value_expressions(unsigned int val)1046e4b17023SJohn Marino debug_value_expressions (unsigned int val)
1047e4b17023SJohn Marino {
1048e4b17023SJohn Marino   print_value_expressions (stderr, val);
1049e4b17023SJohn Marino }
1050e4b17023SJohn Marino 
1051e4b17023SJohn Marino /* Given a CONSTANT, allocate a new CONSTANT type PRE_EXPR to
1052e4b17023SJohn Marino    represent it.  */
1053e4b17023SJohn Marino 
1054e4b17023SJohn Marino static pre_expr
get_or_alloc_expr_for_constant(tree constant)1055e4b17023SJohn Marino get_or_alloc_expr_for_constant (tree constant)
1056e4b17023SJohn Marino {
1057e4b17023SJohn Marino   unsigned int result_id;
1058e4b17023SJohn Marino   unsigned int value_id;
1059e4b17023SJohn Marino   struct pre_expr_d expr;
1060e4b17023SJohn Marino   pre_expr newexpr;
1061e4b17023SJohn Marino 
1062e4b17023SJohn Marino   expr.kind = CONSTANT;
1063e4b17023SJohn Marino   PRE_EXPR_CONSTANT (&expr) = constant;
1064e4b17023SJohn Marino   result_id = lookup_expression_id (&expr);
1065e4b17023SJohn Marino   if (result_id != 0)
1066e4b17023SJohn Marino     return expression_for_id (result_id);
1067e4b17023SJohn Marino 
1068e4b17023SJohn Marino   newexpr = (pre_expr) pool_alloc (pre_expr_pool);
1069e4b17023SJohn Marino   newexpr->kind = CONSTANT;
1070e4b17023SJohn Marino   PRE_EXPR_CONSTANT (newexpr) = constant;
1071e4b17023SJohn Marino   alloc_expression_id (newexpr);
1072e4b17023SJohn Marino   value_id = get_or_alloc_constant_value_id (constant);
1073e4b17023SJohn Marino   add_to_value (value_id, newexpr);
1074e4b17023SJohn Marino   return newexpr;
1075e4b17023SJohn Marino }
1076e4b17023SJohn Marino 
1077e4b17023SJohn Marino /* Given a value id V, find the actual tree representing the constant
1078e4b17023SJohn Marino    value if there is one, and return it. Return NULL if we can't find
1079e4b17023SJohn Marino    a constant.  */
1080e4b17023SJohn Marino 
1081e4b17023SJohn Marino static tree
get_constant_for_value_id(unsigned int v)1082e4b17023SJohn Marino get_constant_for_value_id (unsigned int v)
1083e4b17023SJohn Marino {
1084e4b17023SJohn Marino   if (value_id_constant_p (v))
1085e4b17023SJohn Marino     {
1086e4b17023SJohn Marino       unsigned int i;
1087e4b17023SJohn Marino       bitmap_iterator bi;
1088e4b17023SJohn Marino       bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, v);
1089e4b17023SJohn Marino 
1090e4b17023SJohn Marino       FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
1091e4b17023SJohn Marino 	{
1092e4b17023SJohn Marino 	  pre_expr expr = expression_for_id (i);
1093e4b17023SJohn Marino 	  if (expr->kind == CONSTANT)
1094e4b17023SJohn Marino 	    return PRE_EXPR_CONSTANT (expr);
1095e4b17023SJohn Marino 	}
1096e4b17023SJohn Marino     }
1097e4b17023SJohn Marino   return NULL;
1098e4b17023SJohn Marino }
1099e4b17023SJohn Marino 
1100e4b17023SJohn Marino /* Get or allocate a pre_expr for a piece of GIMPLE, and return it.
1101e4b17023SJohn Marino    Currently only supports constants and SSA_NAMES.  */
1102e4b17023SJohn Marino static pre_expr
get_or_alloc_expr_for(tree t)1103e4b17023SJohn Marino get_or_alloc_expr_for (tree t)
1104e4b17023SJohn Marino {
1105e4b17023SJohn Marino   if (TREE_CODE (t) == SSA_NAME)
1106e4b17023SJohn Marino     return get_or_alloc_expr_for_name (t);
1107e4b17023SJohn Marino   else if (is_gimple_min_invariant (t))
1108e4b17023SJohn Marino     return get_or_alloc_expr_for_constant (t);
1109e4b17023SJohn Marino   else
1110e4b17023SJohn Marino     {
1111e4b17023SJohn Marino       /* More complex expressions can result from SCCVN expression
1112e4b17023SJohn Marino 	 simplification that inserts values for them.  As they all
1113e4b17023SJohn Marino 	 do not have VOPs the get handled by the nary ops struct.  */
1114e4b17023SJohn Marino       vn_nary_op_t result;
1115e4b17023SJohn Marino       unsigned int result_id;
1116e4b17023SJohn Marino       vn_nary_op_lookup (t, &result);
1117e4b17023SJohn Marino       if (result != NULL)
1118e4b17023SJohn Marino 	{
1119e4b17023SJohn Marino 	  pre_expr e = (pre_expr) pool_alloc (pre_expr_pool);
1120e4b17023SJohn Marino 	  e->kind = NARY;
1121e4b17023SJohn Marino 	  PRE_EXPR_NARY (e) = result;
1122e4b17023SJohn Marino 	  result_id = lookup_expression_id (e);
1123e4b17023SJohn Marino 	  if (result_id != 0)
1124e4b17023SJohn Marino 	    {
1125e4b17023SJohn Marino 	      pool_free (pre_expr_pool, e);
1126e4b17023SJohn Marino 	      e = expression_for_id (result_id);
1127e4b17023SJohn Marino 	      return e;
1128e4b17023SJohn Marino 	    }
1129e4b17023SJohn Marino 	  alloc_expression_id (e);
1130e4b17023SJohn Marino 	  return e;
1131e4b17023SJohn Marino 	}
1132e4b17023SJohn Marino     }
1133e4b17023SJohn Marino   return NULL;
1134e4b17023SJohn Marino }
1135e4b17023SJohn Marino 
1136e4b17023SJohn Marino /* Return the folded version of T if T, when folded, is a gimple
1137e4b17023SJohn Marino    min_invariant.  Otherwise, return T.  */
1138e4b17023SJohn Marino 
1139e4b17023SJohn Marino static pre_expr
fully_constant_expression(pre_expr e)1140e4b17023SJohn Marino fully_constant_expression (pre_expr e)
1141e4b17023SJohn Marino {
1142e4b17023SJohn Marino   switch (e->kind)
1143e4b17023SJohn Marino     {
1144e4b17023SJohn Marino     case CONSTANT:
1145e4b17023SJohn Marino       return e;
1146e4b17023SJohn Marino     case NARY:
1147e4b17023SJohn Marino       {
1148e4b17023SJohn Marino 	vn_nary_op_t nary = PRE_EXPR_NARY (e);
1149e4b17023SJohn Marino 	switch (TREE_CODE_CLASS (nary->opcode))
1150e4b17023SJohn Marino 	  {
1151e4b17023SJohn Marino 	  case tcc_binary:
1152e4b17023SJohn Marino 	  case tcc_comparison:
1153e4b17023SJohn Marino 	    {
1154e4b17023SJohn Marino 	      /* We have to go from trees to pre exprs to value ids to
1155e4b17023SJohn Marino 		 constants.  */
1156e4b17023SJohn Marino 	      tree naryop0 = nary->op[0];
1157e4b17023SJohn Marino 	      tree naryop1 = nary->op[1];
1158e4b17023SJohn Marino 	      tree result;
1159e4b17023SJohn Marino 	      if (!is_gimple_min_invariant (naryop0))
1160e4b17023SJohn Marino 		{
1161e4b17023SJohn Marino 		  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
1162e4b17023SJohn Marino 		  unsigned int vrep0 = get_expr_value_id (rep0);
1163e4b17023SJohn Marino 		  tree const0 = get_constant_for_value_id (vrep0);
1164e4b17023SJohn Marino 		  if (const0)
1165e4b17023SJohn Marino 		    naryop0 = fold_convert (TREE_TYPE (naryop0), const0);
1166e4b17023SJohn Marino 		}
1167e4b17023SJohn Marino 	      if (!is_gimple_min_invariant (naryop1))
1168e4b17023SJohn Marino 		{
1169e4b17023SJohn Marino 		  pre_expr rep1 = get_or_alloc_expr_for (naryop1);
1170e4b17023SJohn Marino 		  unsigned int vrep1 = get_expr_value_id (rep1);
1171e4b17023SJohn Marino 		  tree const1 = get_constant_for_value_id (vrep1);
1172e4b17023SJohn Marino 		  if (const1)
1173e4b17023SJohn Marino 		    naryop1 = fold_convert (TREE_TYPE (naryop1), const1);
1174e4b17023SJohn Marino 		}
1175e4b17023SJohn Marino 	      result = fold_binary (nary->opcode, nary->type,
1176e4b17023SJohn Marino 				    naryop0, naryop1);
1177e4b17023SJohn Marino 	      if (result && is_gimple_min_invariant (result))
1178e4b17023SJohn Marino 		return get_or_alloc_expr_for_constant (result);
1179e4b17023SJohn Marino 	      /* We might have simplified the expression to a
1180e4b17023SJohn Marino 		 SSA_NAME for example from x_1 * 1.  But we cannot
1181e4b17023SJohn Marino 		 insert a PHI for x_1 unconditionally as x_1 might
1182e4b17023SJohn Marino 		 not be available readily.  */
1183e4b17023SJohn Marino 	      return e;
1184e4b17023SJohn Marino 	    }
1185e4b17023SJohn Marino 	  case tcc_reference:
1186e4b17023SJohn Marino 	    if (nary->opcode != REALPART_EXPR
1187e4b17023SJohn Marino 		&& nary->opcode != IMAGPART_EXPR
1188e4b17023SJohn Marino 		&& nary->opcode != VIEW_CONVERT_EXPR)
1189e4b17023SJohn Marino 	      return e;
1190e4b17023SJohn Marino 	    /* Fallthrough.  */
1191e4b17023SJohn Marino 	  case tcc_unary:
1192e4b17023SJohn Marino 	    {
1193e4b17023SJohn Marino 	      /* We have to go from trees to pre exprs to value ids to
1194e4b17023SJohn Marino 		 constants.  */
1195e4b17023SJohn Marino 	      tree naryop0 = nary->op[0];
1196e4b17023SJohn Marino 	      tree const0, result;
1197e4b17023SJohn Marino 	      if (is_gimple_min_invariant (naryop0))
1198e4b17023SJohn Marino 		const0 = naryop0;
1199e4b17023SJohn Marino 	      else
1200e4b17023SJohn Marino 		{
1201e4b17023SJohn Marino 		  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
1202e4b17023SJohn Marino 		  unsigned int vrep0 = get_expr_value_id (rep0);
1203e4b17023SJohn Marino 		  const0 = get_constant_for_value_id (vrep0);
1204e4b17023SJohn Marino 		}
1205e4b17023SJohn Marino 	      result = NULL;
1206e4b17023SJohn Marino 	      if (const0)
1207e4b17023SJohn Marino 		{
1208e4b17023SJohn Marino 		  tree type1 = TREE_TYPE (nary->op[0]);
1209e4b17023SJohn Marino 		  const0 = fold_convert (type1, const0);
1210e4b17023SJohn Marino 		  result = fold_unary (nary->opcode, nary->type, const0);
1211e4b17023SJohn Marino 		}
1212e4b17023SJohn Marino 	      if (result && is_gimple_min_invariant (result))
1213e4b17023SJohn Marino 		return get_or_alloc_expr_for_constant (result);
1214e4b17023SJohn Marino 	      return e;
1215e4b17023SJohn Marino 	    }
1216e4b17023SJohn Marino 	  default:
1217e4b17023SJohn Marino 	    return e;
1218e4b17023SJohn Marino 	  }
1219e4b17023SJohn Marino       }
1220e4b17023SJohn Marino     case REFERENCE:
1221e4b17023SJohn Marino       {
1222e4b17023SJohn Marino 	vn_reference_t ref = PRE_EXPR_REFERENCE (e);
1223e4b17023SJohn Marino 	tree folded;
1224e4b17023SJohn Marino 	if ((folded = fully_constant_vn_reference_p (ref)))
1225e4b17023SJohn Marino 	  return get_or_alloc_expr_for_constant (folded);
1226e4b17023SJohn Marino 	return e;
1227e4b17023SJohn Marino       }
1228e4b17023SJohn Marino     default:
1229e4b17023SJohn Marino       return e;
1230e4b17023SJohn Marino     }
1231e4b17023SJohn Marino   return e;
1232e4b17023SJohn Marino }
1233e4b17023SJohn Marino 
1234e4b17023SJohn Marino /* Translate the VUSE backwards through phi nodes in PHIBLOCK, so that
1235e4b17023SJohn Marino    it has the value it would have in BLOCK.  Set *SAME_VALID to true
1236e4b17023SJohn Marino    in case the new vuse doesn't change the value id of the OPERANDS.  */
1237e4b17023SJohn Marino 
1238e4b17023SJohn Marino static tree
translate_vuse_through_block(VEC (vn_reference_op_s,heap)* operands,alias_set_type set,tree type,tree vuse,basic_block phiblock,basic_block block,bool * same_valid)1239e4b17023SJohn Marino translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
1240e4b17023SJohn Marino 			      alias_set_type set, tree type, tree vuse,
1241e4b17023SJohn Marino 			      basic_block phiblock,
1242e4b17023SJohn Marino 			      basic_block block, bool *same_valid)
1243e4b17023SJohn Marino {
1244e4b17023SJohn Marino   gimple phi = SSA_NAME_DEF_STMT (vuse);
1245e4b17023SJohn Marino   ao_ref ref;
1246e4b17023SJohn Marino   edge e = NULL;
1247e4b17023SJohn Marino   bool use_oracle;
1248e4b17023SJohn Marino 
1249e4b17023SJohn Marino   *same_valid = true;
1250e4b17023SJohn Marino 
1251e4b17023SJohn Marino   if (gimple_bb (phi) != phiblock)
1252e4b17023SJohn Marino     return vuse;
1253e4b17023SJohn Marino 
1254e4b17023SJohn Marino   use_oracle = ao_ref_init_from_vn_reference (&ref, set, type, operands);
1255e4b17023SJohn Marino 
1256e4b17023SJohn Marino   /* Use the alias-oracle to find either the PHI node in this block,
1257e4b17023SJohn Marino      the first VUSE used in this block that is equivalent to vuse or
1258e4b17023SJohn Marino      the first VUSE which definition in this block kills the value.  */
1259e4b17023SJohn Marino   if (gimple_code (phi) == GIMPLE_PHI)
1260e4b17023SJohn Marino     e = find_edge (block, phiblock);
1261e4b17023SJohn Marino   else if (use_oracle)
1262e4b17023SJohn Marino     while (!stmt_may_clobber_ref_p_1 (phi, &ref))
1263e4b17023SJohn Marino       {
1264e4b17023SJohn Marino 	vuse = gimple_vuse (phi);
1265e4b17023SJohn Marino 	phi = SSA_NAME_DEF_STMT (vuse);
1266e4b17023SJohn Marino 	if (gimple_bb (phi) != phiblock)
1267e4b17023SJohn Marino 	  return vuse;
1268e4b17023SJohn Marino 	if (gimple_code (phi) == GIMPLE_PHI)
1269e4b17023SJohn Marino 	  {
1270e4b17023SJohn Marino 	    e = find_edge (block, phiblock);
1271e4b17023SJohn Marino 	    break;
1272e4b17023SJohn Marino 	  }
1273e4b17023SJohn Marino       }
1274e4b17023SJohn Marino   else
1275e4b17023SJohn Marino     return NULL_TREE;
1276e4b17023SJohn Marino 
1277e4b17023SJohn Marino   if (e)
1278e4b17023SJohn Marino     {
1279e4b17023SJohn Marino       if (use_oracle)
1280e4b17023SJohn Marino 	{
1281e4b17023SJohn Marino 	  bitmap visited = NULL;
1282e4b17023SJohn Marino 	  /* Try to find a vuse that dominates this phi node by skipping
1283e4b17023SJohn Marino 	     non-clobbering statements.  */
1284e4b17023SJohn Marino 	  vuse = get_continuation_for_phi (phi, &ref, &visited, false);
1285e4b17023SJohn Marino 	  if (visited)
1286e4b17023SJohn Marino 	    BITMAP_FREE (visited);
1287e4b17023SJohn Marino 	}
1288e4b17023SJohn Marino       else
1289e4b17023SJohn Marino 	vuse = NULL_TREE;
1290e4b17023SJohn Marino       if (!vuse)
1291e4b17023SJohn Marino 	{
1292e4b17023SJohn Marino 	  /* If we didn't find any, the value ID can't stay the same,
1293e4b17023SJohn Marino 	     but return the translated vuse.  */
1294e4b17023SJohn Marino 	  *same_valid = false;
1295e4b17023SJohn Marino 	  vuse = PHI_ARG_DEF (phi, e->dest_idx);
1296e4b17023SJohn Marino 	}
1297e4b17023SJohn Marino       /* ??? We would like to return vuse here as this is the canonical
1298e4b17023SJohn Marino          upmost vdef that this reference is associated with.  But during
1299e4b17023SJohn Marino 	 insertion of the references into the hash tables we only ever
1300e4b17023SJohn Marino 	 directly insert with their direct gimple_vuse, hence returning
1301e4b17023SJohn Marino 	 something else would make us not find the other expression.  */
1302e4b17023SJohn Marino       return PHI_ARG_DEF (phi, e->dest_idx);
1303e4b17023SJohn Marino     }
1304e4b17023SJohn Marino 
1305e4b17023SJohn Marino   return NULL_TREE;
1306e4b17023SJohn Marino }
1307e4b17023SJohn Marino 
1308e4b17023SJohn Marino /* Like bitmap_find_leader, but checks for the value existing in SET1 *or*
1309e4b17023SJohn Marino    SET2.  This is used to avoid making a set consisting of the union
1310e4b17023SJohn Marino    of PA_IN and ANTIC_IN during insert.  */
1311e4b17023SJohn Marino 
1312e4b17023SJohn Marino static inline pre_expr
find_leader_in_sets(unsigned int val,bitmap_set_t set1,bitmap_set_t set2)1313e4b17023SJohn Marino find_leader_in_sets (unsigned int val, bitmap_set_t set1, bitmap_set_t set2)
1314e4b17023SJohn Marino {
1315e4b17023SJohn Marino   pre_expr result;
1316e4b17023SJohn Marino 
1317e4b17023SJohn Marino   result = bitmap_find_leader (set1, val, NULL);
1318e4b17023SJohn Marino   if (!result && set2)
1319e4b17023SJohn Marino     result = bitmap_find_leader (set2, val, NULL);
1320e4b17023SJohn Marino   return result;
1321e4b17023SJohn Marino }
1322e4b17023SJohn Marino 
1323e4b17023SJohn Marino /* Get the tree type for our PRE expression e.  */
1324e4b17023SJohn Marino 
1325e4b17023SJohn Marino static tree
get_expr_type(const pre_expr e)1326e4b17023SJohn Marino get_expr_type (const pre_expr e)
1327e4b17023SJohn Marino {
1328e4b17023SJohn Marino   switch (e->kind)
1329e4b17023SJohn Marino     {
1330e4b17023SJohn Marino     case NAME:
1331e4b17023SJohn Marino       return TREE_TYPE (PRE_EXPR_NAME (e));
1332e4b17023SJohn Marino     case CONSTANT:
1333e4b17023SJohn Marino       return TREE_TYPE (PRE_EXPR_CONSTANT (e));
1334e4b17023SJohn Marino     case REFERENCE:
1335e4b17023SJohn Marino       return PRE_EXPR_REFERENCE (e)->type;
1336e4b17023SJohn Marino     case NARY:
1337e4b17023SJohn Marino       return PRE_EXPR_NARY (e)->type;
1338e4b17023SJohn Marino     }
1339e4b17023SJohn Marino   gcc_unreachable();
1340e4b17023SJohn Marino }
1341e4b17023SJohn Marino 
1342e4b17023SJohn Marino /* Get a representative SSA_NAME for a given expression.
1343e4b17023SJohn Marino    Since all of our sub-expressions are treated as values, we require
1344e4b17023SJohn Marino    them to be SSA_NAME's for simplicity.
1345e4b17023SJohn Marino    Prior versions of GVNPRE used to use "value handles" here, so that
1346e4b17023SJohn Marino    an expression would be VH.11 + VH.10 instead of d_3 + e_6.  In
1347e4b17023SJohn Marino    either case, the operands are really values (IE we do not expect
1348e4b17023SJohn Marino    them to be usable without finding leaders).  */
1349e4b17023SJohn Marino 
1350e4b17023SJohn Marino static tree
get_representative_for(const pre_expr e)1351e4b17023SJohn Marino get_representative_for (const pre_expr e)
1352e4b17023SJohn Marino {
1353e4b17023SJohn Marino   tree exprtype;
1354e4b17023SJohn Marino   tree name;
1355e4b17023SJohn Marino   unsigned int value_id = get_expr_value_id (e);
1356e4b17023SJohn Marino 
1357e4b17023SJohn Marino   switch (e->kind)
1358e4b17023SJohn Marino     {
1359e4b17023SJohn Marino     case NAME:
1360e4b17023SJohn Marino       return PRE_EXPR_NAME (e);
1361e4b17023SJohn Marino     case CONSTANT:
1362e4b17023SJohn Marino       return PRE_EXPR_CONSTANT (e);
1363e4b17023SJohn Marino     case NARY:
1364e4b17023SJohn Marino     case REFERENCE:
1365e4b17023SJohn Marino       {
1366e4b17023SJohn Marino 	/* Go through all of the expressions representing this value
1367e4b17023SJohn Marino 	   and pick out an SSA_NAME.  */
1368e4b17023SJohn Marino 	unsigned int i;
1369e4b17023SJohn Marino 	bitmap_iterator bi;
1370e4b17023SJohn Marino 	bitmap_set_t exprs = VEC_index (bitmap_set_t, value_expressions,
1371e4b17023SJohn Marino 					value_id);
1372e4b17023SJohn Marino 	FOR_EACH_EXPR_ID_IN_SET (exprs, i, bi)
1373e4b17023SJohn Marino 	  {
1374e4b17023SJohn Marino 	    pre_expr rep = expression_for_id (i);
1375e4b17023SJohn Marino 	    if (rep->kind == NAME)
1376e4b17023SJohn Marino 	      return PRE_EXPR_NAME (rep);
1377e4b17023SJohn Marino 	  }
1378e4b17023SJohn Marino       }
1379e4b17023SJohn Marino       break;
1380e4b17023SJohn Marino     }
1381e4b17023SJohn Marino   /* If we reached here we couldn't find an SSA_NAME.  This can
1382e4b17023SJohn Marino      happen when we've discovered a value that has never appeared in
1383e4b17023SJohn Marino      the program as set to an SSA_NAME, most likely as the result of
1384e4b17023SJohn Marino      phi translation.  */
1385e4b17023SJohn Marino   if (dump_file)
1386e4b17023SJohn Marino     {
1387e4b17023SJohn Marino       fprintf (dump_file,
1388e4b17023SJohn Marino 	       "Could not find SSA_NAME representative for expression:");
1389e4b17023SJohn Marino       print_pre_expr (dump_file, e);
1390e4b17023SJohn Marino       fprintf (dump_file, "\n");
1391e4b17023SJohn Marino     }
1392e4b17023SJohn Marino 
1393e4b17023SJohn Marino   exprtype = get_expr_type (e);
1394e4b17023SJohn Marino 
1395e4b17023SJohn Marino   /* Build and insert the assignment of the end result to the temporary
1396e4b17023SJohn Marino      that we will return.  */
1397e4b17023SJohn Marino   if (!pretemp || exprtype != TREE_TYPE (pretemp))
1398e4b17023SJohn Marino     {
1399e4b17023SJohn Marino       pretemp = create_tmp_reg (exprtype, "pretmp");
1400e4b17023SJohn Marino       add_referenced_var (pretemp);
1401e4b17023SJohn Marino     }
1402e4b17023SJohn Marino 
1403e4b17023SJohn Marino   name = make_ssa_name (pretemp, gimple_build_nop ());
1404e4b17023SJohn Marino   VN_INFO_GET (name)->value_id = value_id;
1405e4b17023SJohn Marino   if (e->kind == CONSTANT)
1406e4b17023SJohn Marino     VN_INFO (name)->valnum = PRE_EXPR_CONSTANT (e);
1407e4b17023SJohn Marino   else
1408e4b17023SJohn Marino     VN_INFO (name)->valnum = name;
1409e4b17023SJohn Marino 
1410e4b17023SJohn Marino   add_to_value (value_id, get_or_alloc_expr_for_name (name));
1411e4b17023SJohn Marino   if (dump_file)
1412e4b17023SJohn Marino     {
1413e4b17023SJohn Marino       fprintf (dump_file, "Created SSA_NAME representative ");
1414e4b17023SJohn Marino       print_generic_expr (dump_file, name, 0);
1415e4b17023SJohn Marino       fprintf (dump_file, " for expression:");
1416e4b17023SJohn Marino       print_pre_expr (dump_file, e);
1417e4b17023SJohn Marino       fprintf (dump_file, "\n");
1418e4b17023SJohn Marino     }
1419e4b17023SJohn Marino 
1420e4b17023SJohn Marino   return name;
1421e4b17023SJohn Marino }
1422e4b17023SJohn Marino 
1423e4b17023SJohn Marino 
1424e4b17023SJohn Marino 
1425e4b17023SJohn Marino static pre_expr
1426e4b17023SJohn Marino phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
1427e4b17023SJohn Marino 	       basic_block pred, basic_block phiblock);
1428e4b17023SJohn Marino 
1429e4b17023SJohn Marino /* Translate EXPR using phis in PHIBLOCK, so that it has the values of
1430e4b17023SJohn Marino    the phis in PRED.  Return NULL if we can't find a leader for each part
1431e4b17023SJohn Marino    of the translated expression.  */
1432e4b17023SJohn Marino 
1433e4b17023SJohn Marino static pre_expr
phi_translate_1(pre_expr expr,bitmap_set_t set1,bitmap_set_t set2,basic_block pred,basic_block phiblock)1434e4b17023SJohn Marino phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
1435e4b17023SJohn Marino 		 basic_block pred, basic_block phiblock)
1436e4b17023SJohn Marino {
1437e4b17023SJohn Marino   switch (expr->kind)
1438e4b17023SJohn Marino     {
1439e4b17023SJohn Marino     case NARY:
1440e4b17023SJohn Marino       {
1441e4b17023SJohn Marino 	unsigned int i;
1442e4b17023SJohn Marino 	bool changed = false;
1443e4b17023SJohn Marino 	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
1444e4b17023SJohn Marino 	vn_nary_op_t newnary = XALLOCAVAR (struct vn_nary_op_s,
1445e4b17023SJohn Marino 					   sizeof_vn_nary_op (nary->length));
1446e4b17023SJohn Marino 	memcpy (newnary, nary, sizeof_vn_nary_op (nary->length));
1447e4b17023SJohn Marino 
1448e4b17023SJohn Marino 	for (i = 0; i < newnary->length; i++)
1449e4b17023SJohn Marino 	  {
1450e4b17023SJohn Marino 	    if (TREE_CODE (newnary->op[i]) != SSA_NAME)
1451e4b17023SJohn Marino 	      continue;
1452e4b17023SJohn Marino 	    else
1453e4b17023SJohn Marino 	      {
1454e4b17023SJohn Marino                 pre_expr leader, result;
1455e4b17023SJohn Marino 		unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id;
1456e4b17023SJohn Marino 		leader = find_leader_in_sets (op_val_id, set1, set2);
1457e4b17023SJohn Marino                 result = phi_translate (leader, set1, set2, pred, phiblock);
1458e4b17023SJohn Marino 		if (result && result != leader)
1459e4b17023SJohn Marino 		  {
1460e4b17023SJohn Marino 		    tree name = get_representative_for (result);
1461e4b17023SJohn Marino 		    if (!name)
1462e4b17023SJohn Marino 		      return NULL;
1463e4b17023SJohn Marino 		    newnary->op[i] = name;
1464e4b17023SJohn Marino 		  }
1465e4b17023SJohn Marino 		else if (!result)
1466e4b17023SJohn Marino 		  return NULL;
1467e4b17023SJohn Marino 
1468e4b17023SJohn Marino 		changed |= newnary->op[i] != nary->op[i];
1469e4b17023SJohn Marino 	      }
1470e4b17023SJohn Marino 	  }
1471e4b17023SJohn Marino 	if (changed)
1472e4b17023SJohn Marino 	  {
1473e4b17023SJohn Marino 	    pre_expr constant;
1474e4b17023SJohn Marino 	    unsigned int new_val_id;
1475e4b17023SJohn Marino 
1476e4b17023SJohn Marino 	    tree result = vn_nary_op_lookup_pieces (newnary->length,
1477e4b17023SJohn Marino 						    newnary->opcode,
1478e4b17023SJohn Marino 						    newnary->type,
1479e4b17023SJohn Marino 						    &newnary->op[0],
1480e4b17023SJohn Marino 						    &nary);
1481e4b17023SJohn Marino 	    if (result && is_gimple_min_invariant (result))
1482e4b17023SJohn Marino 	      return get_or_alloc_expr_for_constant (result);
1483e4b17023SJohn Marino 
1484e4b17023SJohn Marino 	    expr = (pre_expr) pool_alloc (pre_expr_pool);
1485e4b17023SJohn Marino 	    expr->kind = NARY;
1486e4b17023SJohn Marino 	    expr->id = 0;
1487e4b17023SJohn Marino 	    if (nary)
1488e4b17023SJohn Marino 	      {
1489e4b17023SJohn Marino 		PRE_EXPR_NARY (expr) = nary;
1490e4b17023SJohn Marino 		constant = fully_constant_expression (expr);
1491e4b17023SJohn Marino 		if (constant != expr)
1492e4b17023SJohn Marino 		  return constant;
1493e4b17023SJohn Marino 
1494e4b17023SJohn Marino 		new_val_id = nary->value_id;
1495e4b17023SJohn Marino 		get_or_alloc_expression_id (expr);
1496e4b17023SJohn Marino 	      }
1497e4b17023SJohn Marino 	    else
1498e4b17023SJohn Marino 	      {
1499e4b17023SJohn Marino 		new_val_id = get_next_value_id ();
1500e4b17023SJohn Marino 		VEC_safe_grow_cleared (bitmap_set_t, heap,
1501e4b17023SJohn Marino 				       value_expressions,
1502e4b17023SJohn Marino 				       get_max_value_id() + 1);
1503e4b17023SJohn Marino 		nary = vn_nary_op_insert_pieces (newnary->length,
1504e4b17023SJohn Marino 						 newnary->opcode,
1505e4b17023SJohn Marino 						 newnary->type,
1506e4b17023SJohn Marino 						 &newnary->op[0],
1507e4b17023SJohn Marino 						 result, new_val_id);
1508e4b17023SJohn Marino 		PRE_EXPR_NARY (expr) = nary;
1509e4b17023SJohn Marino 		constant = fully_constant_expression (expr);
1510e4b17023SJohn Marino 		if (constant != expr)
1511e4b17023SJohn Marino 		  return constant;
1512e4b17023SJohn Marino 		get_or_alloc_expression_id (expr);
1513e4b17023SJohn Marino 	      }
1514e4b17023SJohn Marino 	    add_to_value (new_val_id, expr);
1515e4b17023SJohn Marino 	  }
1516e4b17023SJohn Marino 	return expr;
1517e4b17023SJohn Marino       }
1518e4b17023SJohn Marino       break;
1519e4b17023SJohn Marino 
1520e4b17023SJohn Marino     case REFERENCE:
1521e4b17023SJohn Marino       {
1522e4b17023SJohn Marino 	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
1523e4b17023SJohn Marino 	VEC (vn_reference_op_s, heap) *operands = ref->operands;
1524e4b17023SJohn Marino 	tree vuse = ref->vuse;
1525e4b17023SJohn Marino 	tree newvuse = vuse;
1526e4b17023SJohn Marino 	VEC (vn_reference_op_s, heap) *newoperands = NULL;
1527e4b17023SJohn Marino 	bool changed = false, same_valid = true;
1528e4b17023SJohn Marino 	unsigned int i, j, n;
1529e4b17023SJohn Marino 	vn_reference_op_t operand;
1530e4b17023SJohn Marino 	vn_reference_t newref;
1531e4b17023SJohn Marino 
1532e4b17023SJohn Marino 	for (i = 0, j = 0;
1533e4b17023SJohn Marino 	     VEC_iterate (vn_reference_op_s, operands, i, operand); i++, j++)
1534e4b17023SJohn Marino 	  {
1535e4b17023SJohn Marino 	    pre_expr opresult;
1536e4b17023SJohn Marino 	    pre_expr leader;
1537e4b17023SJohn Marino 	    tree op[3];
1538e4b17023SJohn Marino 	    tree type = operand->type;
1539e4b17023SJohn Marino 	    vn_reference_op_s newop = *operand;
1540e4b17023SJohn Marino 	    op[0] = operand->op0;
1541e4b17023SJohn Marino 	    op[1] = operand->op1;
1542e4b17023SJohn Marino 	    op[2] = operand->op2;
1543e4b17023SJohn Marino 	    for (n = 0; n < 3; ++n)
1544e4b17023SJohn Marino 	      {
1545e4b17023SJohn Marino 		unsigned int op_val_id;
1546e4b17023SJohn Marino 		if (!op[n])
1547e4b17023SJohn Marino 		  continue;
1548e4b17023SJohn Marino 		if (TREE_CODE (op[n]) != SSA_NAME)
1549e4b17023SJohn Marino 		  {
1550e4b17023SJohn Marino 		    /* We can't possibly insert these.  */
1551e4b17023SJohn Marino 		    if (n != 0
1552e4b17023SJohn Marino 			&& !is_gimple_min_invariant (op[n]))
1553e4b17023SJohn Marino 		      break;
1554e4b17023SJohn Marino 		    continue;
1555e4b17023SJohn Marino 		  }
1556e4b17023SJohn Marino 		op_val_id = VN_INFO (op[n])->value_id;
1557e4b17023SJohn Marino 		leader = find_leader_in_sets (op_val_id, set1, set2);
1558e4b17023SJohn Marino 		if (!leader)
1559e4b17023SJohn Marino 		  break;
1560e4b17023SJohn Marino 		/* Make sure we do not recursively translate ourselves
1561e4b17023SJohn Marino 		   like for translating a[n_1] with the leader for
1562e4b17023SJohn Marino 		   n_1 being a[n_1].  */
1563e4b17023SJohn Marino 		if (get_expression_id (leader) != get_expression_id (expr))
1564e4b17023SJohn Marino 		  {
1565e4b17023SJohn Marino 		    opresult = phi_translate (leader, set1, set2,
1566e4b17023SJohn Marino 					      pred, phiblock);
1567e4b17023SJohn Marino 		    if (!opresult)
1568e4b17023SJohn Marino 		      break;
1569e4b17023SJohn Marino 		    if (opresult != leader)
1570e4b17023SJohn Marino 		      {
1571e4b17023SJohn Marino 			tree name = get_representative_for (opresult);
1572e4b17023SJohn Marino 			if (!name)
1573e4b17023SJohn Marino 			  break;
1574e4b17023SJohn Marino 			changed |= name != op[n];
1575e4b17023SJohn Marino 			op[n] = name;
1576e4b17023SJohn Marino 		      }
1577e4b17023SJohn Marino 		  }
1578e4b17023SJohn Marino 	      }
1579e4b17023SJohn Marino 	    if (n != 3)
1580e4b17023SJohn Marino 	      {
1581e4b17023SJohn Marino 		if (newoperands)
1582e4b17023SJohn Marino 		  VEC_free (vn_reference_op_s, heap, newoperands);
1583e4b17023SJohn Marino 		return NULL;
1584e4b17023SJohn Marino 	      }
1585e4b17023SJohn Marino 	    if (!newoperands)
1586e4b17023SJohn Marino 	      newoperands = VEC_copy (vn_reference_op_s, heap, operands);
1587e4b17023SJohn Marino 	    /* We may have changed from an SSA_NAME to a constant */
1588e4b17023SJohn Marino 	    if (newop.opcode == SSA_NAME && TREE_CODE (op[0]) != SSA_NAME)
1589e4b17023SJohn Marino 	      newop.opcode = TREE_CODE (op[0]);
1590e4b17023SJohn Marino 	    newop.type = type;
1591e4b17023SJohn Marino 	    newop.op0 = op[0];
1592e4b17023SJohn Marino 	    newop.op1 = op[1];
1593e4b17023SJohn Marino 	    newop.op2 = op[2];
1594e4b17023SJohn Marino 	    /* If it transforms a non-constant ARRAY_REF into a constant
1595e4b17023SJohn Marino 	       one, adjust the constant offset.  */
1596e4b17023SJohn Marino 	    if (newop.opcode == ARRAY_REF
1597e4b17023SJohn Marino 		&& newop.off == -1
1598e4b17023SJohn Marino 		&& TREE_CODE (op[0]) == INTEGER_CST
1599e4b17023SJohn Marino 		&& TREE_CODE (op[1]) == INTEGER_CST
1600e4b17023SJohn Marino 		&& TREE_CODE (op[2]) == INTEGER_CST)
1601e4b17023SJohn Marino 	      {
1602e4b17023SJohn Marino 		double_int off = tree_to_double_int (op[0]);
1603e4b17023SJohn Marino 		off = double_int_add (off,
1604e4b17023SJohn Marino 				      double_int_neg
1605e4b17023SJohn Marino 				        (tree_to_double_int (op[1])));
1606e4b17023SJohn Marino 		off = double_int_mul (off, tree_to_double_int (op[2]));
1607e4b17023SJohn Marino 		if (double_int_fits_in_shwi_p (off))
1608e4b17023SJohn Marino 		  newop.off = off.low;
1609e4b17023SJohn Marino 	      }
1610e4b17023SJohn Marino 	    VEC_replace (vn_reference_op_s, newoperands, j, &newop);
1611e4b17023SJohn Marino 	    /* If it transforms from an SSA_NAME to an address, fold with
1612e4b17023SJohn Marino 	       a preceding indirect reference.  */
1613e4b17023SJohn Marino 	    if (j > 0 && op[0] && TREE_CODE (op[0]) == ADDR_EXPR
1614e4b17023SJohn Marino 		&& VEC_index (vn_reference_op_s,
1615e4b17023SJohn Marino 			      newoperands, j - 1)->opcode == MEM_REF)
1616e4b17023SJohn Marino 	      vn_reference_fold_indirect (&newoperands, &j);
1617e4b17023SJohn Marino 	  }
1618e4b17023SJohn Marino 	if (i != VEC_length (vn_reference_op_s, operands))
1619e4b17023SJohn Marino 	  {
1620e4b17023SJohn Marino 	    if (newoperands)
1621e4b17023SJohn Marino 	      VEC_free (vn_reference_op_s, heap, newoperands);
1622e4b17023SJohn Marino 	    return NULL;
1623e4b17023SJohn Marino 	  }
1624e4b17023SJohn Marino 
1625e4b17023SJohn Marino 	if (vuse)
1626e4b17023SJohn Marino 	  {
1627e4b17023SJohn Marino 	    newvuse = translate_vuse_through_block (newoperands,
1628e4b17023SJohn Marino 						    ref->set, ref->type,
1629e4b17023SJohn Marino 						    vuse, phiblock, pred,
1630e4b17023SJohn Marino 						    &same_valid);
1631e4b17023SJohn Marino 	    if (newvuse == NULL_TREE)
1632e4b17023SJohn Marino 	      {
1633e4b17023SJohn Marino 		VEC_free (vn_reference_op_s, heap, newoperands);
1634e4b17023SJohn Marino 		return NULL;
1635e4b17023SJohn Marino 	      }
1636e4b17023SJohn Marino 	  }
1637e4b17023SJohn Marino 
1638e4b17023SJohn Marino 	if (changed || newvuse != vuse)
1639e4b17023SJohn Marino 	  {
1640e4b17023SJohn Marino 	    unsigned int new_val_id;
1641e4b17023SJohn Marino 	    pre_expr constant;
1642e4b17023SJohn Marino 	    bool converted = false;
1643e4b17023SJohn Marino 
1644e4b17023SJohn Marino 	    tree result = vn_reference_lookup_pieces (newvuse, ref->set,
1645e4b17023SJohn Marino 						      ref->type,
1646e4b17023SJohn Marino 						      newoperands,
1647e4b17023SJohn Marino 						      &newref, VN_WALK);
1648e4b17023SJohn Marino 	    if (result)
1649e4b17023SJohn Marino 	      VEC_free (vn_reference_op_s, heap, newoperands);
1650e4b17023SJohn Marino 
1651e4b17023SJohn Marino 	    if (result
1652e4b17023SJohn Marino 		&& !useless_type_conversion_p (ref->type, TREE_TYPE (result)))
1653e4b17023SJohn Marino 	      {
1654e4b17023SJohn Marino 		result = fold_build1 (VIEW_CONVERT_EXPR, ref->type, result);
1655e4b17023SJohn Marino 		converted = true;
1656e4b17023SJohn Marino 	      }
1657e4b17023SJohn Marino 	    else if (!result && newref
1658e4b17023SJohn Marino 		     && !useless_type_conversion_p (ref->type, newref->type))
1659e4b17023SJohn Marino 	      {
1660e4b17023SJohn Marino 		VEC_free (vn_reference_op_s, heap, newoperands);
1661e4b17023SJohn Marino 		return NULL;
1662e4b17023SJohn Marino 	      }
1663e4b17023SJohn Marino 
1664e4b17023SJohn Marino 	    if (result && is_gimple_min_invariant (result))
1665e4b17023SJohn Marino 	      {
1666e4b17023SJohn Marino 	        gcc_assert (!newoperands);
1667e4b17023SJohn Marino 	        return get_or_alloc_expr_for_constant (result);
1668e4b17023SJohn Marino 	      }
1669e4b17023SJohn Marino 
1670e4b17023SJohn Marino 	    expr = (pre_expr) pool_alloc (pre_expr_pool);
1671e4b17023SJohn Marino 	    expr->kind = REFERENCE;
1672e4b17023SJohn Marino 	    expr->id = 0;
1673e4b17023SJohn Marino 
1674e4b17023SJohn Marino 	    if (converted)
1675e4b17023SJohn Marino 	      {
1676e4b17023SJohn Marino 		vn_nary_op_t nary;
1677e4b17023SJohn Marino 		tree nresult;
1678e4b17023SJohn Marino 
1679e4b17023SJohn Marino 		gcc_assert (CONVERT_EXPR_P (result)
1680e4b17023SJohn Marino 			    || TREE_CODE (result) == VIEW_CONVERT_EXPR);
1681e4b17023SJohn Marino 
1682e4b17023SJohn Marino 		nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result),
1683e4b17023SJohn Marino 						    TREE_TYPE (result),
1684e4b17023SJohn Marino 						    &TREE_OPERAND (result, 0),
1685e4b17023SJohn Marino 						    &nary);
1686e4b17023SJohn Marino 		if (nresult && is_gimple_min_invariant (nresult))
1687e4b17023SJohn Marino 		  return get_or_alloc_expr_for_constant (nresult);
1688e4b17023SJohn Marino 
1689e4b17023SJohn Marino 		expr->kind = NARY;
1690e4b17023SJohn Marino 		if (nary)
1691e4b17023SJohn Marino 		  {
1692e4b17023SJohn Marino 		    PRE_EXPR_NARY (expr) = nary;
1693e4b17023SJohn Marino 		    constant = fully_constant_expression (expr);
1694e4b17023SJohn Marino 		    if (constant != expr)
1695e4b17023SJohn Marino 		      return constant;
1696e4b17023SJohn Marino 
1697e4b17023SJohn Marino 		    new_val_id = nary->value_id;
1698e4b17023SJohn Marino 		    get_or_alloc_expression_id (expr);
1699e4b17023SJohn Marino 		  }
1700e4b17023SJohn Marino 		else
1701e4b17023SJohn Marino 		  {
1702e4b17023SJohn Marino 		    new_val_id = get_next_value_id ();
1703e4b17023SJohn Marino 		    VEC_safe_grow_cleared (bitmap_set_t, heap,
1704e4b17023SJohn Marino 					   value_expressions,
1705e4b17023SJohn Marino 					   get_max_value_id() + 1);
1706e4b17023SJohn Marino 		    nary = vn_nary_op_insert_pieces (1, TREE_CODE (result),
1707e4b17023SJohn Marino 						     TREE_TYPE (result),
1708e4b17023SJohn Marino 						     &TREE_OPERAND (result, 0),
1709e4b17023SJohn Marino 						     NULL_TREE,
1710e4b17023SJohn Marino 						     new_val_id);
1711e4b17023SJohn Marino 		    PRE_EXPR_NARY (expr) = nary;
1712e4b17023SJohn Marino 		    constant = fully_constant_expression (expr);
1713e4b17023SJohn Marino 		    if (constant != expr)
1714e4b17023SJohn Marino 		      return constant;
1715e4b17023SJohn Marino 		    get_or_alloc_expression_id (expr);
1716e4b17023SJohn Marino 		  }
1717e4b17023SJohn Marino 	      }
1718e4b17023SJohn Marino 	    else if (newref)
1719e4b17023SJohn Marino 	      {
1720e4b17023SJohn Marino 		PRE_EXPR_REFERENCE (expr) = newref;
1721e4b17023SJohn Marino 		constant = fully_constant_expression (expr);
1722e4b17023SJohn Marino 		if (constant != expr)
1723e4b17023SJohn Marino 		  return constant;
1724e4b17023SJohn Marino 
1725e4b17023SJohn Marino 		new_val_id = newref->value_id;
1726e4b17023SJohn Marino 		get_or_alloc_expression_id (expr);
1727e4b17023SJohn Marino 	      }
1728e4b17023SJohn Marino 	    else
1729e4b17023SJohn Marino 	      {
1730e4b17023SJohn Marino 		if (changed || !same_valid)
1731e4b17023SJohn Marino 		  {
1732e4b17023SJohn Marino 		    new_val_id = get_next_value_id ();
1733e4b17023SJohn Marino 		    VEC_safe_grow_cleared (bitmap_set_t, heap,
1734e4b17023SJohn Marino 					   value_expressions,
1735e4b17023SJohn Marino 					   get_max_value_id() + 1);
1736e4b17023SJohn Marino 		  }
1737e4b17023SJohn Marino 		else
1738e4b17023SJohn Marino 		  new_val_id = ref->value_id;
1739e4b17023SJohn Marino 		newref = vn_reference_insert_pieces (newvuse, ref->set,
1740e4b17023SJohn Marino 						     ref->type,
1741e4b17023SJohn Marino 						     newoperands,
1742e4b17023SJohn Marino 						     result, new_val_id);
1743e4b17023SJohn Marino 		newoperands = NULL;
1744e4b17023SJohn Marino 		PRE_EXPR_REFERENCE (expr) = newref;
1745e4b17023SJohn Marino 		constant = fully_constant_expression (expr);
1746e4b17023SJohn Marino 		if (constant != expr)
1747e4b17023SJohn Marino 		  return constant;
1748e4b17023SJohn Marino 		get_or_alloc_expression_id (expr);
1749e4b17023SJohn Marino 	      }
1750e4b17023SJohn Marino 	    add_to_value (new_val_id, expr);
1751e4b17023SJohn Marino 	  }
1752e4b17023SJohn Marino 	VEC_free (vn_reference_op_s, heap, newoperands);
1753e4b17023SJohn Marino 	return expr;
1754e4b17023SJohn Marino       }
1755e4b17023SJohn Marino       break;
1756e4b17023SJohn Marino 
1757e4b17023SJohn Marino     case NAME:
1758e4b17023SJohn Marino       {
1759e4b17023SJohn Marino 	tree name = PRE_EXPR_NAME (expr);
1760*95d28233SJohn Marino 	gimple def_stmt = SSA_NAME_DEF_STMT (name);
1761*95d28233SJohn Marino 	/* If the SSA name is defined by a PHI node in this block,
1762*95d28233SJohn Marino 	   translate it.  */
1763e4b17023SJohn Marino 	if (gimple_code (def_stmt) == GIMPLE_PHI
1764e4b17023SJohn Marino 	    && gimple_bb (def_stmt) == phiblock)
1765e4b17023SJohn Marino 	  {
1766*95d28233SJohn Marino 	    edge e = find_edge (pred, gimple_bb (def_stmt));
1767*95d28233SJohn Marino 	    tree def = PHI_ARG_DEF (def_stmt, e->dest_idx);
1768e4b17023SJohn Marino 
1769e4b17023SJohn Marino 	    /* Handle constant. */
1770e4b17023SJohn Marino 	    if (is_gimple_min_invariant (def))
1771e4b17023SJohn Marino 	      return get_or_alloc_expr_for_constant (def);
1772e4b17023SJohn Marino 
1773*95d28233SJohn Marino 	    return get_or_alloc_expr_for_name (def);
1774e4b17023SJohn Marino 	  }
1775*95d28233SJohn Marino 	/* Otherwise return it unchanged - it will get cleaned if its
1776*95d28233SJohn Marino 	   value is not available in PREDs AVAIL_OUT set of expressions.  */
1777e4b17023SJohn Marino 	return expr;
1778*95d28233SJohn Marino       }
1779e4b17023SJohn Marino 
1780e4b17023SJohn Marino     default:
1781e4b17023SJohn Marino       gcc_unreachable ();
1782e4b17023SJohn Marino     }
1783e4b17023SJohn Marino }
1784e4b17023SJohn Marino 
1785e4b17023SJohn Marino /* Wrapper around phi_translate_1 providing caching functionality.  */
1786e4b17023SJohn Marino 
1787e4b17023SJohn Marino static pre_expr
phi_translate(pre_expr expr,bitmap_set_t set1,bitmap_set_t set2,basic_block pred,basic_block phiblock)1788e4b17023SJohn Marino phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
1789e4b17023SJohn Marino 	       basic_block pred, basic_block phiblock)
1790e4b17023SJohn Marino {
1791e4b17023SJohn Marino   pre_expr phitrans;
1792e4b17023SJohn Marino 
1793e4b17023SJohn Marino   if (!expr)
1794e4b17023SJohn Marino     return NULL;
1795e4b17023SJohn Marino 
1796e4b17023SJohn Marino   /* Constants contain no values that need translation.  */
1797e4b17023SJohn Marino   if (expr->kind == CONSTANT)
1798e4b17023SJohn Marino     return expr;
1799e4b17023SJohn Marino 
1800e4b17023SJohn Marino   if (value_id_constant_p (get_expr_value_id (expr)))
1801e4b17023SJohn Marino     return expr;
1802e4b17023SJohn Marino 
1803e4b17023SJohn Marino   if (expr->kind != NAME)
1804e4b17023SJohn Marino     {
1805e4b17023SJohn Marino       phitrans = phi_trans_lookup (expr, pred);
1806e4b17023SJohn Marino       if (phitrans)
1807e4b17023SJohn Marino 	return phitrans;
1808e4b17023SJohn Marino     }
1809e4b17023SJohn Marino 
1810e4b17023SJohn Marino   /* Translate.  */
1811e4b17023SJohn Marino   phitrans = phi_translate_1 (expr, set1, set2, pred, phiblock);
1812e4b17023SJohn Marino 
1813e4b17023SJohn Marino   /* Don't add empty translations to the cache.  Neither add
1814e4b17023SJohn Marino      translations of NAMEs as those are cheap to translate.  */
1815e4b17023SJohn Marino   if (phitrans
1816e4b17023SJohn Marino       && expr->kind != NAME)
1817e4b17023SJohn Marino     phi_trans_add (expr, phitrans, pred);
1818e4b17023SJohn Marino 
1819e4b17023SJohn Marino   return phitrans;
1820e4b17023SJohn Marino }
1821e4b17023SJohn Marino 
1822e4b17023SJohn Marino 
1823e4b17023SJohn Marino /* For each expression in SET, translate the values through phi nodes
1824e4b17023SJohn Marino    in PHIBLOCK using edge PHIBLOCK->PRED, and store the resulting
1825e4b17023SJohn Marino    expressions in DEST.  */
1826e4b17023SJohn Marino 
1827e4b17023SJohn Marino static void
phi_translate_set(bitmap_set_t dest,bitmap_set_t set,basic_block pred,basic_block phiblock)1828e4b17023SJohn Marino phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
1829e4b17023SJohn Marino 		   basic_block phiblock)
1830e4b17023SJohn Marino {
1831e4b17023SJohn Marino   VEC (pre_expr, heap) *exprs;
1832e4b17023SJohn Marino   pre_expr expr;
1833e4b17023SJohn Marino   int i;
1834e4b17023SJohn Marino 
1835e4b17023SJohn Marino   if (gimple_seq_empty_p (phi_nodes (phiblock)))
1836e4b17023SJohn Marino     {
1837e4b17023SJohn Marino       bitmap_set_copy (dest, set);
1838e4b17023SJohn Marino       return;
1839e4b17023SJohn Marino     }
1840e4b17023SJohn Marino 
1841e4b17023SJohn Marino   exprs = sorted_array_from_bitmap_set (set);
1842e4b17023SJohn Marino   FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
1843e4b17023SJohn Marino     {
1844e4b17023SJohn Marino       pre_expr translated;
1845e4b17023SJohn Marino       translated = phi_translate (expr, set, NULL, pred, phiblock);
1846e4b17023SJohn Marino       if (!translated)
1847e4b17023SJohn Marino 	continue;
1848e4b17023SJohn Marino 
1849e4b17023SJohn Marino       /* We might end up with multiple expressions from SET being
1850e4b17023SJohn Marino 	 translated to the same value.  In this case we do not want
1851e4b17023SJohn Marino 	 to retain the NARY or REFERENCE expression but prefer a NAME
1852e4b17023SJohn Marino 	 which would be the leader.  */
1853e4b17023SJohn Marino       if (translated->kind == NAME)
1854e4b17023SJohn Marino 	bitmap_value_replace_in_set (dest, translated);
1855e4b17023SJohn Marino       else
1856e4b17023SJohn Marino 	bitmap_value_insert_into_set (dest, translated);
1857e4b17023SJohn Marino     }
1858e4b17023SJohn Marino   VEC_free (pre_expr, heap, exprs);
1859e4b17023SJohn Marino }
1860e4b17023SJohn Marino 
1861e4b17023SJohn Marino /* Find the leader for a value (i.e., the name representing that
1862e4b17023SJohn Marino    value) in a given set, and return it.  If STMT is non-NULL it
1863e4b17023SJohn Marino    makes sure the defining statement for the leader dominates it.
1864e4b17023SJohn Marino    Return NULL if no leader is found.  */
1865e4b17023SJohn Marino 
1866e4b17023SJohn Marino static pre_expr
bitmap_find_leader(bitmap_set_t set,unsigned int val,gimple stmt)1867e4b17023SJohn Marino bitmap_find_leader (bitmap_set_t set, unsigned int val, gimple stmt)
1868e4b17023SJohn Marino {
1869e4b17023SJohn Marino   if (value_id_constant_p (val))
1870e4b17023SJohn Marino     {
1871e4b17023SJohn Marino       unsigned int i;
1872e4b17023SJohn Marino       bitmap_iterator bi;
1873e4b17023SJohn Marino       bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, val);
1874e4b17023SJohn Marino 
1875e4b17023SJohn Marino       FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
1876e4b17023SJohn Marino 	{
1877e4b17023SJohn Marino 	  pre_expr expr = expression_for_id (i);
1878e4b17023SJohn Marino 	  if (expr->kind == CONSTANT)
1879e4b17023SJohn Marino 	    return expr;
1880e4b17023SJohn Marino 	}
1881e4b17023SJohn Marino     }
1882e4b17023SJohn Marino   if (bitmap_set_contains_value (set, val))
1883e4b17023SJohn Marino     {
1884e4b17023SJohn Marino       /* Rather than walk the entire bitmap of expressions, and see
1885e4b17023SJohn Marino 	 whether any of them has the value we are looking for, we look
1886e4b17023SJohn Marino 	 at the reverse mapping, which tells us the set of expressions
1887e4b17023SJohn Marino 	 that have a given value (IE value->expressions with that
1888e4b17023SJohn Marino 	 value) and see if any of those expressions are in our set.
1889e4b17023SJohn Marino 	 The number of expressions per value is usually significantly
1890e4b17023SJohn Marino 	 less than the number of expressions in the set.  In fact, for
1891e4b17023SJohn Marino 	 large testcases, doing it this way is roughly 5-10x faster
1892e4b17023SJohn Marino 	 than walking the bitmap.
1893e4b17023SJohn Marino 	 If this is somehow a significant lose for some cases, we can
1894e4b17023SJohn Marino 	 choose which set to walk based on which set is smaller.  */
1895e4b17023SJohn Marino       unsigned int i;
1896e4b17023SJohn Marino       bitmap_iterator bi;
1897e4b17023SJohn Marino       bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, val);
1898e4b17023SJohn Marino 
1899e4b17023SJohn Marino       EXECUTE_IF_AND_IN_BITMAP (&exprset->expressions,
1900e4b17023SJohn Marino 				&set->expressions, 0, i, bi)
1901e4b17023SJohn Marino 	{
1902e4b17023SJohn Marino 	  pre_expr val = expression_for_id (i);
1903e4b17023SJohn Marino 	  /* At the point where stmt is not null, there should always
1904e4b17023SJohn Marino 	     be an SSA_NAME first in the list of expressions.  */
1905e4b17023SJohn Marino 	  if (stmt)
1906e4b17023SJohn Marino 	    {
1907e4b17023SJohn Marino 	      gimple def_stmt = SSA_NAME_DEF_STMT (PRE_EXPR_NAME (val));
1908e4b17023SJohn Marino 	      if (gimple_code (def_stmt) != GIMPLE_PHI
1909e4b17023SJohn Marino 		  && gimple_bb (def_stmt) == gimple_bb (stmt)
1910e4b17023SJohn Marino 		  /* PRE insertions are at the end of the basic-block
1911e4b17023SJohn Marino 		     and have UID 0.  */
1912e4b17023SJohn Marino 		  && (gimple_uid (def_stmt) == 0
1913e4b17023SJohn Marino 		      || gimple_uid (def_stmt) >= gimple_uid (stmt)))
1914e4b17023SJohn Marino 		continue;
1915e4b17023SJohn Marino 	    }
1916e4b17023SJohn Marino 	  return val;
1917e4b17023SJohn Marino 	}
1918e4b17023SJohn Marino     }
1919e4b17023SJohn Marino   return NULL;
1920e4b17023SJohn Marino }
1921e4b17023SJohn Marino 
1922e4b17023SJohn Marino /* Determine if EXPR, a memory expression, is ANTIC_IN at the top of
1923e4b17023SJohn Marino    BLOCK by seeing if it is not killed in the block.  Note that we are
1924e4b17023SJohn Marino    only determining whether there is a store that kills it.  Because
1925e4b17023SJohn Marino    of the order in which clean iterates over values, we are guaranteed
1926e4b17023SJohn Marino    that altered operands will have caused us to be eliminated from the
1927e4b17023SJohn Marino    ANTIC_IN set already.  */
1928e4b17023SJohn Marino 
1929e4b17023SJohn Marino static bool
value_dies_in_block_x(pre_expr expr,basic_block block)1930e4b17023SJohn Marino value_dies_in_block_x (pre_expr expr, basic_block block)
1931e4b17023SJohn Marino {
1932e4b17023SJohn Marino   tree vuse = PRE_EXPR_REFERENCE (expr)->vuse;
1933e4b17023SJohn Marino   vn_reference_t refx = PRE_EXPR_REFERENCE (expr);
1934e4b17023SJohn Marino   gimple def;
1935e4b17023SJohn Marino   gimple_stmt_iterator gsi;
1936e4b17023SJohn Marino   unsigned id = get_expression_id (expr);
1937e4b17023SJohn Marino   bool res = false;
1938e4b17023SJohn Marino   ao_ref ref;
1939e4b17023SJohn Marino 
1940e4b17023SJohn Marino   if (!vuse)
1941e4b17023SJohn Marino     return false;
1942e4b17023SJohn Marino 
1943e4b17023SJohn Marino   /* Lookup a previously calculated result.  */
1944e4b17023SJohn Marino   if (EXPR_DIES (block)
1945e4b17023SJohn Marino       && bitmap_bit_p (EXPR_DIES (block), id * 2))
1946e4b17023SJohn Marino     return bitmap_bit_p (EXPR_DIES (block), id * 2 + 1);
1947e4b17023SJohn Marino 
1948e4b17023SJohn Marino   /* A memory expression {e, VUSE} dies in the block if there is a
1949e4b17023SJohn Marino      statement that may clobber e.  If, starting statement walk from the
1950e4b17023SJohn Marino      top of the basic block, a statement uses VUSE there can be no kill
1951e4b17023SJohn Marino      inbetween that use and the original statement that loaded {e, VUSE},
1952e4b17023SJohn Marino      so we can stop walking.  */
1953e4b17023SJohn Marino   ref.base = NULL_TREE;
1954e4b17023SJohn Marino   for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
1955e4b17023SJohn Marino     {
1956e4b17023SJohn Marino       tree def_vuse, def_vdef;
1957e4b17023SJohn Marino       def = gsi_stmt (gsi);
1958e4b17023SJohn Marino       def_vuse = gimple_vuse (def);
1959e4b17023SJohn Marino       def_vdef = gimple_vdef (def);
1960e4b17023SJohn Marino 
1961e4b17023SJohn Marino       /* Not a memory statement.  */
1962e4b17023SJohn Marino       if (!def_vuse)
1963e4b17023SJohn Marino 	continue;
1964e4b17023SJohn Marino 
1965e4b17023SJohn Marino       /* Not a may-def.  */
1966e4b17023SJohn Marino       if (!def_vdef)
1967e4b17023SJohn Marino 	{
1968e4b17023SJohn Marino 	  /* A load with the same VUSE, we're done.  */
1969e4b17023SJohn Marino 	  if (def_vuse == vuse)
1970e4b17023SJohn Marino 	    break;
1971e4b17023SJohn Marino 
1972e4b17023SJohn Marino 	  continue;
1973e4b17023SJohn Marino 	}
1974e4b17023SJohn Marino 
1975e4b17023SJohn Marino       /* Init ref only if we really need it.  */
1976e4b17023SJohn Marino       if (ref.base == NULL_TREE
1977e4b17023SJohn Marino 	  && !ao_ref_init_from_vn_reference (&ref, refx->set, refx->type,
1978e4b17023SJohn Marino 					     refx->operands))
1979e4b17023SJohn Marino 	{
1980e4b17023SJohn Marino 	  res = true;
1981e4b17023SJohn Marino 	  break;
1982e4b17023SJohn Marino 	}
1983e4b17023SJohn Marino       /* If the statement may clobber expr, it dies.  */
1984e4b17023SJohn Marino       if (stmt_may_clobber_ref_p_1 (def, &ref))
1985e4b17023SJohn Marino 	{
1986e4b17023SJohn Marino 	  res = true;
1987e4b17023SJohn Marino 	  break;
1988e4b17023SJohn Marino 	}
1989e4b17023SJohn Marino     }
1990e4b17023SJohn Marino 
1991e4b17023SJohn Marino   /* Remember the result.  */
1992e4b17023SJohn Marino   if (!EXPR_DIES (block))
1993e4b17023SJohn Marino     EXPR_DIES (block) = BITMAP_ALLOC (&grand_bitmap_obstack);
1994e4b17023SJohn Marino   bitmap_set_bit (EXPR_DIES (block), id * 2);
1995e4b17023SJohn Marino   if (res)
1996e4b17023SJohn Marino     bitmap_set_bit (EXPR_DIES (block), id * 2 + 1);
1997e4b17023SJohn Marino 
1998e4b17023SJohn Marino   return res;
1999e4b17023SJohn Marino }
2000e4b17023SJohn Marino 
2001e4b17023SJohn Marino 
2002e4b17023SJohn Marino #define union_contains_value(SET1, SET2, VAL)			\
2003e4b17023SJohn Marino   (bitmap_set_contains_value ((SET1), (VAL))			\
2004e4b17023SJohn Marino    || ((SET2) && bitmap_set_contains_value ((SET2), (VAL))))
2005e4b17023SJohn Marino 
2006e4b17023SJohn Marino /* Determine if vn_reference_op_t VRO is legal in SET1 U SET2.
2007e4b17023SJohn Marino  */
2008e4b17023SJohn Marino static bool
vro_valid_in_sets(bitmap_set_t set1,bitmap_set_t set2,vn_reference_op_t vro)2009e4b17023SJohn Marino vro_valid_in_sets (bitmap_set_t set1, bitmap_set_t set2,
2010e4b17023SJohn Marino 		   vn_reference_op_t vro)
2011e4b17023SJohn Marino {
2012e4b17023SJohn Marino   if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
2013e4b17023SJohn Marino     {
2014e4b17023SJohn Marino       struct pre_expr_d temp;
2015e4b17023SJohn Marino       temp.kind = NAME;
2016e4b17023SJohn Marino       temp.id = 0;
2017e4b17023SJohn Marino       PRE_EXPR_NAME (&temp) = vro->op0;
2018e4b17023SJohn Marino       temp.id = lookup_expression_id (&temp);
2019e4b17023SJohn Marino       if (temp.id == 0)
2020e4b17023SJohn Marino 	return false;
2021e4b17023SJohn Marino       if (!union_contains_value (set1, set2,
2022e4b17023SJohn Marino 				 get_expr_value_id (&temp)))
2023e4b17023SJohn Marino 	return false;
2024e4b17023SJohn Marino     }
2025e4b17023SJohn Marino   if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
2026e4b17023SJohn Marino     {
2027e4b17023SJohn Marino       struct pre_expr_d temp;
2028e4b17023SJohn Marino       temp.kind = NAME;
2029e4b17023SJohn Marino       temp.id = 0;
2030e4b17023SJohn Marino       PRE_EXPR_NAME (&temp) = vro->op1;
2031e4b17023SJohn Marino       temp.id = lookup_expression_id (&temp);
2032e4b17023SJohn Marino       if (temp.id == 0)
2033e4b17023SJohn Marino 	return false;
2034e4b17023SJohn Marino       if (!union_contains_value (set1, set2,
2035e4b17023SJohn Marino 				 get_expr_value_id (&temp)))
2036e4b17023SJohn Marino 	return false;
2037e4b17023SJohn Marino     }
2038e4b17023SJohn Marino 
2039e4b17023SJohn Marino   if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
2040e4b17023SJohn Marino     {
2041e4b17023SJohn Marino       struct pre_expr_d temp;
2042e4b17023SJohn Marino       temp.kind = NAME;
2043e4b17023SJohn Marino       temp.id = 0;
2044e4b17023SJohn Marino       PRE_EXPR_NAME (&temp) = vro->op2;
2045e4b17023SJohn Marino       temp.id = lookup_expression_id (&temp);
2046e4b17023SJohn Marino       if (temp.id == 0)
2047e4b17023SJohn Marino 	return false;
2048e4b17023SJohn Marino       if (!union_contains_value (set1, set2,
2049e4b17023SJohn Marino 				 get_expr_value_id (&temp)))
2050e4b17023SJohn Marino 	return false;
2051e4b17023SJohn Marino     }
2052e4b17023SJohn Marino 
2053e4b17023SJohn Marino   return true;
2054e4b17023SJohn Marino }
2055e4b17023SJohn Marino 
2056e4b17023SJohn Marino /* Determine if the expression EXPR is valid in SET1 U SET2.
2057e4b17023SJohn Marino    ONLY SET2 CAN BE NULL.
2058e4b17023SJohn Marino    This means that we have a leader for each part of the expression
2059e4b17023SJohn Marino    (if it consists of values), or the expression is an SSA_NAME.
2060e4b17023SJohn Marino    For loads/calls, we also see if the vuse is killed in this block.  */
2061e4b17023SJohn Marino 
2062e4b17023SJohn Marino static bool
valid_in_sets(bitmap_set_t set1,bitmap_set_t set2,pre_expr expr,basic_block block)2063e4b17023SJohn Marino valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
2064e4b17023SJohn Marino 	       basic_block block)
2065e4b17023SJohn Marino {
2066e4b17023SJohn Marino   switch (expr->kind)
2067e4b17023SJohn Marino     {
2068e4b17023SJohn Marino     case NAME:
2069e4b17023SJohn Marino       return bitmap_set_contains_expr (AVAIL_OUT (block), expr);
2070e4b17023SJohn Marino     case NARY:
2071e4b17023SJohn Marino       {
2072e4b17023SJohn Marino 	unsigned int i;
2073e4b17023SJohn Marino 	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
2074e4b17023SJohn Marino 	for (i = 0; i < nary->length; i++)
2075e4b17023SJohn Marino 	  {
2076e4b17023SJohn Marino 	    if (TREE_CODE (nary->op[i]) == SSA_NAME)
2077e4b17023SJohn Marino 	      {
2078e4b17023SJohn Marino 		struct pre_expr_d temp;
2079e4b17023SJohn Marino 		temp.kind = NAME;
2080e4b17023SJohn Marino 		temp.id = 0;
2081e4b17023SJohn Marino 		PRE_EXPR_NAME (&temp) = nary->op[i];
2082e4b17023SJohn Marino 		temp.id = lookup_expression_id (&temp);
2083e4b17023SJohn Marino 		if (temp.id == 0)
2084e4b17023SJohn Marino 		  return false;
2085e4b17023SJohn Marino 		if (!union_contains_value (set1, set2,
2086e4b17023SJohn Marino 					   get_expr_value_id (&temp)))
2087e4b17023SJohn Marino 		  return false;
2088e4b17023SJohn Marino 	      }
2089e4b17023SJohn Marino 	  }
2090e4b17023SJohn Marino 	/* If the NARY may trap make sure the block does not contain
2091e4b17023SJohn Marino 	   a possible exit point.
2092e4b17023SJohn Marino 	   ???  This is overly conservative if we translate AVAIL_OUT
2093e4b17023SJohn Marino 	   as the available expression might be after the exit point.  */
2094e4b17023SJohn Marino 	if (BB_MAY_NOTRETURN (block)
2095e4b17023SJohn Marino 	    && vn_nary_may_trap (nary))
2096e4b17023SJohn Marino 	  return false;
2097e4b17023SJohn Marino 	return true;
2098e4b17023SJohn Marino       }
2099e4b17023SJohn Marino       break;
2100e4b17023SJohn Marino     case REFERENCE:
2101e4b17023SJohn Marino       {
2102e4b17023SJohn Marino 	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
2103e4b17023SJohn Marino 	vn_reference_op_t vro;
2104e4b17023SJohn Marino 	unsigned int i;
2105e4b17023SJohn Marino 
2106e4b17023SJohn Marino 	FOR_EACH_VEC_ELT (vn_reference_op_s, ref->operands, i, vro)
2107e4b17023SJohn Marino 	  {
2108e4b17023SJohn Marino 	    if (!vro_valid_in_sets (set1, set2, vro))
2109e4b17023SJohn Marino 	      return false;
2110e4b17023SJohn Marino 	  }
2111e4b17023SJohn Marino 	if (ref->vuse)
2112e4b17023SJohn Marino 	  {
2113e4b17023SJohn Marino 	    gimple def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
2114e4b17023SJohn Marino 	    if (!gimple_nop_p (def_stmt)
2115e4b17023SJohn Marino 		&& gimple_bb (def_stmt) != block
2116e4b17023SJohn Marino 		&& !dominated_by_p (CDI_DOMINATORS,
2117e4b17023SJohn Marino 				    block, gimple_bb (def_stmt)))
2118e4b17023SJohn Marino 	      return false;
2119e4b17023SJohn Marino 	  }
2120e4b17023SJohn Marino 	return !value_dies_in_block_x (expr, block);
2121e4b17023SJohn Marino       }
2122e4b17023SJohn Marino     default:
2123e4b17023SJohn Marino       gcc_unreachable ();
2124e4b17023SJohn Marino     }
2125e4b17023SJohn Marino }
2126e4b17023SJohn Marino 
2127e4b17023SJohn Marino /* Clean the set of expressions that are no longer valid in SET1 or
2128e4b17023SJohn Marino    SET2.  This means expressions that are made up of values we have no
2129e4b17023SJohn Marino    leaders for in SET1 or SET2.  This version is used for partial
2130e4b17023SJohn Marino    anticipation, which means it is not valid in either ANTIC_IN or
2131e4b17023SJohn Marino    PA_IN.  */
2132e4b17023SJohn Marino 
2133e4b17023SJohn Marino static void
dependent_clean(bitmap_set_t set1,bitmap_set_t set2,basic_block block)2134e4b17023SJohn Marino dependent_clean (bitmap_set_t set1, bitmap_set_t set2, basic_block block)
2135e4b17023SJohn Marino {
2136e4b17023SJohn Marino   VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set1);
2137e4b17023SJohn Marino   pre_expr expr;
2138e4b17023SJohn Marino   int i;
2139e4b17023SJohn Marino 
2140e4b17023SJohn Marino   FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
2141e4b17023SJohn Marino     {
2142e4b17023SJohn Marino       if (!valid_in_sets (set1, set2, expr, block))
2143e4b17023SJohn Marino 	bitmap_remove_from_set (set1, expr);
2144e4b17023SJohn Marino     }
2145e4b17023SJohn Marino   VEC_free (pre_expr, heap, exprs);
2146e4b17023SJohn Marino }
2147e4b17023SJohn Marino 
2148e4b17023SJohn Marino /* Clean the set of expressions that are no longer valid in SET.  This
2149e4b17023SJohn Marino    means expressions that are made up of values we have no leaders for
2150e4b17023SJohn Marino    in SET.  */
2151e4b17023SJohn Marino 
2152e4b17023SJohn Marino static void
clean(bitmap_set_t set,basic_block block)2153e4b17023SJohn Marino clean (bitmap_set_t set, basic_block block)
2154e4b17023SJohn Marino {
2155e4b17023SJohn Marino   VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set);
2156e4b17023SJohn Marino   pre_expr expr;
2157e4b17023SJohn Marino   int i;
2158e4b17023SJohn Marino 
2159e4b17023SJohn Marino   FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
2160e4b17023SJohn Marino     {
2161e4b17023SJohn Marino       if (!valid_in_sets (set, NULL, expr, block))
2162e4b17023SJohn Marino 	bitmap_remove_from_set (set, expr);
2163e4b17023SJohn Marino     }
2164e4b17023SJohn Marino   VEC_free (pre_expr, heap, exprs);
2165e4b17023SJohn Marino }
2166e4b17023SJohn Marino 
2167e4b17023SJohn Marino static sbitmap has_abnormal_preds;
2168e4b17023SJohn Marino 
2169e4b17023SJohn Marino /* List of blocks that may have changed during ANTIC computation and
2170e4b17023SJohn Marino    thus need to be iterated over.  */
2171e4b17023SJohn Marino 
2172e4b17023SJohn Marino static sbitmap changed_blocks;
2173e4b17023SJohn Marino 
2174e4b17023SJohn Marino /* Decide whether to defer a block for a later iteration, or PHI
2175e4b17023SJohn Marino    translate SOURCE to DEST using phis in PHIBLOCK.  Return false if we
2176e4b17023SJohn Marino    should defer the block, and true if we processed it.  */
2177e4b17023SJohn Marino 
2178e4b17023SJohn Marino static bool
defer_or_phi_translate_block(bitmap_set_t dest,bitmap_set_t source,basic_block block,basic_block phiblock)2179e4b17023SJohn Marino defer_or_phi_translate_block (bitmap_set_t dest, bitmap_set_t source,
2180e4b17023SJohn Marino 			      basic_block block, basic_block phiblock)
2181e4b17023SJohn Marino {
2182e4b17023SJohn Marino   if (!BB_VISITED (phiblock))
2183e4b17023SJohn Marino     {
2184e4b17023SJohn Marino       SET_BIT (changed_blocks, block->index);
2185e4b17023SJohn Marino       BB_VISITED (block) = 0;
2186e4b17023SJohn Marino       BB_DEFERRED (block) = 1;
2187e4b17023SJohn Marino       return false;
2188e4b17023SJohn Marino     }
2189e4b17023SJohn Marino   else
2190e4b17023SJohn Marino     phi_translate_set (dest, source, block, phiblock);
2191e4b17023SJohn Marino   return true;
2192e4b17023SJohn Marino }
2193e4b17023SJohn Marino 
2194e4b17023SJohn Marino /* Compute the ANTIC set for BLOCK.
2195e4b17023SJohn Marino 
2196e4b17023SJohn Marino    If succs(BLOCK) > 1 then
2197e4b17023SJohn Marino      ANTIC_OUT[BLOCK] = intersection of ANTIC_IN[b] for all succ(BLOCK)
2198e4b17023SJohn Marino    else if succs(BLOCK) == 1 then
2199e4b17023SJohn Marino      ANTIC_OUT[BLOCK] = phi_translate (ANTIC_IN[succ(BLOCK)])
2200e4b17023SJohn Marino 
2201e4b17023SJohn Marino    ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] - TMP_GEN[BLOCK])
2202e4b17023SJohn Marino */
2203e4b17023SJohn Marino 
2204e4b17023SJohn Marino static bool
compute_antic_aux(basic_block block,bool block_has_abnormal_pred_edge)2205e4b17023SJohn Marino compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
2206e4b17023SJohn Marino {
2207e4b17023SJohn Marino   bool changed = false;
2208e4b17023SJohn Marino   bitmap_set_t S, old, ANTIC_OUT;
2209e4b17023SJohn Marino   bitmap_iterator bi;
2210e4b17023SJohn Marino   unsigned int bii;
2211e4b17023SJohn Marino   edge e;
2212e4b17023SJohn Marino   edge_iterator ei;
2213e4b17023SJohn Marino 
2214e4b17023SJohn Marino   old = ANTIC_OUT = S = NULL;
2215e4b17023SJohn Marino   BB_VISITED (block) = 1;
2216e4b17023SJohn Marino 
2217e4b17023SJohn Marino   /* If any edges from predecessors are abnormal, antic_in is empty,
2218e4b17023SJohn Marino      so do nothing.  */
2219e4b17023SJohn Marino   if (block_has_abnormal_pred_edge)
2220e4b17023SJohn Marino     goto maybe_dump_sets;
2221e4b17023SJohn Marino 
2222e4b17023SJohn Marino   old = ANTIC_IN (block);
2223e4b17023SJohn Marino   ANTIC_OUT = bitmap_set_new ();
2224e4b17023SJohn Marino 
2225e4b17023SJohn Marino   /* If the block has no successors, ANTIC_OUT is empty.  */
2226e4b17023SJohn Marino   if (EDGE_COUNT (block->succs) == 0)
2227e4b17023SJohn Marino     ;
2228e4b17023SJohn Marino   /* If we have one successor, we could have some phi nodes to
2229e4b17023SJohn Marino      translate through.  */
2230e4b17023SJohn Marino   else if (single_succ_p (block))
2231e4b17023SJohn Marino     {
2232e4b17023SJohn Marino       basic_block succ_bb = single_succ (block);
2233e4b17023SJohn Marino 
2234e4b17023SJohn Marino       /* We trade iterations of the dataflow equations for having to
2235e4b17023SJohn Marino 	 phi translate the maximal set, which is incredibly slow
2236e4b17023SJohn Marino 	 (since the maximal set often has 300+ members, even when you
2237e4b17023SJohn Marino 	 have a small number of blocks).
2238e4b17023SJohn Marino 	 Basically, we defer the computation of ANTIC for this block
2239e4b17023SJohn Marino 	 until we have processed it's successor, which will inevitably
2240e4b17023SJohn Marino 	 have a *much* smaller set of values to phi translate once
2241e4b17023SJohn Marino 	 clean has been run on it.
2242e4b17023SJohn Marino 	 The cost of doing this is that we technically perform more
2243e4b17023SJohn Marino 	 iterations, however, they are lower cost iterations.
2244e4b17023SJohn Marino 
2245e4b17023SJohn Marino 	 Timings for PRE on tramp3d-v4:
2246e4b17023SJohn Marino 	 without maximal set fix: 11 seconds
2247e4b17023SJohn Marino 	 with maximal set fix/without deferring: 26 seconds
2248e4b17023SJohn Marino 	 with maximal set fix/with deferring: 11 seconds
2249e4b17023SJohn Marino      */
2250e4b17023SJohn Marino 
2251e4b17023SJohn Marino       if (!defer_or_phi_translate_block (ANTIC_OUT, ANTIC_IN (succ_bb),
2252e4b17023SJohn Marino 					block, succ_bb))
2253e4b17023SJohn Marino 	{
2254e4b17023SJohn Marino 	  changed = true;
2255e4b17023SJohn Marino 	  goto maybe_dump_sets;
2256e4b17023SJohn Marino 	}
2257e4b17023SJohn Marino     }
2258e4b17023SJohn Marino   /* If we have multiple successors, we take the intersection of all of
2259e4b17023SJohn Marino      them.  Note that in the case of loop exit phi nodes, we may have
2260e4b17023SJohn Marino      phis to translate through.  */
2261e4b17023SJohn Marino   else
2262e4b17023SJohn Marino     {
2263e4b17023SJohn Marino       VEC(basic_block, heap) * worklist;
2264e4b17023SJohn Marino       size_t i;
2265e4b17023SJohn Marino       basic_block bprime, first = NULL;
2266e4b17023SJohn Marino 
2267e4b17023SJohn Marino       worklist = VEC_alloc (basic_block, heap, EDGE_COUNT (block->succs));
2268e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, block->succs)
2269e4b17023SJohn Marino 	{
2270e4b17023SJohn Marino 	  if (!first
2271e4b17023SJohn Marino 	      && BB_VISITED (e->dest))
2272e4b17023SJohn Marino 	    first = e->dest;
2273e4b17023SJohn Marino 	  else if (BB_VISITED (e->dest))
2274e4b17023SJohn Marino 	    VEC_quick_push (basic_block, worklist, e->dest);
2275e4b17023SJohn Marino 	}
2276e4b17023SJohn Marino 
2277e4b17023SJohn Marino       /* Of multiple successors we have to have visited one already.  */
2278e4b17023SJohn Marino       if (!first)
2279e4b17023SJohn Marino 	{
2280e4b17023SJohn Marino 	  SET_BIT (changed_blocks, block->index);
2281e4b17023SJohn Marino 	  BB_VISITED (block) = 0;
2282e4b17023SJohn Marino 	  BB_DEFERRED (block) = 1;
2283e4b17023SJohn Marino 	  changed = true;
2284e4b17023SJohn Marino 	  VEC_free (basic_block, heap, worklist);
2285e4b17023SJohn Marino 	  goto maybe_dump_sets;
2286e4b17023SJohn Marino 	}
2287e4b17023SJohn Marino 
2288e4b17023SJohn Marino       if (!gimple_seq_empty_p (phi_nodes (first)))
2289e4b17023SJohn Marino 	phi_translate_set (ANTIC_OUT, ANTIC_IN (first), block, first);
2290e4b17023SJohn Marino       else
2291e4b17023SJohn Marino 	bitmap_set_copy (ANTIC_OUT, ANTIC_IN (first));
2292e4b17023SJohn Marino 
2293e4b17023SJohn Marino       FOR_EACH_VEC_ELT (basic_block, worklist, i, bprime)
2294e4b17023SJohn Marino 	{
2295e4b17023SJohn Marino 	  if (!gimple_seq_empty_p (phi_nodes (bprime)))
2296e4b17023SJohn Marino 	    {
2297e4b17023SJohn Marino 	      bitmap_set_t tmp = bitmap_set_new ();
2298e4b17023SJohn Marino 	      phi_translate_set (tmp, ANTIC_IN (bprime), block, bprime);
2299e4b17023SJohn Marino 	      bitmap_set_and (ANTIC_OUT, tmp);
2300e4b17023SJohn Marino 	      bitmap_set_free (tmp);
2301e4b17023SJohn Marino 	    }
2302e4b17023SJohn Marino 	  else
2303e4b17023SJohn Marino 	    bitmap_set_and (ANTIC_OUT, ANTIC_IN (bprime));
2304e4b17023SJohn Marino 	}
2305e4b17023SJohn Marino       VEC_free (basic_block, heap, worklist);
2306e4b17023SJohn Marino     }
2307e4b17023SJohn Marino 
2308e4b17023SJohn Marino   /* Generate ANTIC_OUT - TMP_GEN.  */
2309e4b17023SJohn Marino   S = bitmap_set_subtract (ANTIC_OUT, TMP_GEN (block));
2310e4b17023SJohn Marino 
2311e4b17023SJohn Marino   /* Start ANTIC_IN with EXP_GEN - TMP_GEN.  */
2312e4b17023SJohn Marino   ANTIC_IN (block) = bitmap_set_subtract (EXP_GEN (block),
2313e4b17023SJohn Marino 					  TMP_GEN (block));
2314e4b17023SJohn Marino 
2315e4b17023SJohn Marino   /* Then union in the ANTIC_OUT - TMP_GEN values,
2316e4b17023SJohn Marino      to get ANTIC_OUT U EXP_GEN - TMP_GEN */
2317e4b17023SJohn Marino   FOR_EACH_EXPR_ID_IN_SET (S, bii, bi)
2318e4b17023SJohn Marino     bitmap_value_insert_into_set (ANTIC_IN (block),
2319e4b17023SJohn Marino 				  expression_for_id (bii));
2320e4b17023SJohn Marino 
2321e4b17023SJohn Marino   clean (ANTIC_IN (block), block);
2322e4b17023SJohn Marino 
2323e4b17023SJohn Marino   if (!bitmap_set_equal (old, ANTIC_IN (block)))
2324e4b17023SJohn Marino     {
2325e4b17023SJohn Marino       changed = true;
2326e4b17023SJohn Marino       SET_BIT (changed_blocks, block->index);
2327e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, block->preds)
2328e4b17023SJohn Marino 	SET_BIT (changed_blocks, e->src->index);
2329e4b17023SJohn Marino     }
2330e4b17023SJohn Marino   else
2331e4b17023SJohn Marino     RESET_BIT (changed_blocks, block->index);
2332e4b17023SJohn Marino 
2333e4b17023SJohn Marino  maybe_dump_sets:
2334e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
2335e4b17023SJohn Marino     {
2336e4b17023SJohn Marino       if (!BB_DEFERRED (block) || BB_VISITED (block))
2337e4b17023SJohn Marino 	{
2338e4b17023SJohn Marino 	  if (ANTIC_OUT)
2339e4b17023SJohn Marino 	    print_bitmap_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);
2340e4b17023SJohn Marino 
2341e4b17023SJohn Marino 	  print_bitmap_set (dump_file, ANTIC_IN (block), "ANTIC_IN",
2342e4b17023SJohn Marino 			    block->index);
2343e4b17023SJohn Marino 
2344e4b17023SJohn Marino 	  if (S)
2345e4b17023SJohn Marino 	    print_bitmap_set (dump_file, S, "S", block->index);
2346e4b17023SJohn Marino 	}
2347e4b17023SJohn Marino       else
2348e4b17023SJohn Marino 	{
2349e4b17023SJohn Marino 	  fprintf (dump_file,
2350e4b17023SJohn Marino 		   "Block %d was deferred for a future iteration.\n",
2351e4b17023SJohn Marino 		   block->index);
2352e4b17023SJohn Marino 	}
2353e4b17023SJohn Marino     }
2354e4b17023SJohn Marino   if (old)
2355e4b17023SJohn Marino     bitmap_set_free (old);
2356e4b17023SJohn Marino   if (S)
2357e4b17023SJohn Marino     bitmap_set_free (S);
2358e4b17023SJohn Marino   if (ANTIC_OUT)
2359e4b17023SJohn Marino     bitmap_set_free (ANTIC_OUT);
2360e4b17023SJohn Marino   return changed;
2361e4b17023SJohn Marino }
2362e4b17023SJohn Marino 
2363e4b17023SJohn Marino /* Compute PARTIAL_ANTIC for BLOCK.
2364e4b17023SJohn Marino 
2365e4b17023SJohn Marino    If succs(BLOCK) > 1 then
2366e4b17023SJohn Marino      PA_OUT[BLOCK] = value wise union of PA_IN[b] + all ANTIC_IN not
2367e4b17023SJohn Marino      in ANTIC_OUT for all succ(BLOCK)
2368e4b17023SJohn Marino    else if succs(BLOCK) == 1 then
2369e4b17023SJohn Marino      PA_OUT[BLOCK] = phi_translate (PA_IN[succ(BLOCK)])
2370e4b17023SJohn Marino 
2371e4b17023SJohn Marino    PA_IN[BLOCK] = dependent_clean(PA_OUT[BLOCK] - TMP_GEN[BLOCK]
2372e4b17023SJohn Marino 				  - ANTIC_IN[BLOCK])
2373e4b17023SJohn Marino 
2374e4b17023SJohn Marino */
2375e4b17023SJohn Marino static bool
compute_partial_antic_aux(basic_block block,bool block_has_abnormal_pred_edge)2376e4b17023SJohn Marino compute_partial_antic_aux (basic_block block,
2377e4b17023SJohn Marino 			   bool block_has_abnormal_pred_edge)
2378e4b17023SJohn Marino {
2379e4b17023SJohn Marino   bool changed = false;
2380e4b17023SJohn Marino   bitmap_set_t old_PA_IN;
2381e4b17023SJohn Marino   bitmap_set_t PA_OUT;
2382e4b17023SJohn Marino   edge e;
2383e4b17023SJohn Marino   edge_iterator ei;
2384e4b17023SJohn Marino   unsigned long max_pa = PARAM_VALUE (PARAM_MAX_PARTIAL_ANTIC_LENGTH);
2385e4b17023SJohn Marino 
2386e4b17023SJohn Marino   old_PA_IN = PA_OUT = NULL;
2387e4b17023SJohn Marino 
2388e4b17023SJohn Marino   /* If any edges from predecessors are abnormal, antic_in is empty,
2389e4b17023SJohn Marino      so do nothing.  */
2390e4b17023SJohn Marino   if (block_has_abnormal_pred_edge)
2391e4b17023SJohn Marino     goto maybe_dump_sets;
2392e4b17023SJohn Marino 
2393e4b17023SJohn Marino   /* If there are too many partially anticipatable values in the
2394e4b17023SJohn Marino      block, phi_translate_set can take an exponential time: stop
2395e4b17023SJohn Marino      before the translation starts.  */
2396e4b17023SJohn Marino   if (max_pa
2397e4b17023SJohn Marino       && single_succ_p (block)
2398e4b17023SJohn Marino       && bitmap_count_bits (&PA_IN (single_succ (block))->values) > max_pa)
2399e4b17023SJohn Marino     goto maybe_dump_sets;
2400e4b17023SJohn Marino 
2401e4b17023SJohn Marino   old_PA_IN = PA_IN (block);
2402e4b17023SJohn Marino   PA_OUT = bitmap_set_new ();
2403e4b17023SJohn Marino 
2404e4b17023SJohn Marino   /* If the block has no successors, ANTIC_OUT is empty.  */
2405e4b17023SJohn Marino   if (EDGE_COUNT (block->succs) == 0)
2406e4b17023SJohn Marino     ;
2407e4b17023SJohn Marino   /* If we have one successor, we could have some phi nodes to
2408e4b17023SJohn Marino      translate through.  Note that we can't phi translate across DFS
2409e4b17023SJohn Marino      back edges in partial antic, because it uses a union operation on
2410e4b17023SJohn Marino      the successors.  For recurrences like IV's, we will end up
2411e4b17023SJohn Marino      generating a new value in the set on each go around (i + 3 (VH.1)
2412e4b17023SJohn Marino      VH.1 + 1 (VH.2), VH.2 + 1 (VH.3), etc), forever.  */
2413e4b17023SJohn Marino   else if (single_succ_p (block))
2414e4b17023SJohn Marino     {
2415e4b17023SJohn Marino       basic_block succ = single_succ (block);
2416e4b17023SJohn Marino       if (!(single_succ_edge (block)->flags & EDGE_DFS_BACK))
2417e4b17023SJohn Marino 	phi_translate_set (PA_OUT, PA_IN (succ), block, succ);
2418e4b17023SJohn Marino     }
2419e4b17023SJohn Marino   /* If we have multiple successors, we take the union of all of
2420e4b17023SJohn Marino      them.  */
2421e4b17023SJohn Marino   else
2422e4b17023SJohn Marino     {
2423e4b17023SJohn Marino       VEC(basic_block, heap) * worklist;
2424e4b17023SJohn Marino       size_t i;
2425e4b17023SJohn Marino       basic_block bprime;
2426e4b17023SJohn Marino 
2427e4b17023SJohn Marino       worklist = VEC_alloc (basic_block, heap, EDGE_COUNT (block->succs));
2428e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, block->succs)
2429e4b17023SJohn Marino 	{
2430e4b17023SJohn Marino 	  if (e->flags & EDGE_DFS_BACK)
2431e4b17023SJohn Marino 	    continue;
2432e4b17023SJohn Marino 	  VEC_quick_push (basic_block, worklist, e->dest);
2433e4b17023SJohn Marino 	}
2434e4b17023SJohn Marino       if (VEC_length (basic_block, worklist) > 0)
2435e4b17023SJohn Marino 	{
2436e4b17023SJohn Marino 	  FOR_EACH_VEC_ELT (basic_block, worklist, i, bprime)
2437e4b17023SJohn Marino 	    {
2438e4b17023SJohn Marino 	      unsigned int i;
2439e4b17023SJohn Marino 	      bitmap_iterator bi;
2440e4b17023SJohn Marino 
2441e4b17023SJohn Marino 	      FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (bprime), i, bi)
2442e4b17023SJohn Marino 		bitmap_value_insert_into_set (PA_OUT,
2443e4b17023SJohn Marino 					      expression_for_id (i));
2444e4b17023SJohn Marino 	      if (!gimple_seq_empty_p (phi_nodes (bprime)))
2445e4b17023SJohn Marino 		{
2446e4b17023SJohn Marino 		  bitmap_set_t pa_in = bitmap_set_new ();
2447e4b17023SJohn Marino 		  phi_translate_set (pa_in, PA_IN (bprime), block, bprime);
2448e4b17023SJohn Marino 		  FOR_EACH_EXPR_ID_IN_SET (pa_in, i, bi)
2449e4b17023SJohn Marino 		    bitmap_value_insert_into_set (PA_OUT,
2450e4b17023SJohn Marino 						  expression_for_id (i));
2451e4b17023SJohn Marino 		  bitmap_set_free (pa_in);
2452e4b17023SJohn Marino 		}
2453e4b17023SJohn Marino 	      else
2454e4b17023SJohn Marino 		FOR_EACH_EXPR_ID_IN_SET (PA_IN (bprime), i, bi)
2455e4b17023SJohn Marino 		  bitmap_value_insert_into_set (PA_OUT,
2456e4b17023SJohn Marino 						expression_for_id (i));
2457e4b17023SJohn Marino 	    }
2458e4b17023SJohn Marino 	}
2459e4b17023SJohn Marino       VEC_free (basic_block, heap, worklist);
2460e4b17023SJohn Marino     }
2461e4b17023SJohn Marino 
2462e4b17023SJohn Marino   /* PA_IN starts with PA_OUT - TMP_GEN.
2463e4b17023SJohn Marino      Then we subtract things from ANTIC_IN.  */
2464e4b17023SJohn Marino   PA_IN (block) = bitmap_set_subtract (PA_OUT, TMP_GEN (block));
2465e4b17023SJohn Marino 
2466e4b17023SJohn Marino   /* For partial antic, we want to put back in the phi results, since
2467e4b17023SJohn Marino      we will properly avoid making them partially antic over backedges.  */
2468e4b17023SJohn Marino   bitmap_ior_into (&PA_IN (block)->values, &PHI_GEN (block)->values);
2469e4b17023SJohn Marino   bitmap_ior_into (&PA_IN (block)->expressions, &PHI_GEN (block)->expressions);
2470e4b17023SJohn Marino 
2471e4b17023SJohn Marino   /* PA_IN[block] = PA_IN[block] - ANTIC_IN[block] */
2472e4b17023SJohn Marino   bitmap_set_subtract_values (PA_IN (block), ANTIC_IN (block));
2473e4b17023SJohn Marino 
2474e4b17023SJohn Marino   dependent_clean (PA_IN (block), ANTIC_IN (block), block);
2475e4b17023SJohn Marino 
2476e4b17023SJohn Marino   if (!bitmap_set_equal (old_PA_IN, PA_IN (block)))
2477e4b17023SJohn Marino     {
2478e4b17023SJohn Marino       changed = true;
2479e4b17023SJohn Marino       SET_BIT (changed_blocks, block->index);
2480e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, block->preds)
2481e4b17023SJohn Marino 	SET_BIT (changed_blocks, e->src->index);
2482e4b17023SJohn Marino     }
2483e4b17023SJohn Marino   else
2484e4b17023SJohn Marino     RESET_BIT (changed_blocks, block->index);
2485e4b17023SJohn Marino 
2486e4b17023SJohn Marino  maybe_dump_sets:
2487e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
2488e4b17023SJohn Marino     {
2489e4b17023SJohn Marino       if (PA_OUT)
2490e4b17023SJohn Marino 	print_bitmap_set (dump_file, PA_OUT, "PA_OUT", block->index);
2491e4b17023SJohn Marino 
2492e4b17023SJohn Marino       print_bitmap_set (dump_file, PA_IN (block), "PA_IN", block->index);
2493e4b17023SJohn Marino     }
2494e4b17023SJohn Marino   if (old_PA_IN)
2495e4b17023SJohn Marino     bitmap_set_free (old_PA_IN);
2496e4b17023SJohn Marino   if (PA_OUT)
2497e4b17023SJohn Marino     bitmap_set_free (PA_OUT);
2498e4b17023SJohn Marino   return changed;
2499e4b17023SJohn Marino }
2500e4b17023SJohn Marino 
2501e4b17023SJohn Marino /* Compute ANTIC and partial ANTIC sets.  */
2502e4b17023SJohn Marino 
2503e4b17023SJohn Marino static void
compute_antic(void)2504e4b17023SJohn Marino compute_antic (void)
2505e4b17023SJohn Marino {
2506e4b17023SJohn Marino   bool changed = true;
2507e4b17023SJohn Marino   int num_iterations = 0;
2508e4b17023SJohn Marino   basic_block block;
2509e4b17023SJohn Marino   int i;
2510e4b17023SJohn Marino 
2511e4b17023SJohn Marino   /* If any predecessor edges are abnormal, we punt, so antic_in is empty.
2512e4b17023SJohn Marino      We pre-build the map of blocks with incoming abnormal edges here.  */
2513e4b17023SJohn Marino   has_abnormal_preds = sbitmap_alloc (last_basic_block);
2514e4b17023SJohn Marino   sbitmap_zero (has_abnormal_preds);
2515e4b17023SJohn Marino 
2516e4b17023SJohn Marino   FOR_EACH_BB (block)
2517e4b17023SJohn Marino     {
2518e4b17023SJohn Marino       edge_iterator ei;
2519e4b17023SJohn Marino       edge e;
2520e4b17023SJohn Marino 
2521e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, block->preds)
2522e4b17023SJohn Marino 	{
2523e4b17023SJohn Marino 	  e->flags &= ~EDGE_DFS_BACK;
2524e4b17023SJohn Marino 	  if (e->flags & EDGE_ABNORMAL)
2525e4b17023SJohn Marino 	    {
2526e4b17023SJohn Marino 	      SET_BIT (has_abnormal_preds, block->index);
2527e4b17023SJohn Marino 	      break;
2528e4b17023SJohn Marino 	    }
2529e4b17023SJohn Marino 	}
2530e4b17023SJohn Marino 
2531e4b17023SJohn Marino       BB_VISITED (block) = 0;
2532e4b17023SJohn Marino       BB_DEFERRED (block) = 0;
2533e4b17023SJohn Marino 
2534e4b17023SJohn Marino       /* While we are here, give empty ANTIC_IN sets to each block.  */
2535e4b17023SJohn Marino       ANTIC_IN (block) = bitmap_set_new ();
2536e4b17023SJohn Marino       PA_IN (block) = bitmap_set_new ();
2537e4b17023SJohn Marino     }
2538e4b17023SJohn Marino 
2539e4b17023SJohn Marino   /* At the exit block we anticipate nothing.  */
2540e4b17023SJohn Marino   ANTIC_IN (EXIT_BLOCK_PTR) = bitmap_set_new ();
2541e4b17023SJohn Marino   BB_VISITED (EXIT_BLOCK_PTR) = 1;
2542e4b17023SJohn Marino   PA_IN (EXIT_BLOCK_PTR) = bitmap_set_new ();
2543e4b17023SJohn Marino 
2544e4b17023SJohn Marino   changed_blocks = sbitmap_alloc (last_basic_block + 1);
2545e4b17023SJohn Marino   sbitmap_ones (changed_blocks);
2546e4b17023SJohn Marino   while (changed)
2547e4b17023SJohn Marino     {
2548e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
2549e4b17023SJohn Marino 	fprintf (dump_file, "Starting iteration %d\n", num_iterations);
2550e4b17023SJohn Marino       /* ???  We need to clear our PHI translation cache here as the
2551e4b17023SJohn Marino          ANTIC sets shrink and we restrict valid translations to
2552e4b17023SJohn Marino 	 those having operands with leaders in ANTIC.  Same below
2553e4b17023SJohn Marino 	 for PA ANTIC computation.  */
2554e4b17023SJohn Marino       num_iterations++;
2555e4b17023SJohn Marino       changed = false;
2556e4b17023SJohn Marino       for (i = n_basic_blocks - NUM_FIXED_BLOCKS - 1; i >= 0; i--)
2557e4b17023SJohn Marino 	{
2558e4b17023SJohn Marino 	  if (TEST_BIT (changed_blocks, postorder[i]))
2559e4b17023SJohn Marino 	    {
2560e4b17023SJohn Marino 	      basic_block block = BASIC_BLOCK (postorder[i]);
2561e4b17023SJohn Marino 	      changed |= compute_antic_aux (block,
2562e4b17023SJohn Marino 					    TEST_BIT (has_abnormal_preds,
2563e4b17023SJohn Marino 						      block->index));
2564e4b17023SJohn Marino 	    }
2565e4b17023SJohn Marino 	}
2566e4b17023SJohn Marino       /* Theoretically possible, but *highly* unlikely.  */
2567e4b17023SJohn Marino       gcc_checking_assert (num_iterations < 500);
2568e4b17023SJohn Marino     }
2569e4b17023SJohn Marino 
2570e4b17023SJohn Marino   statistics_histogram_event (cfun, "compute_antic iterations",
2571e4b17023SJohn Marino 			      num_iterations);
2572e4b17023SJohn Marino 
2573e4b17023SJohn Marino   if (do_partial_partial)
2574e4b17023SJohn Marino     {
2575e4b17023SJohn Marino       sbitmap_ones (changed_blocks);
2576e4b17023SJohn Marino       mark_dfs_back_edges ();
2577e4b17023SJohn Marino       num_iterations = 0;
2578e4b17023SJohn Marino       changed = true;
2579e4b17023SJohn Marino       while (changed)
2580e4b17023SJohn Marino 	{
2581e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
2582e4b17023SJohn Marino 	    fprintf (dump_file, "Starting iteration %d\n", num_iterations);
2583e4b17023SJohn Marino 	  num_iterations++;
2584e4b17023SJohn Marino 	  changed = false;
2585e4b17023SJohn Marino 	  for (i = n_basic_blocks - NUM_FIXED_BLOCKS - 1 ; i >= 0; i--)
2586e4b17023SJohn Marino 	    {
2587e4b17023SJohn Marino 	      if (TEST_BIT (changed_blocks, postorder[i]))
2588e4b17023SJohn Marino 		{
2589e4b17023SJohn Marino 		  basic_block block = BASIC_BLOCK (postorder[i]);
2590e4b17023SJohn Marino 		  changed
2591e4b17023SJohn Marino 		    |= compute_partial_antic_aux (block,
2592e4b17023SJohn Marino 						  TEST_BIT (has_abnormal_preds,
2593e4b17023SJohn Marino 							    block->index));
2594e4b17023SJohn Marino 		}
2595e4b17023SJohn Marino 	    }
2596e4b17023SJohn Marino 	  /* Theoretically possible, but *highly* unlikely.  */
2597e4b17023SJohn Marino 	  gcc_checking_assert (num_iterations < 500);
2598e4b17023SJohn Marino 	}
2599e4b17023SJohn Marino       statistics_histogram_event (cfun, "compute_partial_antic iterations",
2600e4b17023SJohn Marino 				  num_iterations);
2601e4b17023SJohn Marino     }
2602e4b17023SJohn Marino   sbitmap_free (has_abnormal_preds);
2603e4b17023SJohn Marino   sbitmap_free (changed_blocks);
2604e4b17023SJohn Marino }
2605e4b17023SJohn Marino 
2606e4b17023SJohn Marino /* Return true if OP is a tree which we can perform PRE on.
2607e4b17023SJohn Marino    This may not match the operations we can value number, but in
2608e4b17023SJohn Marino    a perfect world would.  */
2609e4b17023SJohn Marino 
2610e4b17023SJohn Marino static bool
can_PRE_operation(tree op)2611e4b17023SJohn Marino can_PRE_operation (tree op)
2612e4b17023SJohn Marino {
2613e4b17023SJohn Marino   return UNARY_CLASS_P (op)
2614e4b17023SJohn Marino     || BINARY_CLASS_P (op)
2615e4b17023SJohn Marino     || COMPARISON_CLASS_P (op)
2616e4b17023SJohn Marino     || TREE_CODE (op) == MEM_REF
2617e4b17023SJohn Marino     || TREE_CODE (op) == COMPONENT_REF
2618e4b17023SJohn Marino     || TREE_CODE (op) == VIEW_CONVERT_EXPR
2619e4b17023SJohn Marino     || TREE_CODE (op) == CALL_EXPR
2620e4b17023SJohn Marino     || TREE_CODE (op) == ARRAY_REF;
2621e4b17023SJohn Marino }
2622e4b17023SJohn Marino 
2623e4b17023SJohn Marino 
2624e4b17023SJohn Marino /* Inserted expressions are placed onto this worklist, which is used
2625e4b17023SJohn Marino    for performing quick dead code elimination of insertions we made
2626e4b17023SJohn Marino    that didn't turn out to be necessary.   */
2627e4b17023SJohn Marino static bitmap inserted_exprs;
2628e4b17023SJohn Marino 
2629e4b17023SJohn Marino /* Pool allocated fake store expressions are placed onto this
2630e4b17023SJohn Marino    worklist, which, after performing dead code elimination, is walked
2631e4b17023SJohn Marino    to see which expressions need to be put into GC'able memory  */
VEC(gimple,heap)2632e4b17023SJohn Marino static VEC(gimple, heap) *need_creation;
2633e4b17023SJohn Marino 
2634e4b17023SJohn Marino /* The actual worker for create_component_ref_by_pieces.  */
2635e4b17023SJohn Marino 
2636e4b17023SJohn Marino static tree
2637e4b17023SJohn Marino create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
2638e4b17023SJohn Marino 				  unsigned int *operand, gimple_seq *stmts,
2639e4b17023SJohn Marino 				  gimple domstmt)
2640e4b17023SJohn Marino {
2641e4b17023SJohn Marino   vn_reference_op_t currop = VEC_index (vn_reference_op_s, ref->operands,
2642e4b17023SJohn Marino 					*operand);
2643e4b17023SJohn Marino   tree genop;
2644e4b17023SJohn Marino   ++*operand;
2645e4b17023SJohn Marino   switch (currop->opcode)
2646e4b17023SJohn Marino     {
2647e4b17023SJohn Marino     case CALL_EXPR:
2648e4b17023SJohn Marino       {
2649e4b17023SJohn Marino 	tree folded, sc = NULL_TREE;
2650e4b17023SJohn Marino 	unsigned int nargs = 0;
2651e4b17023SJohn Marino 	tree fn, *args;
2652e4b17023SJohn Marino 	if (TREE_CODE (currop->op0) == FUNCTION_DECL)
2653e4b17023SJohn Marino 	  fn = currop->op0;
2654e4b17023SJohn Marino 	else
2655e4b17023SJohn Marino 	  {
2656e4b17023SJohn Marino 	    pre_expr op0 = get_or_alloc_expr_for (currop->op0);
2657e4b17023SJohn Marino 	    fn = find_or_generate_expression (block, op0, stmts, domstmt);
2658e4b17023SJohn Marino 	    if (!fn)
2659e4b17023SJohn Marino 	      return NULL_TREE;
2660e4b17023SJohn Marino 	  }
2661e4b17023SJohn Marino 	if (currop->op1)
2662e4b17023SJohn Marino 	  {
2663e4b17023SJohn Marino 	    pre_expr scexpr = get_or_alloc_expr_for (currop->op1);
2664e4b17023SJohn Marino 	    sc = find_or_generate_expression (block, scexpr, stmts, domstmt);
2665e4b17023SJohn Marino 	    if (!sc)
2666e4b17023SJohn Marino 	      return NULL_TREE;
2667e4b17023SJohn Marino 	  }
2668e4b17023SJohn Marino 	args = XNEWVEC (tree, VEC_length (vn_reference_op_s,
2669e4b17023SJohn Marino 					  ref->operands) - 1);
2670e4b17023SJohn Marino 	while (*operand < VEC_length (vn_reference_op_s, ref->operands))
2671e4b17023SJohn Marino 	  {
2672e4b17023SJohn Marino 	    args[nargs] = create_component_ref_by_pieces_1 (block, ref,
2673e4b17023SJohn Marino 							    operand, stmts,
2674e4b17023SJohn Marino 							    domstmt);
2675e4b17023SJohn Marino 	    if (!args[nargs])
2676e4b17023SJohn Marino 	      {
2677e4b17023SJohn Marino 		free (args);
2678e4b17023SJohn Marino 		return NULL_TREE;
2679e4b17023SJohn Marino 	      }
2680e4b17023SJohn Marino 	    nargs++;
2681e4b17023SJohn Marino 	  }
2682e4b17023SJohn Marino 	folded = build_call_array (currop->type,
2683e4b17023SJohn Marino 				   (TREE_CODE (fn) == FUNCTION_DECL
2684e4b17023SJohn Marino 				    ? build_fold_addr_expr (fn) : fn),
2685e4b17023SJohn Marino 				   nargs, args);
2686e4b17023SJohn Marino 	free (args);
2687e4b17023SJohn Marino 	if (sc)
2688e4b17023SJohn Marino 	  CALL_EXPR_STATIC_CHAIN (folded) = sc;
2689e4b17023SJohn Marino 	return folded;
2690e4b17023SJohn Marino       }
2691e4b17023SJohn Marino       break;
2692e4b17023SJohn Marino     case MEM_REF:
2693e4b17023SJohn Marino       {
2694e4b17023SJohn Marino 	tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
2695e4b17023SJohn Marino 							stmts, domstmt);
2696e4b17023SJohn Marino 	tree offset = currop->op0;
2697e4b17023SJohn Marino 	if (!baseop)
2698e4b17023SJohn Marino 	  return NULL_TREE;
2699e4b17023SJohn Marino 	if (TREE_CODE (baseop) == ADDR_EXPR
2700e4b17023SJohn Marino 	    && handled_component_p (TREE_OPERAND (baseop, 0)))
2701e4b17023SJohn Marino 	  {
2702e4b17023SJohn Marino 	    HOST_WIDE_INT off;
2703e4b17023SJohn Marino 	    tree base;
2704e4b17023SJohn Marino 	    base = get_addr_base_and_unit_offset (TREE_OPERAND (baseop, 0),
2705e4b17023SJohn Marino 						  &off);
2706e4b17023SJohn Marino 	    gcc_assert (base);
2707e4b17023SJohn Marino 	    offset = int_const_binop (PLUS_EXPR, offset,
2708e4b17023SJohn Marino 				      build_int_cst (TREE_TYPE (offset),
2709e4b17023SJohn Marino 						     off));
2710e4b17023SJohn Marino 	    baseop = build_fold_addr_expr (base);
2711e4b17023SJohn Marino 	  }
2712e4b17023SJohn Marino 	return fold_build2 (MEM_REF, currop->type, baseop, offset);
2713e4b17023SJohn Marino       }
2714e4b17023SJohn Marino       break;
2715e4b17023SJohn Marino     case TARGET_MEM_REF:
2716e4b17023SJohn Marino       {
2717e4b17023SJohn Marino 	pre_expr op0expr, op1expr;
2718e4b17023SJohn Marino 	tree genop0 = NULL_TREE, genop1 = NULL_TREE;
2719e4b17023SJohn Marino 	vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
2720e4b17023SJohn Marino 					      ++*operand);
2721e4b17023SJohn Marino 	tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
2722e4b17023SJohn Marino 							stmts, domstmt);
2723e4b17023SJohn Marino 	if (!baseop)
2724e4b17023SJohn Marino 	  return NULL_TREE;
2725e4b17023SJohn Marino 	if (currop->op0)
2726e4b17023SJohn Marino 	  {
2727e4b17023SJohn Marino 	    op0expr = get_or_alloc_expr_for (currop->op0);
2728e4b17023SJohn Marino 	    genop0 = find_or_generate_expression (block, op0expr,
2729e4b17023SJohn Marino 						  stmts, domstmt);
2730e4b17023SJohn Marino 	    if (!genop0)
2731e4b17023SJohn Marino 	      return NULL_TREE;
2732e4b17023SJohn Marino 	  }
2733e4b17023SJohn Marino 	if (nextop->op0)
2734e4b17023SJohn Marino 	  {
2735e4b17023SJohn Marino 	    op1expr = get_or_alloc_expr_for (nextop->op0);
2736e4b17023SJohn Marino 	    genop1 = find_or_generate_expression (block, op1expr,
2737e4b17023SJohn Marino 						  stmts, domstmt);
2738e4b17023SJohn Marino 	    if (!genop1)
2739e4b17023SJohn Marino 	      return NULL_TREE;
2740e4b17023SJohn Marino 	  }
2741e4b17023SJohn Marino 	return build5 (TARGET_MEM_REF, currop->type,
2742e4b17023SJohn Marino 		       baseop, currop->op2, genop0, currop->op1, genop1);
2743e4b17023SJohn Marino       }
2744e4b17023SJohn Marino       break;
2745e4b17023SJohn Marino     case ADDR_EXPR:
2746e4b17023SJohn Marino       if (currop->op0)
2747e4b17023SJohn Marino 	{
2748e4b17023SJohn Marino 	  gcc_assert (is_gimple_min_invariant (currop->op0));
2749e4b17023SJohn Marino 	  return currop->op0;
2750e4b17023SJohn Marino 	}
2751e4b17023SJohn Marino       /* Fallthrough.  */
2752e4b17023SJohn Marino     case REALPART_EXPR:
2753e4b17023SJohn Marino     case IMAGPART_EXPR:
2754e4b17023SJohn Marino     case VIEW_CONVERT_EXPR:
2755e4b17023SJohn Marino       {
2756e4b17023SJohn Marino 	tree folded;
2757e4b17023SJohn Marino 	tree genop0 = create_component_ref_by_pieces_1 (block, ref,
2758e4b17023SJohn Marino 							operand,
2759e4b17023SJohn Marino 							stmts, domstmt);
2760e4b17023SJohn Marino 	if (!genop0)
2761e4b17023SJohn Marino 	  return NULL_TREE;
2762e4b17023SJohn Marino 	folded = fold_build1 (currop->opcode, currop->type,
2763e4b17023SJohn Marino 			      genop0);
2764e4b17023SJohn Marino 	return folded;
2765e4b17023SJohn Marino       }
2766e4b17023SJohn Marino       break;
2767e4b17023SJohn Marino     case WITH_SIZE_EXPR:
2768e4b17023SJohn Marino       {
2769e4b17023SJohn Marino 	tree genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
2770e4b17023SJohn Marino 							stmts, domstmt);
2771e4b17023SJohn Marino 	pre_expr op1expr = get_or_alloc_expr_for (currop->op0);
2772e4b17023SJohn Marino 	tree genop1;
2773e4b17023SJohn Marino 
2774e4b17023SJohn Marino 	if (!genop0)
2775e4b17023SJohn Marino 	  return NULL_TREE;
2776e4b17023SJohn Marino 
2777e4b17023SJohn Marino 	genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
2778e4b17023SJohn Marino 	if (!genop1)
2779e4b17023SJohn Marino 	  return NULL_TREE;
2780e4b17023SJohn Marino 
2781e4b17023SJohn Marino 	return fold_build2 (currop->opcode, currop->type, genop0, genop1);
2782e4b17023SJohn Marino       }
2783e4b17023SJohn Marino       break;
2784e4b17023SJohn Marino     case BIT_FIELD_REF:
2785e4b17023SJohn Marino       {
2786e4b17023SJohn Marino 	tree folded;
2787e4b17023SJohn Marino 	tree genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
2788e4b17023SJohn Marino 							stmts, domstmt);
2789e4b17023SJohn Marino 	pre_expr op1expr = get_or_alloc_expr_for (currop->op0);
2790e4b17023SJohn Marino 	pre_expr op2expr = get_or_alloc_expr_for (currop->op1);
2791e4b17023SJohn Marino 	tree genop1;
2792e4b17023SJohn Marino 	tree genop2;
2793e4b17023SJohn Marino 
2794e4b17023SJohn Marino 	if (!genop0)
2795e4b17023SJohn Marino 	  return NULL_TREE;
2796e4b17023SJohn Marino 	genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
2797e4b17023SJohn Marino 	if (!genop1)
2798e4b17023SJohn Marino 	  return NULL_TREE;
2799e4b17023SJohn Marino 	genop2 = find_or_generate_expression (block, op2expr, stmts, domstmt);
2800e4b17023SJohn Marino 	if (!genop2)
2801e4b17023SJohn Marino 	  return NULL_TREE;
2802e4b17023SJohn Marino 	folded = fold_build3 (BIT_FIELD_REF, currop->type, genop0, genop1,
2803e4b17023SJohn Marino 			      genop2);
2804e4b17023SJohn Marino 	return folded;
2805e4b17023SJohn Marino       }
2806e4b17023SJohn Marino 
2807e4b17023SJohn Marino       /* For array ref vn_reference_op's, operand 1 of the array ref
2808e4b17023SJohn Marino 	 is op0 of the reference op and operand 3 of the array ref is
2809e4b17023SJohn Marino 	 op1.  */
2810e4b17023SJohn Marino     case ARRAY_RANGE_REF:
2811e4b17023SJohn Marino     case ARRAY_REF:
2812e4b17023SJohn Marino       {
2813e4b17023SJohn Marino 	tree genop0;
2814e4b17023SJohn Marino 	tree genop1 = currop->op0;
2815e4b17023SJohn Marino 	pre_expr op1expr;
2816e4b17023SJohn Marino 	tree genop2 = currop->op1;
2817e4b17023SJohn Marino 	pre_expr op2expr;
2818e4b17023SJohn Marino 	tree genop3 = currop->op2;
2819e4b17023SJohn Marino 	pre_expr op3expr;
2820e4b17023SJohn Marino 	genop0 = create_component_ref_by_pieces_1 (block, ref, operand,
2821e4b17023SJohn Marino 						   stmts, domstmt);
2822e4b17023SJohn Marino 	if (!genop0)
2823e4b17023SJohn Marino 	  return NULL_TREE;
2824e4b17023SJohn Marino 	op1expr = get_or_alloc_expr_for (genop1);
2825e4b17023SJohn Marino 	genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
2826e4b17023SJohn Marino 	if (!genop1)
2827e4b17023SJohn Marino 	  return NULL_TREE;
2828e4b17023SJohn Marino 	if (genop2)
2829e4b17023SJohn Marino 	  {
2830e4b17023SJohn Marino 	    tree domain_type = TYPE_DOMAIN (TREE_TYPE (genop0));
2831e4b17023SJohn Marino 	    /* Drop zero minimum index if redundant.  */
2832e4b17023SJohn Marino 	    if (integer_zerop (genop2)
2833e4b17023SJohn Marino 		&& (!domain_type
2834e4b17023SJohn Marino 		    || integer_zerop (TYPE_MIN_VALUE (domain_type))))
2835e4b17023SJohn Marino 	      genop2 = NULL_TREE;
2836e4b17023SJohn Marino 	    else
2837e4b17023SJohn Marino 	      {
2838e4b17023SJohn Marino 		op2expr = get_or_alloc_expr_for (genop2);
2839e4b17023SJohn Marino 		genop2 = find_or_generate_expression (block, op2expr, stmts,
2840e4b17023SJohn Marino 						      domstmt);
2841e4b17023SJohn Marino 		if (!genop2)
2842e4b17023SJohn Marino 		  return NULL_TREE;
2843e4b17023SJohn Marino 	      }
2844e4b17023SJohn Marino 	  }
2845e4b17023SJohn Marino 	if (genop3)
2846e4b17023SJohn Marino 	  {
2847e4b17023SJohn Marino 	    tree elmt_type = TREE_TYPE (TREE_TYPE (genop0));
2848e4b17023SJohn Marino 	    /* We can't always put a size in units of the element alignment
2849e4b17023SJohn Marino 	       here as the element alignment may be not visible.  See
2850e4b17023SJohn Marino 	       PR43783.  Simply drop the element size for constant
2851e4b17023SJohn Marino 	       sizes.  */
2852e4b17023SJohn Marino 	    if (tree_int_cst_equal (genop3, TYPE_SIZE_UNIT (elmt_type)))
2853e4b17023SJohn Marino 	      genop3 = NULL_TREE;
2854e4b17023SJohn Marino 	    else
2855e4b17023SJohn Marino 	      {
2856e4b17023SJohn Marino 		genop3 = size_binop (EXACT_DIV_EXPR, genop3,
2857e4b17023SJohn Marino 				     size_int (TYPE_ALIGN_UNIT (elmt_type)));
2858e4b17023SJohn Marino 		op3expr = get_or_alloc_expr_for (genop3);
2859e4b17023SJohn Marino 		genop3 = find_or_generate_expression (block, op3expr, stmts,
2860e4b17023SJohn Marino 						      domstmt);
2861e4b17023SJohn Marino 		if (!genop3)
2862e4b17023SJohn Marino 		  return NULL_TREE;
2863e4b17023SJohn Marino 	      }
2864e4b17023SJohn Marino 	  }
2865e4b17023SJohn Marino 	return build4 (currop->opcode, currop->type, genop0, genop1,
2866e4b17023SJohn Marino 		       genop2, genop3);
2867e4b17023SJohn Marino       }
2868e4b17023SJohn Marino     case COMPONENT_REF:
2869e4b17023SJohn Marino       {
2870e4b17023SJohn Marino 	tree op0;
2871e4b17023SJohn Marino 	tree op1;
2872e4b17023SJohn Marino 	tree genop2 = currop->op1;
2873e4b17023SJohn Marino 	pre_expr op2expr;
2874e4b17023SJohn Marino 	op0 = create_component_ref_by_pieces_1 (block, ref, operand,
2875e4b17023SJohn Marino 						stmts, domstmt);
2876e4b17023SJohn Marino 	if (!op0)
2877e4b17023SJohn Marino 	  return NULL_TREE;
2878e4b17023SJohn Marino 	/* op1 should be a FIELD_DECL, which are represented by
2879e4b17023SJohn Marino 	   themselves.  */
2880e4b17023SJohn Marino 	op1 = currop->op0;
2881e4b17023SJohn Marino 	if (genop2)
2882e4b17023SJohn Marino 	  {
2883e4b17023SJohn Marino 	    op2expr = get_or_alloc_expr_for (genop2);
2884e4b17023SJohn Marino 	    genop2 = find_or_generate_expression (block, op2expr, stmts,
2885e4b17023SJohn Marino 						  domstmt);
2886e4b17023SJohn Marino 	    if (!genop2)
2887e4b17023SJohn Marino 	      return NULL_TREE;
2888e4b17023SJohn Marino 	  }
2889e4b17023SJohn Marino 
2890e4b17023SJohn Marino 	return fold_build3 (COMPONENT_REF, TREE_TYPE (op1), op0, op1,
2891e4b17023SJohn Marino 			    genop2);
2892e4b17023SJohn Marino       }
2893e4b17023SJohn Marino       break;
2894e4b17023SJohn Marino     case SSA_NAME:
2895e4b17023SJohn Marino       {
2896e4b17023SJohn Marino 	pre_expr op0expr = get_or_alloc_expr_for (currop->op0);
2897e4b17023SJohn Marino 	genop = find_or_generate_expression (block, op0expr, stmts, domstmt);
2898e4b17023SJohn Marino 	return genop;
2899e4b17023SJohn Marino       }
2900e4b17023SJohn Marino     case STRING_CST:
2901e4b17023SJohn Marino     case INTEGER_CST:
2902e4b17023SJohn Marino     case COMPLEX_CST:
2903e4b17023SJohn Marino     case VECTOR_CST:
2904e4b17023SJohn Marino     case REAL_CST:
2905e4b17023SJohn Marino     case CONSTRUCTOR:
2906e4b17023SJohn Marino     case VAR_DECL:
2907e4b17023SJohn Marino     case PARM_DECL:
2908e4b17023SJohn Marino     case CONST_DECL:
2909e4b17023SJohn Marino     case RESULT_DECL:
2910e4b17023SJohn Marino     case FUNCTION_DECL:
2911e4b17023SJohn Marino       return currop->op0;
2912e4b17023SJohn Marino 
2913e4b17023SJohn Marino     default:
2914e4b17023SJohn Marino       gcc_unreachable ();
2915e4b17023SJohn Marino     }
2916e4b17023SJohn Marino }
2917e4b17023SJohn Marino 
2918e4b17023SJohn Marino /* For COMPONENT_REF's and ARRAY_REF's, we can't have any intermediates for the
2919e4b17023SJohn Marino    COMPONENT_REF or MEM_REF or ARRAY_REF portion, because we'd end up with
2920e4b17023SJohn Marino    trying to rename aggregates into ssa form directly, which is a no no.
2921e4b17023SJohn Marino 
2922e4b17023SJohn Marino    Thus, this routine doesn't create temporaries, it just builds a
2923e4b17023SJohn Marino    single access expression for the array, calling
2924e4b17023SJohn Marino    find_or_generate_expression to build the innermost pieces.
2925e4b17023SJohn Marino 
2926e4b17023SJohn Marino    This function is a subroutine of create_expression_by_pieces, and
2927e4b17023SJohn Marino    should not be called on it's own unless you really know what you
2928e4b17023SJohn Marino    are doing.  */
2929e4b17023SJohn Marino 
2930e4b17023SJohn Marino static tree
create_component_ref_by_pieces(basic_block block,vn_reference_t ref,gimple_seq * stmts,gimple domstmt)2931e4b17023SJohn Marino create_component_ref_by_pieces (basic_block block, vn_reference_t ref,
2932e4b17023SJohn Marino 				gimple_seq *stmts, gimple domstmt)
2933e4b17023SJohn Marino {
2934e4b17023SJohn Marino   unsigned int op = 0;
2935e4b17023SJohn Marino   return create_component_ref_by_pieces_1 (block, ref, &op, stmts, domstmt);
2936e4b17023SJohn Marino }
2937e4b17023SJohn Marino 
2938e4b17023SJohn Marino /* Find a leader for an expression, or generate one using
2939e4b17023SJohn Marino    create_expression_by_pieces if it's ANTIC but
2940e4b17023SJohn Marino    complex.
2941e4b17023SJohn Marino    BLOCK is the basic_block we are looking for leaders in.
2942e4b17023SJohn Marino    EXPR is the expression to find a leader or generate for.
2943e4b17023SJohn Marino    STMTS is the statement list to put the inserted expressions on.
2944e4b17023SJohn Marino    Returns the SSA_NAME of the LHS of the generated expression or the
2945e4b17023SJohn Marino    leader.
2946e4b17023SJohn Marino    DOMSTMT if non-NULL is a statement that should be dominated by
2947e4b17023SJohn Marino    all uses in the generated expression.  If DOMSTMT is non-NULL this
2948e4b17023SJohn Marino    routine can fail and return NULL_TREE.  Otherwise it will assert
2949e4b17023SJohn Marino    on failure.  */
2950e4b17023SJohn Marino 
2951e4b17023SJohn Marino static tree
find_or_generate_expression(basic_block block,pre_expr expr,gimple_seq * stmts,gimple domstmt)2952e4b17023SJohn Marino find_or_generate_expression (basic_block block, pre_expr expr,
2953e4b17023SJohn Marino 			     gimple_seq *stmts, gimple domstmt)
2954e4b17023SJohn Marino {
2955e4b17023SJohn Marino   pre_expr leader = bitmap_find_leader (AVAIL_OUT (block),
2956e4b17023SJohn Marino 					get_expr_value_id (expr), domstmt);
2957e4b17023SJohn Marino   tree genop = NULL;
2958e4b17023SJohn Marino   if (leader)
2959e4b17023SJohn Marino     {
2960e4b17023SJohn Marino       if (leader->kind == NAME)
2961e4b17023SJohn Marino 	genop = PRE_EXPR_NAME (leader);
2962e4b17023SJohn Marino       else if (leader->kind == CONSTANT)
2963e4b17023SJohn Marino 	genop = PRE_EXPR_CONSTANT (leader);
2964e4b17023SJohn Marino     }
2965e4b17023SJohn Marino 
2966e4b17023SJohn Marino   /* If it's still NULL, it must be a complex expression, so generate
2967e4b17023SJohn Marino      it recursively.  Not so if inserting expressions for values generated
2968e4b17023SJohn Marino      by SCCVN.  */
2969e4b17023SJohn Marino   if (genop == NULL
2970e4b17023SJohn Marino       && !domstmt)
2971e4b17023SJohn Marino     {
2972e4b17023SJohn Marino       bitmap_set_t exprset;
2973e4b17023SJohn Marino       unsigned int lookfor = get_expr_value_id (expr);
2974e4b17023SJohn Marino       bool handled = false;
2975e4b17023SJohn Marino       bitmap_iterator bi;
2976e4b17023SJohn Marino       unsigned int i;
2977e4b17023SJohn Marino 
2978e4b17023SJohn Marino       exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
2979e4b17023SJohn Marino       FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
2980e4b17023SJohn Marino 	{
2981e4b17023SJohn Marino 	  pre_expr temp = expression_for_id (i);
2982e4b17023SJohn Marino 	  if (temp->kind != NAME)
2983e4b17023SJohn Marino 	    {
2984e4b17023SJohn Marino 	      handled = true;
2985e4b17023SJohn Marino 	      genop = create_expression_by_pieces (block, temp, stmts,
2986e4b17023SJohn Marino 						   domstmt,
2987e4b17023SJohn Marino 						   get_expr_type (expr));
2988e4b17023SJohn Marino 	      break;
2989e4b17023SJohn Marino 	    }
2990e4b17023SJohn Marino 	}
2991e4b17023SJohn Marino       if (!handled && domstmt)
2992e4b17023SJohn Marino 	return NULL_TREE;
2993e4b17023SJohn Marino 
2994e4b17023SJohn Marino       gcc_assert (handled);
2995e4b17023SJohn Marino     }
2996e4b17023SJohn Marino   return genop;
2997e4b17023SJohn Marino }
2998e4b17023SJohn Marino 
2999e4b17023SJohn Marino #define NECESSARY GF_PLF_1
3000e4b17023SJohn Marino 
3001e4b17023SJohn Marino /* Create an expression in pieces, so that we can handle very complex
3002e4b17023SJohn Marino    expressions that may be ANTIC, but not necessary GIMPLE.
3003e4b17023SJohn Marino    BLOCK is the basic block the expression will be inserted into,
3004e4b17023SJohn Marino    EXPR is the expression to insert (in value form)
3005e4b17023SJohn Marino    STMTS is a statement list to append the necessary insertions into.
3006e4b17023SJohn Marino 
3007e4b17023SJohn Marino    This function will die if we hit some value that shouldn't be
3008e4b17023SJohn Marino    ANTIC but is (IE there is no leader for it, or its components).
3009e4b17023SJohn Marino    This function may also generate expressions that are themselves
3010e4b17023SJohn Marino    partially or fully redundant.  Those that are will be either made
3011e4b17023SJohn Marino    fully redundant during the next iteration of insert (for partially
3012e4b17023SJohn Marino    redundant ones), or eliminated by eliminate (for fully redundant
3013e4b17023SJohn Marino    ones).
3014e4b17023SJohn Marino 
3015e4b17023SJohn Marino    If DOMSTMT is non-NULL then we make sure that all uses in the
3016e4b17023SJohn Marino    expressions dominate that statement.  In this case the function
3017e4b17023SJohn Marino    can return NULL_TREE to signal failure.  */
3018e4b17023SJohn Marino 
3019e4b17023SJohn Marino static tree
create_expression_by_pieces(basic_block block,pre_expr expr,gimple_seq * stmts,gimple domstmt,tree type)3020e4b17023SJohn Marino create_expression_by_pieces (basic_block block, pre_expr expr,
3021e4b17023SJohn Marino 			     gimple_seq *stmts, gimple domstmt, tree type)
3022e4b17023SJohn Marino {
3023e4b17023SJohn Marino   tree temp, name;
3024e4b17023SJohn Marino   tree folded;
3025e4b17023SJohn Marino   gimple_seq forced_stmts = NULL;
3026e4b17023SJohn Marino   unsigned int value_id;
3027e4b17023SJohn Marino   gimple_stmt_iterator gsi;
3028e4b17023SJohn Marino   tree exprtype = type ? type : get_expr_type (expr);
3029e4b17023SJohn Marino   pre_expr nameexpr;
3030e4b17023SJohn Marino   gimple newstmt;
3031e4b17023SJohn Marino 
3032e4b17023SJohn Marino   switch (expr->kind)
3033e4b17023SJohn Marino     {
3034e4b17023SJohn Marino       /* We may hit the NAME/CONSTANT case if we have to convert types
3035e4b17023SJohn Marino 	 that value numbering saw through.  */
3036e4b17023SJohn Marino     case NAME:
3037e4b17023SJohn Marino       folded = PRE_EXPR_NAME (expr);
3038e4b17023SJohn Marino       break;
3039e4b17023SJohn Marino     case CONSTANT:
3040e4b17023SJohn Marino       folded = PRE_EXPR_CONSTANT (expr);
3041e4b17023SJohn Marino       break;
3042e4b17023SJohn Marino     case REFERENCE:
3043e4b17023SJohn Marino       {
3044e4b17023SJohn Marino 	vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
3045e4b17023SJohn Marino 	folded = create_component_ref_by_pieces (block, ref, stmts, domstmt);
3046e4b17023SJohn Marino       }
3047e4b17023SJohn Marino       break;
3048e4b17023SJohn Marino     case NARY:
3049e4b17023SJohn Marino       {
3050e4b17023SJohn Marino 	vn_nary_op_t nary = PRE_EXPR_NARY (expr);
30515ce9237cSJohn Marino 	tree *genop = XALLOCAVEC (tree, nary->length);
3052e4b17023SJohn Marino 	unsigned i;
3053e4b17023SJohn Marino 	for (i = 0; i < nary->length; ++i)
3054e4b17023SJohn Marino 	  {
3055e4b17023SJohn Marino 	    pre_expr op = get_or_alloc_expr_for (nary->op[i]);
3056e4b17023SJohn Marino 	    genop[i] = find_or_generate_expression (block, op,
3057e4b17023SJohn Marino 						    stmts, domstmt);
3058e4b17023SJohn Marino 	    if (!genop[i])
3059e4b17023SJohn Marino 	      return NULL_TREE;
3060e4b17023SJohn Marino 	    /* Ensure genop[] is properly typed for POINTER_PLUS_EXPR.  It
3061e4b17023SJohn Marino 	       may have conversions stripped.  */
3062e4b17023SJohn Marino 	    if (nary->opcode == POINTER_PLUS_EXPR)
3063e4b17023SJohn Marino 	      {
3064e4b17023SJohn Marino 		if (i == 0)
3065e4b17023SJohn Marino 		  genop[i] = fold_convert (nary->type, genop[i]);
3066e4b17023SJohn Marino 		else if (i == 1)
3067e4b17023SJohn Marino 		  genop[i] = convert_to_ptrofftype (genop[i]);
3068e4b17023SJohn Marino 	      }
3069e4b17023SJohn Marino 	    else
3070e4b17023SJohn Marino 	      genop[i] = fold_convert (TREE_TYPE (nary->op[i]), genop[i]);
3071e4b17023SJohn Marino 	  }
3072e4b17023SJohn Marino 	if (nary->opcode == CONSTRUCTOR)
3073e4b17023SJohn Marino 	  {
3074e4b17023SJohn Marino 	    VEC(constructor_elt,gc) *elts = NULL;
3075e4b17023SJohn Marino 	    for (i = 0; i < nary->length; ++i)
3076e4b17023SJohn Marino 	      CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, genop[i]);
3077e4b17023SJohn Marino 	    folded = build_constructor (nary->type, elts);
3078e4b17023SJohn Marino 	  }
3079e4b17023SJohn Marino 	else
3080e4b17023SJohn Marino 	  {
3081e4b17023SJohn Marino 	    switch (nary->length)
3082e4b17023SJohn Marino 	      {
3083e4b17023SJohn Marino 	      case 1:
3084e4b17023SJohn Marino 		folded = fold_build1 (nary->opcode, nary->type,
3085e4b17023SJohn Marino 				      genop[0]);
3086e4b17023SJohn Marino 		break;
3087e4b17023SJohn Marino 	      case 2:
3088e4b17023SJohn Marino 		folded = fold_build2 (nary->opcode, nary->type,
3089e4b17023SJohn Marino 				      genop[0], genop[1]);
3090e4b17023SJohn Marino 		break;
3091e4b17023SJohn Marino 	      case 3:
3092e4b17023SJohn Marino 		folded = fold_build3 (nary->opcode, nary->type,
30935ce9237cSJohn Marino 				      genop[0], genop[1], genop[2]);
3094e4b17023SJohn Marino 		break;
3095e4b17023SJohn Marino 	      default:
3096e4b17023SJohn Marino 		gcc_unreachable ();
3097e4b17023SJohn Marino 	      }
3098e4b17023SJohn Marino 	  }
3099e4b17023SJohn Marino       }
3100e4b17023SJohn Marino       break;
3101e4b17023SJohn Marino     default:
3102e4b17023SJohn Marino       return NULL_TREE;
3103e4b17023SJohn Marino     }
3104e4b17023SJohn Marino 
3105e4b17023SJohn Marino   if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
3106e4b17023SJohn Marino     folded = fold_convert (exprtype, folded);
3107e4b17023SJohn Marino 
3108e4b17023SJohn Marino   /* Force the generated expression to be a sequence of GIMPLE
3109e4b17023SJohn Marino      statements.
3110e4b17023SJohn Marino      We have to call unshare_expr because force_gimple_operand may
3111e4b17023SJohn Marino      modify the tree we pass to it.  */
3112e4b17023SJohn Marino   folded = force_gimple_operand (unshare_expr (folded), &forced_stmts,
3113e4b17023SJohn Marino 				 false, NULL);
3114e4b17023SJohn Marino 
3115e4b17023SJohn Marino   /* If we have any intermediate expressions to the value sets, add them
3116e4b17023SJohn Marino      to the value sets and chain them in the instruction stream.  */
3117e4b17023SJohn Marino   if (forced_stmts)
3118e4b17023SJohn Marino     {
3119e4b17023SJohn Marino       gsi = gsi_start (forced_stmts);
3120e4b17023SJohn Marino       for (; !gsi_end_p (gsi); gsi_next (&gsi))
3121e4b17023SJohn Marino 	{
3122e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (gsi);
3123e4b17023SJohn Marino 	  tree forcedname = gimple_get_lhs (stmt);
3124e4b17023SJohn Marino 	  pre_expr nameexpr;
3125e4b17023SJohn Marino 
3126e4b17023SJohn Marino 	  if (TREE_CODE (forcedname) == SSA_NAME)
3127e4b17023SJohn Marino 	    {
3128e4b17023SJohn Marino 	      bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
3129e4b17023SJohn Marino 	      VN_INFO_GET (forcedname)->valnum = forcedname;
3130e4b17023SJohn Marino 	      VN_INFO (forcedname)->value_id = get_next_value_id ();
3131e4b17023SJohn Marino 	      nameexpr = get_or_alloc_expr_for_name (forcedname);
3132e4b17023SJohn Marino 	      add_to_value (VN_INFO (forcedname)->value_id, nameexpr);
3133e4b17023SJohn Marino 	      if (!in_fre)
3134e4b17023SJohn Marino 		bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
3135e4b17023SJohn Marino 	      bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
3136e4b17023SJohn Marino 	    }
3137e4b17023SJohn Marino 	  mark_symbols_for_renaming (stmt);
3138e4b17023SJohn Marino 	}
3139e4b17023SJohn Marino       gimple_seq_add_seq (stmts, forced_stmts);
3140e4b17023SJohn Marino     }
3141e4b17023SJohn Marino 
3142e4b17023SJohn Marino   /* Build and insert the assignment of the end result to the temporary
3143e4b17023SJohn Marino      that we will return.  */
3144e4b17023SJohn Marino   if (!pretemp || exprtype != TREE_TYPE (pretemp))
3145e4b17023SJohn Marino     pretemp = create_tmp_reg (exprtype, "pretmp");
3146e4b17023SJohn Marino 
3147e4b17023SJohn Marino   temp = pretemp;
3148e4b17023SJohn Marino   add_referenced_var (temp);
3149e4b17023SJohn Marino 
3150e4b17023SJohn Marino   newstmt = gimple_build_assign (temp, folded);
3151e4b17023SJohn Marino   name = make_ssa_name (temp, newstmt);
3152e4b17023SJohn Marino   gimple_assign_set_lhs (newstmt, name);
3153e4b17023SJohn Marino   gimple_set_plf (newstmt, NECESSARY, false);
3154e4b17023SJohn Marino 
3155e4b17023SJohn Marino   gimple_seq_add_stmt (stmts, newstmt);
3156e4b17023SJohn Marino   bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
3157e4b17023SJohn Marino 
3158e4b17023SJohn Marino   /* All the symbols in NEWEXPR should be put into SSA form.  */
3159e4b17023SJohn Marino   mark_symbols_for_renaming (newstmt);
3160e4b17023SJohn Marino 
3161e4b17023SJohn Marino   /* Fold the last statement.  */
3162e4b17023SJohn Marino   gsi = gsi_last (*stmts);
3163e4b17023SJohn Marino   if (fold_stmt_inplace (&gsi))
3164e4b17023SJohn Marino     update_stmt (gsi_stmt (gsi));
3165e4b17023SJohn Marino 
3166e4b17023SJohn Marino   /* Add a value number to the temporary.
3167e4b17023SJohn Marino      The value may already exist in either NEW_SETS, or AVAIL_OUT, because
3168e4b17023SJohn Marino      we are creating the expression by pieces, and this particular piece of
3169e4b17023SJohn Marino      the expression may have been represented.  There is no harm in replacing
3170e4b17023SJohn Marino      here.  */
3171e4b17023SJohn Marino   VN_INFO_GET (name)->valnum = name;
3172e4b17023SJohn Marino   value_id = get_expr_value_id (expr);
3173e4b17023SJohn Marino   VN_INFO (name)->value_id = value_id;
3174e4b17023SJohn Marino   nameexpr = get_or_alloc_expr_for_name (name);
3175e4b17023SJohn Marino   add_to_value (value_id, nameexpr);
3176e4b17023SJohn Marino   if (NEW_SETS (block))
3177e4b17023SJohn Marino     bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
3178e4b17023SJohn Marino   bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
3179e4b17023SJohn Marino 
3180e4b17023SJohn Marino   pre_stats.insertions++;
3181e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
3182e4b17023SJohn Marino     {
3183e4b17023SJohn Marino       fprintf (dump_file, "Inserted ");
3184e4b17023SJohn Marino       print_gimple_stmt (dump_file, newstmt, 0, 0);
3185e4b17023SJohn Marino       fprintf (dump_file, " in predecessor %d\n", block->index);
3186e4b17023SJohn Marino     }
3187e4b17023SJohn Marino 
3188e4b17023SJohn Marino   return name;
3189e4b17023SJohn Marino }
3190e4b17023SJohn Marino 
3191e4b17023SJohn Marino 
3192e4b17023SJohn Marino /* Returns true if we want to inhibit the insertions of PHI nodes
3193e4b17023SJohn Marino    for the given EXPR for basic block BB (a member of a loop).
3194e4b17023SJohn Marino    We want to do this, when we fear that the induction variable we
3195e4b17023SJohn Marino    create might inhibit vectorization.  */
3196e4b17023SJohn Marino 
3197e4b17023SJohn Marino static bool
inhibit_phi_insertion(basic_block bb,pre_expr expr)3198e4b17023SJohn Marino inhibit_phi_insertion (basic_block bb, pre_expr expr)
3199e4b17023SJohn Marino {
3200e4b17023SJohn Marino   vn_reference_t vr = PRE_EXPR_REFERENCE (expr);
3201e4b17023SJohn Marino   VEC (vn_reference_op_s, heap) *ops = vr->operands;
3202e4b17023SJohn Marino   vn_reference_op_t op;
3203e4b17023SJohn Marino   unsigned i;
3204e4b17023SJohn Marino 
3205e4b17023SJohn Marino   /* If we aren't going to vectorize we don't inhibit anything.  */
3206e4b17023SJohn Marino   if (!flag_tree_vectorize)
3207e4b17023SJohn Marino     return false;
3208e4b17023SJohn Marino 
3209e4b17023SJohn Marino   /* Otherwise we inhibit the insertion when the address of the
3210e4b17023SJohn Marino      memory reference is a simple induction variable.  In other
3211e4b17023SJohn Marino      cases the vectorizer won't do anything anyway (either it's
3212e4b17023SJohn Marino      loop invariant or a complicated expression).  */
3213e4b17023SJohn Marino   FOR_EACH_VEC_ELT (vn_reference_op_s, ops, i, op)
3214e4b17023SJohn Marino     {
3215e4b17023SJohn Marino       switch (op->opcode)
3216e4b17023SJohn Marino 	{
3217e4b17023SJohn Marino 	case ARRAY_REF:
3218e4b17023SJohn Marino 	case ARRAY_RANGE_REF:
3219e4b17023SJohn Marino 	  if (TREE_CODE (op->op0) != SSA_NAME)
3220e4b17023SJohn Marino 	    break;
3221e4b17023SJohn Marino 	  /* Fallthru.  */
3222e4b17023SJohn Marino 	case SSA_NAME:
3223e4b17023SJohn Marino 	  {
3224e4b17023SJohn Marino 	    basic_block defbb = gimple_bb (SSA_NAME_DEF_STMT (op->op0));
3225e4b17023SJohn Marino 	    affine_iv iv;
3226e4b17023SJohn Marino 	    /* Default defs are loop invariant.  */
3227e4b17023SJohn Marino 	    if (!defbb)
3228e4b17023SJohn Marino 	      break;
3229e4b17023SJohn Marino 	    /* Defined outside this loop, also loop invariant.  */
3230e4b17023SJohn Marino 	    if (!flow_bb_inside_loop_p (bb->loop_father, defbb))
3231e4b17023SJohn Marino 	      break;
3232e4b17023SJohn Marino 	    /* If it's a simple induction variable inhibit insertion,
3233e4b17023SJohn Marino 	       the vectorizer might be interested in this one.  */
3234e4b17023SJohn Marino 	    if (simple_iv (bb->loop_father, bb->loop_father,
3235e4b17023SJohn Marino 			   op->op0, &iv, true))
3236e4b17023SJohn Marino 	      return true;
3237e4b17023SJohn Marino 	    /* No simple IV, vectorizer can't do anything, hence no
3238e4b17023SJohn Marino 	       reason to inhibit the transformation for this operand.  */
3239e4b17023SJohn Marino 	    break;
3240e4b17023SJohn Marino 	  }
3241e4b17023SJohn Marino 	default:
3242e4b17023SJohn Marino 	  break;
3243e4b17023SJohn Marino 	}
3244e4b17023SJohn Marino     }
3245e4b17023SJohn Marino   return false;
3246e4b17023SJohn Marino }
3247e4b17023SJohn Marino 
3248e4b17023SJohn Marino /* Insert the to-be-made-available values of expression EXPRNUM for each
3249e4b17023SJohn Marino    predecessor, stored in AVAIL, into the predecessors of BLOCK, and
3250e4b17023SJohn Marino    merge the result with a phi node, given the same value number as
3251e4b17023SJohn Marino    NODE.  Return true if we have inserted new stuff.  */
3252e4b17023SJohn Marino 
3253e4b17023SJohn Marino static bool
insert_into_preds_of_block(basic_block block,unsigned int exprnum,pre_expr * avail)3254e4b17023SJohn Marino insert_into_preds_of_block (basic_block block, unsigned int exprnum,
3255e4b17023SJohn Marino 			    pre_expr *avail)
3256e4b17023SJohn Marino {
3257e4b17023SJohn Marino   pre_expr expr = expression_for_id (exprnum);
3258e4b17023SJohn Marino   pre_expr newphi;
3259e4b17023SJohn Marino   unsigned int val = get_expr_value_id (expr);
3260e4b17023SJohn Marino   edge pred;
3261e4b17023SJohn Marino   bool insertions = false;
3262e4b17023SJohn Marino   bool nophi = false;
3263e4b17023SJohn Marino   basic_block bprime;
3264e4b17023SJohn Marino   pre_expr eprime;
3265e4b17023SJohn Marino   edge_iterator ei;
3266e4b17023SJohn Marino   tree type = get_expr_type (expr);
3267e4b17023SJohn Marino   tree temp;
3268e4b17023SJohn Marino   gimple phi;
3269e4b17023SJohn Marino 
3270e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
3271e4b17023SJohn Marino     {
3272e4b17023SJohn Marino       fprintf (dump_file, "Found partial redundancy for expression ");
3273e4b17023SJohn Marino       print_pre_expr (dump_file, expr);
3274e4b17023SJohn Marino       fprintf (dump_file, " (%04d)\n", val);
3275e4b17023SJohn Marino     }
3276e4b17023SJohn Marino 
3277e4b17023SJohn Marino   /* Make sure we aren't creating an induction variable.  */
3278e4b17023SJohn Marino   if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2)
3279e4b17023SJohn Marino     {
3280e4b17023SJohn Marino       bool firstinsideloop = false;
3281e4b17023SJohn Marino       bool secondinsideloop = false;
3282e4b17023SJohn Marino       firstinsideloop = flow_bb_inside_loop_p (block->loop_father,
3283e4b17023SJohn Marino 					       EDGE_PRED (block, 0)->src);
3284e4b17023SJohn Marino       secondinsideloop = flow_bb_inside_loop_p (block->loop_father,
3285e4b17023SJohn Marino 						EDGE_PRED (block, 1)->src);
3286e4b17023SJohn Marino       /* Induction variables only have one edge inside the loop.  */
3287e4b17023SJohn Marino       if ((firstinsideloop ^ secondinsideloop)
3288e4b17023SJohn Marino 	  && (expr->kind != REFERENCE
3289e4b17023SJohn Marino 	      || inhibit_phi_insertion (block, expr)))
3290e4b17023SJohn Marino 	{
3291e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
3292e4b17023SJohn Marino 	    fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
3293e4b17023SJohn Marino 	  nophi = true;
3294e4b17023SJohn Marino 	}
3295e4b17023SJohn Marino     }
3296e4b17023SJohn Marino 
3297e4b17023SJohn Marino   /* Make the necessary insertions.  */
3298e4b17023SJohn Marino   FOR_EACH_EDGE (pred, ei, block->preds)
3299e4b17023SJohn Marino     {
3300e4b17023SJohn Marino       gimple_seq stmts = NULL;
3301e4b17023SJohn Marino       tree builtexpr;
3302e4b17023SJohn Marino       bprime = pred->src;
3303e4b17023SJohn Marino       eprime = avail[bprime->index];
3304e4b17023SJohn Marino 
3305e4b17023SJohn Marino       if (eprime->kind != NAME && eprime->kind != CONSTANT)
3306e4b17023SJohn Marino 	{
3307e4b17023SJohn Marino 	  builtexpr = create_expression_by_pieces (bprime,
3308e4b17023SJohn Marino 						   eprime,
3309e4b17023SJohn Marino 						   &stmts, NULL,
3310e4b17023SJohn Marino 						   type);
3311e4b17023SJohn Marino 	  gcc_assert (!(pred->flags & EDGE_ABNORMAL));
3312e4b17023SJohn Marino 	  gsi_insert_seq_on_edge (pred, stmts);
3313e4b17023SJohn Marino 	  avail[bprime->index] = get_or_alloc_expr_for_name (builtexpr);
3314e4b17023SJohn Marino 	  insertions = true;
3315e4b17023SJohn Marino 	}
3316e4b17023SJohn Marino       else if (eprime->kind == CONSTANT)
3317e4b17023SJohn Marino 	{
3318e4b17023SJohn Marino 	  /* Constants may not have the right type, fold_convert
3319e4b17023SJohn Marino 	     should give us back a constant with the right type.
3320e4b17023SJohn Marino 	  */
3321e4b17023SJohn Marino 	  tree constant = PRE_EXPR_CONSTANT (eprime);
3322e4b17023SJohn Marino 	  if (!useless_type_conversion_p (type, TREE_TYPE (constant)))
3323e4b17023SJohn Marino 	    {
3324e4b17023SJohn Marino 	      tree builtexpr = fold_convert (type, constant);
3325e4b17023SJohn Marino 	      if (!is_gimple_min_invariant (builtexpr))
3326e4b17023SJohn Marino 		{
3327e4b17023SJohn Marino 		  tree forcedexpr = force_gimple_operand (builtexpr,
3328e4b17023SJohn Marino 							  &stmts, true,
3329e4b17023SJohn Marino 							  NULL);
3330e4b17023SJohn Marino 		  if (!is_gimple_min_invariant (forcedexpr))
3331e4b17023SJohn Marino 		    {
3332e4b17023SJohn Marino 		      if (forcedexpr != builtexpr)
3333e4b17023SJohn Marino 			{
3334e4b17023SJohn Marino 			  VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime);
3335e4b17023SJohn Marino 			  VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime);
3336e4b17023SJohn Marino 			}
3337e4b17023SJohn Marino 		      if (stmts)
3338e4b17023SJohn Marino 			{
3339e4b17023SJohn Marino 			  gimple_stmt_iterator gsi;
3340e4b17023SJohn Marino 			  gsi = gsi_start (stmts);
3341e4b17023SJohn Marino 			  for (; !gsi_end_p (gsi); gsi_next (&gsi))
3342e4b17023SJohn Marino 			    {
3343e4b17023SJohn Marino 			      gimple stmt = gsi_stmt (gsi);
3344e4b17023SJohn Marino 			      tree lhs = gimple_get_lhs (stmt);
3345e4b17023SJohn Marino 			      if (TREE_CODE (lhs) == SSA_NAME)
3346e4b17023SJohn Marino 				bitmap_set_bit (inserted_exprs,
3347e4b17023SJohn Marino 						SSA_NAME_VERSION (lhs));
3348e4b17023SJohn Marino 			      gimple_set_plf (stmt, NECESSARY, false);
3349e4b17023SJohn Marino 			    }
3350e4b17023SJohn Marino 			  gsi_insert_seq_on_edge (pred, stmts);
3351e4b17023SJohn Marino 			}
3352e4b17023SJohn Marino 		      avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
3353e4b17023SJohn Marino 		    }
3354e4b17023SJohn Marino 		}
3355e4b17023SJohn Marino 	      else
3356e4b17023SJohn Marino 		avail[bprime->index] = get_or_alloc_expr_for_constant (builtexpr);
3357e4b17023SJohn Marino 	    }
3358e4b17023SJohn Marino 	}
3359e4b17023SJohn Marino       else if (eprime->kind == NAME)
3360e4b17023SJohn Marino 	{
3361e4b17023SJohn Marino 	  /* We may have to do a conversion because our value
3362e4b17023SJohn Marino 	     numbering can look through types in certain cases, but
3363e4b17023SJohn Marino 	     our IL requires all operands of a phi node have the same
3364e4b17023SJohn Marino 	     type.  */
3365e4b17023SJohn Marino 	  tree name = PRE_EXPR_NAME (eprime);
3366e4b17023SJohn Marino 	  if (!useless_type_conversion_p (type, TREE_TYPE (name)))
3367e4b17023SJohn Marino 	    {
3368e4b17023SJohn Marino 	      tree builtexpr;
3369e4b17023SJohn Marino 	      tree forcedexpr;
3370e4b17023SJohn Marino 	      builtexpr = fold_convert (type, name);
3371e4b17023SJohn Marino 	      forcedexpr = force_gimple_operand (builtexpr,
3372e4b17023SJohn Marino 						 &stmts, true,
3373e4b17023SJohn Marino 						 NULL);
3374e4b17023SJohn Marino 
3375e4b17023SJohn Marino 	      if (forcedexpr != name)
3376e4b17023SJohn Marino 		{
3377e4b17023SJohn Marino 		  VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum;
3378e4b17023SJohn Marino 		  VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id;
3379e4b17023SJohn Marino 		}
3380e4b17023SJohn Marino 
3381e4b17023SJohn Marino 	      if (stmts)
3382e4b17023SJohn Marino 		{
3383e4b17023SJohn Marino 		  gimple_stmt_iterator gsi;
3384e4b17023SJohn Marino 		  gsi = gsi_start (stmts);
3385e4b17023SJohn Marino 		  for (; !gsi_end_p (gsi); gsi_next (&gsi))
3386e4b17023SJohn Marino 		    {
3387e4b17023SJohn Marino 		      gimple stmt = gsi_stmt (gsi);
3388e4b17023SJohn Marino 		      tree lhs = gimple_get_lhs (stmt);
3389e4b17023SJohn Marino 		      if (TREE_CODE (lhs) == SSA_NAME)
3390e4b17023SJohn Marino 			bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
3391e4b17023SJohn Marino 		      gimple_set_plf (stmt, NECESSARY, false);
3392e4b17023SJohn Marino 		    }
3393e4b17023SJohn Marino 		  gsi_insert_seq_on_edge (pred, stmts);
3394e4b17023SJohn Marino 		}
3395e4b17023SJohn Marino 	      avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
3396e4b17023SJohn Marino 	    }
3397e4b17023SJohn Marino 	}
3398e4b17023SJohn Marino     }
3399e4b17023SJohn Marino   /* If we didn't want a phi node, and we made insertions, we still have
3400e4b17023SJohn Marino      inserted new stuff, and thus return true.  If we didn't want a phi node,
3401e4b17023SJohn Marino      and didn't make insertions, we haven't added anything new, so return
3402e4b17023SJohn Marino      false.  */
3403e4b17023SJohn Marino   if (nophi && insertions)
3404e4b17023SJohn Marino     return true;
3405e4b17023SJohn Marino   else if (nophi && !insertions)
3406e4b17023SJohn Marino     return false;
3407e4b17023SJohn Marino 
3408e4b17023SJohn Marino   /* Now build a phi for the new variable.  */
3409e4b17023SJohn Marino   if (!prephitemp || TREE_TYPE (prephitemp) != type)
3410e4b17023SJohn Marino     prephitemp = create_tmp_var (type, "prephitmp");
3411e4b17023SJohn Marino 
3412e4b17023SJohn Marino   temp = prephitemp;
3413e4b17023SJohn Marino   add_referenced_var (temp);
3414e4b17023SJohn Marino 
3415e4b17023SJohn Marino   if (TREE_CODE (type) == COMPLEX_TYPE
3416e4b17023SJohn Marino       || TREE_CODE (type) == VECTOR_TYPE)
3417e4b17023SJohn Marino     DECL_GIMPLE_REG_P (temp) = 1;
3418e4b17023SJohn Marino   phi = create_phi_node (temp, block);
3419e4b17023SJohn Marino 
3420e4b17023SJohn Marino   gimple_set_plf (phi, NECESSARY, false);
3421e4b17023SJohn Marino   VN_INFO_GET (gimple_phi_result (phi))->valnum = gimple_phi_result (phi);
3422e4b17023SJohn Marino   VN_INFO (gimple_phi_result (phi))->value_id = val;
3423e4b17023SJohn Marino   bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (gimple_phi_result (phi)));
3424e4b17023SJohn Marino   FOR_EACH_EDGE (pred, ei, block->preds)
3425e4b17023SJohn Marino     {
3426e4b17023SJohn Marino       pre_expr ae = avail[pred->src->index];
3427e4b17023SJohn Marino       gcc_assert (get_expr_type (ae) == type
3428e4b17023SJohn Marino 		  || useless_type_conversion_p (type, get_expr_type (ae)));
3429e4b17023SJohn Marino       if (ae->kind == CONSTANT)
3430e4b17023SJohn Marino 	add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION);
3431e4b17023SJohn Marino       else
3432e4b17023SJohn Marino 	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
3433e4b17023SJohn Marino 		     UNKNOWN_LOCATION);
3434e4b17023SJohn Marino     }
3435e4b17023SJohn Marino 
3436e4b17023SJohn Marino   newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
3437e4b17023SJohn Marino   add_to_value (val, newphi);
3438e4b17023SJohn Marino 
3439e4b17023SJohn Marino   /* The value should *not* exist in PHI_GEN, or else we wouldn't be doing
3440e4b17023SJohn Marino      this insertion, since we test for the existence of this value in PHI_GEN
3441e4b17023SJohn Marino      before proceeding with the partial redundancy checks in insert_aux.
3442e4b17023SJohn Marino 
3443e4b17023SJohn Marino      The value may exist in AVAIL_OUT, in particular, it could be represented
3444e4b17023SJohn Marino      by the expression we are trying to eliminate, in which case we want the
3445e4b17023SJohn Marino      replacement to occur.  If it's not existing in AVAIL_OUT, we want it
3446e4b17023SJohn Marino      inserted there.
3447e4b17023SJohn Marino 
3448e4b17023SJohn Marino      Similarly, to the PHI_GEN case, the value should not exist in NEW_SETS of
3449e4b17023SJohn Marino      this block, because if it did, it would have existed in our dominator's
3450e4b17023SJohn Marino      AVAIL_OUT, and would have been skipped due to the full redundancy check.
3451e4b17023SJohn Marino   */
3452e4b17023SJohn Marino 
3453e4b17023SJohn Marino   bitmap_insert_into_set (PHI_GEN (block), newphi);
3454e4b17023SJohn Marino   bitmap_value_replace_in_set (AVAIL_OUT (block),
3455e4b17023SJohn Marino 			       newphi);
3456e4b17023SJohn Marino   bitmap_insert_into_set (NEW_SETS (block),
3457e4b17023SJohn Marino 			  newphi);
3458e4b17023SJohn Marino 
3459e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
3460e4b17023SJohn Marino     {
3461e4b17023SJohn Marino       fprintf (dump_file, "Created phi ");
3462e4b17023SJohn Marino       print_gimple_stmt (dump_file, phi, 0, 0);
3463e4b17023SJohn Marino       fprintf (dump_file, " in block %d\n", block->index);
3464e4b17023SJohn Marino     }
3465e4b17023SJohn Marino   pre_stats.phis++;
3466e4b17023SJohn Marino   return true;
3467e4b17023SJohn Marino }
3468e4b17023SJohn Marino 
3469e4b17023SJohn Marino 
3470e4b17023SJohn Marino 
3471e4b17023SJohn Marino /* Perform insertion of partially redundant values.
3472e4b17023SJohn Marino    For BLOCK, do the following:
3473e4b17023SJohn Marino    1.  Propagate the NEW_SETS of the dominator into the current block.
3474e4b17023SJohn Marino    If the block has multiple predecessors,
3475e4b17023SJohn Marino        2a. Iterate over the ANTIC expressions for the block to see if
3476e4b17023SJohn Marino 	   any of them are partially redundant.
3477e4b17023SJohn Marino        2b. If so, insert them into the necessary predecessors to make
3478e4b17023SJohn Marino 	   the expression fully redundant.
3479e4b17023SJohn Marino        2c. Insert a new PHI merging the values of the predecessors.
3480e4b17023SJohn Marino        2d. Insert the new PHI, and the new expressions, into the
3481e4b17023SJohn Marino 	   NEW_SETS set.
3482e4b17023SJohn Marino    3. Recursively call ourselves on the dominator children of BLOCK.
3483e4b17023SJohn Marino 
3484e4b17023SJohn Marino    Steps 1, 2a, and 3 are done by insert_aux. 2b, 2c and 2d are done by
3485e4b17023SJohn Marino    do_regular_insertion and do_partial_insertion.
3486e4b17023SJohn Marino 
3487e4b17023SJohn Marino */
3488e4b17023SJohn Marino 
3489e4b17023SJohn Marino static bool
do_regular_insertion(basic_block block,basic_block dom)3490e4b17023SJohn Marino do_regular_insertion (basic_block block, basic_block dom)
3491e4b17023SJohn Marino {
3492e4b17023SJohn Marino   bool new_stuff = false;
3493e4b17023SJohn Marino   VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
3494e4b17023SJohn Marino   pre_expr expr;
3495e4b17023SJohn Marino   int i;
3496e4b17023SJohn Marino 
3497e4b17023SJohn Marino   FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
3498e4b17023SJohn Marino     {
34995ce9237cSJohn Marino       if (expr->kind == NARY
35005ce9237cSJohn Marino 	  || expr->kind == REFERENCE)
3501e4b17023SJohn Marino 	{
3502e4b17023SJohn Marino 	  pre_expr *avail;
3503e4b17023SJohn Marino 	  unsigned int val;
3504e4b17023SJohn Marino 	  bool by_some = false;
3505e4b17023SJohn Marino 	  bool cant_insert = false;
3506e4b17023SJohn Marino 	  bool all_same = true;
3507e4b17023SJohn Marino 	  pre_expr first_s = NULL;
3508e4b17023SJohn Marino 	  edge pred;
3509e4b17023SJohn Marino 	  basic_block bprime;
3510e4b17023SJohn Marino 	  pre_expr eprime = NULL;
3511e4b17023SJohn Marino 	  edge_iterator ei;
3512e4b17023SJohn Marino 	  pre_expr edoubleprime = NULL;
3513e4b17023SJohn Marino 	  bool do_insertion = false;
3514e4b17023SJohn Marino 
3515e4b17023SJohn Marino 	  val = get_expr_value_id (expr);
3516e4b17023SJohn Marino 	  if (bitmap_set_contains_value (PHI_GEN (block), val))
3517e4b17023SJohn Marino 	    continue;
3518e4b17023SJohn Marino 	  if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
3519e4b17023SJohn Marino 	    {
3520e4b17023SJohn Marino 	      if (dump_file && (dump_flags & TDF_DETAILS))
3521e4b17023SJohn Marino 		fprintf (dump_file, "Found fully redundant value\n");
3522e4b17023SJohn Marino 	      continue;
3523e4b17023SJohn Marino 	    }
3524e4b17023SJohn Marino 
3525e4b17023SJohn Marino 	  avail = XCNEWVEC (pre_expr, last_basic_block);
3526e4b17023SJohn Marino 	  FOR_EACH_EDGE (pred, ei, block->preds)
3527e4b17023SJohn Marino 	    {
3528e4b17023SJohn Marino 	      unsigned int vprime;
3529e4b17023SJohn Marino 
3530e4b17023SJohn Marino 	      /* We should never run insertion for the exit block
3531e4b17023SJohn Marino 	         and so not come across fake pred edges.  */
3532e4b17023SJohn Marino 	      gcc_assert (!(pred->flags & EDGE_FAKE));
3533e4b17023SJohn Marino 	      bprime = pred->src;
3534e4b17023SJohn Marino 	      eprime = phi_translate (expr, ANTIC_IN (block), NULL,
3535e4b17023SJohn Marino 				      bprime, block);
3536e4b17023SJohn Marino 
3537e4b17023SJohn Marino 	      /* eprime will generally only be NULL if the
3538e4b17023SJohn Marino 		 value of the expression, translated
3539e4b17023SJohn Marino 		 through the PHI for this predecessor, is
3540e4b17023SJohn Marino 		 undefined.  If that is the case, we can't
3541e4b17023SJohn Marino 		 make the expression fully redundant,
3542e4b17023SJohn Marino 		 because its value is undefined along a
3543e4b17023SJohn Marino 		 predecessor path.  We can thus break out
3544e4b17023SJohn Marino 		 early because it doesn't matter what the
3545e4b17023SJohn Marino 		 rest of the results are.  */
3546e4b17023SJohn Marino 	      if (eprime == NULL)
3547e4b17023SJohn Marino 		{
3548e4b17023SJohn Marino 		  cant_insert = true;
3549e4b17023SJohn Marino 		  break;
3550e4b17023SJohn Marino 		}
3551e4b17023SJohn Marino 
3552e4b17023SJohn Marino 	      eprime = fully_constant_expression (eprime);
3553e4b17023SJohn Marino 	      vprime = get_expr_value_id (eprime);
3554e4b17023SJohn Marino 	      edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
3555e4b17023SJohn Marino 						 vprime, NULL);
3556e4b17023SJohn Marino 	      if (edoubleprime == NULL)
3557e4b17023SJohn Marino 		{
3558e4b17023SJohn Marino 		  avail[bprime->index] = eprime;
3559e4b17023SJohn Marino 		  all_same = false;
3560e4b17023SJohn Marino 		}
3561e4b17023SJohn Marino 	      else
3562e4b17023SJohn Marino 		{
3563e4b17023SJohn Marino 		  avail[bprime->index] = edoubleprime;
3564e4b17023SJohn Marino 		  by_some = true;
3565e4b17023SJohn Marino 		  /* We want to perform insertions to remove a redundancy on
3566e4b17023SJohn Marino 		     a path in the CFG we want to optimize for speed.  */
3567e4b17023SJohn Marino 		  if (optimize_edge_for_speed_p (pred))
3568e4b17023SJohn Marino 		    do_insertion = true;
3569e4b17023SJohn Marino 		  if (first_s == NULL)
3570e4b17023SJohn Marino 		    first_s = edoubleprime;
3571e4b17023SJohn Marino 		  else if (!pre_expr_eq (first_s, edoubleprime))
3572e4b17023SJohn Marino 		    all_same = false;
3573e4b17023SJohn Marino 		}
3574e4b17023SJohn Marino 	    }
3575e4b17023SJohn Marino 	  /* If we can insert it, it's not the same value
3576e4b17023SJohn Marino 	     already existing along every predecessor, and
3577e4b17023SJohn Marino 	     it's defined by some predecessor, it is
3578e4b17023SJohn Marino 	     partially redundant.  */
3579e4b17023SJohn Marino 	  if (!cant_insert && !all_same && by_some)
3580e4b17023SJohn Marino 	    {
3581e4b17023SJohn Marino 	      if (!do_insertion)
3582e4b17023SJohn Marino 		{
3583e4b17023SJohn Marino 		  if (dump_file && (dump_flags & TDF_DETAILS))
3584e4b17023SJohn Marino 		    {
3585e4b17023SJohn Marino 		      fprintf (dump_file, "Skipping partial redundancy for "
3586e4b17023SJohn Marino 			       "expression ");
3587e4b17023SJohn Marino 		      print_pre_expr (dump_file, expr);
3588e4b17023SJohn Marino 		      fprintf (dump_file, " (%04d), no redundancy on to be "
3589e4b17023SJohn Marino 			       "optimized for speed edge\n", val);
3590e4b17023SJohn Marino 		    }
3591e4b17023SJohn Marino 		}
3592e4b17023SJohn Marino 	      else if (dbg_cnt (treepre_insert)
3593e4b17023SJohn Marino 		       && insert_into_preds_of_block (block,
3594e4b17023SJohn Marino 						      get_expression_id (expr),
3595e4b17023SJohn Marino 						      avail))
3596e4b17023SJohn Marino 		new_stuff = true;
3597e4b17023SJohn Marino 	    }
3598e4b17023SJohn Marino 	  /* If all edges produce the same value and that value is
3599e4b17023SJohn Marino 	     an invariant, then the PHI has the same value on all
3600e4b17023SJohn Marino 	     edges.  Note this.  */
36015ce9237cSJohn Marino 	  else if (!cant_insert && all_same)
3602e4b17023SJohn Marino 	    {
36035ce9237cSJohn Marino 	      tree exprtype = get_expr_type (expr);
36045ce9237cSJohn Marino 	      tree temp;
36055ce9237cSJohn Marino 	      gimple assign;
36065ce9237cSJohn Marino 	      pre_expr newe;
36075ce9237cSJohn Marino 	      gimple_stmt_iterator gsi;
3608e4b17023SJohn Marino 
36095ce9237cSJohn Marino 	      gcc_assert (edoubleprime->kind == CONSTANT
36105ce9237cSJohn Marino 			  || edoubleprime->kind == NAME);
3611e4b17023SJohn Marino 
36125ce9237cSJohn Marino 	      if (!pretemp || TREE_TYPE (pretemp) != exprtype)
3613e4b17023SJohn Marino 		{
36145ce9237cSJohn Marino 		  pretemp = create_tmp_reg (exprtype, "pretmp");
36155ce9237cSJohn Marino 		  add_referenced_var (pretemp);
3616e4b17023SJohn Marino 		}
36175ce9237cSJohn Marino 	      temp = make_ssa_name (pretemp, NULL);
36185ce9237cSJohn Marino 	      assign = gimple_build_assign (temp,
36195ce9237cSJohn Marino 					    edoubleprime->kind == CONSTANT ? PRE_EXPR_CONSTANT (edoubleprime) : PRE_EXPR_NAME (edoubleprime));
36205ce9237cSJohn Marino 	      gsi = gsi_after_labels (block);
36215ce9237cSJohn Marino 	      gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
36225ce9237cSJohn Marino 
36235ce9237cSJohn Marino 	      gimple_set_plf (assign, NECESSARY, false);
36245ce9237cSJohn Marino 	      VN_INFO_GET (temp)->value_id = val;
36255ce9237cSJohn Marino 	      VN_INFO (temp)->valnum = temp;
36265ce9237cSJohn Marino 	      bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp));
36275ce9237cSJohn Marino 	      newe = get_or_alloc_expr_for_name (temp);
36285ce9237cSJohn Marino 	      add_to_value (val, newe);
36295ce9237cSJohn Marino 	      bitmap_value_replace_in_set (AVAIL_OUT (block), newe);
36305ce9237cSJohn Marino 	      bitmap_insert_into_set (NEW_SETS (block), newe);
3631e4b17023SJohn Marino 	    }
3632e4b17023SJohn Marino 	  free (avail);
3633e4b17023SJohn Marino 	}
3634e4b17023SJohn Marino     }
3635e4b17023SJohn Marino 
3636e4b17023SJohn Marino   VEC_free (pre_expr, heap, exprs);
3637e4b17023SJohn Marino   return new_stuff;
3638e4b17023SJohn Marino }
3639e4b17023SJohn Marino 
3640e4b17023SJohn Marino 
3641e4b17023SJohn Marino /* Perform insertion for partially anticipatable expressions.  There
3642e4b17023SJohn Marino    is only one case we will perform insertion for these.  This case is
3643e4b17023SJohn Marino    if the expression is partially anticipatable, and fully available.
3644e4b17023SJohn Marino    In this case, we know that putting it earlier will enable us to
3645e4b17023SJohn Marino    remove the later computation.  */
3646e4b17023SJohn Marino 
3647e4b17023SJohn Marino 
3648e4b17023SJohn Marino static bool
do_partial_partial_insertion(basic_block block,basic_block dom)3649e4b17023SJohn Marino do_partial_partial_insertion (basic_block block, basic_block dom)
3650e4b17023SJohn Marino {
3651e4b17023SJohn Marino   bool new_stuff = false;
3652e4b17023SJohn Marino   VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (PA_IN (block));
3653e4b17023SJohn Marino   pre_expr expr;
3654e4b17023SJohn Marino   int i;
3655e4b17023SJohn Marino 
3656e4b17023SJohn Marino   FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
3657e4b17023SJohn Marino     {
36585ce9237cSJohn Marino       if (expr->kind == NARY
36595ce9237cSJohn Marino 	  || expr->kind == REFERENCE)
3660e4b17023SJohn Marino 	{
3661e4b17023SJohn Marino 	  pre_expr *avail;
3662e4b17023SJohn Marino 	  unsigned int val;
3663e4b17023SJohn Marino 	  bool by_all = true;
3664e4b17023SJohn Marino 	  bool cant_insert = false;
3665e4b17023SJohn Marino 	  edge pred;
3666e4b17023SJohn Marino 	  basic_block bprime;
3667e4b17023SJohn Marino 	  pre_expr eprime = NULL;
3668e4b17023SJohn Marino 	  edge_iterator ei;
3669e4b17023SJohn Marino 
3670e4b17023SJohn Marino 	  val = get_expr_value_id (expr);
3671e4b17023SJohn Marino 	  if (bitmap_set_contains_value (PHI_GEN (block), val))
3672e4b17023SJohn Marino 	    continue;
3673e4b17023SJohn Marino 	  if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
3674e4b17023SJohn Marino 	    continue;
3675e4b17023SJohn Marino 
3676e4b17023SJohn Marino 	  avail = XCNEWVEC (pre_expr, last_basic_block);
3677e4b17023SJohn Marino 	  FOR_EACH_EDGE (pred, ei, block->preds)
3678e4b17023SJohn Marino 	    {
3679e4b17023SJohn Marino 	      unsigned int vprime;
3680e4b17023SJohn Marino 	      pre_expr edoubleprime;
3681e4b17023SJohn Marino 
3682e4b17023SJohn Marino 	      /* We should never run insertion for the exit block
3683e4b17023SJohn Marino 	         and so not come across fake pred edges.  */
3684e4b17023SJohn Marino 	      gcc_assert (!(pred->flags & EDGE_FAKE));
3685e4b17023SJohn Marino 	      bprime = pred->src;
3686e4b17023SJohn Marino 	      eprime = phi_translate (expr, ANTIC_IN (block),
3687e4b17023SJohn Marino 				      PA_IN (block),
3688e4b17023SJohn Marino 				      bprime, block);
3689e4b17023SJohn Marino 
3690e4b17023SJohn Marino 	      /* eprime will generally only be NULL if the
3691e4b17023SJohn Marino 		 value of the expression, translated
3692e4b17023SJohn Marino 		 through the PHI for this predecessor, is
3693e4b17023SJohn Marino 		 undefined.  If that is the case, we can't
3694e4b17023SJohn Marino 		 make the expression fully redundant,
3695e4b17023SJohn Marino 		 because its value is undefined along a
3696e4b17023SJohn Marino 		 predecessor path.  We can thus break out
3697e4b17023SJohn Marino 		 early because it doesn't matter what the
3698e4b17023SJohn Marino 		 rest of the results are.  */
3699e4b17023SJohn Marino 	      if (eprime == NULL)
3700e4b17023SJohn Marino 		{
3701e4b17023SJohn Marino 		  cant_insert = true;
3702e4b17023SJohn Marino 		  break;
3703e4b17023SJohn Marino 		}
3704e4b17023SJohn Marino 
3705e4b17023SJohn Marino 	      eprime = fully_constant_expression (eprime);
3706e4b17023SJohn Marino 	      vprime = get_expr_value_id (eprime);
3707e4b17023SJohn Marino 	      edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
3708e4b17023SJohn Marino 						 vprime, NULL);
3709e4b17023SJohn Marino 	      if (edoubleprime == NULL)
3710e4b17023SJohn Marino 		{
3711e4b17023SJohn Marino 		  by_all = false;
3712e4b17023SJohn Marino 		  break;
3713e4b17023SJohn Marino 		}
3714e4b17023SJohn Marino 	      else
3715e4b17023SJohn Marino 		avail[bprime->index] = edoubleprime;
3716e4b17023SJohn Marino 
3717e4b17023SJohn Marino 	    }
3718e4b17023SJohn Marino 
3719e4b17023SJohn Marino 	  /* If we can insert it, it's not the same value
3720e4b17023SJohn Marino 	     already existing along every predecessor, and
3721e4b17023SJohn Marino 	     it's defined by some predecessor, it is
3722e4b17023SJohn Marino 	     partially redundant.  */
3723e4b17023SJohn Marino 	  if (!cant_insert && by_all && dbg_cnt (treepre_insert))
3724e4b17023SJohn Marino 	    {
3725e4b17023SJohn Marino 	      pre_stats.pa_insert++;
3726e4b17023SJohn Marino 	      if (insert_into_preds_of_block (block, get_expression_id (expr),
3727e4b17023SJohn Marino 					      avail))
3728e4b17023SJohn Marino 		new_stuff = true;
3729e4b17023SJohn Marino 	    }
3730e4b17023SJohn Marino 	  free (avail);
3731e4b17023SJohn Marino 	}
3732e4b17023SJohn Marino     }
3733e4b17023SJohn Marino 
3734e4b17023SJohn Marino   VEC_free (pre_expr, heap, exprs);
3735e4b17023SJohn Marino   return new_stuff;
3736e4b17023SJohn Marino }
3737e4b17023SJohn Marino 
3738e4b17023SJohn Marino static bool
insert_aux(basic_block block)3739e4b17023SJohn Marino insert_aux (basic_block block)
3740e4b17023SJohn Marino {
3741e4b17023SJohn Marino   basic_block son;
3742e4b17023SJohn Marino   bool new_stuff = false;
3743e4b17023SJohn Marino 
3744e4b17023SJohn Marino   if (block)
3745e4b17023SJohn Marino     {
3746e4b17023SJohn Marino       basic_block dom;
3747e4b17023SJohn Marino       dom = get_immediate_dominator (CDI_DOMINATORS, block);
3748e4b17023SJohn Marino       if (dom)
3749e4b17023SJohn Marino 	{
3750e4b17023SJohn Marino 	  unsigned i;
3751e4b17023SJohn Marino 	  bitmap_iterator bi;
3752e4b17023SJohn Marino 	  bitmap_set_t newset = NEW_SETS (dom);
3753e4b17023SJohn Marino 	  if (newset)
3754e4b17023SJohn Marino 	    {
3755e4b17023SJohn Marino 	      /* Note that we need to value_replace both NEW_SETS, and
3756e4b17023SJohn Marino 		 AVAIL_OUT. For both the case of NEW_SETS, the value may be
3757e4b17023SJohn Marino 		 represented by some non-simple expression here that we want
3758e4b17023SJohn Marino 		 to replace it with.  */
3759e4b17023SJohn Marino 	      FOR_EACH_EXPR_ID_IN_SET (newset, i, bi)
3760e4b17023SJohn Marino 		{
3761e4b17023SJohn Marino 		  pre_expr expr = expression_for_id (i);
3762e4b17023SJohn Marino 		  bitmap_value_replace_in_set (NEW_SETS (block), expr);
3763e4b17023SJohn Marino 		  bitmap_value_replace_in_set (AVAIL_OUT (block), expr);
3764e4b17023SJohn Marino 		}
3765e4b17023SJohn Marino 	    }
3766e4b17023SJohn Marino 	  if (!single_pred_p (block))
3767e4b17023SJohn Marino 	    {
3768e4b17023SJohn Marino 	      new_stuff |= do_regular_insertion (block, dom);
3769e4b17023SJohn Marino 	      if (do_partial_partial)
3770e4b17023SJohn Marino 		new_stuff |= do_partial_partial_insertion (block, dom);
3771e4b17023SJohn Marino 	    }
3772e4b17023SJohn Marino 	}
3773e4b17023SJohn Marino     }
3774e4b17023SJohn Marino   for (son = first_dom_son (CDI_DOMINATORS, block);
3775e4b17023SJohn Marino        son;
3776e4b17023SJohn Marino        son = next_dom_son (CDI_DOMINATORS, son))
3777e4b17023SJohn Marino     {
3778e4b17023SJohn Marino       new_stuff |= insert_aux (son);
3779e4b17023SJohn Marino     }
3780e4b17023SJohn Marino 
3781e4b17023SJohn Marino   return new_stuff;
3782e4b17023SJohn Marino }
3783e4b17023SJohn Marino 
3784e4b17023SJohn Marino /* Perform insertion of partially redundant values.  */
3785e4b17023SJohn Marino 
3786e4b17023SJohn Marino static void
insert(void)3787e4b17023SJohn Marino insert (void)
3788e4b17023SJohn Marino {
3789e4b17023SJohn Marino   bool new_stuff = true;
3790e4b17023SJohn Marino   basic_block bb;
3791e4b17023SJohn Marino   int num_iterations = 0;
3792e4b17023SJohn Marino 
3793e4b17023SJohn Marino   FOR_ALL_BB (bb)
3794e4b17023SJohn Marino     NEW_SETS (bb) = bitmap_set_new ();
3795e4b17023SJohn Marino 
3796e4b17023SJohn Marino   while (new_stuff)
3797e4b17023SJohn Marino     {
3798e4b17023SJohn Marino       num_iterations++;
3799e4b17023SJohn Marino       new_stuff = insert_aux (ENTRY_BLOCK_PTR);
3800e4b17023SJohn Marino     }
3801e4b17023SJohn Marino   statistics_histogram_event (cfun, "insert iterations", num_iterations);
3802e4b17023SJohn Marino }
3803e4b17023SJohn Marino 
3804e4b17023SJohn Marino 
3805e4b17023SJohn Marino /* Add OP to EXP_GEN (block), and possibly to the maximal set.  */
3806e4b17023SJohn Marino 
3807e4b17023SJohn Marino static void
add_to_exp_gen(basic_block block,tree op)3808e4b17023SJohn Marino add_to_exp_gen (basic_block block, tree op)
3809e4b17023SJohn Marino {
3810e4b17023SJohn Marino   if (!in_fre)
3811e4b17023SJohn Marino     {
3812e4b17023SJohn Marino       pre_expr result;
3813e4b17023SJohn Marino       if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op))
3814e4b17023SJohn Marino 	return;
3815e4b17023SJohn Marino       result = get_or_alloc_expr_for_name (op);
3816e4b17023SJohn Marino       bitmap_value_insert_into_set (EXP_GEN (block), result);
3817e4b17023SJohn Marino     }
3818e4b17023SJohn Marino }
3819e4b17023SJohn Marino 
3820e4b17023SJohn Marino /* Create value ids for PHI in BLOCK.  */
3821e4b17023SJohn Marino 
3822e4b17023SJohn Marino static void
make_values_for_phi(gimple phi,basic_block block)3823e4b17023SJohn Marino make_values_for_phi (gimple phi, basic_block block)
3824e4b17023SJohn Marino {
3825e4b17023SJohn Marino   tree result = gimple_phi_result (phi);
3826e4b17023SJohn Marino 
3827e4b17023SJohn Marino   /* We have no need for virtual phis, as they don't represent
3828e4b17023SJohn Marino      actual computations.  */
3829e4b17023SJohn Marino   if (is_gimple_reg (result))
3830e4b17023SJohn Marino     {
3831e4b17023SJohn Marino       pre_expr e = get_or_alloc_expr_for_name (result);
3832e4b17023SJohn Marino       add_to_value (get_expr_value_id (e), e);
3833e4b17023SJohn Marino       bitmap_insert_into_set (PHI_GEN (block), e);
3834e4b17023SJohn Marino       bitmap_value_insert_into_set (AVAIL_OUT (block), e);
3835e4b17023SJohn Marino       if (!in_fre)
3836e4b17023SJohn Marino 	{
3837e4b17023SJohn Marino 	  unsigned i;
3838e4b17023SJohn Marino 	  for (i = 0; i < gimple_phi_num_args (phi); ++i)
3839e4b17023SJohn Marino 	    {
3840e4b17023SJohn Marino 	      tree arg = gimple_phi_arg_def (phi, i);
3841e4b17023SJohn Marino 	      if (TREE_CODE (arg) == SSA_NAME)
3842e4b17023SJohn Marino 		{
3843e4b17023SJohn Marino 		  e = get_or_alloc_expr_for_name (arg);
3844e4b17023SJohn Marino 		  add_to_value (get_expr_value_id (e), e);
3845e4b17023SJohn Marino 		}
3846e4b17023SJohn Marino 	    }
3847e4b17023SJohn Marino 	}
3848e4b17023SJohn Marino     }
3849e4b17023SJohn Marino }
3850e4b17023SJohn Marino 
3851e4b17023SJohn Marino /* Compute the AVAIL set for all basic blocks.
3852e4b17023SJohn Marino 
3853e4b17023SJohn Marino    This function performs value numbering of the statements in each basic
3854e4b17023SJohn Marino    block.  The AVAIL sets are built from information we glean while doing
3855e4b17023SJohn Marino    this value numbering, since the AVAIL sets contain only one entry per
3856e4b17023SJohn Marino    value.
3857e4b17023SJohn Marino 
3858e4b17023SJohn Marino    AVAIL_IN[BLOCK] = AVAIL_OUT[dom(BLOCK)].
3859e4b17023SJohn Marino    AVAIL_OUT[BLOCK] = AVAIL_IN[BLOCK] U PHI_GEN[BLOCK] U TMP_GEN[BLOCK].  */
3860e4b17023SJohn Marino 
3861e4b17023SJohn Marino static void
compute_avail(void)3862e4b17023SJohn Marino compute_avail (void)
3863e4b17023SJohn Marino {
3864e4b17023SJohn Marino 
3865e4b17023SJohn Marino   basic_block block, son;
3866e4b17023SJohn Marino   basic_block *worklist;
3867e4b17023SJohn Marino   size_t sp = 0;
3868e4b17023SJohn Marino   unsigned i;
3869e4b17023SJohn Marino 
3870e4b17023SJohn Marino   /* We pretend that default definitions are defined in the entry block.
3871e4b17023SJohn Marino      This includes function arguments and the static chain decl.  */
3872e4b17023SJohn Marino   for (i = 1; i < num_ssa_names; ++i)
3873e4b17023SJohn Marino     {
3874e4b17023SJohn Marino       tree name = ssa_name (i);
3875e4b17023SJohn Marino       pre_expr e;
3876e4b17023SJohn Marino       if (!name
3877e4b17023SJohn Marino 	  || !SSA_NAME_IS_DEFAULT_DEF (name)
3878e4b17023SJohn Marino 	  || has_zero_uses (name)
3879e4b17023SJohn Marino 	  || !is_gimple_reg (name))
3880e4b17023SJohn Marino 	continue;
3881e4b17023SJohn Marino 
3882e4b17023SJohn Marino       e = get_or_alloc_expr_for_name (name);
3883e4b17023SJohn Marino       add_to_value (get_expr_value_id (e), e);
3884e4b17023SJohn Marino       if (!in_fre)
3885e4b17023SJohn Marino 	bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
3886e4b17023SJohn Marino       bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), e);
3887e4b17023SJohn Marino     }
3888e4b17023SJohn Marino 
3889e4b17023SJohn Marino   /* Allocate the worklist.  */
3890e4b17023SJohn Marino   worklist = XNEWVEC (basic_block, n_basic_blocks);
3891e4b17023SJohn Marino 
3892e4b17023SJohn Marino   /* Seed the algorithm by putting the dominator children of the entry
3893e4b17023SJohn Marino      block on the worklist.  */
3894e4b17023SJohn Marino   for (son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR);
3895e4b17023SJohn Marino        son;
3896e4b17023SJohn Marino        son = next_dom_son (CDI_DOMINATORS, son))
3897e4b17023SJohn Marino     worklist[sp++] = son;
3898e4b17023SJohn Marino 
3899e4b17023SJohn Marino   /* Loop until the worklist is empty.  */
3900e4b17023SJohn Marino   while (sp)
3901e4b17023SJohn Marino     {
3902e4b17023SJohn Marino       gimple_stmt_iterator gsi;
3903e4b17023SJohn Marino       gimple stmt;
3904e4b17023SJohn Marino       basic_block dom;
3905e4b17023SJohn Marino       unsigned int stmt_uid = 1;
3906e4b17023SJohn Marino 
3907e4b17023SJohn Marino       /* Pick a block from the worklist.  */
3908e4b17023SJohn Marino       block = worklist[--sp];
3909e4b17023SJohn Marino 
3910e4b17023SJohn Marino       /* Initially, the set of available values in BLOCK is that of
3911e4b17023SJohn Marino 	 its immediate dominator.  */
3912e4b17023SJohn Marino       dom = get_immediate_dominator (CDI_DOMINATORS, block);
3913e4b17023SJohn Marino       if (dom)
3914e4b17023SJohn Marino 	bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
3915e4b17023SJohn Marino 
3916e4b17023SJohn Marino       /* Generate values for PHI nodes.  */
3917e4b17023SJohn Marino       for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
3918e4b17023SJohn Marino 	make_values_for_phi (gsi_stmt (gsi), block);
3919e4b17023SJohn Marino 
3920e4b17023SJohn Marino       BB_MAY_NOTRETURN (block) = 0;
3921e4b17023SJohn Marino 
3922e4b17023SJohn Marino       /* Now compute value numbers and populate value sets with all
3923e4b17023SJohn Marino 	 the expressions computed in BLOCK.  */
3924e4b17023SJohn Marino       for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
3925e4b17023SJohn Marino 	{
3926e4b17023SJohn Marino 	  ssa_op_iter iter;
3927e4b17023SJohn Marino 	  tree op;
3928e4b17023SJohn Marino 
3929e4b17023SJohn Marino 	  stmt = gsi_stmt (gsi);
3930e4b17023SJohn Marino 	  gimple_set_uid (stmt, stmt_uid++);
3931e4b17023SJohn Marino 
3932e4b17023SJohn Marino 	  /* Cache whether the basic-block has any non-visible side-effect
3933e4b17023SJohn Marino 	     or control flow.
3934e4b17023SJohn Marino 	     If this isn't a call or it is the last stmt in the
3935e4b17023SJohn Marino 	     basic-block then the CFG represents things correctly.  */
3936e4b17023SJohn Marino 	  if (is_gimple_call (stmt) && !stmt_ends_bb_p (stmt))
3937e4b17023SJohn Marino 	    {
3938e4b17023SJohn Marino 	      /* Non-looping const functions always return normally.
3939e4b17023SJohn Marino 		 Otherwise the call might not return or have side-effects
3940e4b17023SJohn Marino 		 that forbids hoisting possibly trapping expressions
3941e4b17023SJohn Marino 		 before it.  */
3942e4b17023SJohn Marino 	      int flags = gimple_call_flags (stmt);
3943e4b17023SJohn Marino 	      if (!(flags & ECF_CONST)
3944e4b17023SJohn Marino 		  || (flags & ECF_LOOPING_CONST_OR_PURE))
3945e4b17023SJohn Marino 		BB_MAY_NOTRETURN (block) = 1;
3946e4b17023SJohn Marino 	    }
3947e4b17023SJohn Marino 
3948e4b17023SJohn Marino 	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
3949e4b17023SJohn Marino 	    {
3950e4b17023SJohn Marino 	      pre_expr e = get_or_alloc_expr_for_name (op);
3951e4b17023SJohn Marino 
3952e4b17023SJohn Marino 	      add_to_value (get_expr_value_id (e), e);
3953e4b17023SJohn Marino 	      if (!in_fre)
3954e4b17023SJohn Marino 		bitmap_insert_into_set (TMP_GEN (block), e);
3955e4b17023SJohn Marino 	      bitmap_value_insert_into_set (AVAIL_OUT (block), e);
3956e4b17023SJohn Marino 	    }
3957e4b17023SJohn Marino 
3958e4b17023SJohn Marino 	  if (gimple_has_side_effects (stmt) || stmt_could_throw_p (stmt))
3959e4b17023SJohn Marino 	    continue;
3960e4b17023SJohn Marino 
3961e4b17023SJohn Marino 	  switch (gimple_code (stmt))
3962e4b17023SJohn Marino 	    {
3963e4b17023SJohn Marino 	    case GIMPLE_RETURN:
3964e4b17023SJohn Marino 	      FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
3965e4b17023SJohn Marino 		add_to_exp_gen (block, op);
3966e4b17023SJohn Marino 	      continue;
3967e4b17023SJohn Marino 
3968e4b17023SJohn Marino 	    case GIMPLE_CALL:
3969e4b17023SJohn Marino 	      {
3970e4b17023SJohn Marino 		vn_reference_t ref;
3971e4b17023SJohn Marino 		unsigned int i;
3972e4b17023SJohn Marino 		vn_reference_op_t vro;
3973e4b17023SJohn Marino 		pre_expr result = NULL;
3974e4b17023SJohn Marino 		VEC(vn_reference_op_s, heap) *ops = NULL;
3975e4b17023SJohn Marino 
3976e4b17023SJohn Marino 		/* We can value number only calls to real functions.  */
3977e4b17023SJohn Marino 		if (gimple_call_internal_p (stmt))
3978e4b17023SJohn Marino 		  continue;
3979e4b17023SJohn Marino 
3980e4b17023SJohn Marino 		copy_reference_ops_from_call (stmt, &ops);
3981e4b17023SJohn Marino 		vn_reference_lookup_pieces (gimple_vuse (stmt), 0,
3982e4b17023SJohn Marino 					    gimple_expr_type (stmt),
3983e4b17023SJohn Marino 					    ops, &ref, VN_NOWALK);
3984e4b17023SJohn Marino 		VEC_free (vn_reference_op_s, heap, ops);
3985e4b17023SJohn Marino 		if (!ref)
3986e4b17023SJohn Marino 		  continue;
3987e4b17023SJohn Marino 
3988e4b17023SJohn Marino 		for (i = 0; VEC_iterate (vn_reference_op_s,
3989e4b17023SJohn Marino 					 ref->operands, i,
3990e4b17023SJohn Marino 					 vro); i++)
3991e4b17023SJohn Marino 		  {
3992e4b17023SJohn Marino 		    if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
3993e4b17023SJohn Marino 		      add_to_exp_gen (block, vro->op0);
3994e4b17023SJohn Marino 		    if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
3995e4b17023SJohn Marino 		      add_to_exp_gen (block, vro->op1);
3996e4b17023SJohn Marino 		    if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
3997e4b17023SJohn Marino 		      add_to_exp_gen (block, vro->op2);
3998e4b17023SJohn Marino 		  }
3999e4b17023SJohn Marino 		result = (pre_expr) pool_alloc (pre_expr_pool);
4000e4b17023SJohn Marino 		result->kind = REFERENCE;
4001e4b17023SJohn Marino 		result->id = 0;
4002e4b17023SJohn Marino 		PRE_EXPR_REFERENCE (result) = ref;
4003e4b17023SJohn Marino 
4004e4b17023SJohn Marino 		get_or_alloc_expression_id (result);
4005e4b17023SJohn Marino 		add_to_value (get_expr_value_id (result), result);
4006e4b17023SJohn Marino 		if (!in_fre)
4007e4b17023SJohn Marino 		  bitmap_value_insert_into_set (EXP_GEN (block), result);
4008e4b17023SJohn Marino 		continue;
4009e4b17023SJohn Marino 	      }
4010e4b17023SJohn Marino 
4011e4b17023SJohn Marino 	    case GIMPLE_ASSIGN:
4012e4b17023SJohn Marino 	      {
4013e4b17023SJohn Marino 		pre_expr result = NULL;
4014e4b17023SJohn Marino 		switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
4015e4b17023SJohn Marino 		  {
4016e4b17023SJohn Marino 		  case tcc_unary:
4017e4b17023SJohn Marino 		  case tcc_binary:
4018e4b17023SJohn Marino 		  case tcc_comparison:
4019e4b17023SJohn Marino 		    {
4020e4b17023SJohn Marino 		      vn_nary_op_t nary;
4021e4b17023SJohn Marino 		      unsigned int i;
4022e4b17023SJohn Marino 
4023e4b17023SJohn Marino 		      vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1,
4024e4b17023SJohn Marino 						gimple_assign_rhs_code (stmt),
4025e4b17023SJohn Marino 						gimple_expr_type (stmt),
4026e4b17023SJohn Marino 						gimple_assign_rhs1_ptr (stmt),
4027e4b17023SJohn Marino 						&nary);
4028e4b17023SJohn Marino 
4029e4b17023SJohn Marino 		      if (!nary)
4030e4b17023SJohn Marino 			continue;
4031e4b17023SJohn Marino 
4032e4b17023SJohn Marino 		      for (i = 0; i < nary->length; i++)
4033e4b17023SJohn Marino 			if (TREE_CODE (nary->op[i]) == SSA_NAME)
4034e4b17023SJohn Marino 			  add_to_exp_gen (block, nary->op[i]);
4035e4b17023SJohn Marino 
4036e4b17023SJohn Marino 		      result = (pre_expr) pool_alloc (pre_expr_pool);
4037e4b17023SJohn Marino 		      result->kind = NARY;
4038e4b17023SJohn Marino 		      result->id = 0;
4039e4b17023SJohn Marino 		      PRE_EXPR_NARY (result) = nary;
4040e4b17023SJohn Marino 		      break;
4041e4b17023SJohn Marino 		    }
4042e4b17023SJohn Marino 
4043e4b17023SJohn Marino 		  case tcc_declaration:
4044e4b17023SJohn Marino 		  case tcc_reference:
4045e4b17023SJohn Marino 		    {
4046e4b17023SJohn Marino 		      vn_reference_t ref;
4047e4b17023SJohn Marino 		      unsigned int i;
4048e4b17023SJohn Marino 		      vn_reference_op_t vro;
4049e4b17023SJohn Marino 
4050e4b17023SJohn Marino 		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
4051e4b17023SJohn Marino 					   gimple_vuse (stmt),
4052e4b17023SJohn Marino 					   VN_WALK, &ref);
4053e4b17023SJohn Marino 		      if (!ref)
4054e4b17023SJohn Marino 			continue;
4055e4b17023SJohn Marino 
4056e4b17023SJohn Marino 		      for (i = 0; VEC_iterate (vn_reference_op_s,
4057e4b17023SJohn Marino 					       ref->operands, i,
4058e4b17023SJohn Marino 					       vro); i++)
4059e4b17023SJohn Marino 			{
4060e4b17023SJohn Marino 			  if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
4061e4b17023SJohn Marino 			    add_to_exp_gen (block, vro->op0);
4062e4b17023SJohn Marino 			  if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
4063e4b17023SJohn Marino 			    add_to_exp_gen (block, vro->op1);
4064e4b17023SJohn Marino 			  if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
4065e4b17023SJohn Marino 			    add_to_exp_gen (block, vro->op2);
4066e4b17023SJohn Marino 			}
4067e4b17023SJohn Marino 		      result = (pre_expr) pool_alloc (pre_expr_pool);
4068e4b17023SJohn Marino 		      result->kind = REFERENCE;
4069e4b17023SJohn Marino 		      result->id = 0;
4070e4b17023SJohn Marino 		      PRE_EXPR_REFERENCE (result) = ref;
4071e4b17023SJohn Marino 		      break;
4072e4b17023SJohn Marino 		    }
4073e4b17023SJohn Marino 
4074e4b17023SJohn Marino 		  default:
4075e4b17023SJohn Marino 		    /* For any other statement that we don't
4076e4b17023SJohn Marino 		       recognize, simply add all referenced
4077e4b17023SJohn Marino 		       SSA_NAMEs to EXP_GEN.  */
4078e4b17023SJohn Marino 		    FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
4079e4b17023SJohn Marino 		      add_to_exp_gen (block, op);
4080e4b17023SJohn Marino 		    continue;
4081e4b17023SJohn Marino 		  }
4082e4b17023SJohn Marino 
4083e4b17023SJohn Marino 		get_or_alloc_expression_id (result);
4084e4b17023SJohn Marino 		add_to_value (get_expr_value_id (result), result);
4085e4b17023SJohn Marino 		if (!in_fre)
4086e4b17023SJohn Marino 		  bitmap_value_insert_into_set (EXP_GEN (block), result);
4087e4b17023SJohn Marino 
4088e4b17023SJohn Marino 		continue;
4089e4b17023SJohn Marino 	      }
4090e4b17023SJohn Marino 	    default:
4091e4b17023SJohn Marino 	      break;
4092e4b17023SJohn Marino 	    }
4093e4b17023SJohn Marino 	}
4094e4b17023SJohn Marino 
4095e4b17023SJohn Marino       /* Put the dominator children of BLOCK on the worklist of blocks
4096e4b17023SJohn Marino 	 to compute available sets for.  */
4097e4b17023SJohn Marino       for (son = first_dom_son (CDI_DOMINATORS, block);
4098e4b17023SJohn Marino 	   son;
4099e4b17023SJohn Marino 	   son = next_dom_son (CDI_DOMINATORS, son))
4100e4b17023SJohn Marino 	worklist[sp++] = son;
4101e4b17023SJohn Marino     }
4102e4b17023SJohn Marino 
4103e4b17023SJohn Marino   free (worklist);
4104e4b17023SJohn Marino }
4105e4b17023SJohn Marino 
4106e4b17023SJohn Marino /* Insert the expression for SSA_VN that SCCVN thought would be simpler
4107e4b17023SJohn Marino    than the available expressions for it.  The insertion point is
4108e4b17023SJohn Marino    right before the first use in STMT.  Returns the SSA_NAME that should
4109e4b17023SJohn Marino    be used for replacement.  */
4110e4b17023SJohn Marino 
4111e4b17023SJohn Marino static tree
do_SCCVN_insertion(gimple stmt,tree ssa_vn)4112e4b17023SJohn Marino do_SCCVN_insertion (gimple stmt, tree ssa_vn)
4113e4b17023SJohn Marino {
4114e4b17023SJohn Marino   basic_block bb = gimple_bb (stmt);
4115e4b17023SJohn Marino   gimple_stmt_iterator gsi;
4116e4b17023SJohn Marino   gimple_seq stmts = NULL;
4117e4b17023SJohn Marino   tree expr;
4118e4b17023SJohn Marino   pre_expr e;
4119e4b17023SJohn Marino 
4120e4b17023SJohn Marino   /* First create a value expression from the expression we want
4121e4b17023SJohn Marino      to insert and associate it with the value handle for SSA_VN.  */
4122e4b17023SJohn Marino   e = get_or_alloc_expr_for (vn_get_expr_for (ssa_vn));
4123e4b17023SJohn Marino   if (e == NULL)
4124e4b17023SJohn Marino     return NULL_TREE;
4125e4b17023SJohn Marino 
4126e4b17023SJohn Marino   /* Then use create_expression_by_pieces to generate a valid
4127e4b17023SJohn Marino      expression to insert at this point of the IL stream.  */
4128e4b17023SJohn Marino   expr = create_expression_by_pieces (bb, e, &stmts, stmt, NULL);
4129e4b17023SJohn Marino   if (expr == NULL_TREE)
4130e4b17023SJohn Marino     return NULL_TREE;
4131e4b17023SJohn Marino   gsi = gsi_for_stmt (stmt);
4132e4b17023SJohn Marino   gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
4133e4b17023SJohn Marino 
4134e4b17023SJohn Marino   return expr;
4135e4b17023SJohn Marino }
4136e4b17023SJohn Marino 
4137e4b17023SJohn Marino /* Eliminate fully redundant computations.  */
4138e4b17023SJohn Marino 
4139e4b17023SJohn Marino static unsigned int
eliminate(void)4140e4b17023SJohn Marino eliminate (void)
4141e4b17023SJohn Marino {
4142e4b17023SJohn Marino   VEC (gimple, heap) *to_remove = NULL;
4143e4b17023SJohn Marino   VEC (gimple, heap) *to_update = NULL;
4144e4b17023SJohn Marino   basic_block b;
4145e4b17023SJohn Marino   unsigned int todo = 0;
4146e4b17023SJohn Marino   gimple_stmt_iterator gsi;
4147e4b17023SJohn Marino   gimple stmt;
4148e4b17023SJohn Marino   unsigned i;
4149e4b17023SJohn Marino 
4150e4b17023SJohn Marino   FOR_EACH_BB (b)
4151e4b17023SJohn Marino     {
4152e4b17023SJohn Marino       for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
4153e4b17023SJohn Marino 	{
4154e4b17023SJohn Marino 	  tree lhs = NULL_TREE;
4155e4b17023SJohn Marino 	  tree rhs = NULL_TREE;
4156e4b17023SJohn Marino 
4157e4b17023SJohn Marino 	  stmt = gsi_stmt (gsi);
4158e4b17023SJohn Marino 
4159e4b17023SJohn Marino 	  if (gimple_has_lhs (stmt))
4160e4b17023SJohn Marino 	    lhs = gimple_get_lhs (stmt);
4161e4b17023SJohn Marino 
4162e4b17023SJohn Marino 	  if (gimple_assign_single_p (stmt))
4163e4b17023SJohn Marino 	    rhs = gimple_assign_rhs1 (stmt);
4164e4b17023SJohn Marino 
4165e4b17023SJohn Marino 	  /* Lookup the RHS of the expression, see if we have an
4166e4b17023SJohn Marino 	     available computation for it.  If so, replace the RHS with
4167e4b17023SJohn Marino 	     the available computation.
4168e4b17023SJohn Marino 
4169e4b17023SJohn Marino 	     See PR43491.
4170e4b17023SJohn Marino 	     We don't replace global register variable when it is a the RHS of
4171e4b17023SJohn Marino 	     a single assign. We do replace local register variable since gcc
4172e4b17023SJohn Marino 	     does not guarantee local variable will be allocated in register.  */
4173e4b17023SJohn Marino 	  if (gimple_has_lhs (stmt)
4174e4b17023SJohn Marino 	      && TREE_CODE (lhs) == SSA_NAME
4175e4b17023SJohn Marino 	      && !gimple_assign_ssa_name_copy_p (stmt)
4176e4b17023SJohn Marino 	      && (!gimple_assign_single_p (stmt)
4177e4b17023SJohn Marino 		  || (!is_gimple_min_invariant (rhs)
4178e4b17023SJohn Marino                       && (gimple_assign_rhs_code (stmt) != VAR_DECL
4179e4b17023SJohn Marino                           || !is_global_var (rhs)
4180e4b17023SJohn Marino                           || !DECL_HARD_REGISTER (rhs))))
4181e4b17023SJohn Marino 	      && !gimple_has_volatile_ops  (stmt)
4182e4b17023SJohn Marino 	      && !has_zero_uses (lhs))
4183e4b17023SJohn Marino 	    {
4184e4b17023SJohn Marino 	      tree sprime = NULL;
4185e4b17023SJohn Marino 	      pre_expr lhsexpr = get_or_alloc_expr_for_name (lhs);
4186e4b17023SJohn Marino 	      pre_expr sprimeexpr;
4187e4b17023SJohn Marino 	      gimple orig_stmt = stmt;
4188e4b17023SJohn Marino 
4189e4b17023SJohn Marino 	      sprimeexpr = bitmap_find_leader (AVAIL_OUT (b),
4190e4b17023SJohn Marino 					       get_expr_value_id (lhsexpr),
4191e4b17023SJohn Marino 					       NULL);
4192e4b17023SJohn Marino 
4193e4b17023SJohn Marino 	      if (sprimeexpr)
4194e4b17023SJohn Marino 		{
4195e4b17023SJohn Marino 		  if (sprimeexpr->kind == CONSTANT)
4196e4b17023SJohn Marino 		    sprime = PRE_EXPR_CONSTANT (sprimeexpr);
4197e4b17023SJohn Marino 		  else if (sprimeexpr->kind == NAME)
4198e4b17023SJohn Marino 		    sprime = PRE_EXPR_NAME (sprimeexpr);
4199e4b17023SJohn Marino 		  else
4200e4b17023SJohn Marino 		    gcc_unreachable ();
4201e4b17023SJohn Marino 		}
4202e4b17023SJohn Marino 
4203e4b17023SJohn Marino 	      /* If there is no existing leader but SCCVN knows this
4204e4b17023SJohn Marino 		 value is constant, use that constant.  */
4205e4b17023SJohn Marino 	      if (!sprime && is_gimple_min_invariant (VN_INFO (lhs)->valnum))
4206e4b17023SJohn Marino 		{
4207e4b17023SJohn Marino 		  sprime = VN_INFO (lhs)->valnum;
4208e4b17023SJohn Marino 		  if (!useless_type_conversion_p (TREE_TYPE (lhs),
4209e4b17023SJohn Marino 						  TREE_TYPE (sprime)))
4210e4b17023SJohn Marino 		    sprime = fold_convert (TREE_TYPE (lhs), sprime);
4211e4b17023SJohn Marino 
4212e4b17023SJohn Marino 		  if (dump_file && (dump_flags & TDF_DETAILS))
4213e4b17023SJohn Marino 		    {
4214e4b17023SJohn Marino 		      fprintf (dump_file, "Replaced ");
4215e4b17023SJohn Marino 		      print_gimple_expr (dump_file, stmt, 0, 0);
4216e4b17023SJohn Marino 		      fprintf (dump_file, " with ");
4217e4b17023SJohn Marino 		      print_generic_expr (dump_file, sprime, 0);
4218e4b17023SJohn Marino 		      fprintf (dump_file, " in ");
4219e4b17023SJohn Marino 		      print_gimple_stmt (dump_file, stmt, 0, 0);
4220e4b17023SJohn Marino 		    }
4221e4b17023SJohn Marino 		  pre_stats.eliminations++;
4222e4b17023SJohn Marino 		  propagate_tree_value_into_stmt (&gsi, sprime);
4223e4b17023SJohn Marino 		  stmt = gsi_stmt (gsi);
4224e4b17023SJohn Marino 		  update_stmt (stmt);
4225e4b17023SJohn Marino 
4226e4b17023SJohn Marino 		  /* If we removed EH side-effects from the statement, clean
4227e4b17023SJohn Marino 		     its EH information.  */
4228e4b17023SJohn Marino 		  if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
4229e4b17023SJohn Marino 		    {
4230e4b17023SJohn Marino 		      bitmap_set_bit (need_eh_cleanup,
4231e4b17023SJohn Marino 				      gimple_bb (stmt)->index);
4232e4b17023SJohn Marino 		      if (dump_file && (dump_flags & TDF_DETAILS))
4233e4b17023SJohn Marino 			fprintf (dump_file, "  Removed EH side-effects.\n");
4234e4b17023SJohn Marino 		    }
4235e4b17023SJohn Marino 		  continue;
4236e4b17023SJohn Marino 		}
4237e4b17023SJohn Marino 
4238e4b17023SJohn Marino 	      /* If there is no existing usable leader but SCCVN thinks
4239e4b17023SJohn Marino 		 it has an expression it wants to use as replacement,
4240e4b17023SJohn Marino 		 insert that.  */
4241e4b17023SJohn Marino 	      if (!sprime || sprime == lhs)
4242e4b17023SJohn Marino 		{
4243e4b17023SJohn Marino 		  tree val = VN_INFO (lhs)->valnum;
4244e4b17023SJohn Marino 		  if (val != VN_TOP
4245e4b17023SJohn Marino 		      && TREE_CODE (val) == SSA_NAME
4246e4b17023SJohn Marino 		      && VN_INFO (val)->needs_insertion
4247e4b17023SJohn Marino 		      && can_PRE_operation (vn_get_expr_for (val)))
4248e4b17023SJohn Marino 		    sprime = do_SCCVN_insertion (stmt, val);
4249e4b17023SJohn Marino 		}
4250e4b17023SJohn Marino 	      if (sprime
4251e4b17023SJohn Marino 		  && sprime != lhs
4252e4b17023SJohn Marino 		  && (rhs == NULL_TREE
4253e4b17023SJohn Marino 		      || TREE_CODE (rhs) != SSA_NAME
4254e4b17023SJohn Marino 		      || may_propagate_copy (rhs, sprime)))
4255e4b17023SJohn Marino 		{
4256e4b17023SJohn Marino 		  bool can_make_abnormal_goto
4257e4b17023SJohn Marino 		    = is_gimple_call (stmt)
4258e4b17023SJohn Marino 		      && stmt_can_make_abnormal_goto (stmt);
4259e4b17023SJohn Marino 
4260e4b17023SJohn Marino 		  gcc_assert (sprime != rhs);
4261e4b17023SJohn Marino 
4262e4b17023SJohn Marino 		  if (dump_file && (dump_flags & TDF_DETAILS))
4263e4b17023SJohn Marino 		    {
4264e4b17023SJohn Marino 		      fprintf (dump_file, "Replaced ");
4265e4b17023SJohn Marino 		      print_gimple_expr (dump_file, stmt, 0, 0);
4266e4b17023SJohn Marino 		      fprintf (dump_file, " with ");
4267e4b17023SJohn Marino 		      print_generic_expr (dump_file, sprime, 0);
4268e4b17023SJohn Marino 		      fprintf (dump_file, " in ");
4269e4b17023SJohn Marino 		      print_gimple_stmt (dump_file, stmt, 0, 0);
4270e4b17023SJohn Marino 		    }
4271e4b17023SJohn Marino 
4272e4b17023SJohn Marino 		  if (TREE_CODE (sprime) == SSA_NAME)
4273e4b17023SJohn Marino 		    gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
4274e4b17023SJohn Marino 				    NECESSARY, true);
4275e4b17023SJohn Marino 		  /* We need to make sure the new and old types actually match,
4276e4b17023SJohn Marino 		     which may require adding a simple cast, which fold_convert
4277e4b17023SJohn Marino 		     will do for us.  */
4278e4b17023SJohn Marino 		  if ((!rhs || TREE_CODE (rhs) != SSA_NAME)
4279e4b17023SJohn Marino 		      && !useless_type_conversion_p (gimple_expr_type (stmt),
4280e4b17023SJohn Marino 						     TREE_TYPE (sprime)))
4281e4b17023SJohn Marino 		    sprime = fold_convert (gimple_expr_type (stmt), sprime);
4282e4b17023SJohn Marino 
4283e4b17023SJohn Marino 		  pre_stats.eliminations++;
4284e4b17023SJohn Marino 		  propagate_tree_value_into_stmt (&gsi, sprime);
4285e4b17023SJohn Marino 		  stmt = gsi_stmt (gsi);
4286e4b17023SJohn Marino 		  update_stmt (stmt);
4287e4b17023SJohn Marino 
4288e4b17023SJohn Marino 		  /* If we removed EH side-effects from the statement, clean
4289e4b17023SJohn Marino 		     its EH information.  */
4290e4b17023SJohn Marino 		  if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
4291e4b17023SJohn Marino 		    {
4292e4b17023SJohn Marino 		      bitmap_set_bit (need_eh_cleanup,
4293e4b17023SJohn Marino 				      gimple_bb (stmt)->index);
4294e4b17023SJohn Marino 		      if (dump_file && (dump_flags & TDF_DETAILS))
4295e4b17023SJohn Marino 			fprintf (dump_file, "  Removed EH side-effects.\n");
4296e4b17023SJohn Marino 		    }
4297e4b17023SJohn Marino 
4298e4b17023SJohn Marino 		  /* Likewise for AB side-effects.  */
4299e4b17023SJohn Marino 		  if (can_make_abnormal_goto
4300e4b17023SJohn Marino 		      && !stmt_can_make_abnormal_goto (stmt))
4301e4b17023SJohn Marino 		    {
4302e4b17023SJohn Marino 		      bitmap_set_bit (need_ab_cleanup,
4303e4b17023SJohn Marino 				      gimple_bb (stmt)->index);
4304e4b17023SJohn Marino 		      if (dump_file && (dump_flags & TDF_DETAILS))
4305e4b17023SJohn Marino 			fprintf (dump_file, "  Removed AB side-effects.\n");
4306e4b17023SJohn Marino 		    }
4307e4b17023SJohn Marino 		}
4308e4b17023SJohn Marino 	    }
4309e4b17023SJohn Marino 	  /* If the statement is a scalar store, see if the expression
4310e4b17023SJohn Marino 	     has the same value number as its rhs.  If so, the store is
4311e4b17023SJohn Marino 	     dead.  */
4312e4b17023SJohn Marino 	  else if (gimple_assign_single_p (stmt)
4313e4b17023SJohn Marino 		   && !gimple_has_volatile_ops (stmt)
4314e4b17023SJohn Marino 		   && !is_gimple_reg (gimple_assign_lhs (stmt))
4315e4b17023SJohn Marino 		   && (TREE_CODE (rhs) == SSA_NAME
4316e4b17023SJohn Marino 		       || is_gimple_min_invariant (rhs)))
4317e4b17023SJohn Marino 	    {
4318e4b17023SJohn Marino 	      tree val;
4319e4b17023SJohn Marino 	      val = vn_reference_lookup (gimple_assign_lhs (stmt),
4320e4b17023SJohn Marino 					 gimple_vuse (stmt), VN_WALK, NULL);
4321e4b17023SJohn Marino 	      if (TREE_CODE (rhs) == SSA_NAME)
4322e4b17023SJohn Marino 		rhs = VN_INFO (rhs)->valnum;
4323e4b17023SJohn Marino 	      if (val
4324e4b17023SJohn Marino 		  && operand_equal_p (val, rhs, 0))
4325e4b17023SJohn Marino 		{
4326e4b17023SJohn Marino 		  if (dump_file && (dump_flags & TDF_DETAILS))
4327e4b17023SJohn Marino 		    {
4328e4b17023SJohn Marino 		      fprintf (dump_file, "Deleted redundant store ");
4329e4b17023SJohn Marino 		      print_gimple_stmt (dump_file, stmt, 0, 0);
4330e4b17023SJohn Marino 		    }
4331e4b17023SJohn Marino 
4332e4b17023SJohn Marino 		  /* Queue stmt for removal.  */
4333e4b17023SJohn Marino 		  VEC_safe_push (gimple, heap, to_remove, stmt);
4334e4b17023SJohn Marino 		}
4335e4b17023SJohn Marino 	    }
4336e4b17023SJohn Marino 	  /* Visit COND_EXPRs and fold the comparison with the
4337e4b17023SJohn Marino 	     available value-numbers.  */
4338e4b17023SJohn Marino 	  else if (gimple_code (stmt) == GIMPLE_COND)
4339e4b17023SJohn Marino 	    {
4340e4b17023SJohn Marino 	      tree op0 = gimple_cond_lhs (stmt);
4341e4b17023SJohn Marino 	      tree op1 = gimple_cond_rhs (stmt);
4342e4b17023SJohn Marino 	      tree result;
4343e4b17023SJohn Marino 
4344e4b17023SJohn Marino 	      if (TREE_CODE (op0) == SSA_NAME)
4345e4b17023SJohn Marino 		op0 = VN_INFO (op0)->valnum;
4346e4b17023SJohn Marino 	      if (TREE_CODE (op1) == SSA_NAME)
4347e4b17023SJohn Marino 		op1 = VN_INFO (op1)->valnum;
4348e4b17023SJohn Marino 	      result = fold_binary (gimple_cond_code (stmt), boolean_type_node,
4349e4b17023SJohn Marino 				    op0, op1);
4350e4b17023SJohn Marino 	      if (result && TREE_CODE (result) == INTEGER_CST)
4351e4b17023SJohn Marino 		{
4352e4b17023SJohn Marino 		  if (integer_zerop (result))
4353e4b17023SJohn Marino 		    gimple_cond_make_false (stmt);
4354e4b17023SJohn Marino 		  else
4355e4b17023SJohn Marino 		    gimple_cond_make_true (stmt);
4356e4b17023SJohn Marino 		  update_stmt (stmt);
4357e4b17023SJohn Marino 		  todo = TODO_cleanup_cfg;
4358e4b17023SJohn Marino 		}
4359e4b17023SJohn Marino 	    }
4360e4b17023SJohn Marino 	  /* Visit indirect calls and turn them into direct calls if
4361e4b17023SJohn Marino 	     possible.  */
4362e4b17023SJohn Marino 	  if (is_gimple_call (stmt))
4363e4b17023SJohn Marino 	    {
4364e4b17023SJohn Marino 	      tree orig_fn = gimple_call_fn (stmt);
4365e4b17023SJohn Marino 	      tree fn;
4366e4b17023SJohn Marino 	      if (!orig_fn)
4367e4b17023SJohn Marino 		continue;
4368e4b17023SJohn Marino 	      if (TREE_CODE (orig_fn) == SSA_NAME)
4369e4b17023SJohn Marino 		fn = VN_INFO (orig_fn)->valnum;
4370e4b17023SJohn Marino 	      else if (TREE_CODE (orig_fn) == OBJ_TYPE_REF
4371e4b17023SJohn Marino 		       && TREE_CODE (OBJ_TYPE_REF_EXPR (orig_fn)) == SSA_NAME)
4372e4b17023SJohn Marino 		fn = VN_INFO (OBJ_TYPE_REF_EXPR (orig_fn))->valnum;
4373e4b17023SJohn Marino 	      else
4374e4b17023SJohn Marino 		continue;
4375e4b17023SJohn Marino 	      if (gimple_call_addr_fndecl (fn) != NULL_TREE
4376e4b17023SJohn Marino 		  && useless_type_conversion_p (TREE_TYPE (orig_fn),
4377e4b17023SJohn Marino 						TREE_TYPE (fn)))
4378e4b17023SJohn Marino 		{
4379e4b17023SJohn Marino 		  bool can_make_abnormal_goto
4380e4b17023SJohn Marino 		    = stmt_can_make_abnormal_goto (stmt);
4381e4b17023SJohn Marino 		  bool was_noreturn = gimple_call_noreturn_p (stmt);
4382e4b17023SJohn Marino 
4383e4b17023SJohn Marino 		  if (dump_file && (dump_flags & TDF_DETAILS))
4384e4b17023SJohn Marino 		    {
4385e4b17023SJohn Marino 		      fprintf (dump_file, "Replacing call target with ");
4386e4b17023SJohn Marino 		      print_generic_expr (dump_file, fn, 0);
4387e4b17023SJohn Marino 		      fprintf (dump_file, " in ");
4388e4b17023SJohn Marino 		      print_gimple_stmt (dump_file, stmt, 0, 0);
4389e4b17023SJohn Marino 		    }
4390e4b17023SJohn Marino 
4391e4b17023SJohn Marino 		  gimple_call_set_fn (stmt, fn);
4392e4b17023SJohn Marino 		  VEC_safe_push (gimple, heap, to_update, stmt);
4393e4b17023SJohn Marino 
4394e4b17023SJohn Marino 		  /* When changing a call into a noreturn call, cfg cleanup
4395e4b17023SJohn Marino 		     is needed to fix up the noreturn call.  */
4396e4b17023SJohn Marino 		  if (!was_noreturn && gimple_call_noreturn_p (stmt))
4397e4b17023SJohn Marino 		    todo |= TODO_cleanup_cfg;
4398e4b17023SJohn Marino 
4399e4b17023SJohn Marino 		  /* If we removed EH side-effects from the statement, clean
4400e4b17023SJohn Marino 		     its EH information.  */
4401e4b17023SJohn Marino 		  if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
4402e4b17023SJohn Marino 		    {
4403e4b17023SJohn Marino 		      bitmap_set_bit (need_eh_cleanup,
4404e4b17023SJohn Marino 				      gimple_bb (stmt)->index);
4405e4b17023SJohn Marino 		      if (dump_file && (dump_flags & TDF_DETAILS))
4406e4b17023SJohn Marino 			fprintf (dump_file, "  Removed EH side-effects.\n");
4407e4b17023SJohn Marino 		    }
4408e4b17023SJohn Marino 
4409e4b17023SJohn Marino 		  /* Likewise for AB side-effects.  */
4410e4b17023SJohn Marino 		  if (can_make_abnormal_goto
4411e4b17023SJohn Marino 		      && !stmt_can_make_abnormal_goto (stmt))
4412e4b17023SJohn Marino 		    {
4413e4b17023SJohn Marino 		      bitmap_set_bit (need_ab_cleanup,
4414e4b17023SJohn Marino 				      gimple_bb (stmt)->index);
4415e4b17023SJohn Marino 		      if (dump_file && (dump_flags & TDF_DETAILS))
4416e4b17023SJohn Marino 			fprintf (dump_file, "  Removed AB side-effects.\n");
4417e4b17023SJohn Marino 		    }
4418e4b17023SJohn Marino 
4419e4b17023SJohn Marino 		  /* Changing an indirect call to a direct call may
4420e4b17023SJohn Marino 		     have exposed different semantics.  This may
4421e4b17023SJohn Marino 		     require an SSA update.  */
4422e4b17023SJohn Marino 		  todo |= TODO_update_ssa_only_virtuals;
4423e4b17023SJohn Marino 		}
4424e4b17023SJohn Marino 	    }
4425e4b17023SJohn Marino 	}
4426e4b17023SJohn Marino 
4427e4b17023SJohn Marino       for (gsi = gsi_start_phis (b); !gsi_end_p (gsi);)
4428e4b17023SJohn Marino 	{
4429e4b17023SJohn Marino 	  gimple stmt, phi = gsi_stmt (gsi);
4430e4b17023SJohn Marino 	  tree sprime = NULL_TREE, res = PHI_RESULT (phi);
4431e4b17023SJohn Marino 	  pre_expr sprimeexpr, resexpr;
4432e4b17023SJohn Marino 	  gimple_stmt_iterator gsi2;
4433e4b17023SJohn Marino 
4434e4b17023SJohn Marino 	  /* We want to perform redundant PHI elimination.  Do so by
4435e4b17023SJohn Marino 	     replacing the PHI with a single copy if possible.
4436e4b17023SJohn Marino 	     Do not touch inserted, single-argument or virtual PHIs.  */
4437e4b17023SJohn Marino 	  if (gimple_phi_num_args (phi) == 1
4438e4b17023SJohn Marino 	      || !is_gimple_reg (res))
4439e4b17023SJohn Marino 	    {
4440e4b17023SJohn Marino 	      gsi_next (&gsi);
4441e4b17023SJohn Marino 	      continue;
4442e4b17023SJohn Marino 	    }
4443e4b17023SJohn Marino 
4444e4b17023SJohn Marino 	  resexpr = get_or_alloc_expr_for_name (res);
4445e4b17023SJohn Marino 	  sprimeexpr = bitmap_find_leader (AVAIL_OUT (b),
4446e4b17023SJohn Marino 					   get_expr_value_id (resexpr), NULL);
4447e4b17023SJohn Marino 	  if (sprimeexpr)
4448e4b17023SJohn Marino 	    {
4449e4b17023SJohn Marino 	      if (sprimeexpr->kind == CONSTANT)
4450e4b17023SJohn Marino 		sprime = PRE_EXPR_CONSTANT (sprimeexpr);
4451e4b17023SJohn Marino 	      else if (sprimeexpr->kind == NAME)
4452e4b17023SJohn Marino 		sprime = PRE_EXPR_NAME (sprimeexpr);
4453e4b17023SJohn Marino 	      else
4454e4b17023SJohn Marino 		gcc_unreachable ();
4455e4b17023SJohn Marino 	    }
4456e4b17023SJohn Marino 	  if (!sprime && is_gimple_min_invariant (VN_INFO (res)->valnum))
4457e4b17023SJohn Marino 	    {
4458e4b17023SJohn Marino 	      sprime = VN_INFO (res)->valnum;
4459e4b17023SJohn Marino 	      if (!useless_type_conversion_p (TREE_TYPE (res),
4460e4b17023SJohn Marino 					      TREE_TYPE (sprime)))
4461e4b17023SJohn Marino 		sprime = fold_convert (TREE_TYPE (res), sprime);
4462e4b17023SJohn Marino 	    }
4463e4b17023SJohn Marino 	  if (!sprime
4464e4b17023SJohn Marino 	      || sprime == res)
4465e4b17023SJohn Marino 	    {
4466e4b17023SJohn Marino 	      gsi_next (&gsi);
4467e4b17023SJohn Marino 	      continue;
4468e4b17023SJohn Marino 	    }
4469e4b17023SJohn Marino 
4470e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
4471e4b17023SJohn Marino 	    {
4472e4b17023SJohn Marino 	      fprintf (dump_file, "Replaced redundant PHI node defining ");
4473e4b17023SJohn Marino 	      print_generic_expr (dump_file, res, 0);
4474e4b17023SJohn Marino 	      fprintf (dump_file, " with ");
4475e4b17023SJohn Marino 	      print_generic_expr (dump_file, sprime, 0);
4476e4b17023SJohn Marino 	      fprintf (dump_file, "\n");
4477e4b17023SJohn Marino 	    }
4478e4b17023SJohn Marino 
4479e4b17023SJohn Marino 	  remove_phi_node (&gsi, false);
4480e4b17023SJohn Marino 
4481e4b17023SJohn Marino 	  if (!bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res))
4482e4b17023SJohn Marino 	      && TREE_CODE (sprime) == SSA_NAME)
4483e4b17023SJohn Marino 	    gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true);
4484e4b17023SJohn Marino 
4485e4b17023SJohn Marino 	  if (!useless_type_conversion_p (TREE_TYPE (res), TREE_TYPE (sprime)))
4486e4b17023SJohn Marino 	    sprime = fold_convert (TREE_TYPE (res), sprime);
4487e4b17023SJohn Marino 	  stmt = gimple_build_assign (res, sprime);
4488e4b17023SJohn Marino 	  SSA_NAME_DEF_STMT (res) = stmt;
4489e4b17023SJohn Marino 	  gimple_set_plf (stmt, NECESSARY, gimple_plf (phi, NECESSARY));
4490e4b17023SJohn Marino 
4491e4b17023SJohn Marino 	  gsi2 = gsi_after_labels (b);
4492e4b17023SJohn Marino 	  gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
4493e4b17023SJohn Marino 	  /* Queue the copy for eventual removal.  */
4494e4b17023SJohn Marino 	  VEC_safe_push (gimple, heap, to_remove, stmt);
4495e4b17023SJohn Marino 	  /* If we inserted this PHI node ourself, it's not an elimination.  */
4496e4b17023SJohn Marino 	  if (bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (res)))
4497e4b17023SJohn Marino 	    pre_stats.phis--;
4498e4b17023SJohn Marino 	  else
4499e4b17023SJohn Marino 	    pre_stats.eliminations++;
4500e4b17023SJohn Marino 	}
4501e4b17023SJohn Marino     }
4502e4b17023SJohn Marino 
4503e4b17023SJohn Marino   /* We cannot remove stmts during BB walk, especially not release SSA
4504e4b17023SJohn Marino      names there as this confuses the VN machinery.  The stmts ending
4505e4b17023SJohn Marino      up in to_remove are either stores or simple copies.  */
4506e4b17023SJohn Marino   FOR_EACH_VEC_ELT (gimple, to_remove, i, stmt)
4507e4b17023SJohn Marino     {
4508e4b17023SJohn Marino       tree lhs = gimple_assign_lhs (stmt);
4509e4b17023SJohn Marino       tree rhs = gimple_assign_rhs1 (stmt);
4510e4b17023SJohn Marino       use_operand_p use_p;
4511e4b17023SJohn Marino       gimple use_stmt;
4512e4b17023SJohn Marino 
4513e4b17023SJohn Marino       /* If there is a single use only, propagate the equivalency
4514e4b17023SJohn Marino 	 instead of keeping the copy.  */
4515e4b17023SJohn Marino       if (TREE_CODE (lhs) == SSA_NAME
4516e4b17023SJohn Marino 	  && TREE_CODE (rhs) == SSA_NAME
4517e4b17023SJohn Marino 	  && single_imm_use (lhs, &use_p, &use_stmt)
4518e4b17023SJohn Marino 	  && may_propagate_copy (USE_FROM_PTR (use_p), rhs))
4519e4b17023SJohn Marino 	{
4520e4b17023SJohn Marino 	  SET_USE (use_p, rhs);
4521e4b17023SJohn Marino 	  update_stmt (use_stmt);
4522e4b17023SJohn Marino 	  if (bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs))
4523e4b17023SJohn Marino 	      && TREE_CODE (rhs) == SSA_NAME)
4524e4b17023SJohn Marino 	    gimple_set_plf (SSA_NAME_DEF_STMT (rhs), NECESSARY, true);
4525e4b17023SJohn Marino 	}
4526e4b17023SJohn Marino 
4527e4b17023SJohn Marino       /* If this is a store or a now unused copy, remove it.  */
4528e4b17023SJohn Marino       if (TREE_CODE (lhs) != SSA_NAME
4529e4b17023SJohn Marino 	  || has_zero_uses (lhs))
4530e4b17023SJohn Marino 	{
4531e4b17023SJohn Marino 	  basic_block bb = gimple_bb (stmt);
4532e4b17023SJohn Marino 	  gsi = gsi_for_stmt (stmt);
4533e4b17023SJohn Marino 	  unlink_stmt_vdef (stmt);
4534e4b17023SJohn Marino 	  gsi_remove (&gsi, true);
4535e4b17023SJohn Marino 	  /* ???  gsi_remove doesn't tell us whether the stmt was
4536e4b17023SJohn Marino 	     in EH tables and thus whether we need to purge EH edges.
4537e4b17023SJohn Marino 	     Simply schedule the block for a cleanup.  */
4538e4b17023SJohn Marino 	  bitmap_set_bit (need_eh_cleanup, bb->index);
4539e4b17023SJohn Marino 	  if (TREE_CODE (lhs) == SSA_NAME)
4540e4b17023SJohn Marino 	    bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
4541e4b17023SJohn Marino 	  release_defs (stmt);
4542e4b17023SJohn Marino 	}
4543e4b17023SJohn Marino     }
4544e4b17023SJohn Marino   VEC_free (gimple, heap, to_remove);
4545e4b17023SJohn Marino 
4546e4b17023SJohn Marino   /* We cannot update call statements with virtual operands during
4547e4b17023SJohn Marino      SSA walk.  This might remove them which in turn makes our
4548e4b17023SJohn Marino      VN lattice invalid.  */
4549e4b17023SJohn Marino   FOR_EACH_VEC_ELT (gimple, to_update, i, stmt)
4550e4b17023SJohn Marino     update_stmt (stmt);
4551e4b17023SJohn Marino   VEC_free (gimple, heap, to_update);
4552e4b17023SJohn Marino 
4553e4b17023SJohn Marino   return todo;
4554e4b17023SJohn Marino }
4555e4b17023SJohn Marino 
4556e4b17023SJohn Marino /* Borrow a bit of tree-ssa-dce.c for the moment.
4557e4b17023SJohn Marino    XXX: In 4.1, we should be able to just run a DCE pass after PRE, though
4558e4b17023SJohn Marino    this may be a bit faster, and we may want critical edges kept split.  */
4559e4b17023SJohn Marino 
4560e4b17023SJohn Marino /* If OP's defining statement has not already been determined to be necessary,
4561e4b17023SJohn Marino    mark that statement necessary. Return the stmt, if it is newly
4562e4b17023SJohn Marino    necessary.  */
4563e4b17023SJohn Marino 
4564e4b17023SJohn Marino static inline gimple
mark_operand_necessary(tree op)4565e4b17023SJohn Marino mark_operand_necessary (tree op)
4566e4b17023SJohn Marino {
4567e4b17023SJohn Marino   gimple stmt;
4568e4b17023SJohn Marino 
4569e4b17023SJohn Marino   gcc_assert (op);
4570e4b17023SJohn Marino 
4571e4b17023SJohn Marino   if (TREE_CODE (op) != SSA_NAME)
4572e4b17023SJohn Marino     return NULL;
4573e4b17023SJohn Marino 
4574e4b17023SJohn Marino   stmt = SSA_NAME_DEF_STMT (op);
4575e4b17023SJohn Marino   gcc_assert (stmt);
4576e4b17023SJohn Marino 
4577e4b17023SJohn Marino   if (gimple_plf (stmt, NECESSARY)
4578e4b17023SJohn Marino       || gimple_nop_p (stmt))
4579e4b17023SJohn Marino     return NULL;
4580e4b17023SJohn Marino 
4581e4b17023SJohn Marino   gimple_set_plf (stmt, NECESSARY, true);
4582e4b17023SJohn Marino   return stmt;
4583e4b17023SJohn Marino }
4584e4b17023SJohn Marino 
4585e4b17023SJohn Marino /* Because we don't follow exactly the standard PRE algorithm, and decide not
4586e4b17023SJohn Marino    to insert PHI nodes sometimes, and because value numbering of casts isn't
4587e4b17023SJohn Marino    perfect, we sometimes end up inserting dead code.   This simple DCE-like
4588e4b17023SJohn Marino    pass removes any insertions we made that weren't actually used.  */
4589e4b17023SJohn Marino 
4590e4b17023SJohn Marino static void
remove_dead_inserted_code(void)4591e4b17023SJohn Marino remove_dead_inserted_code (void)
4592e4b17023SJohn Marino {
4593e4b17023SJohn Marino   bitmap worklist;
4594e4b17023SJohn Marino   unsigned i;
4595e4b17023SJohn Marino   bitmap_iterator bi;
4596e4b17023SJohn Marino   gimple t;
4597e4b17023SJohn Marino 
4598e4b17023SJohn Marino   worklist = BITMAP_ALLOC (NULL);
4599e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
4600e4b17023SJohn Marino     {
4601e4b17023SJohn Marino       t = SSA_NAME_DEF_STMT (ssa_name (i));
4602e4b17023SJohn Marino       if (gimple_plf (t, NECESSARY))
4603e4b17023SJohn Marino 	bitmap_set_bit (worklist, i);
4604e4b17023SJohn Marino     }
4605e4b17023SJohn Marino   while (!bitmap_empty_p (worklist))
4606e4b17023SJohn Marino     {
4607e4b17023SJohn Marino       i = bitmap_first_set_bit (worklist);
4608e4b17023SJohn Marino       bitmap_clear_bit (worklist, i);
4609e4b17023SJohn Marino       t = SSA_NAME_DEF_STMT (ssa_name (i));
4610e4b17023SJohn Marino 
4611e4b17023SJohn Marino       /* PHI nodes are somewhat special in that each PHI alternative has
4612e4b17023SJohn Marino 	 data and control dependencies.  All the statements feeding the
4613e4b17023SJohn Marino 	 PHI node's arguments are always necessary. */
4614e4b17023SJohn Marino       if (gimple_code (t) == GIMPLE_PHI)
4615e4b17023SJohn Marino 	{
4616e4b17023SJohn Marino 	  unsigned k;
4617e4b17023SJohn Marino 
4618e4b17023SJohn Marino 	  for (k = 0; k < gimple_phi_num_args (t); k++)
4619e4b17023SJohn Marino 	    {
4620e4b17023SJohn Marino 	      tree arg = PHI_ARG_DEF (t, k);
4621e4b17023SJohn Marino 	      if (TREE_CODE (arg) == SSA_NAME)
4622e4b17023SJohn Marino 		{
4623e4b17023SJohn Marino 		  gimple n = mark_operand_necessary (arg);
4624e4b17023SJohn Marino 		  if (n)
4625e4b17023SJohn Marino 		    bitmap_set_bit (worklist, SSA_NAME_VERSION (arg));
4626e4b17023SJohn Marino 		}
4627e4b17023SJohn Marino 	    }
4628e4b17023SJohn Marino 	}
4629e4b17023SJohn Marino       else
4630e4b17023SJohn Marino 	{
4631e4b17023SJohn Marino 	  /* Propagate through the operands.  Examine all the USE, VUSE and
4632e4b17023SJohn Marino 	     VDEF operands in this statement.  Mark all the statements
4633e4b17023SJohn Marino 	     which feed this statement's uses as necessary.  */
4634e4b17023SJohn Marino 	  ssa_op_iter iter;
4635e4b17023SJohn Marino 	  tree use;
4636e4b17023SJohn Marino 
4637e4b17023SJohn Marino 	  /* The operands of VDEF expressions are also needed as they
4638e4b17023SJohn Marino 	     represent potential definitions that may reach this
4639e4b17023SJohn Marino 	     statement (VDEF operands allow us to follow def-def
4640e4b17023SJohn Marino 	     links).  */
4641e4b17023SJohn Marino 
4642e4b17023SJohn Marino 	  FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES)
4643e4b17023SJohn Marino 	    {
4644e4b17023SJohn Marino 	      gimple n = mark_operand_necessary (use);
4645e4b17023SJohn Marino 	      if (n)
4646e4b17023SJohn Marino 		bitmap_set_bit (worklist, SSA_NAME_VERSION (use));
4647e4b17023SJohn Marino 	    }
4648e4b17023SJohn Marino 	}
4649e4b17023SJohn Marino     }
4650e4b17023SJohn Marino 
4651e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (inserted_exprs, 0, i, bi)
4652e4b17023SJohn Marino     {
4653e4b17023SJohn Marino       t = SSA_NAME_DEF_STMT (ssa_name (i));
4654e4b17023SJohn Marino       if (!gimple_plf (t, NECESSARY))
4655e4b17023SJohn Marino 	{
4656e4b17023SJohn Marino 	  gimple_stmt_iterator gsi;
4657e4b17023SJohn Marino 
4658e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
4659e4b17023SJohn Marino 	    {
4660e4b17023SJohn Marino 	      fprintf (dump_file, "Removing unnecessary insertion:");
4661e4b17023SJohn Marino 	      print_gimple_stmt (dump_file, t, 0, 0);
4662e4b17023SJohn Marino 	    }
4663e4b17023SJohn Marino 
4664e4b17023SJohn Marino 	  gsi = gsi_for_stmt (t);
4665e4b17023SJohn Marino 	  if (gimple_code (t) == GIMPLE_PHI)
4666e4b17023SJohn Marino 	    remove_phi_node (&gsi, true);
4667e4b17023SJohn Marino 	  else
4668e4b17023SJohn Marino 	    {
4669e4b17023SJohn Marino 	      gsi_remove (&gsi, true);
4670e4b17023SJohn Marino 	      release_defs (t);
4671e4b17023SJohn Marino 	    }
4672e4b17023SJohn Marino 	}
4673e4b17023SJohn Marino     }
4674e4b17023SJohn Marino   BITMAP_FREE (worklist);
4675e4b17023SJohn Marino }
4676e4b17023SJohn Marino 
4677e4b17023SJohn Marino /* Compute a reverse post-order in *POST_ORDER.  If INCLUDE_ENTRY_EXIT is
4678e4b17023SJohn Marino    true, then then ENTRY_BLOCK and EXIT_BLOCK are included.  Returns
4679e4b17023SJohn Marino    the number of visited blocks.  */
4680e4b17023SJohn Marino 
4681e4b17023SJohn Marino static int
my_rev_post_order_compute(int * post_order,bool include_entry_exit)4682e4b17023SJohn Marino my_rev_post_order_compute (int *post_order, bool include_entry_exit)
4683e4b17023SJohn Marino {
4684e4b17023SJohn Marino   edge_iterator *stack;
4685e4b17023SJohn Marino   int sp;
4686e4b17023SJohn Marino   int post_order_num = 0;
4687e4b17023SJohn Marino   sbitmap visited;
4688e4b17023SJohn Marino 
4689e4b17023SJohn Marino   if (include_entry_exit)
4690e4b17023SJohn Marino     post_order[post_order_num++] = EXIT_BLOCK;
4691e4b17023SJohn Marino 
4692e4b17023SJohn Marino   /* Allocate stack for back-tracking up CFG.  */
4693e4b17023SJohn Marino   stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
4694e4b17023SJohn Marino   sp = 0;
4695e4b17023SJohn Marino 
4696e4b17023SJohn Marino   /* Allocate bitmap to track nodes that have been visited.  */
4697e4b17023SJohn Marino   visited = sbitmap_alloc (last_basic_block);
4698e4b17023SJohn Marino 
4699e4b17023SJohn Marino   /* None of the nodes in the CFG have been visited yet.  */
4700e4b17023SJohn Marino   sbitmap_zero (visited);
4701e4b17023SJohn Marino 
4702e4b17023SJohn Marino   /* Push the last edge on to the stack.  */
4703e4b17023SJohn Marino   stack[sp++] = ei_start (EXIT_BLOCK_PTR->preds);
4704e4b17023SJohn Marino 
4705e4b17023SJohn Marino   while (sp)
4706e4b17023SJohn Marino     {
4707e4b17023SJohn Marino       edge_iterator ei;
4708e4b17023SJohn Marino       basic_block src;
4709e4b17023SJohn Marino       basic_block dest;
4710e4b17023SJohn Marino 
4711e4b17023SJohn Marino       /* Look at the edge on the top of the stack.  */
4712e4b17023SJohn Marino       ei = stack[sp - 1];
4713e4b17023SJohn Marino       src = ei_edge (ei)->src;
4714e4b17023SJohn Marino       dest = ei_edge (ei)->dest;
4715e4b17023SJohn Marino 
4716e4b17023SJohn Marino       /* Check if the edge destination has been visited yet.  */
4717e4b17023SJohn Marino       if (src != ENTRY_BLOCK_PTR && ! TEST_BIT (visited, src->index))
4718e4b17023SJohn Marino         {
4719e4b17023SJohn Marino           /* Mark that we have visited the destination.  */
4720e4b17023SJohn Marino           SET_BIT (visited, src->index);
4721e4b17023SJohn Marino 
4722e4b17023SJohn Marino           if (EDGE_COUNT (src->preds) > 0)
4723e4b17023SJohn Marino             /* Since the DEST node has been visited for the first
4724e4b17023SJohn Marino                time, check its successors.  */
4725e4b17023SJohn Marino             stack[sp++] = ei_start (src->preds);
4726e4b17023SJohn Marino           else
4727e4b17023SJohn Marino             post_order[post_order_num++] = src->index;
4728e4b17023SJohn Marino         }
4729e4b17023SJohn Marino       else
4730e4b17023SJohn Marino         {
4731e4b17023SJohn Marino           if (ei_one_before_end_p (ei) && dest != EXIT_BLOCK_PTR)
4732e4b17023SJohn Marino             post_order[post_order_num++] = dest->index;
4733e4b17023SJohn Marino 
4734e4b17023SJohn Marino           if (!ei_one_before_end_p (ei))
4735e4b17023SJohn Marino             ei_next (&stack[sp - 1]);
4736e4b17023SJohn Marino           else
4737e4b17023SJohn Marino             sp--;
4738e4b17023SJohn Marino         }
4739e4b17023SJohn Marino     }
4740e4b17023SJohn Marino 
4741e4b17023SJohn Marino   if (include_entry_exit)
4742e4b17023SJohn Marino     post_order[post_order_num++] = ENTRY_BLOCK;
4743e4b17023SJohn Marino 
4744e4b17023SJohn Marino   free (stack);
4745e4b17023SJohn Marino   sbitmap_free (visited);
4746e4b17023SJohn Marino   return post_order_num;
4747e4b17023SJohn Marino }
4748e4b17023SJohn Marino 
4749e4b17023SJohn Marino 
4750e4b17023SJohn Marino /* Initialize data structures used by PRE.  */
4751e4b17023SJohn Marino 
4752e4b17023SJohn Marino static void
init_pre(bool do_fre)4753e4b17023SJohn Marino init_pre (bool do_fre)
4754e4b17023SJohn Marino {
4755e4b17023SJohn Marino   basic_block bb;
4756e4b17023SJohn Marino 
4757e4b17023SJohn Marino   next_expression_id = 1;
4758e4b17023SJohn Marino   expressions = NULL;
4759e4b17023SJohn Marino   VEC_safe_push (pre_expr, heap, expressions, NULL);
4760e4b17023SJohn Marino   value_expressions = VEC_alloc (bitmap_set_t, heap, get_max_value_id () + 1);
4761e4b17023SJohn Marino   VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
4762e4b17023SJohn Marino 			 get_max_value_id() + 1);
4763e4b17023SJohn Marino   name_to_id = NULL;
4764e4b17023SJohn Marino 
4765e4b17023SJohn Marino   in_fre = do_fre;
4766e4b17023SJohn Marino 
4767e4b17023SJohn Marino   inserted_exprs = BITMAP_ALLOC (NULL);
4768e4b17023SJohn Marino   need_creation = NULL;
4769e4b17023SJohn Marino   pretemp = NULL_TREE;
4770e4b17023SJohn Marino   storetemp = NULL_TREE;
4771e4b17023SJohn Marino   prephitemp = NULL_TREE;
4772e4b17023SJohn Marino 
4773e4b17023SJohn Marino   connect_infinite_loops_to_exit ();
4774e4b17023SJohn Marino   memset (&pre_stats, 0, sizeof (pre_stats));
4775e4b17023SJohn Marino 
4776e4b17023SJohn Marino 
4777e4b17023SJohn Marino   postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
4778e4b17023SJohn Marino   my_rev_post_order_compute (postorder, false);
4779e4b17023SJohn Marino 
4780e4b17023SJohn Marino   alloc_aux_for_blocks (sizeof (struct bb_bitmap_sets));
4781e4b17023SJohn Marino 
4782e4b17023SJohn Marino   calculate_dominance_info (CDI_POST_DOMINATORS);
4783e4b17023SJohn Marino   calculate_dominance_info (CDI_DOMINATORS);
4784e4b17023SJohn Marino 
4785e4b17023SJohn Marino   bitmap_obstack_initialize (&grand_bitmap_obstack);
4786e4b17023SJohn Marino   phi_translate_table = htab_create (5110, expr_pred_trans_hash,
4787e4b17023SJohn Marino 				     expr_pred_trans_eq, free);
4788e4b17023SJohn Marino   expression_to_id = htab_create (num_ssa_names * 3,
4789e4b17023SJohn Marino 				  pre_expr_hash,
4790e4b17023SJohn Marino 				  pre_expr_eq, NULL);
4791e4b17023SJohn Marino   bitmap_set_pool = create_alloc_pool ("Bitmap sets",
4792e4b17023SJohn Marino 				       sizeof (struct bitmap_set), 30);
4793e4b17023SJohn Marino   pre_expr_pool = create_alloc_pool ("pre_expr nodes",
4794e4b17023SJohn Marino 				     sizeof (struct pre_expr_d), 30);
4795e4b17023SJohn Marino   FOR_ALL_BB (bb)
4796e4b17023SJohn Marino     {
4797e4b17023SJohn Marino       EXP_GEN (bb) = bitmap_set_new ();
4798e4b17023SJohn Marino       PHI_GEN (bb) = bitmap_set_new ();
4799e4b17023SJohn Marino       TMP_GEN (bb) = bitmap_set_new ();
4800e4b17023SJohn Marino       AVAIL_OUT (bb) = bitmap_set_new ();
4801e4b17023SJohn Marino     }
4802e4b17023SJohn Marino 
4803e4b17023SJohn Marino   need_eh_cleanup = BITMAP_ALLOC (NULL);
4804e4b17023SJohn Marino   need_ab_cleanup = BITMAP_ALLOC (NULL);
4805e4b17023SJohn Marino }
4806e4b17023SJohn Marino 
4807e4b17023SJohn Marino 
4808e4b17023SJohn Marino /* Deallocate data structures used by PRE.  */
4809e4b17023SJohn Marino 
48105ce9237cSJohn Marino static unsigned
fini_pre(bool do_fre)4811e4b17023SJohn Marino fini_pre (bool do_fre)
4812e4b17023SJohn Marino {
4813e4b17023SJohn Marino   bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup);
4814e4b17023SJohn Marino   bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup);
48155ce9237cSJohn Marino   unsigned todo = 0;
4816e4b17023SJohn Marino 
4817e4b17023SJohn Marino   free (postorder);
4818e4b17023SJohn Marino   VEC_free (bitmap_set_t, heap, value_expressions);
4819e4b17023SJohn Marino   BITMAP_FREE (inserted_exprs);
4820e4b17023SJohn Marino   VEC_free (gimple, heap, need_creation);
4821e4b17023SJohn Marino   bitmap_obstack_release (&grand_bitmap_obstack);
4822e4b17023SJohn Marino   free_alloc_pool (bitmap_set_pool);
4823e4b17023SJohn Marino   free_alloc_pool (pre_expr_pool);
4824e4b17023SJohn Marino   htab_delete (phi_translate_table);
4825e4b17023SJohn Marino   htab_delete (expression_to_id);
4826e4b17023SJohn Marino   VEC_free (unsigned, heap, name_to_id);
4827e4b17023SJohn Marino 
4828e4b17023SJohn Marino   free_aux_for_blocks ();
4829e4b17023SJohn Marino 
4830e4b17023SJohn Marino   free_dominance_info (CDI_POST_DOMINATORS);
4831e4b17023SJohn Marino 
4832e4b17023SJohn Marino   if (do_eh_cleanup)
4833e4b17023SJohn Marino     gimple_purge_all_dead_eh_edges (need_eh_cleanup);
4834e4b17023SJohn Marino 
4835e4b17023SJohn Marino   if (do_ab_cleanup)
4836e4b17023SJohn Marino     gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
4837e4b17023SJohn Marino 
4838e4b17023SJohn Marino   BITMAP_FREE (need_eh_cleanup);
4839e4b17023SJohn Marino   BITMAP_FREE (need_ab_cleanup);
4840e4b17023SJohn Marino 
4841e4b17023SJohn Marino   if (do_eh_cleanup || do_ab_cleanup)
48425ce9237cSJohn Marino     todo = TODO_cleanup_cfg;
4843e4b17023SJohn Marino 
4844e4b17023SJohn Marino   if (!do_fre)
4845e4b17023SJohn Marino     loop_optimizer_finalize ();
48465ce9237cSJohn Marino 
48475ce9237cSJohn Marino   return todo;
4848e4b17023SJohn Marino }
4849e4b17023SJohn Marino 
4850e4b17023SJohn Marino /* Main entry point to the SSA-PRE pass.  DO_FRE is true if the caller
4851e4b17023SJohn Marino    only wants to do full redundancy elimination.  */
4852e4b17023SJohn Marino 
4853e4b17023SJohn Marino static unsigned int
execute_pre(bool do_fre)4854e4b17023SJohn Marino execute_pre (bool do_fre)
4855e4b17023SJohn Marino {
4856e4b17023SJohn Marino   unsigned int todo = 0;
4857e4b17023SJohn Marino 
4858e4b17023SJohn Marino   do_partial_partial = optimize > 2 && optimize_function_for_speed_p (cfun);
4859e4b17023SJohn Marino 
4860e4b17023SJohn Marino   /* This has to happen before SCCVN runs because
4861e4b17023SJohn Marino      loop_optimizer_init may create new phis, etc.  */
4862e4b17023SJohn Marino   if (!do_fre)
4863e4b17023SJohn Marino     loop_optimizer_init (LOOPS_NORMAL);
4864e4b17023SJohn Marino 
4865e4b17023SJohn Marino   if (!run_scc_vn (do_fre ? VN_WALKREWRITE : VN_WALK))
4866e4b17023SJohn Marino     {
4867e4b17023SJohn Marino       if (!do_fre)
4868e4b17023SJohn Marino 	loop_optimizer_finalize ();
4869e4b17023SJohn Marino 
4870e4b17023SJohn Marino       return 0;
4871e4b17023SJohn Marino     }
4872e4b17023SJohn Marino 
4873e4b17023SJohn Marino   init_pre (do_fre);
4874e4b17023SJohn Marino   scev_initialize ();
4875e4b17023SJohn Marino 
4876e4b17023SJohn Marino   /* Collect and value number expressions computed in each basic block.  */
4877e4b17023SJohn Marino   compute_avail ();
4878e4b17023SJohn Marino 
4879e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
4880e4b17023SJohn Marino     {
4881e4b17023SJohn Marino       basic_block bb;
4882e4b17023SJohn Marino 
4883e4b17023SJohn Marino       FOR_ALL_BB (bb)
4884e4b17023SJohn Marino 	{
4885e4b17023SJohn Marino 	  print_bitmap_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
4886e4b17023SJohn Marino 	  print_bitmap_set (dump_file, PHI_GEN (bb), "phi_gen", bb->index);
4887e4b17023SJohn Marino 	  print_bitmap_set (dump_file, TMP_GEN (bb), "tmp_gen", bb->index);
4888e4b17023SJohn Marino 	  print_bitmap_set (dump_file, AVAIL_OUT (bb), "avail_out", bb->index);
4889e4b17023SJohn Marino 	}
4890e4b17023SJohn Marino     }
4891e4b17023SJohn Marino 
4892e4b17023SJohn Marino   /* Insert can get quite slow on an incredibly large number of basic
4893e4b17023SJohn Marino      blocks due to some quadratic behavior.  Until this behavior is
4894e4b17023SJohn Marino      fixed, don't run it when he have an incredibly large number of
4895e4b17023SJohn Marino      bb's.  If we aren't going to run insert, there is no point in
4896e4b17023SJohn Marino      computing ANTIC, either, even though it's plenty fast.  */
4897e4b17023SJohn Marino   if (!do_fre && n_basic_blocks < 4000)
4898e4b17023SJohn Marino     {
4899e4b17023SJohn Marino       compute_antic ();
4900e4b17023SJohn Marino       insert ();
4901e4b17023SJohn Marino     }
4902e4b17023SJohn Marino 
4903e4b17023SJohn Marino   /* Make sure to remove fake edges before committing our inserts.
4904e4b17023SJohn Marino      This makes sure we don't end up with extra critical edges that
4905e4b17023SJohn Marino      we would need to split.  */
4906e4b17023SJohn Marino   remove_fake_exit_edges ();
4907e4b17023SJohn Marino   gsi_commit_edge_inserts ();
4908e4b17023SJohn Marino 
4909e4b17023SJohn Marino   /* Remove all the redundant expressions.  */
4910e4b17023SJohn Marino   todo |= eliminate ();
4911e4b17023SJohn Marino 
4912e4b17023SJohn Marino   statistics_counter_event (cfun, "Insertions", pre_stats.insertions);
4913e4b17023SJohn Marino   statistics_counter_event (cfun, "PA inserted", pre_stats.pa_insert);
4914e4b17023SJohn Marino   statistics_counter_event (cfun, "New PHIs", pre_stats.phis);
4915e4b17023SJohn Marino   statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
4916e4b17023SJohn Marino 
4917e4b17023SJohn Marino   clear_expression_ids ();
4918e4b17023SJohn Marino   if (!do_fre)
4919e4b17023SJohn Marino     {
4920e4b17023SJohn Marino       remove_dead_inserted_code ();
4921e4b17023SJohn Marino       todo |= TODO_verify_flow;
4922e4b17023SJohn Marino     }
4923e4b17023SJohn Marino 
4924e4b17023SJohn Marino   scev_finalize ();
49255ce9237cSJohn Marino   todo |= fini_pre (do_fre);
4926e4b17023SJohn Marino 
4927e4b17023SJohn Marino   if (!do_fre)
4928e4b17023SJohn Marino     /* TODO: tail_merge_optimize may merge all predecessors of a block, in which
4929e4b17023SJohn Marino        case we can merge the block with the remaining predecessor of the block.
4930e4b17023SJohn Marino        It should either:
4931e4b17023SJohn Marino        - call merge_blocks after each tail merge iteration
4932e4b17023SJohn Marino        - call merge_blocks after all tail merge iterations
4933e4b17023SJohn Marino        - mark TODO_cleanup_cfg when necessary
4934e4b17023SJohn Marino        - share the cfg cleanup with fini_pre.  */
4935e4b17023SJohn Marino     todo |= tail_merge_optimize (todo);
4936e4b17023SJohn Marino   free_scc_vn ();
4937e4b17023SJohn Marino 
49385ce9237cSJohn Marino   /* Tail merging invalidates the virtual SSA web, together with
49395ce9237cSJohn Marino      cfg-cleanup opportunities exposed by PRE this will wreck the
49405ce9237cSJohn Marino      SSA updating machinery.  So make sure to run update-ssa
49415ce9237cSJohn Marino      manually, before eventually scheduling cfg-cleanup as part of
49425ce9237cSJohn Marino      the todo.  */
49435ce9237cSJohn Marino   update_ssa (TODO_update_ssa_only_virtuals);
49445ce9237cSJohn Marino 
4945e4b17023SJohn Marino   return todo;
4946e4b17023SJohn Marino }
4947e4b17023SJohn Marino 
4948e4b17023SJohn Marino /* Gate and execute functions for PRE.  */
4949e4b17023SJohn Marino 
4950e4b17023SJohn Marino static unsigned int
do_pre(void)4951e4b17023SJohn Marino do_pre (void)
4952e4b17023SJohn Marino {
4953e4b17023SJohn Marino   return execute_pre (false);
4954e4b17023SJohn Marino }
4955e4b17023SJohn Marino 
4956e4b17023SJohn Marino static bool
gate_pre(void)4957e4b17023SJohn Marino gate_pre (void)
4958e4b17023SJohn Marino {
4959e4b17023SJohn Marino   return flag_tree_pre != 0;
4960e4b17023SJohn Marino }
4961e4b17023SJohn Marino 
4962e4b17023SJohn Marino struct gimple_opt_pass pass_pre =
4963e4b17023SJohn Marino {
4964e4b17023SJohn Marino  {
4965e4b17023SJohn Marino   GIMPLE_PASS,
4966e4b17023SJohn Marino   "pre",				/* name */
4967e4b17023SJohn Marino   gate_pre,				/* gate */
4968e4b17023SJohn Marino   do_pre,				/* execute */
4969e4b17023SJohn Marino   NULL,					/* sub */
4970e4b17023SJohn Marino   NULL,					/* next */
4971e4b17023SJohn Marino   0,					/* static_pass_number */
4972e4b17023SJohn Marino   TV_TREE_PRE,				/* tv_id */
4973e4b17023SJohn Marino   PROP_no_crit_edges | PROP_cfg
4974e4b17023SJohn Marino     | PROP_ssa,				/* properties_required */
4975e4b17023SJohn Marino   0,					/* properties_provided */
4976e4b17023SJohn Marino   0,					/* properties_destroyed */
4977e4b17023SJohn Marino   TODO_rebuild_alias,			/* todo_flags_start */
49785ce9237cSJohn Marino   TODO_ggc_collect | TODO_verify_ssa	/* todo_flags_finish */
4979e4b17023SJohn Marino  }
4980e4b17023SJohn Marino };
4981e4b17023SJohn Marino 
4982e4b17023SJohn Marino 
4983e4b17023SJohn Marino /* Gate and execute functions for FRE.  */
4984e4b17023SJohn Marino 
4985e4b17023SJohn Marino static unsigned int
execute_fre(void)4986e4b17023SJohn Marino execute_fre (void)
4987e4b17023SJohn Marino {
4988e4b17023SJohn Marino   return execute_pre (true);
4989e4b17023SJohn Marino }
4990e4b17023SJohn Marino 
4991e4b17023SJohn Marino static bool
gate_fre(void)4992e4b17023SJohn Marino gate_fre (void)
4993e4b17023SJohn Marino {
4994e4b17023SJohn Marino   return flag_tree_fre != 0;
4995e4b17023SJohn Marino }
4996e4b17023SJohn Marino 
4997e4b17023SJohn Marino struct gimple_opt_pass pass_fre =
4998e4b17023SJohn Marino {
4999e4b17023SJohn Marino  {
5000e4b17023SJohn Marino   GIMPLE_PASS,
5001e4b17023SJohn Marino   "fre",				/* name */
5002e4b17023SJohn Marino   gate_fre,				/* gate */
5003e4b17023SJohn Marino   execute_fre,				/* execute */
5004e4b17023SJohn Marino   NULL,					/* sub */
5005e4b17023SJohn Marino   NULL,					/* next */
5006e4b17023SJohn Marino   0,					/* static_pass_number */
5007e4b17023SJohn Marino   TV_TREE_FRE,				/* tv_id */
5008e4b17023SJohn Marino   PROP_cfg | PROP_ssa,			/* properties_required */
5009e4b17023SJohn Marino   0,					/* properties_provided */
5010e4b17023SJohn Marino   0,					/* properties_destroyed */
5011e4b17023SJohn Marino   0,					/* todo_flags_start */
5012e4b17023SJohn Marino   TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
5013e4b17023SJohn Marino  }
5014e4b17023SJohn Marino };
5015