1e4b17023SJohn Marino /* Tail merging for gimple.
2e4b17023SJohn Marino Copyright (C) 2011, 2012 Free Software Foundation, Inc.
3e4b17023SJohn Marino Contributed by Tom de Vries (tom@codesourcery.com)
4e4b17023SJohn Marino
5e4b17023SJohn Marino This file is part of GCC.
6e4b17023SJohn Marino
7e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
8e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
10e4b17023SJohn Marino any later version.
11e4b17023SJohn Marino
12e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
13e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15e4b17023SJohn Marino GNU General Public License for more details.
16e4b17023SJohn Marino
17e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20e4b17023SJohn Marino
21e4b17023SJohn Marino /* Pass overview.
22e4b17023SJohn Marino
23e4b17023SJohn Marino
24e4b17023SJohn Marino MOTIVATIONAL EXAMPLE
25e4b17023SJohn Marino
26e4b17023SJohn Marino gimple representation of gcc/testsuite/gcc.dg/pr43864.c at
27e4b17023SJohn Marino
28e4b17023SJohn Marino hprofStartupp (charD.1 * outputFileNameD.2600, charD.1 * ctxD.2601)
29e4b17023SJohn Marino {
30e4b17023SJohn Marino struct FILED.1638 * fpD.2605;
31e4b17023SJohn Marino charD.1 fileNameD.2604[1000];
32e4b17023SJohn Marino intD.0 D.3915;
33e4b17023SJohn Marino const charD.1 * restrict outputFileName.0D.3914;
34e4b17023SJohn Marino
35e4b17023SJohn Marino # BLOCK 2 freq:10000
36e4b17023SJohn Marino # PRED: ENTRY [100.0%] (fallthru,exec)
37e4b17023SJohn Marino # PT = nonlocal { D.3926 } (restr)
38e4b17023SJohn Marino outputFileName.0D.3914_3
39e4b17023SJohn Marino = (const charD.1 * restrict) outputFileNameD.2600_2(D);
40e4b17023SJohn Marino # .MEMD.3923_13 = VDEF <.MEMD.3923_12(D)>
41e4b17023SJohn Marino # USE = nonlocal null { fileNameD.2604 D.3926 } (restr)
42e4b17023SJohn Marino # CLB = nonlocal null { fileNameD.2604 D.3926 } (restr)
43e4b17023SJohn Marino sprintfD.759 (&fileNameD.2604, outputFileName.0D.3914_3);
44e4b17023SJohn Marino # .MEMD.3923_14 = VDEF <.MEMD.3923_13>
45e4b17023SJohn Marino # USE = nonlocal null { fileNameD.2604 D.3926 } (restr)
46e4b17023SJohn Marino # CLB = nonlocal null { fileNameD.2604 D.3926 } (restr)
47e4b17023SJohn Marino D.3915_4 = accessD.2606 (&fileNameD.2604, 1);
48e4b17023SJohn Marino if (D.3915_4 == 0)
49e4b17023SJohn Marino goto <bb 3>;
50e4b17023SJohn Marino else
51e4b17023SJohn Marino goto <bb 4>;
52e4b17023SJohn Marino # SUCC: 3 [10.0%] (true,exec) 4 [90.0%] (false,exec)
53e4b17023SJohn Marino
54e4b17023SJohn Marino # BLOCK 3 freq:1000
55e4b17023SJohn Marino # PRED: 2 [10.0%] (true,exec)
56e4b17023SJohn Marino # .MEMD.3923_15 = VDEF <.MEMD.3923_14>
57e4b17023SJohn Marino # USE = nonlocal null { fileNameD.2604 D.3926 } (restr)
58e4b17023SJohn Marino # CLB = nonlocal null { fileNameD.2604 D.3926 } (restr)
59e4b17023SJohn Marino freeD.898 (ctxD.2601_5(D));
60e4b17023SJohn Marino goto <bb 7>;
61e4b17023SJohn Marino # SUCC: 7 [100.0%] (fallthru,exec)
62e4b17023SJohn Marino
63e4b17023SJohn Marino # BLOCK 4 freq:9000
64e4b17023SJohn Marino # PRED: 2 [90.0%] (false,exec)
65e4b17023SJohn Marino # .MEMD.3923_16 = VDEF <.MEMD.3923_14>
66e4b17023SJohn Marino # PT = nonlocal escaped
67e4b17023SJohn Marino # USE = nonlocal null { fileNameD.2604 D.3926 } (restr)
68e4b17023SJohn Marino # CLB = nonlocal null { fileNameD.2604 D.3926 } (restr)
69e4b17023SJohn Marino fpD.2605_8 = fopenD.1805 (&fileNameD.2604[0], 0B);
70e4b17023SJohn Marino if (fpD.2605_8 == 0B)
71e4b17023SJohn Marino goto <bb 5>;
72e4b17023SJohn Marino else
73e4b17023SJohn Marino goto <bb 6>;
74e4b17023SJohn Marino # SUCC: 5 [1.9%] (true,exec) 6 [98.1%] (false,exec)
75e4b17023SJohn Marino
76e4b17023SJohn Marino # BLOCK 5 freq:173
77e4b17023SJohn Marino # PRED: 4 [1.9%] (true,exec)
78e4b17023SJohn Marino # .MEMD.3923_17 = VDEF <.MEMD.3923_16>
79e4b17023SJohn Marino # USE = nonlocal null { fileNameD.2604 D.3926 } (restr)
80e4b17023SJohn Marino # CLB = nonlocal null { fileNameD.2604 D.3926 } (restr)
81e4b17023SJohn Marino freeD.898 (ctxD.2601_5(D));
82e4b17023SJohn Marino goto <bb 7>;
83e4b17023SJohn Marino # SUCC: 7 [100.0%] (fallthru,exec)
84e4b17023SJohn Marino
85e4b17023SJohn Marino # BLOCK 6 freq:8827
86e4b17023SJohn Marino # PRED: 4 [98.1%] (false,exec)
87e4b17023SJohn Marino # .MEMD.3923_18 = VDEF <.MEMD.3923_16>
88e4b17023SJohn Marino # USE = nonlocal null { fileNameD.2604 D.3926 } (restr)
89e4b17023SJohn Marino # CLB = nonlocal null { fileNameD.2604 D.3926 } (restr)
90e4b17023SJohn Marino fooD.2599 (outputFileNameD.2600_2(D), fpD.2605_8);
91e4b17023SJohn Marino # SUCC: 7 [100.0%] (fallthru,exec)
92e4b17023SJohn Marino
93e4b17023SJohn Marino # BLOCK 7 freq:10000
94e4b17023SJohn Marino # PRED: 3 [100.0%] (fallthru,exec) 5 [100.0%] (fallthru,exec)
95e4b17023SJohn Marino 6 [100.0%] (fallthru,exec)
96e4b17023SJohn Marino # PT = nonlocal null
97e4b17023SJohn Marino
98e4b17023SJohn Marino # ctxD.2601_1 = PHI <0B(3), 0B(5), ctxD.2601_5(D)(6)>
99e4b17023SJohn Marino # .MEMD.3923_11 = PHI <.MEMD.3923_15(3), .MEMD.3923_17(5),
100e4b17023SJohn Marino .MEMD.3923_18(6)>
101e4b17023SJohn Marino # VUSE <.MEMD.3923_11>
102e4b17023SJohn Marino return ctxD.2601_1;
103e4b17023SJohn Marino # SUCC: EXIT [100.0%]
104e4b17023SJohn Marino }
105e4b17023SJohn Marino
106e4b17023SJohn Marino bb 3 and bb 5 can be merged. The blocks have different predecessors, but the
107e4b17023SJohn Marino same successors, and the same operations.
108e4b17023SJohn Marino
109e4b17023SJohn Marino
110e4b17023SJohn Marino CONTEXT
111e4b17023SJohn Marino
112e4b17023SJohn Marino A technique called tail merging (or cross jumping) can fix the example
113e4b17023SJohn Marino above. For a block, we look for common code at the end (the tail) of the
114e4b17023SJohn Marino predecessor blocks, and insert jumps from one block to the other.
115e4b17023SJohn Marino The example is a special case for tail merging, in that 2 whole blocks
116e4b17023SJohn Marino can be merged, rather than just the end parts of it.
117e4b17023SJohn Marino We currently only focus on whole block merging, so in that sense
118e4b17023SJohn Marino calling this pass tail merge is a bit of a misnomer.
119e4b17023SJohn Marino
120e4b17023SJohn Marino We distinguish 2 kinds of situations in which blocks can be merged:
121e4b17023SJohn Marino - same operations, same predecessors. The successor edges coming from one
122e4b17023SJohn Marino block are redirected to come from the other block.
123e4b17023SJohn Marino - same operations, same successors. The predecessor edges entering one block
124e4b17023SJohn Marino are redirected to enter the other block. Note that this operation might
125e4b17023SJohn Marino involve introducing phi operations.
126e4b17023SJohn Marino
127e4b17023SJohn Marino For efficient implementation, we would like to value numbers the blocks, and
128e4b17023SJohn Marino have a comparison operator that tells us whether the blocks are equal.
129e4b17023SJohn Marino Besides being runtime efficient, block value numbering should also abstract
130e4b17023SJohn Marino from irrelevant differences in order of operations, much like normal value
131e4b17023SJohn Marino numbering abstracts from irrelevant order of operations.
132e4b17023SJohn Marino
133e4b17023SJohn Marino For the first situation (same_operations, same predecessors), normal value
134e4b17023SJohn Marino numbering fits well. We can calculate a block value number based on the
135e4b17023SJohn Marino value numbers of the defs and vdefs.
136e4b17023SJohn Marino
137e4b17023SJohn Marino For the second situation (same operations, same successors), this approach
138e4b17023SJohn Marino doesn't work so well. We can illustrate this using the example. The calls
139e4b17023SJohn Marino to free use different vdefs: MEMD.3923_16 and MEMD.3923_14, and these will
140e4b17023SJohn Marino remain different in value numbering, since they represent different memory
141e4b17023SJohn Marino states. So the resulting vdefs of the frees will be different in value
142e4b17023SJohn Marino numbering, so the block value numbers will be different.
143e4b17023SJohn Marino
144e4b17023SJohn Marino The reason why we call the blocks equal is not because they define the same
145e4b17023SJohn Marino values, but because uses in the blocks use (possibly different) defs in the
146e4b17023SJohn Marino same way. To be able to detect this efficiently, we need to do some kind of
147e4b17023SJohn Marino reverse value numbering, meaning number the uses rather than the defs, and
148e4b17023SJohn Marino calculate a block value number based on the value number of the uses.
149e4b17023SJohn Marino Ideally, a block comparison operator will also indicate which phis are needed
150e4b17023SJohn Marino to merge the blocks.
151e4b17023SJohn Marino
152e4b17023SJohn Marino For the moment, we don't do block value numbering, but we do insn-by-insn
153e4b17023SJohn Marino matching, using scc value numbers to match operations with results, and
154e4b17023SJohn Marino structural comparison otherwise, while ignoring vop mismatches.
155e4b17023SJohn Marino
156e4b17023SJohn Marino
157e4b17023SJohn Marino IMPLEMENTATION
158e4b17023SJohn Marino
159e4b17023SJohn Marino 1. The pass first determines all groups of blocks with the same successor
160e4b17023SJohn Marino blocks.
161e4b17023SJohn Marino 2. Within each group, it tries to determine clusters of equal basic blocks.
162e4b17023SJohn Marino 3. The clusters are applied.
163e4b17023SJohn Marino 4. The same successor groups are updated.
164e4b17023SJohn Marino 5. This process is repeated from 2 onwards, until no more changes.
165e4b17023SJohn Marino
166e4b17023SJohn Marino
167e4b17023SJohn Marino LIMITATIONS/TODO
168e4b17023SJohn Marino
169e4b17023SJohn Marino - block only
170e4b17023SJohn Marino - handles only 'same operations, same successors'.
171e4b17023SJohn Marino It handles same predecessors as a special subcase though.
172e4b17023SJohn Marino - does not implement the reverse value numbering and block value numbering.
173e4b17023SJohn Marino - improve memory allocation: use garbage collected memory, obstacks,
174e4b17023SJohn Marino allocpools where appropriate.
175e4b17023SJohn Marino - no insertion of gimple_reg phis, We only introduce vop-phis.
176e4b17023SJohn Marino - handle blocks with gimple_reg phi_nodes.
177e4b17023SJohn Marino
178e4b17023SJohn Marino
179e4b17023SJohn Marino SWITCHES
180e4b17023SJohn Marino
181e4b17023SJohn Marino - ftree-tail-merge. On at -O2. We may have to enable it only at -Os. */
182e4b17023SJohn Marino
183e4b17023SJohn Marino #include "config.h"
184e4b17023SJohn Marino #include "system.h"
185e4b17023SJohn Marino #include "coretypes.h"
186e4b17023SJohn Marino #include "tm.h"
187e4b17023SJohn Marino #include "tree.h"
188e4b17023SJohn Marino #include "tm_p.h"
189e4b17023SJohn Marino #include "basic-block.h"
190e4b17023SJohn Marino #include "output.h"
191e4b17023SJohn Marino #include "flags.h"
192e4b17023SJohn Marino #include "function.h"
193e4b17023SJohn Marino #include "tree-flow.h"
194e4b17023SJohn Marino #include "timevar.h"
195e4b17023SJohn Marino #include "bitmap.h"
196e4b17023SJohn Marino #include "tree-ssa-alias.h"
197e4b17023SJohn Marino #include "params.h"
198e4b17023SJohn Marino #include "tree-pretty-print.h"
199e4b17023SJohn Marino #include "hashtab.h"
200e4b17023SJohn Marino #include "gimple-pretty-print.h"
201e4b17023SJohn Marino #include "tree-ssa-sccvn.h"
202e4b17023SJohn Marino #include "tree-dump.h"
203e4b17023SJohn Marino
204e4b17023SJohn Marino /* Describes a group of bbs with the same successors. The successor bbs are
205e4b17023SJohn Marino cached in succs, and the successor edge flags are cached in succ_flags.
206e4b17023SJohn Marino If a bb has the EDGE_TRUE/VALSE_VALUE flags swapped compared to succ_flags,
207e4b17023SJohn Marino it's marked in inverse.
208e4b17023SJohn Marino Additionally, the hash value for the struct is cached in hashval, and
209e4b17023SJohn Marino in_worklist indicates whether it's currently part of worklist. */
210e4b17023SJohn Marino
211e4b17023SJohn Marino struct same_succ_def
212e4b17023SJohn Marino {
213e4b17023SJohn Marino /* The bbs that have the same successor bbs. */
214e4b17023SJohn Marino bitmap bbs;
215e4b17023SJohn Marino /* The successor bbs. */
216e4b17023SJohn Marino bitmap succs;
217e4b17023SJohn Marino /* Indicates whether the EDGE_TRUE/FALSE_VALUEs of succ_flags are swapped for
218e4b17023SJohn Marino bb. */
219e4b17023SJohn Marino bitmap inverse;
220e4b17023SJohn Marino /* The edge flags for each of the successor bbs. */
221e4b17023SJohn Marino VEC (int, heap) *succ_flags;
222e4b17023SJohn Marino /* Indicates whether the struct is currently in the worklist. */
223e4b17023SJohn Marino bool in_worklist;
224e4b17023SJohn Marino /* The hash value of the struct. */
225e4b17023SJohn Marino hashval_t hashval;
226e4b17023SJohn Marino };
227e4b17023SJohn Marino typedef struct same_succ_def *same_succ;
228e4b17023SJohn Marino typedef const struct same_succ_def *const_same_succ;
229e4b17023SJohn Marino
230e4b17023SJohn Marino /* A group of bbs where 1 bb from bbs can replace the other bbs. */
231e4b17023SJohn Marino
232e4b17023SJohn Marino struct bb_cluster_def
233e4b17023SJohn Marino {
234e4b17023SJohn Marino /* The bbs in the cluster. */
235e4b17023SJohn Marino bitmap bbs;
236e4b17023SJohn Marino /* The preds of the bbs in the cluster. */
237e4b17023SJohn Marino bitmap preds;
238e4b17023SJohn Marino /* Index in all_clusters vector. */
239e4b17023SJohn Marino int index;
240e4b17023SJohn Marino /* The bb to replace the cluster with. */
241e4b17023SJohn Marino basic_block rep_bb;
242e4b17023SJohn Marino };
243e4b17023SJohn Marino typedef struct bb_cluster_def *bb_cluster;
244e4b17023SJohn Marino typedef const struct bb_cluster_def *const_bb_cluster;
245e4b17023SJohn Marino
246e4b17023SJohn Marino /* Per bb-info. */
247e4b17023SJohn Marino
248e4b17023SJohn Marino struct aux_bb_info
249e4b17023SJohn Marino {
250e4b17023SJohn Marino /* The number of non-debug statements in the bb. */
251e4b17023SJohn Marino int size;
252e4b17023SJohn Marino /* The same_succ that this bb is a member of. */
253e4b17023SJohn Marino same_succ bb_same_succ;
254e4b17023SJohn Marino /* The cluster that this bb is a member of. */
255e4b17023SJohn Marino bb_cluster cluster;
256e4b17023SJohn Marino /* The vop state at the exit of a bb. This is shortlived data, used to
257e4b17023SJohn Marino communicate data between update_block_by and update_vuses. */
258e4b17023SJohn Marino tree vop_at_exit;
259e4b17023SJohn Marino /* The bb that either contains or is dominated by the dependencies of the
260e4b17023SJohn Marino bb. */
261e4b17023SJohn Marino basic_block dep_bb;
262e4b17023SJohn Marino };
263e4b17023SJohn Marino
264e4b17023SJohn Marino /* Macros to access the fields of struct aux_bb_info. */
265e4b17023SJohn Marino
266e4b17023SJohn Marino #define BB_SIZE(bb) (((struct aux_bb_info *)bb->aux)->size)
267e4b17023SJohn Marino #define BB_SAME_SUCC(bb) (((struct aux_bb_info *)bb->aux)->bb_same_succ)
268e4b17023SJohn Marino #define BB_CLUSTER(bb) (((struct aux_bb_info *)bb->aux)->cluster)
269e4b17023SJohn Marino #define BB_VOP_AT_EXIT(bb) (((struct aux_bb_info *)bb->aux)->vop_at_exit)
270e4b17023SJohn Marino #define BB_DEP_BB(bb) (((struct aux_bb_info *)bb->aux)->dep_bb)
271e4b17023SJohn Marino
272e4b17023SJohn Marino /* VAL1 and VAL2 are either:
273e4b17023SJohn Marino - uses in BB1 and BB2, or
274e4b17023SJohn Marino - phi alternatives for BB1 and BB2.
275e4b17023SJohn Marino Return true if the uses have the same gvn value. */
276e4b17023SJohn Marino
277e4b17023SJohn Marino static bool
gvn_uses_equal(tree val1,tree val2)278e4b17023SJohn Marino gvn_uses_equal (tree val1, tree val2)
279e4b17023SJohn Marino {
280e4b17023SJohn Marino gcc_checking_assert (val1 != NULL_TREE && val2 != NULL_TREE);
281e4b17023SJohn Marino
282e4b17023SJohn Marino if (val1 == val2)
283e4b17023SJohn Marino return true;
284e4b17023SJohn Marino
285e4b17023SJohn Marino if (vn_valueize (val1) != vn_valueize (val2))
286e4b17023SJohn Marino return false;
287e4b17023SJohn Marino
288e4b17023SJohn Marino return ((TREE_CODE (val1) == SSA_NAME || CONSTANT_CLASS_P (val1))
289e4b17023SJohn Marino && (TREE_CODE (val2) == SSA_NAME || CONSTANT_CLASS_P (val2)));
290e4b17023SJohn Marino }
291e4b17023SJohn Marino
292e4b17023SJohn Marino /* Prints E to FILE. */
293e4b17023SJohn Marino
294e4b17023SJohn Marino static void
same_succ_print(FILE * file,const same_succ e)295e4b17023SJohn Marino same_succ_print (FILE *file, const same_succ e)
296e4b17023SJohn Marino {
297e4b17023SJohn Marino unsigned int i;
298e4b17023SJohn Marino bitmap_print (file, e->bbs, "bbs:", "\n");
299e4b17023SJohn Marino bitmap_print (file, e->succs, "succs:", "\n");
300e4b17023SJohn Marino bitmap_print (file, e->inverse, "inverse:", "\n");
301e4b17023SJohn Marino fprintf (file, "flags:");
302e4b17023SJohn Marino for (i = 0; i < VEC_length (int, e->succ_flags); ++i)
303e4b17023SJohn Marino fprintf (file, " %x", VEC_index (int, e->succ_flags, i));
304e4b17023SJohn Marino fprintf (file, "\n");
305e4b17023SJohn Marino }
306e4b17023SJohn Marino
307e4b17023SJohn Marino /* Prints same_succ VE to VFILE. */
308e4b17023SJohn Marino
309e4b17023SJohn Marino static int
same_succ_print_traverse(void ** ve,void * vfile)310e4b17023SJohn Marino same_succ_print_traverse (void **ve, void *vfile)
311e4b17023SJohn Marino {
312e4b17023SJohn Marino const same_succ e = *((const same_succ *)ve);
313e4b17023SJohn Marino FILE *file = ((FILE*)vfile);
314e4b17023SJohn Marino same_succ_print (file, e);
315e4b17023SJohn Marino return 1;
316e4b17023SJohn Marino }
317e4b17023SJohn Marino
318e4b17023SJohn Marino /* Update BB_DEP_BB (USE_BB), given a use of VAL in USE_BB. */
319e4b17023SJohn Marino
320e4b17023SJohn Marino static void
update_dep_bb(basic_block use_bb,tree val)321e4b17023SJohn Marino update_dep_bb (basic_block use_bb, tree val)
322e4b17023SJohn Marino {
323e4b17023SJohn Marino basic_block dep_bb;
324e4b17023SJohn Marino
325e4b17023SJohn Marino /* Not a dep. */
326e4b17023SJohn Marino if (TREE_CODE (val) != SSA_NAME)
327e4b17023SJohn Marino return;
328e4b17023SJohn Marino
329e4b17023SJohn Marino /* Skip use of global def. */
330e4b17023SJohn Marino if (SSA_NAME_IS_DEFAULT_DEF (val))
331e4b17023SJohn Marino return;
332e4b17023SJohn Marino
333e4b17023SJohn Marino /* Skip use of local def. */
334e4b17023SJohn Marino dep_bb = gimple_bb (SSA_NAME_DEF_STMT (val));
335e4b17023SJohn Marino if (dep_bb == use_bb)
336e4b17023SJohn Marino return;
337e4b17023SJohn Marino
338e4b17023SJohn Marino if (BB_DEP_BB (use_bb) == NULL
339e4b17023SJohn Marino || dominated_by_p (CDI_DOMINATORS, dep_bb, BB_DEP_BB (use_bb)))
340e4b17023SJohn Marino BB_DEP_BB (use_bb) = dep_bb;
341e4b17023SJohn Marino }
342e4b17023SJohn Marino
343e4b17023SJohn Marino /* Update BB_DEP_BB, given the dependencies in STMT. */
344e4b17023SJohn Marino
345e4b17023SJohn Marino static void
stmt_update_dep_bb(gimple stmt)346e4b17023SJohn Marino stmt_update_dep_bb (gimple stmt)
347e4b17023SJohn Marino {
348e4b17023SJohn Marino ssa_op_iter iter;
349e4b17023SJohn Marino use_operand_p use;
350e4b17023SJohn Marino
351e4b17023SJohn Marino FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
352e4b17023SJohn Marino update_dep_bb (gimple_bb (stmt), USE_FROM_PTR (use));
353e4b17023SJohn Marino }
354e4b17023SJohn Marino
355e4b17023SJohn Marino /* Returns whether VAL is used in the same bb as in which it is defined, or
356e4b17023SJohn Marino in the phi of a successor bb. */
357e4b17023SJohn Marino
358e4b17023SJohn Marino static bool
local_def(tree val)359e4b17023SJohn Marino local_def (tree val)
360e4b17023SJohn Marino {
361e4b17023SJohn Marino gimple stmt, def_stmt;
362e4b17023SJohn Marino basic_block bb, def_bb;
363e4b17023SJohn Marino imm_use_iterator iter;
364e4b17023SJohn Marino bool res;
365e4b17023SJohn Marino
366e4b17023SJohn Marino if (TREE_CODE (val) != SSA_NAME)
367e4b17023SJohn Marino return false;
368e4b17023SJohn Marino def_stmt = SSA_NAME_DEF_STMT (val);
369e4b17023SJohn Marino def_bb = gimple_bb (def_stmt);
370e4b17023SJohn Marino
371e4b17023SJohn Marino res = true;
372e4b17023SJohn Marino FOR_EACH_IMM_USE_STMT (stmt, iter, val)
373e4b17023SJohn Marino {
374e4b17023SJohn Marino if (is_gimple_debug (stmt))
375e4b17023SJohn Marino continue;
376e4b17023SJohn Marino bb = gimple_bb (stmt);
377e4b17023SJohn Marino if (bb == def_bb)
378e4b17023SJohn Marino continue;
379e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_PHI
380e4b17023SJohn Marino && find_edge (def_bb, bb))
381e4b17023SJohn Marino continue;
382e4b17023SJohn Marino res = false;
383e4b17023SJohn Marino BREAK_FROM_IMM_USE_STMT (iter);
384e4b17023SJohn Marino }
385e4b17023SJohn Marino return res;
386e4b17023SJohn Marino }
387e4b17023SJohn Marino
388e4b17023SJohn Marino /* Calculates hash value for same_succ VE. */
389e4b17023SJohn Marino
390e4b17023SJohn Marino static hashval_t
same_succ_hash(const void * ve)391e4b17023SJohn Marino same_succ_hash (const void *ve)
392e4b17023SJohn Marino {
393e4b17023SJohn Marino const_same_succ e = (const_same_succ)ve;
394e4b17023SJohn Marino hashval_t hashval = bitmap_hash (e->succs);
395e4b17023SJohn Marino int flags;
396e4b17023SJohn Marino unsigned int i;
397e4b17023SJohn Marino unsigned int first = bitmap_first_set_bit (e->bbs);
398e4b17023SJohn Marino basic_block bb = BASIC_BLOCK (first);
399e4b17023SJohn Marino int size = 0;
400e4b17023SJohn Marino gimple_stmt_iterator gsi;
401e4b17023SJohn Marino gimple stmt;
402e4b17023SJohn Marino tree arg;
403e4b17023SJohn Marino unsigned int s;
404e4b17023SJohn Marino bitmap_iterator bs;
405e4b17023SJohn Marino
406e4b17023SJohn Marino for (gsi = gsi_start_nondebug_bb (bb);
407e4b17023SJohn Marino !gsi_end_p (gsi); gsi_next_nondebug (&gsi))
408e4b17023SJohn Marino {
409e4b17023SJohn Marino stmt = gsi_stmt (gsi);
410e4b17023SJohn Marino stmt_update_dep_bb (stmt);
411e4b17023SJohn Marino if (is_gimple_assign (stmt) && local_def (gimple_get_lhs (stmt))
412e4b17023SJohn Marino && !gimple_has_side_effects (stmt))
413e4b17023SJohn Marino continue;
414e4b17023SJohn Marino size++;
415e4b17023SJohn Marino
416e4b17023SJohn Marino hashval = iterative_hash_hashval_t (gimple_code (stmt), hashval);
417e4b17023SJohn Marino if (is_gimple_assign (stmt))
418e4b17023SJohn Marino hashval = iterative_hash_hashval_t (gimple_assign_rhs_code (stmt),
419e4b17023SJohn Marino hashval);
420e4b17023SJohn Marino if (!is_gimple_call (stmt))
421e4b17023SJohn Marino continue;
422e4b17023SJohn Marino if (gimple_call_internal_p (stmt))
423e4b17023SJohn Marino hashval = iterative_hash_hashval_t
424e4b17023SJohn Marino ((hashval_t) gimple_call_internal_fn (stmt), hashval);
425e4b17023SJohn Marino else
426e4b17023SJohn Marino hashval = iterative_hash_expr (gimple_call_fn (stmt), hashval);
427e4b17023SJohn Marino for (i = 0; i < gimple_call_num_args (stmt); i++)
428e4b17023SJohn Marino {
429e4b17023SJohn Marino arg = gimple_call_arg (stmt, i);
430e4b17023SJohn Marino arg = vn_valueize (arg);
431e4b17023SJohn Marino hashval = iterative_hash_expr (arg, hashval);
432e4b17023SJohn Marino }
433e4b17023SJohn Marino }
434e4b17023SJohn Marino
435e4b17023SJohn Marino hashval = iterative_hash_hashval_t (size, hashval);
436e4b17023SJohn Marino BB_SIZE (bb) = size;
437e4b17023SJohn Marino
438e4b17023SJohn Marino for (i = 0; i < VEC_length (int, e->succ_flags); ++i)
439e4b17023SJohn Marino {
440e4b17023SJohn Marino flags = VEC_index (int, e->succ_flags, i);
441e4b17023SJohn Marino flags = flags & ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
442e4b17023SJohn Marino hashval = iterative_hash_hashval_t (flags, hashval);
443e4b17023SJohn Marino }
444e4b17023SJohn Marino
445e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (e->succs, 0, s, bs)
446e4b17023SJohn Marino {
447e4b17023SJohn Marino int n = find_edge (bb, BASIC_BLOCK (s))->dest_idx;
448e4b17023SJohn Marino for (gsi = gsi_start_phis (BASIC_BLOCK (s)); !gsi_end_p (gsi);
449e4b17023SJohn Marino gsi_next (&gsi))
450e4b17023SJohn Marino {
451e4b17023SJohn Marino gimple phi = gsi_stmt (gsi);
452e4b17023SJohn Marino tree lhs = gimple_phi_result (phi);
453e4b17023SJohn Marino tree val = gimple_phi_arg_def (phi, n);
454e4b17023SJohn Marino
455e4b17023SJohn Marino if (!is_gimple_reg (lhs))
456e4b17023SJohn Marino continue;
457e4b17023SJohn Marino update_dep_bb (bb, val);
458e4b17023SJohn Marino }
459e4b17023SJohn Marino }
460e4b17023SJohn Marino
461e4b17023SJohn Marino return hashval;
462e4b17023SJohn Marino }
463e4b17023SJohn Marino
464e4b17023SJohn Marino /* Returns true if E1 and E2 have 2 successors, and if the successor flags
465e4b17023SJohn Marino are inverse for the EDGE_TRUE_VALUE and EDGE_FALSE_VALUE flags, and equal for
466e4b17023SJohn Marino the other edge flags. */
467e4b17023SJohn Marino
468e4b17023SJohn Marino static bool
inverse_flags(const_same_succ e1,const_same_succ e2)469e4b17023SJohn Marino inverse_flags (const_same_succ e1, const_same_succ e2)
470e4b17023SJohn Marino {
471e4b17023SJohn Marino int f1a, f1b, f2a, f2b;
472e4b17023SJohn Marino int mask = ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
473e4b17023SJohn Marino
474e4b17023SJohn Marino if (VEC_length (int, e1->succ_flags) != 2)
475e4b17023SJohn Marino return false;
476e4b17023SJohn Marino
477e4b17023SJohn Marino f1a = VEC_index (int, e1->succ_flags, 0);
478e4b17023SJohn Marino f1b = VEC_index (int, e1->succ_flags, 1);
479e4b17023SJohn Marino f2a = VEC_index (int, e2->succ_flags, 0);
480e4b17023SJohn Marino f2b = VEC_index (int, e2->succ_flags, 1);
481e4b17023SJohn Marino
482e4b17023SJohn Marino if (f1a == f2a && f1b == f2b)
483e4b17023SJohn Marino return false;
484e4b17023SJohn Marino
485e4b17023SJohn Marino return (f1a & mask) == (f2a & mask) && (f1b & mask) == (f2b & mask);
486e4b17023SJohn Marino }
487e4b17023SJohn Marino
488e4b17023SJohn Marino /* Compares SAME_SUCCs VE1 and VE2. */
489e4b17023SJohn Marino
490e4b17023SJohn Marino static int
same_succ_equal(const void * ve1,const void * ve2)491e4b17023SJohn Marino same_succ_equal (const void *ve1, const void *ve2)
492e4b17023SJohn Marino {
493e4b17023SJohn Marino const_same_succ e1 = (const_same_succ)ve1;
494e4b17023SJohn Marino const_same_succ e2 = (const_same_succ)ve2;
495e4b17023SJohn Marino unsigned int i, first1, first2;
496e4b17023SJohn Marino gimple_stmt_iterator gsi1, gsi2;
497e4b17023SJohn Marino gimple s1, s2;
498e4b17023SJohn Marino basic_block bb1, bb2;
499e4b17023SJohn Marino
500e4b17023SJohn Marino if (e1->hashval != e2->hashval)
501e4b17023SJohn Marino return 0;
502e4b17023SJohn Marino
503e4b17023SJohn Marino if (VEC_length (int, e1->succ_flags) != VEC_length (int, e2->succ_flags))
504e4b17023SJohn Marino return 0;
505e4b17023SJohn Marino
506e4b17023SJohn Marino if (!bitmap_equal_p (e1->succs, e2->succs))
507e4b17023SJohn Marino return 0;
508e4b17023SJohn Marino
509e4b17023SJohn Marino if (!inverse_flags (e1, e2))
510e4b17023SJohn Marino {
511e4b17023SJohn Marino for (i = 0; i < VEC_length (int, e1->succ_flags); ++i)
512e4b17023SJohn Marino if (VEC_index (int, e1->succ_flags, i)
513e4b17023SJohn Marino != VEC_index (int, e1->succ_flags, i))
514e4b17023SJohn Marino return 0;
515e4b17023SJohn Marino }
516e4b17023SJohn Marino
517e4b17023SJohn Marino first1 = bitmap_first_set_bit (e1->bbs);
518e4b17023SJohn Marino first2 = bitmap_first_set_bit (e2->bbs);
519e4b17023SJohn Marino
520e4b17023SJohn Marino bb1 = BASIC_BLOCK (first1);
521e4b17023SJohn Marino bb2 = BASIC_BLOCK (first2);
522e4b17023SJohn Marino
523e4b17023SJohn Marino if (BB_SIZE (bb1) != BB_SIZE (bb2))
524e4b17023SJohn Marino return 0;
525e4b17023SJohn Marino
526e4b17023SJohn Marino gsi1 = gsi_start_nondebug_bb (bb1);
527e4b17023SJohn Marino gsi2 = gsi_start_nondebug_bb (bb2);
528e4b17023SJohn Marino while (!(gsi_end_p (gsi1) || gsi_end_p (gsi2)))
529e4b17023SJohn Marino {
530e4b17023SJohn Marino s1 = gsi_stmt (gsi1);
531e4b17023SJohn Marino s2 = gsi_stmt (gsi2);
532e4b17023SJohn Marino if (gimple_code (s1) != gimple_code (s2))
533e4b17023SJohn Marino return 0;
534e4b17023SJohn Marino if (is_gimple_call (s1) && !gimple_call_same_target_p (s1, s2))
535e4b17023SJohn Marino return 0;
536e4b17023SJohn Marino gsi_next_nondebug (&gsi1);
537e4b17023SJohn Marino gsi_next_nondebug (&gsi2);
538e4b17023SJohn Marino }
539e4b17023SJohn Marino
540e4b17023SJohn Marino return 1;
541e4b17023SJohn Marino }
542e4b17023SJohn Marino
543e4b17023SJohn Marino /* Alloc and init a new SAME_SUCC. */
544e4b17023SJohn Marino
545e4b17023SJohn Marino static same_succ
same_succ_alloc(void)546e4b17023SJohn Marino same_succ_alloc (void)
547e4b17023SJohn Marino {
548e4b17023SJohn Marino same_succ same = XNEW (struct same_succ_def);
549e4b17023SJohn Marino
550e4b17023SJohn Marino same->bbs = BITMAP_ALLOC (NULL);
551e4b17023SJohn Marino same->succs = BITMAP_ALLOC (NULL);
552e4b17023SJohn Marino same->inverse = BITMAP_ALLOC (NULL);
553e4b17023SJohn Marino same->succ_flags = VEC_alloc (int, heap, 10);
554e4b17023SJohn Marino same->in_worklist = false;
555e4b17023SJohn Marino
556e4b17023SJohn Marino return same;
557e4b17023SJohn Marino }
558e4b17023SJohn Marino
559e4b17023SJohn Marino /* Delete same_succ VE. */
560e4b17023SJohn Marino
561e4b17023SJohn Marino static void
same_succ_delete(void * ve)562e4b17023SJohn Marino same_succ_delete (void *ve)
563e4b17023SJohn Marino {
564e4b17023SJohn Marino same_succ e = (same_succ)ve;
565e4b17023SJohn Marino
566e4b17023SJohn Marino BITMAP_FREE (e->bbs);
567e4b17023SJohn Marino BITMAP_FREE (e->succs);
568e4b17023SJohn Marino BITMAP_FREE (e->inverse);
569e4b17023SJohn Marino VEC_free (int, heap, e->succ_flags);
570e4b17023SJohn Marino
571e4b17023SJohn Marino XDELETE (ve);
572e4b17023SJohn Marino }
573e4b17023SJohn Marino
574e4b17023SJohn Marino /* Reset same_succ SAME. */
575e4b17023SJohn Marino
576e4b17023SJohn Marino static void
same_succ_reset(same_succ same)577e4b17023SJohn Marino same_succ_reset (same_succ same)
578e4b17023SJohn Marino {
579e4b17023SJohn Marino bitmap_clear (same->bbs);
580e4b17023SJohn Marino bitmap_clear (same->succs);
581e4b17023SJohn Marino bitmap_clear (same->inverse);
582e4b17023SJohn Marino VEC_truncate (int, same->succ_flags, 0);
583e4b17023SJohn Marino }
584e4b17023SJohn Marino
585e4b17023SJohn Marino /* Hash table with all same_succ entries. */
586e4b17023SJohn Marino
587e4b17023SJohn Marino static htab_t same_succ_htab;
588e4b17023SJohn Marino
589e4b17023SJohn Marino /* Array that is used to store the edge flags for a successor. */
590e4b17023SJohn Marino
591e4b17023SJohn Marino static int *same_succ_edge_flags;
592e4b17023SJohn Marino
593e4b17023SJohn Marino /* Bitmap that is used to mark bbs that are recently deleted. */
594e4b17023SJohn Marino
595e4b17023SJohn Marino static bitmap deleted_bbs;
596e4b17023SJohn Marino
597e4b17023SJohn Marino /* Bitmap that is used to mark predecessors of bbs that are
598e4b17023SJohn Marino deleted. */
599e4b17023SJohn Marino
600e4b17023SJohn Marino static bitmap deleted_bb_preds;
601e4b17023SJohn Marino
602e4b17023SJohn Marino /* Prints same_succ_htab to stderr. */
603e4b17023SJohn Marino
604e4b17023SJohn Marino extern void debug_same_succ (void);
605e4b17023SJohn Marino DEBUG_FUNCTION void
debug_same_succ(void)606e4b17023SJohn Marino debug_same_succ ( void)
607e4b17023SJohn Marino {
608e4b17023SJohn Marino htab_traverse (same_succ_htab, same_succ_print_traverse, stderr);
609e4b17023SJohn Marino }
610e4b17023SJohn Marino
611e4b17023SJohn Marino DEF_VEC_P (same_succ);
612e4b17023SJohn Marino DEF_VEC_ALLOC_P (same_succ, heap);
613e4b17023SJohn Marino
614e4b17023SJohn Marino /* Vector of bbs to process. */
615e4b17023SJohn Marino
VEC(same_succ,heap)616e4b17023SJohn Marino static VEC (same_succ, heap) *worklist;
617e4b17023SJohn Marino
618e4b17023SJohn Marino /* Prints worklist to FILE. */
619e4b17023SJohn Marino
620e4b17023SJohn Marino static void
621e4b17023SJohn Marino print_worklist (FILE *file)
622e4b17023SJohn Marino {
623e4b17023SJohn Marino unsigned int i;
624e4b17023SJohn Marino for (i = 0; i < VEC_length (same_succ, worklist); ++i)
625e4b17023SJohn Marino same_succ_print (file, VEC_index (same_succ, worklist, i));
626e4b17023SJohn Marino }
627e4b17023SJohn Marino
628e4b17023SJohn Marino /* Adds SAME to worklist. */
629e4b17023SJohn Marino
630e4b17023SJohn Marino static void
add_to_worklist(same_succ same)631e4b17023SJohn Marino add_to_worklist (same_succ same)
632e4b17023SJohn Marino {
633e4b17023SJohn Marino if (same->in_worklist)
634e4b17023SJohn Marino return;
635e4b17023SJohn Marino
636e4b17023SJohn Marino if (bitmap_count_bits (same->bbs) < 2)
637e4b17023SJohn Marino return;
638e4b17023SJohn Marino
639e4b17023SJohn Marino same->in_worklist = true;
640e4b17023SJohn Marino VEC_safe_push (same_succ, heap, worklist, same);
641e4b17023SJohn Marino }
642e4b17023SJohn Marino
643e4b17023SJohn Marino /* Add BB to same_succ_htab. */
644e4b17023SJohn Marino
645e4b17023SJohn Marino static void
find_same_succ_bb(basic_block bb,same_succ * same_p)646e4b17023SJohn Marino find_same_succ_bb (basic_block bb, same_succ *same_p)
647e4b17023SJohn Marino {
648e4b17023SJohn Marino unsigned int j;
649e4b17023SJohn Marino bitmap_iterator bj;
650e4b17023SJohn Marino same_succ same = *same_p;
651e4b17023SJohn Marino same_succ *slot;
652e4b17023SJohn Marino edge_iterator ei;
653e4b17023SJohn Marino edge e;
654e4b17023SJohn Marino
655e4b17023SJohn Marino if (bb == NULL)
656e4b17023SJohn Marino return;
657e4b17023SJohn Marino bitmap_set_bit (same->bbs, bb->index);
658e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
659e4b17023SJohn Marino {
660e4b17023SJohn Marino int index = e->dest->index;
661e4b17023SJohn Marino bitmap_set_bit (same->succs, index);
662e4b17023SJohn Marino same_succ_edge_flags[index] = e->flags;
663e4b17023SJohn Marino }
664e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (same->succs, 0, j, bj)
665e4b17023SJohn Marino VEC_safe_push (int, heap, same->succ_flags, same_succ_edge_flags[j]);
666e4b17023SJohn Marino
667e4b17023SJohn Marino same->hashval = same_succ_hash (same);
668e4b17023SJohn Marino
669e4b17023SJohn Marino slot = (same_succ *) htab_find_slot_with_hash (same_succ_htab, same,
670e4b17023SJohn Marino same->hashval, INSERT);
671e4b17023SJohn Marino if (*slot == NULL)
672e4b17023SJohn Marino {
673e4b17023SJohn Marino *slot = same;
674e4b17023SJohn Marino BB_SAME_SUCC (bb) = same;
675e4b17023SJohn Marino add_to_worklist (same);
676e4b17023SJohn Marino *same_p = NULL;
677e4b17023SJohn Marino }
678e4b17023SJohn Marino else
679e4b17023SJohn Marino {
680e4b17023SJohn Marino bitmap_set_bit ((*slot)->bbs, bb->index);
681e4b17023SJohn Marino BB_SAME_SUCC (bb) = *slot;
682e4b17023SJohn Marino add_to_worklist (*slot);
683e4b17023SJohn Marino if (inverse_flags (same, *slot))
684e4b17023SJohn Marino bitmap_set_bit ((*slot)->inverse, bb->index);
685e4b17023SJohn Marino same_succ_reset (same);
686e4b17023SJohn Marino }
687e4b17023SJohn Marino }
688e4b17023SJohn Marino
689e4b17023SJohn Marino /* Find bbs with same successors. */
690e4b17023SJohn Marino
691e4b17023SJohn Marino static void
find_same_succ(void)692e4b17023SJohn Marino find_same_succ (void)
693e4b17023SJohn Marino {
694e4b17023SJohn Marino same_succ same = same_succ_alloc ();
695e4b17023SJohn Marino basic_block bb;
696e4b17023SJohn Marino
697e4b17023SJohn Marino FOR_EACH_BB (bb)
698e4b17023SJohn Marino {
699e4b17023SJohn Marino find_same_succ_bb (bb, &same);
700e4b17023SJohn Marino if (same == NULL)
701e4b17023SJohn Marino same = same_succ_alloc ();
702e4b17023SJohn Marino }
703e4b17023SJohn Marino
704e4b17023SJohn Marino same_succ_delete (same);
705e4b17023SJohn Marino }
706e4b17023SJohn Marino
707e4b17023SJohn Marino /* Initializes worklist administration. */
708e4b17023SJohn Marino
709e4b17023SJohn Marino static void
init_worklist(void)710e4b17023SJohn Marino init_worklist (void)
711e4b17023SJohn Marino {
712e4b17023SJohn Marino alloc_aux_for_blocks (sizeof (struct aux_bb_info));
713e4b17023SJohn Marino same_succ_htab
714e4b17023SJohn Marino = htab_create (n_basic_blocks, same_succ_hash, same_succ_equal,
715e4b17023SJohn Marino same_succ_delete);
716e4b17023SJohn Marino same_succ_edge_flags = XCNEWVEC (int, last_basic_block);
717e4b17023SJohn Marino deleted_bbs = BITMAP_ALLOC (NULL);
718e4b17023SJohn Marino deleted_bb_preds = BITMAP_ALLOC (NULL);
719e4b17023SJohn Marino worklist = VEC_alloc (same_succ, heap, n_basic_blocks);
720e4b17023SJohn Marino find_same_succ ();
721e4b17023SJohn Marino
722e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
723e4b17023SJohn Marino {
724e4b17023SJohn Marino fprintf (dump_file, "initial worklist:\n");
725e4b17023SJohn Marino print_worklist (dump_file);
726e4b17023SJohn Marino }
727e4b17023SJohn Marino }
728e4b17023SJohn Marino
729e4b17023SJohn Marino /* Deletes worklist administration. */
730e4b17023SJohn Marino
731e4b17023SJohn Marino static void
delete_worklist(void)732e4b17023SJohn Marino delete_worklist (void)
733e4b17023SJohn Marino {
734e4b17023SJohn Marino free_aux_for_blocks ();
735e4b17023SJohn Marino htab_delete (same_succ_htab);
736e4b17023SJohn Marino same_succ_htab = NULL;
737e4b17023SJohn Marino XDELETEVEC (same_succ_edge_flags);
738e4b17023SJohn Marino same_succ_edge_flags = NULL;
739e4b17023SJohn Marino BITMAP_FREE (deleted_bbs);
740e4b17023SJohn Marino BITMAP_FREE (deleted_bb_preds);
741e4b17023SJohn Marino VEC_free (same_succ, heap, worklist);
742e4b17023SJohn Marino }
743e4b17023SJohn Marino
744e4b17023SJohn Marino /* Mark BB as deleted, and mark its predecessors. */
745e4b17023SJohn Marino
746e4b17023SJohn Marino static void
mark_basic_block_deleted(basic_block bb)747e4b17023SJohn Marino mark_basic_block_deleted (basic_block bb)
748e4b17023SJohn Marino {
749e4b17023SJohn Marino edge e;
750e4b17023SJohn Marino edge_iterator ei;
751e4b17023SJohn Marino
752e4b17023SJohn Marino bitmap_set_bit (deleted_bbs, bb->index);
753e4b17023SJohn Marino
754e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds)
755e4b17023SJohn Marino bitmap_set_bit (deleted_bb_preds, e->src->index);
756e4b17023SJohn Marino }
757e4b17023SJohn Marino
758e4b17023SJohn Marino /* Removes BB from its corresponding same_succ. */
759e4b17023SJohn Marino
760e4b17023SJohn Marino static void
same_succ_flush_bb(basic_block bb)761e4b17023SJohn Marino same_succ_flush_bb (basic_block bb)
762e4b17023SJohn Marino {
763e4b17023SJohn Marino same_succ same = BB_SAME_SUCC (bb);
764e4b17023SJohn Marino BB_SAME_SUCC (bb) = NULL;
765e4b17023SJohn Marino if (bitmap_single_bit_set_p (same->bbs))
766e4b17023SJohn Marino htab_remove_elt_with_hash (same_succ_htab, same, same->hashval);
767e4b17023SJohn Marino else
768e4b17023SJohn Marino bitmap_clear_bit (same->bbs, bb->index);
769e4b17023SJohn Marino }
770e4b17023SJohn Marino
771e4b17023SJohn Marino /* Removes all bbs in BBS from their corresponding same_succ. */
772e4b17023SJohn Marino
773e4b17023SJohn Marino static void
same_succ_flush_bbs(bitmap bbs)774e4b17023SJohn Marino same_succ_flush_bbs (bitmap bbs)
775e4b17023SJohn Marino {
776e4b17023SJohn Marino unsigned int i;
777e4b17023SJohn Marino bitmap_iterator bi;
778e4b17023SJohn Marino
779e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (bbs, 0, i, bi)
780e4b17023SJohn Marino same_succ_flush_bb (BASIC_BLOCK (i));
781e4b17023SJohn Marino }
782e4b17023SJohn Marino
783e4b17023SJohn Marino /* Release the last vdef in BB, either normal or phi result. */
784e4b17023SJohn Marino
785e4b17023SJohn Marino static void
release_last_vdef(basic_block bb)786e4b17023SJohn Marino release_last_vdef (basic_block bb)
787e4b17023SJohn Marino {
788e4b17023SJohn Marino gimple_stmt_iterator i;
789e4b17023SJohn Marino
790e4b17023SJohn Marino for (i = gsi_last_bb (bb); !gsi_end_p (i); gsi_prev_nondebug (&i))
791e4b17023SJohn Marino {
792e4b17023SJohn Marino gimple stmt = gsi_stmt (i);
793e4b17023SJohn Marino if (gimple_vdef (stmt) == NULL_TREE)
794e4b17023SJohn Marino continue;
795e4b17023SJohn Marino
796e4b17023SJohn Marino mark_virtual_operand_for_renaming (gimple_vdef (stmt));
797e4b17023SJohn Marino return;
798e4b17023SJohn Marino }
799e4b17023SJohn Marino
800e4b17023SJohn Marino for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
801e4b17023SJohn Marino {
802e4b17023SJohn Marino gimple phi = gsi_stmt (i);
803e4b17023SJohn Marino tree res = gimple_phi_result (phi);
804e4b17023SJohn Marino
805e4b17023SJohn Marino if (is_gimple_reg (res))
806e4b17023SJohn Marino continue;
807e4b17023SJohn Marino
808e4b17023SJohn Marino mark_virtual_phi_result_for_renaming (phi);
809e4b17023SJohn Marino return;
810e4b17023SJohn Marino }
811e4b17023SJohn Marino
812e4b17023SJohn Marino }
813e4b17023SJohn Marino
814e4b17023SJohn Marino /* For deleted_bb_preds, find bbs with same successors. */
815e4b17023SJohn Marino
816e4b17023SJohn Marino static void
update_worklist(void)817e4b17023SJohn Marino update_worklist (void)
818e4b17023SJohn Marino {
819e4b17023SJohn Marino unsigned int i;
820e4b17023SJohn Marino bitmap_iterator bi;
821e4b17023SJohn Marino basic_block bb;
822e4b17023SJohn Marino same_succ same;
823e4b17023SJohn Marino
824e4b17023SJohn Marino bitmap_and_compl_into (deleted_bb_preds, deleted_bbs);
825e4b17023SJohn Marino bitmap_clear (deleted_bbs);
826e4b17023SJohn Marino
827e4b17023SJohn Marino bitmap_clear_bit (deleted_bb_preds, ENTRY_BLOCK);
828e4b17023SJohn Marino same_succ_flush_bbs (deleted_bb_preds);
829e4b17023SJohn Marino
830e4b17023SJohn Marino same = same_succ_alloc ();
831e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (deleted_bb_preds, 0, i, bi)
832e4b17023SJohn Marino {
833e4b17023SJohn Marino bb = BASIC_BLOCK (i);
834e4b17023SJohn Marino gcc_assert (bb != NULL);
835e4b17023SJohn Marino find_same_succ_bb (bb, &same);
836e4b17023SJohn Marino if (same == NULL)
837e4b17023SJohn Marino same = same_succ_alloc ();
838e4b17023SJohn Marino }
839e4b17023SJohn Marino same_succ_delete (same);
840e4b17023SJohn Marino bitmap_clear (deleted_bb_preds);
841e4b17023SJohn Marino }
842e4b17023SJohn Marino
843e4b17023SJohn Marino /* Prints cluster C to FILE. */
844e4b17023SJohn Marino
845e4b17023SJohn Marino static void
print_cluster(FILE * file,bb_cluster c)846e4b17023SJohn Marino print_cluster (FILE *file, bb_cluster c)
847e4b17023SJohn Marino {
848e4b17023SJohn Marino if (c == NULL)
849e4b17023SJohn Marino return;
850e4b17023SJohn Marino bitmap_print (file, c->bbs, "bbs:", "\n");
851e4b17023SJohn Marino bitmap_print (file, c->preds, "preds:", "\n");
852e4b17023SJohn Marino }
853e4b17023SJohn Marino
854e4b17023SJohn Marino /* Prints cluster C to stderr. */
855e4b17023SJohn Marino
856e4b17023SJohn Marino extern void debug_cluster (bb_cluster);
857e4b17023SJohn Marino DEBUG_FUNCTION void
debug_cluster(bb_cluster c)858e4b17023SJohn Marino debug_cluster (bb_cluster c)
859e4b17023SJohn Marino {
860e4b17023SJohn Marino print_cluster (stderr, c);
861e4b17023SJohn Marino }
862e4b17023SJohn Marino
863e4b17023SJohn Marino /* Update C->rep_bb, given that BB is added to the cluster. */
864e4b17023SJohn Marino
865e4b17023SJohn Marino static void
update_rep_bb(bb_cluster c,basic_block bb)866e4b17023SJohn Marino update_rep_bb (bb_cluster c, basic_block bb)
867e4b17023SJohn Marino {
868e4b17023SJohn Marino /* Initial. */
869e4b17023SJohn Marino if (c->rep_bb == NULL)
870e4b17023SJohn Marino {
871e4b17023SJohn Marino c->rep_bb = bb;
872e4b17023SJohn Marino return;
873e4b17023SJohn Marino }
874e4b17023SJohn Marino
875e4b17023SJohn Marino /* Current needs no deps, keep it. */
876e4b17023SJohn Marino if (BB_DEP_BB (c->rep_bb) == NULL)
877e4b17023SJohn Marino return;
878e4b17023SJohn Marino
879e4b17023SJohn Marino /* Bb needs no deps, change rep_bb. */
880e4b17023SJohn Marino if (BB_DEP_BB (bb) == NULL)
881e4b17023SJohn Marino {
882e4b17023SJohn Marino c->rep_bb = bb;
883e4b17023SJohn Marino return;
884e4b17023SJohn Marino }
885e4b17023SJohn Marino
886e4b17023SJohn Marino /* Bb needs last deps earlier than current, change rep_bb. A potential
887e4b17023SJohn Marino problem with this, is that the first deps might also be earlier, which
888e4b17023SJohn Marino would mean we prefer longer lifetimes for the deps. To be able to check
889e4b17023SJohn Marino for this, we would have to trace BB_FIRST_DEP_BB as well, besides
890e4b17023SJohn Marino BB_DEP_BB, which is really BB_LAST_DEP_BB.
891e4b17023SJohn Marino The benefit of choosing the bb with last deps earlier, is that it can
892e4b17023SJohn Marino potentially be used as replacement for more bbs. */
893e4b17023SJohn Marino if (dominated_by_p (CDI_DOMINATORS, BB_DEP_BB (c->rep_bb), BB_DEP_BB (bb)))
894e4b17023SJohn Marino c->rep_bb = bb;
895e4b17023SJohn Marino }
896e4b17023SJohn Marino
897e4b17023SJohn Marino /* Add BB to cluster C. Sets BB in C->bbs, and preds of BB in C->preds. */
898e4b17023SJohn Marino
899e4b17023SJohn Marino static void
add_bb_to_cluster(bb_cluster c,basic_block bb)900e4b17023SJohn Marino add_bb_to_cluster (bb_cluster c, basic_block bb)
901e4b17023SJohn Marino {
902e4b17023SJohn Marino edge e;
903e4b17023SJohn Marino edge_iterator ei;
904e4b17023SJohn Marino
905e4b17023SJohn Marino bitmap_set_bit (c->bbs, bb->index);
906e4b17023SJohn Marino
907e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds)
908e4b17023SJohn Marino bitmap_set_bit (c->preds, e->src->index);
909e4b17023SJohn Marino
910e4b17023SJohn Marino update_rep_bb (c, bb);
911e4b17023SJohn Marino }
912e4b17023SJohn Marino
913e4b17023SJohn Marino /* Allocate and init new cluster. */
914e4b17023SJohn Marino
915e4b17023SJohn Marino static bb_cluster
new_cluster(void)916e4b17023SJohn Marino new_cluster (void)
917e4b17023SJohn Marino {
918e4b17023SJohn Marino bb_cluster c;
919e4b17023SJohn Marino c = XCNEW (struct bb_cluster_def);
920e4b17023SJohn Marino c->bbs = BITMAP_ALLOC (NULL);
921e4b17023SJohn Marino c->preds = BITMAP_ALLOC (NULL);
922e4b17023SJohn Marino c->rep_bb = NULL;
923e4b17023SJohn Marino return c;
924e4b17023SJohn Marino }
925e4b17023SJohn Marino
926e4b17023SJohn Marino /* Delete clusters. */
927e4b17023SJohn Marino
928e4b17023SJohn Marino static void
delete_cluster(bb_cluster c)929e4b17023SJohn Marino delete_cluster (bb_cluster c)
930e4b17023SJohn Marino {
931e4b17023SJohn Marino if (c == NULL)
932e4b17023SJohn Marino return;
933e4b17023SJohn Marino BITMAP_FREE (c->bbs);
934e4b17023SJohn Marino BITMAP_FREE (c->preds);
935e4b17023SJohn Marino XDELETE (c);
936e4b17023SJohn Marino }
937e4b17023SJohn Marino
938e4b17023SJohn Marino DEF_VEC_P (bb_cluster);
939e4b17023SJohn Marino DEF_VEC_ALLOC_P (bb_cluster, heap);
940e4b17023SJohn Marino
941e4b17023SJohn Marino /* Array that contains all clusters. */
942e4b17023SJohn Marino
VEC(bb_cluster,heap)943e4b17023SJohn Marino static VEC (bb_cluster, heap) *all_clusters;
944e4b17023SJohn Marino
945e4b17023SJohn Marino /* Allocate all cluster vectors. */
946e4b17023SJohn Marino
947e4b17023SJohn Marino static void
948e4b17023SJohn Marino alloc_cluster_vectors (void)
949e4b17023SJohn Marino {
950e4b17023SJohn Marino all_clusters = VEC_alloc (bb_cluster, heap, n_basic_blocks);
951e4b17023SJohn Marino }
952e4b17023SJohn Marino
953e4b17023SJohn Marino /* Reset all cluster vectors. */
954e4b17023SJohn Marino
955e4b17023SJohn Marino static void
reset_cluster_vectors(void)956e4b17023SJohn Marino reset_cluster_vectors (void)
957e4b17023SJohn Marino {
958e4b17023SJohn Marino unsigned int i;
959e4b17023SJohn Marino basic_block bb;
960e4b17023SJohn Marino for (i = 0; i < VEC_length (bb_cluster, all_clusters); ++i)
961e4b17023SJohn Marino delete_cluster (VEC_index (bb_cluster, all_clusters, i));
962e4b17023SJohn Marino VEC_truncate (bb_cluster, all_clusters, 0);
963e4b17023SJohn Marino FOR_EACH_BB (bb)
964e4b17023SJohn Marino BB_CLUSTER (bb) = NULL;
965e4b17023SJohn Marino }
966e4b17023SJohn Marino
967e4b17023SJohn Marino /* Delete all cluster vectors. */
968e4b17023SJohn Marino
969e4b17023SJohn Marino static void
delete_cluster_vectors(void)970e4b17023SJohn Marino delete_cluster_vectors (void)
971e4b17023SJohn Marino {
972e4b17023SJohn Marino unsigned int i;
973e4b17023SJohn Marino for (i = 0; i < VEC_length (bb_cluster, all_clusters); ++i)
974e4b17023SJohn Marino delete_cluster (VEC_index (bb_cluster, all_clusters, i));
975e4b17023SJohn Marino VEC_free (bb_cluster, heap, all_clusters);
976e4b17023SJohn Marino }
977e4b17023SJohn Marino
978e4b17023SJohn Marino /* Merge cluster C2 into C1. */
979e4b17023SJohn Marino
980e4b17023SJohn Marino static void
merge_clusters(bb_cluster c1,bb_cluster c2)981e4b17023SJohn Marino merge_clusters (bb_cluster c1, bb_cluster c2)
982e4b17023SJohn Marino {
983e4b17023SJohn Marino bitmap_ior_into (c1->bbs, c2->bbs);
984e4b17023SJohn Marino bitmap_ior_into (c1->preds, c2->preds);
985e4b17023SJohn Marino }
986e4b17023SJohn Marino
987e4b17023SJohn Marino /* Register equivalence of BB1 and BB2 (members of cluster C). Store c in
988e4b17023SJohn Marino all_clusters, or merge c with existing cluster. */
989e4b17023SJohn Marino
990e4b17023SJohn Marino static void
set_cluster(basic_block bb1,basic_block bb2)991e4b17023SJohn Marino set_cluster (basic_block bb1, basic_block bb2)
992e4b17023SJohn Marino {
993e4b17023SJohn Marino basic_block merge_bb, other_bb;
994e4b17023SJohn Marino bb_cluster merge, old, c;
995e4b17023SJohn Marino
996e4b17023SJohn Marino if (BB_CLUSTER (bb1) == NULL && BB_CLUSTER (bb2) == NULL)
997e4b17023SJohn Marino {
998e4b17023SJohn Marino c = new_cluster ();
999e4b17023SJohn Marino add_bb_to_cluster (c, bb1);
1000e4b17023SJohn Marino add_bb_to_cluster (c, bb2);
1001e4b17023SJohn Marino BB_CLUSTER (bb1) = c;
1002e4b17023SJohn Marino BB_CLUSTER (bb2) = c;
1003e4b17023SJohn Marino c->index = VEC_length (bb_cluster, all_clusters);
1004e4b17023SJohn Marino VEC_safe_push (bb_cluster, heap, all_clusters, c);
1005e4b17023SJohn Marino }
1006e4b17023SJohn Marino else if (BB_CLUSTER (bb1) == NULL || BB_CLUSTER (bb2) == NULL)
1007e4b17023SJohn Marino {
1008e4b17023SJohn Marino merge_bb = BB_CLUSTER (bb1) == NULL ? bb2 : bb1;
1009e4b17023SJohn Marino other_bb = BB_CLUSTER (bb1) == NULL ? bb1 : bb2;
1010e4b17023SJohn Marino merge = BB_CLUSTER (merge_bb);
1011e4b17023SJohn Marino add_bb_to_cluster (merge, other_bb);
1012e4b17023SJohn Marino BB_CLUSTER (other_bb) = merge;
1013e4b17023SJohn Marino }
1014e4b17023SJohn Marino else if (BB_CLUSTER (bb1) != BB_CLUSTER (bb2))
1015e4b17023SJohn Marino {
1016e4b17023SJohn Marino unsigned int i;
1017e4b17023SJohn Marino bitmap_iterator bi;
1018e4b17023SJohn Marino
1019e4b17023SJohn Marino old = BB_CLUSTER (bb2);
1020e4b17023SJohn Marino merge = BB_CLUSTER (bb1);
1021e4b17023SJohn Marino merge_clusters (merge, old);
1022e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (old->bbs, 0, i, bi)
1023e4b17023SJohn Marino BB_CLUSTER (BASIC_BLOCK (i)) = merge;
1024e4b17023SJohn Marino VEC_replace (bb_cluster, all_clusters, old->index, NULL);
1025e4b17023SJohn Marino update_rep_bb (merge, old->rep_bb);
1026e4b17023SJohn Marino delete_cluster (old);
1027e4b17023SJohn Marino }
1028e4b17023SJohn Marino else
1029e4b17023SJohn Marino gcc_unreachable ();
1030e4b17023SJohn Marino }
1031e4b17023SJohn Marino
1032e4b17023SJohn Marino /* Return true if gimple statements S1 and S2 are equal. Gimple_bb (s1) and
1033e4b17023SJohn Marino gimple_bb (s2) are members of SAME_SUCC. */
1034e4b17023SJohn Marino
1035e4b17023SJohn Marino static bool
gimple_equal_p(same_succ same_succ,gimple s1,gimple s2)1036e4b17023SJohn Marino gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
1037e4b17023SJohn Marino {
1038e4b17023SJohn Marino unsigned int i;
1039e4b17023SJohn Marino tree lhs1, lhs2;
1040e4b17023SJohn Marino basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
1041e4b17023SJohn Marino tree t1, t2;
1042e4b17023SJohn Marino bool equal, inv_cond;
1043e4b17023SJohn Marino enum tree_code code1, code2;
1044e4b17023SJohn Marino
1045e4b17023SJohn Marino if (gimple_code (s1) != gimple_code (s2))
1046e4b17023SJohn Marino return false;
1047e4b17023SJohn Marino
1048e4b17023SJohn Marino switch (gimple_code (s1))
1049e4b17023SJohn Marino {
1050e4b17023SJohn Marino case GIMPLE_CALL:
1051e4b17023SJohn Marino if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
1052e4b17023SJohn Marino return false;
1053e4b17023SJohn Marino if (!gimple_call_same_target_p (s1, s2))
1054e4b17023SJohn Marino return false;
1055e4b17023SJohn Marino
1056e4b17023SJohn Marino /* Eventually, we'll significantly complicate the CFG by adding
1057e4b17023SJohn Marino back edges to properly model the effects of transaction restart.
1058e4b17023SJohn Marino For the bulk of optimization this does not matter, but what we
1059e4b17023SJohn Marino cannot recover from is tail merging blocks between two separate
1060e4b17023SJohn Marino transactions. Avoid that by making commit not match. */
1061e4b17023SJohn Marino if (gimple_call_builtin_p (s1, BUILT_IN_TM_COMMIT))
1062e4b17023SJohn Marino return false;
1063e4b17023SJohn Marino
1064e4b17023SJohn Marino equal = true;
1065e4b17023SJohn Marino for (i = 0; i < gimple_call_num_args (s1); ++i)
1066e4b17023SJohn Marino {
1067e4b17023SJohn Marino t1 = gimple_call_arg (s1, i);
1068e4b17023SJohn Marino t2 = gimple_call_arg (s2, i);
1069e4b17023SJohn Marino if (operand_equal_p (t1, t2, 0))
1070e4b17023SJohn Marino continue;
1071e4b17023SJohn Marino if (gvn_uses_equal (t1, t2))
1072e4b17023SJohn Marino continue;
1073e4b17023SJohn Marino equal = false;
1074e4b17023SJohn Marino break;
1075e4b17023SJohn Marino }
1076e4b17023SJohn Marino if (!equal)
1077e4b17023SJohn Marino return false;
1078e4b17023SJohn Marino
1079e4b17023SJohn Marino lhs1 = gimple_get_lhs (s1);
1080e4b17023SJohn Marino lhs2 = gimple_get_lhs (s2);
1081e4b17023SJohn Marino if (lhs1 == NULL_TREE && lhs2 == NULL_TREE)
1082e4b17023SJohn Marino return true;
1083e4b17023SJohn Marino if (lhs1 == NULL_TREE || lhs2 == NULL_TREE)
1084e4b17023SJohn Marino return false;
1085e4b17023SJohn Marino if (TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME)
1086e4b17023SJohn Marino return vn_valueize (lhs1) == vn_valueize (lhs2);
1087e4b17023SJohn Marino return operand_equal_p (lhs1, lhs2, 0);
1088e4b17023SJohn Marino
1089e4b17023SJohn Marino case GIMPLE_ASSIGN:
1090e4b17023SJohn Marino lhs1 = gimple_get_lhs (s1);
1091e4b17023SJohn Marino lhs2 = gimple_get_lhs (s2);
1092e4b17023SJohn Marino return (TREE_CODE (lhs1) == SSA_NAME
1093e4b17023SJohn Marino && TREE_CODE (lhs2) == SSA_NAME
1094e4b17023SJohn Marino && vn_valueize (lhs1) == vn_valueize (lhs2));
1095e4b17023SJohn Marino
1096e4b17023SJohn Marino case GIMPLE_COND:
1097e4b17023SJohn Marino t1 = gimple_cond_lhs (s1);
1098e4b17023SJohn Marino t2 = gimple_cond_lhs (s2);
1099e4b17023SJohn Marino if (!operand_equal_p (t1, t2, 0)
1100e4b17023SJohn Marino && !gvn_uses_equal (t1, t2))
1101e4b17023SJohn Marino return false;
1102e4b17023SJohn Marino
1103e4b17023SJohn Marino t1 = gimple_cond_rhs (s1);
1104e4b17023SJohn Marino t2 = gimple_cond_rhs (s2);
1105e4b17023SJohn Marino if (!operand_equal_p (t1, t2, 0)
1106e4b17023SJohn Marino && !gvn_uses_equal (t1, t2))
1107e4b17023SJohn Marino return false;
1108e4b17023SJohn Marino
1109e4b17023SJohn Marino code1 = gimple_expr_code (s1);
1110e4b17023SJohn Marino code2 = gimple_expr_code (s2);
1111e4b17023SJohn Marino inv_cond = (bitmap_bit_p (same_succ->inverse, bb1->index)
1112e4b17023SJohn Marino != bitmap_bit_p (same_succ->inverse, bb2->index));
1113e4b17023SJohn Marino if (inv_cond)
1114e4b17023SJohn Marino {
1115e4b17023SJohn Marino bool honor_nans
1116e4b17023SJohn Marino = HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (s1))));
1117e4b17023SJohn Marino code2 = invert_tree_comparison (code2, honor_nans);
1118e4b17023SJohn Marino }
1119e4b17023SJohn Marino return code1 == code2;
1120e4b17023SJohn Marino
1121e4b17023SJohn Marino default:
1122e4b17023SJohn Marino return false;
1123e4b17023SJohn Marino }
1124e4b17023SJohn Marino }
1125e4b17023SJohn Marino
1126e4b17023SJohn Marino /* Let GSI skip backwards over local defs. Return the earliest vuse in VUSE.
1127e4b17023SJohn Marino Return true in VUSE_ESCAPED if the vuse influenced a SSA_OP_DEF of one of the
1128e4b17023SJohn Marino processed statements. */
1129e4b17023SJohn Marino
1130e4b17023SJohn Marino static void
gsi_advance_bw_nondebug_nonlocal(gimple_stmt_iterator * gsi,tree * vuse,bool * vuse_escaped)1131e4b17023SJohn Marino gsi_advance_bw_nondebug_nonlocal (gimple_stmt_iterator *gsi, tree *vuse,
1132e4b17023SJohn Marino bool *vuse_escaped)
1133e4b17023SJohn Marino {
1134e4b17023SJohn Marino gimple stmt;
1135e4b17023SJohn Marino tree lvuse;
1136e4b17023SJohn Marino
1137e4b17023SJohn Marino while (true)
1138e4b17023SJohn Marino {
1139e4b17023SJohn Marino if (gsi_end_p (*gsi))
1140e4b17023SJohn Marino return;
1141e4b17023SJohn Marino stmt = gsi_stmt (*gsi);
1142e4b17023SJohn Marino
1143e4b17023SJohn Marino lvuse = gimple_vuse (stmt);
1144e4b17023SJohn Marino if (lvuse != NULL_TREE)
1145e4b17023SJohn Marino {
1146e4b17023SJohn Marino *vuse = lvuse;
1147e4b17023SJohn Marino if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_DEF))
1148e4b17023SJohn Marino *vuse_escaped = true;
1149e4b17023SJohn Marino }
1150e4b17023SJohn Marino
1151e4b17023SJohn Marino if (!(is_gimple_assign (stmt) && local_def (gimple_get_lhs (stmt))
1152e4b17023SJohn Marino && !gimple_has_side_effects (stmt)))
1153e4b17023SJohn Marino return;
1154e4b17023SJohn Marino gsi_prev_nondebug (gsi);
1155e4b17023SJohn Marino }
1156e4b17023SJohn Marino }
1157e4b17023SJohn Marino
1158e4b17023SJohn Marino /* Determines whether BB1 and BB2 (members of same_succ) are duplicates. If so,
1159e4b17023SJohn Marino clusters them. */
1160e4b17023SJohn Marino
1161e4b17023SJohn Marino static void
find_duplicate(same_succ same_succ,basic_block bb1,basic_block bb2)1162e4b17023SJohn Marino find_duplicate (same_succ same_succ, basic_block bb1, basic_block bb2)
1163e4b17023SJohn Marino {
1164e4b17023SJohn Marino gimple_stmt_iterator gsi1 = gsi_last_nondebug_bb (bb1);
1165e4b17023SJohn Marino gimple_stmt_iterator gsi2 = gsi_last_nondebug_bb (bb2);
1166e4b17023SJohn Marino tree vuse1 = NULL_TREE, vuse2 = NULL_TREE;
1167e4b17023SJohn Marino bool vuse_escaped = false;
1168e4b17023SJohn Marino
1169e4b17023SJohn Marino gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped);
1170e4b17023SJohn Marino gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
1171e4b17023SJohn Marino
1172e4b17023SJohn Marino while (!gsi_end_p (gsi1) && !gsi_end_p (gsi2))
1173e4b17023SJohn Marino {
1174e4b17023SJohn Marino if (!gimple_equal_p (same_succ, gsi_stmt (gsi1), gsi_stmt (gsi2)))
1175e4b17023SJohn Marino return;
1176e4b17023SJohn Marino
1177e4b17023SJohn Marino gsi_prev_nondebug (&gsi1);
1178e4b17023SJohn Marino gsi_prev_nondebug (&gsi2);
1179e4b17023SJohn Marino gsi_advance_bw_nondebug_nonlocal (&gsi1, &vuse1, &vuse_escaped);
1180e4b17023SJohn Marino gsi_advance_bw_nondebug_nonlocal (&gsi2, &vuse2, &vuse_escaped);
1181e4b17023SJohn Marino }
1182e4b17023SJohn Marino
1183e4b17023SJohn Marino if (!(gsi_end_p (gsi1) && gsi_end_p (gsi2)))
1184e4b17023SJohn Marino return;
1185e4b17023SJohn Marino
1186e4b17023SJohn Marino /* If the incoming vuses are not the same, and the vuse escaped into an
1187e4b17023SJohn Marino SSA_OP_DEF, then merging the 2 blocks will change the value of the def,
1188e4b17023SJohn Marino which potentially means the semantics of one of the blocks will be changed.
1189e4b17023SJohn Marino TODO: make this check more precise. */
1190e4b17023SJohn Marino if (vuse_escaped && vuse1 != vuse2)
1191e4b17023SJohn Marino return;
1192e4b17023SJohn Marino
1193e4b17023SJohn Marino if (dump_file)
1194e4b17023SJohn Marino fprintf (dump_file, "find_duplicates: <bb %d> duplicate of <bb %d>\n",
1195e4b17023SJohn Marino bb1->index, bb2->index);
1196e4b17023SJohn Marino
1197e4b17023SJohn Marino set_cluster (bb1, bb2);
1198e4b17023SJohn Marino }
1199e4b17023SJohn Marino
1200e4b17023SJohn Marino /* Returns whether for all phis in DEST the phi alternatives for E1 and
1201e4b17023SJohn Marino E2 are equal. */
1202e4b17023SJohn Marino
1203e4b17023SJohn Marino static bool
same_phi_alternatives_1(basic_block dest,edge e1,edge e2)1204e4b17023SJohn Marino same_phi_alternatives_1 (basic_block dest, edge e1, edge e2)
1205e4b17023SJohn Marino {
1206e4b17023SJohn Marino int n1 = e1->dest_idx, n2 = e2->dest_idx;
1207e4b17023SJohn Marino gimple_stmt_iterator gsi;
1208e4b17023SJohn Marino
1209e4b17023SJohn Marino for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
1210e4b17023SJohn Marino {
1211e4b17023SJohn Marino gimple phi = gsi_stmt (gsi);
1212e4b17023SJohn Marino tree lhs = gimple_phi_result (phi);
1213e4b17023SJohn Marino tree val1 = gimple_phi_arg_def (phi, n1);
1214e4b17023SJohn Marino tree val2 = gimple_phi_arg_def (phi, n2);
1215e4b17023SJohn Marino
1216e4b17023SJohn Marino if (!is_gimple_reg (lhs))
1217e4b17023SJohn Marino continue;
1218e4b17023SJohn Marino
1219e4b17023SJohn Marino if (operand_equal_for_phi_arg_p (val1, val2))
1220e4b17023SJohn Marino continue;
1221e4b17023SJohn Marino if (gvn_uses_equal (val1, val2))
1222e4b17023SJohn Marino continue;
1223e4b17023SJohn Marino
1224e4b17023SJohn Marino return false;
1225e4b17023SJohn Marino }
1226e4b17023SJohn Marino
1227e4b17023SJohn Marino return true;
1228e4b17023SJohn Marino }
1229e4b17023SJohn Marino
1230e4b17023SJohn Marino /* Returns whether for all successors of BB1 and BB2 (members of SAME_SUCC), the
1231e4b17023SJohn Marino phi alternatives for BB1 and BB2 are equal. */
1232e4b17023SJohn Marino
1233e4b17023SJohn Marino static bool
same_phi_alternatives(same_succ same_succ,basic_block bb1,basic_block bb2)1234e4b17023SJohn Marino same_phi_alternatives (same_succ same_succ, basic_block bb1, basic_block bb2)
1235e4b17023SJohn Marino {
1236e4b17023SJohn Marino unsigned int s;
1237e4b17023SJohn Marino bitmap_iterator bs;
1238e4b17023SJohn Marino edge e1, e2;
1239e4b17023SJohn Marino basic_block succ;
1240e4b17023SJohn Marino
1241e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (same_succ->succs, 0, s, bs)
1242e4b17023SJohn Marino {
1243e4b17023SJohn Marino succ = BASIC_BLOCK (s);
1244e4b17023SJohn Marino e1 = find_edge (bb1, succ);
1245e4b17023SJohn Marino e2 = find_edge (bb2, succ);
1246e4b17023SJohn Marino if (e1->flags & EDGE_COMPLEX
1247e4b17023SJohn Marino || e2->flags & EDGE_COMPLEX)
1248e4b17023SJohn Marino return false;
1249e4b17023SJohn Marino
1250e4b17023SJohn Marino /* For all phis in bb, the phi alternatives for e1 and e2 need to have
1251e4b17023SJohn Marino the same value. */
1252e4b17023SJohn Marino if (!same_phi_alternatives_1 (succ, e1, e2))
1253e4b17023SJohn Marino return false;
1254e4b17023SJohn Marino }
1255e4b17023SJohn Marino
1256e4b17023SJohn Marino return true;
1257e4b17023SJohn Marino }
1258e4b17023SJohn Marino
1259e4b17023SJohn Marino /* Return true if BB has non-vop phis. */
1260e4b17023SJohn Marino
1261e4b17023SJohn Marino static bool
bb_has_non_vop_phi(basic_block bb)1262e4b17023SJohn Marino bb_has_non_vop_phi (basic_block bb)
1263e4b17023SJohn Marino {
1264e4b17023SJohn Marino gimple_seq phis = phi_nodes (bb);
1265e4b17023SJohn Marino gimple phi;
1266e4b17023SJohn Marino
1267e4b17023SJohn Marino if (phis == NULL)
1268e4b17023SJohn Marino return false;
1269e4b17023SJohn Marino
1270e4b17023SJohn Marino if (!gimple_seq_singleton_p (phis))
1271e4b17023SJohn Marino return true;
1272e4b17023SJohn Marino
1273e4b17023SJohn Marino phi = gimple_seq_first_stmt (phis);
1274e4b17023SJohn Marino return is_gimple_reg (gimple_phi_result (phi));
1275e4b17023SJohn Marino }
1276e4b17023SJohn Marino
1277e4b17023SJohn Marino /* Returns true if redirecting the incoming edges of FROM to TO maintains the
1278e4b17023SJohn Marino invariant that uses in FROM are dominates by their defs. */
1279e4b17023SJohn Marino
1280e4b17023SJohn Marino static bool
deps_ok_for_redirect_from_bb_to_bb(basic_block from,basic_block to)1281e4b17023SJohn Marino deps_ok_for_redirect_from_bb_to_bb (basic_block from, basic_block to)
1282e4b17023SJohn Marino {
1283e4b17023SJohn Marino basic_block cd, dep_bb = BB_DEP_BB (to);
1284e4b17023SJohn Marino edge_iterator ei;
1285e4b17023SJohn Marino edge e;
1286e4b17023SJohn Marino bitmap from_preds = BITMAP_ALLOC (NULL);
1287e4b17023SJohn Marino
1288e4b17023SJohn Marino if (dep_bb == NULL)
1289e4b17023SJohn Marino return true;
1290e4b17023SJohn Marino
1291e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, from->preds)
1292e4b17023SJohn Marino bitmap_set_bit (from_preds, e->src->index);
1293e4b17023SJohn Marino cd = nearest_common_dominator_for_set (CDI_DOMINATORS, from_preds);
1294e4b17023SJohn Marino BITMAP_FREE (from_preds);
1295e4b17023SJohn Marino
1296e4b17023SJohn Marino return dominated_by_p (CDI_DOMINATORS, dep_bb, cd);
1297e4b17023SJohn Marino }
1298e4b17023SJohn Marino
1299e4b17023SJohn Marino /* Returns true if replacing BB1 (or its replacement bb) by BB2 (or its
1300e4b17023SJohn Marino replacement bb) and vice versa maintains the invariant that uses in the
1301e4b17023SJohn Marino replacement are dominates by their defs. */
1302e4b17023SJohn Marino
1303e4b17023SJohn Marino static bool
deps_ok_for_redirect(basic_block bb1,basic_block bb2)1304e4b17023SJohn Marino deps_ok_for_redirect (basic_block bb1, basic_block bb2)
1305e4b17023SJohn Marino {
1306e4b17023SJohn Marino if (BB_CLUSTER (bb1) != NULL)
1307e4b17023SJohn Marino bb1 = BB_CLUSTER (bb1)->rep_bb;
1308e4b17023SJohn Marino
1309e4b17023SJohn Marino if (BB_CLUSTER (bb2) != NULL)
1310e4b17023SJohn Marino bb2 = BB_CLUSTER (bb2)->rep_bb;
1311e4b17023SJohn Marino
1312e4b17023SJohn Marino return (deps_ok_for_redirect_from_bb_to_bb (bb1, bb2)
1313e4b17023SJohn Marino && deps_ok_for_redirect_from_bb_to_bb (bb2, bb1));
1314e4b17023SJohn Marino }
1315e4b17023SJohn Marino
1316e4b17023SJohn Marino /* Within SAME_SUCC->bbs, find clusters of bbs which can be merged. */
1317e4b17023SJohn Marino
1318e4b17023SJohn Marino static void
find_clusters_1(same_succ same_succ)1319e4b17023SJohn Marino find_clusters_1 (same_succ same_succ)
1320e4b17023SJohn Marino {
1321e4b17023SJohn Marino basic_block bb1, bb2;
1322e4b17023SJohn Marino unsigned int i, j;
1323e4b17023SJohn Marino bitmap_iterator bi, bj;
1324e4b17023SJohn Marino int nr_comparisons;
1325e4b17023SJohn Marino int max_comparisons = PARAM_VALUE (PARAM_MAX_TAIL_MERGE_COMPARISONS);
1326e4b17023SJohn Marino
1327e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (same_succ->bbs, 0, i, bi)
1328e4b17023SJohn Marino {
1329e4b17023SJohn Marino bb1 = BASIC_BLOCK (i);
1330e4b17023SJohn Marino
1331e4b17023SJohn Marino /* TODO: handle blocks with phi-nodes. We'll have to find corresponding
1332e4b17023SJohn Marino phi-nodes in bb1 and bb2, with the same alternatives for the same
1333e4b17023SJohn Marino preds. */
1334e4b17023SJohn Marino if (bb_has_non_vop_phi (bb1))
1335e4b17023SJohn Marino continue;
1336e4b17023SJohn Marino
1337e4b17023SJohn Marino nr_comparisons = 0;
1338e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (same_succ->bbs, i + 1, j, bj)
1339e4b17023SJohn Marino {
1340e4b17023SJohn Marino bb2 = BASIC_BLOCK (j);
1341e4b17023SJohn Marino
1342e4b17023SJohn Marino if (bb_has_non_vop_phi (bb2))
1343e4b17023SJohn Marino continue;
1344e4b17023SJohn Marino
1345e4b17023SJohn Marino if (BB_CLUSTER (bb1) != NULL && BB_CLUSTER (bb1) == BB_CLUSTER (bb2))
1346e4b17023SJohn Marino continue;
1347e4b17023SJohn Marino
1348e4b17023SJohn Marino /* Limit quadratic behaviour. */
1349e4b17023SJohn Marino nr_comparisons++;
1350e4b17023SJohn Marino if (nr_comparisons > max_comparisons)
1351e4b17023SJohn Marino break;
1352e4b17023SJohn Marino
1353e4b17023SJohn Marino /* This is a conservative dependency check. We could test more
1354e4b17023SJohn Marino precise for allowed replacement direction. */
1355e4b17023SJohn Marino if (!deps_ok_for_redirect (bb1, bb2))
1356e4b17023SJohn Marino continue;
1357e4b17023SJohn Marino
1358e4b17023SJohn Marino if (!(same_phi_alternatives (same_succ, bb1, bb2)))
1359e4b17023SJohn Marino continue;
1360e4b17023SJohn Marino
1361e4b17023SJohn Marino find_duplicate (same_succ, bb1, bb2);
1362e4b17023SJohn Marino }
1363e4b17023SJohn Marino }
1364e4b17023SJohn Marino }
1365e4b17023SJohn Marino
1366e4b17023SJohn Marino /* Find clusters of bbs which can be merged. */
1367e4b17023SJohn Marino
1368e4b17023SJohn Marino static void
find_clusters(void)1369e4b17023SJohn Marino find_clusters (void)
1370e4b17023SJohn Marino {
1371e4b17023SJohn Marino same_succ same;
1372e4b17023SJohn Marino
1373e4b17023SJohn Marino while (!VEC_empty (same_succ, worklist))
1374e4b17023SJohn Marino {
1375e4b17023SJohn Marino same = VEC_pop (same_succ, worklist);
1376e4b17023SJohn Marino same->in_worklist = false;
1377e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
1378e4b17023SJohn Marino {
1379e4b17023SJohn Marino fprintf (dump_file, "processing worklist entry\n");
1380e4b17023SJohn Marino same_succ_print (dump_file, same);
1381e4b17023SJohn Marino }
1382e4b17023SJohn Marino find_clusters_1 (same);
1383e4b17023SJohn Marino }
1384e4b17023SJohn Marino }
1385e4b17023SJohn Marino
1386e4b17023SJohn Marino /* Returns the vop phi of BB, if any. */
1387e4b17023SJohn Marino
1388e4b17023SJohn Marino static gimple
vop_phi(basic_block bb)1389e4b17023SJohn Marino vop_phi (basic_block bb)
1390e4b17023SJohn Marino {
1391e4b17023SJohn Marino gimple stmt;
1392e4b17023SJohn Marino gimple_stmt_iterator gsi;
1393e4b17023SJohn Marino for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1394e4b17023SJohn Marino {
1395e4b17023SJohn Marino stmt = gsi_stmt (gsi);
1396e4b17023SJohn Marino if (is_gimple_reg (gimple_phi_result (stmt)))
1397e4b17023SJohn Marino continue;
1398e4b17023SJohn Marino return stmt;
1399e4b17023SJohn Marino }
1400e4b17023SJohn Marino return NULL;
1401e4b17023SJohn Marino }
1402e4b17023SJohn Marino
1403e4b17023SJohn Marino /* Redirect all edges from BB1 to BB2, removes BB1 and marks it as removed. */
1404e4b17023SJohn Marino
1405e4b17023SJohn Marino static void
replace_block_by(basic_block bb1,basic_block bb2)1406e4b17023SJohn Marino replace_block_by (basic_block bb1, basic_block bb2)
1407e4b17023SJohn Marino {
1408e4b17023SJohn Marino edge pred_edge;
1409e4b17023SJohn Marino unsigned int i;
1410e4b17023SJohn Marino gimple bb2_phi;
1411e4b17023SJohn Marino
1412e4b17023SJohn Marino bb2_phi = vop_phi (bb2);
1413e4b17023SJohn Marino
1414e4b17023SJohn Marino /* Mark the basic block as deleted. */
1415e4b17023SJohn Marino mark_basic_block_deleted (bb1);
1416e4b17023SJohn Marino
1417e4b17023SJohn Marino /* Redirect the incoming edges of bb1 to bb2. */
1418e4b17023SJohn Marino for (i = EDGE_COUNT (bb1->preds); i > 0 ; --i)
1419e4b17023SJohn Marino {
1420e4b17023SJohn Marino pred_edge = EDGE_PRED (bb1, i - 1);
1421e4b17023SJohn Marino pred_edge = redirect_edge_and_branch (pred_edge, bb2);
1422e4b17023SJohn Marino gcc_assert (pred_edge != NULL);
1423e4b17023SJohn Marino
1424e4b17023SJohn Marino if (bb2_phi == NULL)
1425e4b17023SJohn Marino continue;
1426e4b17023SJohn Marino
1427e4b17023SJohn Marino /* The phi might have run out of capacity when the redirect added an
1428e4b17023SJohn Marino argument, which means it could have been replaced. Refresh it. */
1429e4b17023SJohn Marino bb2_phi = vop_phi (bb2);
1430e4b17023SJohn Marino
1431e4b17023SJohn Marino add_phi_arg (bb2_phi, SSA_NAME_VAR (gimple_phi_result (bb2_phi)),
1432e4b17023SJohn Marino pred_edge, UNKNOWN_LOCATION);
1433e4b17023SJohn Marino }
1434e4b17023SJohn Marino
1435e4b17023SJohn Marino bb2->frequency += bb1->frequency;
1436e4b17023SJohn Marino if (bb2->frequency > BB_FREQ_MAX)
1437e4b17023SJohn Marino bb2->frequency = BB_FREQ_MAX;
1438e4b17023SJohn Marino bb1->frequency = 0;
1439e4b17023SJohn Marino
1440e4b17023SJohn Marino /* Do updates that use bb1, before deleting bb1. */
1441e4b17023SJohn Marino release_last_vdef (bb1);
1442e4b17023SJohn Marino same_succ_flush_bb (bb1);
1443e4b17023SJohn Marino
1444e4b17023SJohn Marino delete_basic_block (bb1);
1445e4b17023SJohn Marino }
1446e4b17023SJohn Marino
1447e4b17023SJohn Marino /* Bbs for which update_debug_stmt need to be called. */
1448e4b17023SJohn Marino
1449e4b17023SJohn Marino static bitmap update_bbs;
1450e4b17023SJohn Marino
1451e4b17023SJohn Marino /* For each cluster in all_clusters, merge all cluster->bbs. Returns
1452e4b17023SJohn Marino number of bbs removed. */
1453e4b17023SJohn Marino
1454e4b17023SJohn Marino static int
apply_clusters(void)1455e4b17023SJohn Marino apply_clusters (void)
1456e4b17023SJohn Marino {
1457e4b17023SJohn Marino basic_block bb1, bb2;
1458e4b17023SJohn Marino bb_cluster c;
1459e4b17023SJohn Marino unsigned int i, j;
1460e4b17023SJohn Marino bitmap_iterator bj;
1461e4b17023SJohn Marino int nr_bbs_removed = 0;
1462e4b17023SJohn Marino
1463e4b17023SJohn Marino for (i = 0; i < VEC_length (bb_cluster, all_clusters); ++i)
1464e4b17023SJohn Marino {
1465e4b17023SJohn Marino c = VEC_index (bb_cluster, all_clusters, i);
1466e4b17023SJohn Marino if (c == NULL)
1467e4b17023SJohn Marino continue;
1468e4b17023SJohn Marino
1469e4b17023SJohn Marino bb2 = c->rep_bb;
1470e4b17023SJohn Marino bitmap_set_bit (update_bbs, bb2->index);
1471e4b17023SJohn Marino
1472e4b17023SJohn Marino bitmap_clear_bit (c->bbs, bb2->index);
1473e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (c->bbs, 0, j, bj)
1474e4b17023SJohn Marino {
1475e4b17023SJohn Marino bb1 = BASIC_BLOCK (j);
1476e4b17023SJohn Marino bitmap_clear_bit (update_bbs, bb1->index);
1477e4b17023SJohn Marino
1478e4b17023SJohn Marino replace_block_by (bb1, bb2);
1479e4b17023SJohn Marino nr_bbs_removed++;
1480e4b17023SJohn Marino }
1481e4b17023SJohn Marino }
1482e4b17023SJohn Marino
1483e4b17023SJohn Marino return nr_bbs_removed;
1484e4b17023SJohn Marino }
1485e4b17023SJohn Marino
1486e4b17023SJohn Marino /* Resets debug statement STMT if it has uses that are not dominated by their
1487e4b17023SJohn Marino defs. */
1488e4b17023SJohn Marino
1489e4b17023SJohn Marino static void
update_debug_stmt(gimple stmt)1490e4b17023SJohn Marino update_debug_stmt (gimple stmt)
1491e4b17023SJohn Marino {
1492e4b17023SJohn Marino use_operand_p use_p;
1493e4b17023SJohn Marino ssa_op_iter oi;
1494e4b17023SJohn Marino basic_block bbdef, bbuse;
1495e4b17023SJohn Marino gimple def_stmt;
1496e4b17023SJohn Marino tree name;
1497e4b17023SJohn Marino
1498e4b17023SJohn Marino if (!gimple_debug_bind_p (stmt))
1499e4b17023SJohn Marino return;
1500e4b17023SJohn Marino
1501e4b17023SJohn Marino bbuse = gimple_bb (stmt);
1502e4b17023SJohn Marino FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, oi, SSA_OP_USE)
1503e4b17023SJohn Marino {
1504e4b17023SJohn Marino name = USE_FROM_PTR (use_p);
1505e4b17023SJohn Marino gcc_assert (TREE_CODE (name) == SSA_NAME);
1506e4b17023SJohn Marino
1507e4b17023SJohn Marino def_stmt = SSA_NAME_DEF_STMT (name);
1508e4b17023SJohn Marino gcc_assert (def_stmt != NULL);
1509e4b17023SJohn Marino
1510e4b17023SJohn Marino bbdef = gimple_bb (def_stmt);
1511e4b17023SJohn Marino if (bbdef == NULL || bbuse == bbdef
1512e4b17023SJohn Marino || dominated_by_p (CDI_DOMINATORS, bbuse, bbdef))
1513e4b17023SJohn Marino continue;
1514e4b17023SJohn Marino
1515e4b17023SJohn Marino gimple_debug_bind_reset_value (stmt);
1516e4b17023SJohn Marino update_stmt (stmt);
1517e4b17023SJohn Marino }
1518e4b17023SJohn Marino }
1519e4b17023SJohn Marino
1520e4b17023SJohn Marino /* Resets all debug statements that have uses that are not
1521e4b17023SJohn Marino dominated by their defs. */
1522e4b17023SJohn Marino
1523e4b17023SJohn Marino static void
update_debug_stmts(void)1524e4b17023SJohn Marino update_debug_stmts (void)
1525e4b17023SJohn Marino {
1526e4b17023SJohn Marino basic_block bb;
1527e4b17023SJohn Marino bitmap_iterator bi;
1528e4b17023SJohn Marino unsigned int i;
1529e4b17023SJohn Marino
1530e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (update_bbs, 0, i, bi)
1531e4b17023SJohn Marino {
1532e4b17023SJohn Marino gimple stmt;
1533e4b17023SJohn Marino gimple_stmt_iterator gsi;
1534e4b17023SJohn Marino
1535e4b17023SJohn Marino bb = BASIC_BLOCK (i);
1536e4b17023SJohn Marino for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1537e4b17023SJohn Marino {
1538e4b17023SJohn Marino stmt = gsi_stmt (gsi);
1539e4b17023SJohn Marino if (!is_gimple_debug (stmt))
1540e4b17023SJohn Marino continue;
1541e4b17023SJohn Marino update_debug_stmt (stmt);
1542e4b17023SJohn Marino }
1543e4b17023SJohn Marino }
1544e4b17023SJohn Marino }
1545e4b17023SJohn Marino
1546e4b17023SJohn Marino /* Runs tail merge optimization. */
1547e4b17023SJohn Marino
1548e4b17023SJohn Marino unsigned int
tail_merge_optimize(unsigned int todo)1549e4b17023SJohn Marino tail_merge_optimize (unsigned int todo)
1550e4b17023SJohn Marino {
1551e4b17023SJohn Marino int nr_bbs_removed_total = 0;
1552e4b17023SJohn Marino int nr_bbs_removed;
1553e4b17023SJohn Marino bool loop_entered = false;
1554e4b17023SJohn Marino int iteration_nr = 0;
1555e4b17023SJohn Marino int max_iterations = PARAM_VALUE (PARAM_MAX_TAIL_MERGE_ITERATIONS);
1556e4b17023SJohn Marino
1557e4b17023SJohn Marino if (!flag_tree_tail_merge || max_iterations == 0)
1558e4b17023SJohn Marino return 0;
1559e4b17023SJohn Marino
1560e4b17023SJohn Marino timevar_push (TV_TREE_TAIL_MERGE);
1561e4b17023SJohn Marino
1562*5ce9237cSJohn Marino if (!dom_info_available_p (CDI_DOMINATORS))
1563*5ce9237cSJohn Marino {
1564*5ce9237cSJohn Marino /* PRE can leave us with unreachable blocks, remove them now. */
1565*5ce9237cSJohn Marino delete_unreachable_blocks ();
1566e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
1567*5ce9237cSJohn Marino }
1568e4b17023SJohn Marino init_worklist ();
1569e4b17023SJohn Marino
1570e4b17023SJohn Marino while (!VEC_empty (same_succ, worklist))
1571e4b17023SJohn Marino {
1572e4b17023SJohn Marino if (!loop_entered)
1573e4b17023SJohn Marino {
1574e4b17023SJohn Marino loop_entered = true;
1575e4b17023SJohn Marino alloc_cluster_vectors ();
1576e4b17023SJohn Marino update_bbs = BITMAP_ALLOC (NULL);
1577e4b17023SJohn Marino }
1578e4b17023SJohn Marino else
1579e4b17023SJohn Marino reset_cluster_vectors ();
1580e4b17023SJohn Marino
1581e4b17023SJohn Marino iteration_nr++;
1582e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
1583e4b17023SJohn Marino fprintf (dump_file, "worklist iteration #%d\n", iteration_nr);
1584e4b17023SJohn Marino
1585e4b17023SJohn Marino find_clusters ();
1586e4b17023SJohn Marino gcc_assert (VEC_empty (same_succ, worklist));
1587e4b17023SJohn Marino if (VEC_empty (bb_cluster, all_clusters))
1588e4b17023SJohn Marino break;
1589e4b17023SJohn Marino
1590e4b17023SJohn Marino nr_bbs_removed = apply_clusters ();
1591e4b17023SJohn Marino nr_bbs_removed_total += nr_bbs_removed;
1592e4b17023SJohn Marino if (nr_bbs_removed == 0)
1593e4b17023SJohn Marino break;
1594e4b17023SJohn Marino
1595e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS);
1596e4b17023SJohn Marino
1597e4b17023SJohn Marino if (iteration_nr == max_iterations)
1598e4b17023SJohn Marino break;
1599e4b17023SJohn Marino
1600e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
1601e4b17023SJohn Marino update_worklist ();
1602e4b17023SJohn Marino }
1603e4b17023SJohn Marino
1604e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
1605e4b17023SJohn Marino fprintf (dump_file, "htab collision / search: %f\n",
1606e4b17023SJohn Marino htab_collisions (same_succ_htab));
1607e4b17023SJohn Marino
1608e4b17023SJohn Marino if (nr_bbs_removed_total > 0)
1609e4b17023SJohn Marino {
1610e4b17023SJohn Marino if (MAY_HAVE_DEBUG_STMTS)
1611e4b17023SJohn Marino {
1612e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
1613e4b17023SJohn Marino update_debug_stmts ();
1614e4b17023SJohn Marino }
1615e4b17023SJohn Marino
1616e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
1617e4b17023SJohn Marino {
1618e4b17023SJohn Marino fprintf (dump_file, "Before TODOs.\n");
1619e4b17023SJohn Marino dump_function_to_file (current_function_decl, dump_file, dump_flags);
1620e4b17023SJohn Marino }
1621e4b17023SJohn Marino
1622e4b17023SJohn Marino todo |= (TODO_verify_ssa | TODO_verify_stmts | TODO_verify_flow
1623e4b17023SJohn Marino | TODO_dump_func);
1624e4b17023SJohn Marino mark_sym_for_renaming (gimple_vop (cfun));
1625e4b17023SJohn Marino }
1626e4b17023SJohn Marino
1627e4b17023SJohn Marino delete_worklist ();
1628e4b17023SJohn Marino if (loop_entered)
1629e4b17023SJohn Marino {
1630e4b17023SJohn Marino delete_cluster_vectors ();
1631e4b17023SJohn Marino BITMAP_FREE (update_bbs);
1632e4b17023SJohn Marino }
1633e4b17023SJohn Marino
1634e4b17023SJohn Marino timevar_pop (TV_TREE_TAIL_MERGE);
1635e4b17023SJohn Marino
1636e4b17023SJohn Marino return todo;
1637e4b17023SJohn Marino }
1638