1*e4b17023SJohn Marino /* Combining of if-expressions on trees.
2*e4b17023SJohn Marino Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
3*e4b17023SJohn Marino Contributed by Richard Guenther <rguenther@suse.de>
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino any later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*e4b17023SJohn Marino GNU General Public License for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "tm.h"
25*e4b17023SJohn Marino #include "tree.h"
26*e4b17023SJohn Marino #include "basic-block.h"
27*e4b17023SJohn Marino #include "timevar.h"
28*e4b17023SJohn Marino #include "tree-pretty-print.h"
29*e4b17023SJohn Marino #include "tree-flow.h"
30*e4b17023SJohn Marino #include "tree-pass.h"
31*e4b17023SJohn Marino #include "tree-dump.h"
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino /* This pass combines COND_EXPRs to simplify control flow. It
34*e4b17023SJohn Marino currently recognizes bit tests and comparisons in chains that
35*e4b17023SJohn Marino represent logical and or logical or of two COND_EXPRs.
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino It does so by walking basic blocks in a approximate reverse
38*e4b17023SJohn Marino post-dominator order and trying to match CFG patterns that
39*e4b17023SJohn Marino represent logical and or logical or of two COND_EXPRs.
40*e4b17023SJohn Marino Transformations are done if the COND_EXPR conditions match
41*e4b17023SJohn Marino either
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino 1. two single bit tests X & (1 << Yn) (for logical and)
44*e4b17023SJohn Marino
45*e4b17023SJohn Marino 2. two bit tests X & Yn (for logical or)
46*e4b17023SJohn Marino
47*e4b17023SJohn Marino 3. two comparisons X OPn Y (for logical or)
48*e4b17023SJohn Marino
49*e4b17023SJohn Marino To simplify this pass, removing basic blocks and dead code
50*e4b17023SJohn Marino is left to CFG cleanup and DCE. */
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino
53*e4b17023SJohn Marino /* Recognize a if-then-else CFG pattern starting to match with the
54*e4b17023SJohn Marino COND_BB basic-block containing the COND_EXPR. The recognized
55*e4b17023SJohn Marino then end else blocks are stored to *THEN_BB and *ELSE_BB. If
56*e4b17023SJohn Marino *THEN_BB and/or *ELSE_BB are already set, they are required to
57*e4b17023SJohn Marino match the then and else basic-blocks to make the pattern match.
58*e4b17023SJohn Marino Returns true if the pattern matched, false otherwise. */
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino static bool
recognize_if_then_else(basic_block cond_bb,basic_block * then_bb,basic_block * else_bb)61*e4b17023SJohn Marino recognize_if_then_else (basic_block cond_bb,
62*e4b17023SJohn Marino basic_block *then_bb, basic_block *else_bb)
63*e4b17023SJohn Marino {
64*e4b17023SJohn Marino edge t, e;
65*e4b17023SJohn Marino
66*e4b17023SJohn Marino if (EDGE_COUNT (cond_bb->succs) != 2)
67*e4b17023SJohn Marino return false;
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino /* Find the then/else edges. */
70*e4b17023SJohn Marino t = EDGE_SUCC (cond_bb, 0);
71*e4b17023SJohn Marino e = EDGE_SUCC (cond_bb, 1);
72*e4b17023SJohn Marino if (!(t->flags & EDGE_TRUE_VALUE))
73*e4b17023SJohn Marino {
74*e4b17023SJohn Marino edge tmp = t;
75*e4b17023SJohn Marino t = e;
76*e4b17023SJohn Marino e = tmp;
77*e4b17023SJohn Marino }
78*e4b17023SJohn Marino if (!(t->flags & EDGE_TRUE_VALUE)
79*e4b17023SJohn Marino || !(e->flags & EDGE_FALSE_VALUE))
80*e4b17023SJohn Marino return false;
81*e4b17023SJohn Marino
82*e4b17023SJohn Marino /* Check if the edge destinations point to the required block. */
83*e4b17023SJohn Marino if (*then_bb
84*e4b17023SJohn Marino && t->dest != *then_bb)
85*e4b17023SJohn Marino return false;
86*e4b17023SJohn Marino if (*else_bb
87*e4b17023SJohn Marino && e->dest != *else_bb)
88*e4b17023SJohn Marino return false;
89*e4b17023SJohn Marino
90*e4b17023SJohn Marino if (!*then_bb)
91*e4b17023SJohn Marino *then_bb = t->dest;
92*e4b17023SJohn Marino if (!*else_bb)
93*e4b17023SJohn Marino *else_bb = e->dest;
94*e4b17023SJohn Marino
95*e4b17023SJohn Marino return true;
96*e4b17023SJohn Marino }
97*e4b17023SJohn Marino
98*e4b17023SJohn Marino /* Verify if the basic block BB does not have side-effects. Return
99*e4b17023SJohn Marino true in this case, else false. */
100*e4b17023SJohn Marino
101*e4b17023SJohn Marino static bool
bb_no_side_effects_p(basic_block bb)102*e4b17023SJohn Marino bb_no_side_effects_p (basic_block bb)
103*e4b17023SJohn Marino {
104*e4b17023SJohn Marino gimple_stmt_iterator gsi;
105*e4b17023SJohn Marino
106*e4b17023SJohn Marino for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
107*e4b17023SJohn Marino {
108*e4b17023SJohn Marino gimple stmt = gsi_stmt (gsi);
109*e4b17023SJohn Marino
110*e4b17023SJohn Marino if (gimple_has_side_effects (stmt)
111*e4b17023SJohn Marino || gimple_vuse (stmt))
112*e4b17023SJohn Marino return false;
113*e4b17023SJohn Marino }
114*e4b17023SJohn Marino
115*e4b17023SJohn Marino return true;
116*e4b17023SJohn Marino }
117*e4b17023SJohn Marino
118*e4b17023SJohn Marino /* Verify if all PHI node arguments in DEST for edges from BB1 or
119*e4b17023SJohn Marino BB2 to DEST are the same. This makes the CFG merge point
120*e4b17023SJohn Marino free from side-effects. Return true in this case, else false. */
121*e4b17023SJohn Marino
122*e4b17023SJohn Marino static bool
same_phi_args_p(basic_block bb1,basic_block bb2,basic_block dest)123*e4b17023SJohn Marino same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
124*e4b17023SJohn Marino {
125*e4b17023SJohn Marino edge e1 = find_edge (bb1, dest);
126*e4b17023SJohn Marino edge e2 = find_edge (bb2, dest);
127*e4b17023SJohn Marino gimple_stmt_iterator gsi;
128*e4b17023SJohn Marino gimple phi;
129*e4b17023SJohn Marino
130*e4b17023SJohn Marino for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
131*e4b17023SJohn Marino {
132*e4b17023SJohn Marino phi = gsi_stmt (gsi);
133*e4b17023SJohn Marino if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
134*e4b17023SJohn Marino PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
135*e4b17023SJohn Marino return false;
136*e4b17023SJohn Marino }
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino return true;
139*e4b17023SJohn Marino }
140*e4b17023SJohn Marino
141*e4b17023SJohn Marino /* Return the best representative SSA name for CANDIDATE which is used
142*e4b17023SJohn Marino in a bit test. */
143*e4b17023SJohn Marino
144*e4b17023SJohn Marino static tree
get_name_for_bit_test(tree candidate)145*e4b17023SJohn Marino get_name_for_bit_test (tree candidate)
146*e4b17023SJohn Marino {
147*e4b17023SJohn Marino /* Skip single-use names in favor of using the name from a
148*e4b17023SJohn Marino non-widening conversion definition. */
149*e4b17023SJohn Marino if (TREE_CODE (candidate) == SSA_NAME
150*e4b17023SJohn Marino && has_single_use (candidate))
151*e4b17023SJohn Marino {
152*e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
153*e4b17023SJohn Marino if (is_gimple_assign (def_stmt)
154*e4b17023SJohn Marino && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
155*e4b17023SJohn Marino {
156*e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (candidate))
157*e4b17023SJohn Marino <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
158*e4b17023SJohn Marino return gimple_assign_rhs1 (def_stmt);
159*e4b17023SJohn Marino }
160*e4b17023SJohn Marino }
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino return candidate;
163*e4b17023SJohn Marino }
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino /* Recognize a single bit test pattern in GIMPLE_COND and its defining
166*e4b17023SJohn Marino statements. Store the name being tested in *NAME and the bit
167*e4b17023SJohn Marino in *BIT. The GIMPLE_COND computes *NAME & (1 << *BIT).
168*e4b17023SJohn Marino Returns true if the pattern matched, false otherwise. */
169*e4b17023SJohn Marino
170*e4b17023SJohn Marino static bool
recognize_single_bit_test(gimple cond,tree * name,tree * bit)171*e4b17023SJohn Marino recognize_single_bit_test (gimple cond, tree *name, tree *bit)
172*e4b17023SJohn Marino {
173*e4b17023SJohn Marino gimple stmt;
174*e4b17023SJohn Marino
175*e4b17023SJohn Marino /* Get at the definition of the result of the bit test. */
176*e4b17023SJohn Marino if (gimple_cond_code (cond) != NE_EXPR
177*e4b17023SJohn Marino || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
178*e4b17023SJohn Marino || !integer_zerop (gimple_cond_rhs (cond)))
179*e4b17023SJohn Marino return false;
180*e4b17023SJohn Marino stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
181*e4b17023SJohn Marino if (!is_gimple_assign (stmt))
182*e4b17023SJohn Marino return false;
183*e4b17023SJohn Marino
184*e4b17023SJohn Marino /* Look at which bit is tested. One form to recognize is
185*e4b17023SJohn Marino D.1985_5 = state_3(D) >> control1_4(D);
186*e4b17023SJohn Marino D.1986_6 = (int) D.1985_5;
187*e4b17023SJohn Marino D.1987_7 = op0 & 1;
188*e4b17023SJohn Marino if (D.1987_7 != 0) */
189*e4b17023SJohn Marino if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
190*e4b17023SJohn Marino && integer_onep (gimple_assign_rhs2 (stmt))
191*e4b17023SJohn Marino && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
192*e4b17023SJohn Marino {
193*e4b17023SJohn Marino tree orig_name = gimple_assign_rhs1 (stmt);
194*e4b17023SJohn Marino
195*e4b17023SJohn Marino /* Look through copies and conversions to eventually
196*e4b17023SJohn Marino find the stmt that computes the shift. */
197*e4b17023SJohn Marino stmt = SSA_NAME_DEF_STMT (orig_name);
198*e4b17023SJohn Marino
199*e4b17023SJohn Marino while (is_gimple_assign (stmt)
200*e4b17023SJohn Marino && ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
201*e4b17023SJohn Marino && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
202*e4b17023SJohn Marino <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
203*e4b17023SJohn Marino || gimple_assign_ssa_name_copy_p (stmt)))
204*e4b17023SJohn Marino stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino /* If we found such, decompose it. */
207*e4b17023SJohn Marino if (is_gimple_assign (stmt)
208*e4b17023SJohn Marino && gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
209*e4b17023SJohn Marino {
210*e4b17023SJohn Marino /* op0 & (1 << op1) */
211*e4b17023SJohn Marino *bit = gimple_assign_rhs2 (stmt);
212*e4b17023SJohn Marino *name = gimple_assign_rhs1 (stmt);
213*e4b17023SJohn Marino }
214*e4b17023SJohn Marino else
215*e4b17023SJohn Marino {
216*e4b17023SJohn Marino /* t & 1 */
217*e4b17023SJohn Marino *bit = integer_zero_node;
218*e4b17023SJohn Marino *name = get_name_for_bit_test (orig_name);
219*e4b17023SJohn Marino }
220*e4b17023SJohn Marino
221*e4b17023SJohn Marino return true;
222*e4b17023SJohn Marino }
223*e4b17023SJohn Marino
224*e4b17023SJohn Marino /* Another form is
225*e4b17023SJohn Marino D.1987_7 = op0 & (1 << CST)
226*e4b17023SJohn Marino if (D.1987_7 != 0) */
227*e4b17023SJohn Marino if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
228*e4b17023SJohn Marino && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
229*e4b17023SJohn Marino && integer_pow2p (gimple_assign_rhs2 (stmt)))
230*e4b17023SJohn Marino {
231*e4b17023SJohn Marino *name = gimple_assign_rhs1 (stmt);
232*e4b17023SJohn Marino *bit = build_int_cst (integer_type_node,
233*e4b17023SJohn Marino tree_log2 (gimple_assign_rhs2 (stmt)));
234*e4b17023SJohn Marino return true;
235*e4b17023SJohn Marino }
236*e4b17023SJohn Marino
237*e4b17023SJohn Marino /* Another form is
238*e4b17023SJohn Marino D.1986_6 = 1 << control1_4(D)
239*e4b17023SJohn Marino D.1987_7 = op0 & D.1986_6
240*e4b17023SJohn Marino if (D.1987_7 != 0) */
241*e4b17023SJohn Marino if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
242*e4b17023SJohn Marino && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
243*e4b17023SJohn Marino && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
244*e4b17023SJohn Marino {
245*e4b17023SJohn Marino gimple tmp;
246*e4b17023SJohn Marino
247*e4b17023SJohn Marino /* Both arguments of the BIT_AND_EXPR can be the single-bit
248*e4b17023SJohn Marino specifying expression. */
249*e4b17023SJohn Marino tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
250*e4b17023SJohn Marino if (is_gimple_assign (tmp)
251*e4b17023SJohn Marino && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
252*e4b17023SJohn Marino && integer_onep (gimple_assign_rhs1 (tmp)))
253*e4b17023SJohn Marino {
254*e4b17023SJohn Marino *name = gimple_assign_rhs2 (stmt);
255*e4b17023SJohn Marino *bit = gimple_assign_rhs2 (tmp);
256*e4b17023SJohn Marino return true;
257*e4b17023SJohn Marino }
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
260*e4b17023SJohn Marino if (is_gimple_assign (tmp)
261*e4b17023SJohn Marino && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
262*e4b17023SJohn Marino && integer_onep (gimple_assign_rhs1 (tmp)))
263*e4b17023SJohn Marino {
264*e4b17023SJohn Marino *name = gimple_assign_rhs1 (stmt);
265*e4b17023SJohn Marino *bit = gimple_assign_rhs2 (tmp);
266*e4b17023SJohn Marino return true;
267*e4b17023SJohn Marino }
268*e4b17023SJohn Marino }
269*e4b17023SJohn Marino
270*e4b17023SJohn Marino return false;
271*e4b17023SJohn Marino }
272*e4b17023SJohn Marino
273*e4b17023SJohn Marino /* Recognize a bit test pattern in a GIMPLE_COND and its defining
274*e4b17023SJohn Marino statements. Store the name being tested in *NAME and the bits
275*e4b17023SJohn Marino in *BITS. The COND_EXPR computes *NAME & *BITS.
276*e4b17023SJohn Marino Returns true if the pattern matched, false otherwise. */
277*e4b17023SJohn Marino
278*e4b17023SJohn Marino static bool
recognize_bits_test(gimple cond,tree * name,tree * bits)279*e4b17023SJohn Marino recognize_bits_test (gimple cond, tree *name, tree *bits)
280*e4b17023SJohn Marino {
281*e4b17023SJohn Marino gimple stmt;
282*e4b17023SJohn Marino
283*e4b17023SJohn Marino /* Get at the definition of the result of the bit test. */
284*e4b17023SJohn Marino if (gimple_cond_code (cond) != NE_EXPR
285*e4b17023SJohn Marino || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
286*e4b17023SJohn Marino || !integer_zerop (gimple_cond_rhs (cond)))
287*e4b17023SJohn Marino return false;
288*e4b17023SJohn Marino stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
289*e4b17023SJohn Marino if (!is_gimple_assign (stmt)
290*e4b17023SJohn Marino || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
291*e4b17023SJohn Marino return false;
292*e4b17023SJohn Marino
293*e4b17023SJohn Marino *name = get_name_for_bit_test (gimple_assign_rhs1 (stmt));
294*e4b17023SJohn Marino *bits = gimple_assign_rhs2 (stmt);
295*e4b17023SJohn Marino
296*e4b17023SJohn Marino return true;
297*e4b17023SJohn Marino }
298*e4b17023SJohn Marino
299*e4b17023SJohn Marino /* If-convert on a and pattern with a common else block. The inner
300*e4b17023SJohn Marino if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
301*e4b17023SJohn Marino Returns true if the edges to the common else basic-block were merged. */
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino static bool
ifcombine_ifandif(basic_block inner_cond_bb,basic_block outer_cond_bb)304*e4b17023SJohn Marino ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
305*e4b17023SJohn Marino {
306*e4b17023SJohn Marino gimple_stmt_iterator gsi;
307*e4b17023SJohn Marino gimple inner_cond, outer_cond;
308*e4b17023SJohn Marino tree name1, name2, bit1, bit2;
309*e4b17023SJohn Marino
310*e4b17023SJohn Marino inner_cond = last_stmt (inner_cond_bb);
311*e4b17023SJohn Marino if (!inner_cond
312*e4b17023SJohn Marino || gimple_code (inner_cond) != GIMPLE_COND)
313*e4b17023SJohn Marino return false;
314*e4b17023SJohn Marino
315*e4b17023SJohn Marino outer_cond = last_stmt (outer_cond_bb);
316*e4b17023SJohn Marino if (!outer_cond
317*e4b17023SJohn Marino || gimple_code (outer_cond) != GIMPLE_COND)
318*e4b17023SJohn Marino return false;
319*e4b17023SJohn Marino
320*e4b17023SJohn Marino /* See if we test a single bit of the same name in both tests. In
321*e4b17023SJohn Marino that case remove the outer test, merging both else edges,
322*e4b17023SJohn Marino and change the inner one to test for
323*e4b17023SJohn Marino name & (bit1 | bit2) == (bit1 | bit2). */
324*e4b17023SJohn Marino if (recognize_single_bit_test (inner_cond, &name1, &bit1)
325*e4b17023SJohn Marino && recognize_single_bit_test (outer_cond, &name2, &bit2)
326*e4b17023SJohn Marino && name1 == name2)
327*e4b17023SJohn Marino {
328*e4b17023SJohn Marino tree t, t2;
329*e4b17023SJohn Marino
330*e4b17023SJohn Marino /* Do it. */
331*e4b17023SJohn Marino gsi = gsi_for_stmt (inner_cond);
332*e4b17023SJohn Marino t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
333*e4b17023SJohn Marino build_int_cst (TREE_TYPE (name1), 1), bit1);
334*e4b17023SJohn Marino t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
335*e4b17023SJohn Marino build_int_cst (TREE_TYPE (name1), 1), bit2);
336*e4b17023SJohn Marino t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
337*e4b17023SJohn Marino t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
338*e4b17023SJohn Marino true, GSI_SAME_STMT);
339*e4b17023SJohn Marino t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
340*e4b17023SJohn Marino t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
341*e4b17023SJohn Marino true, GSI_SAME_STMT);
342*e4b17023SJohn Marino t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
343*e4b17023SJohn Marino t = canonicalize_cond_expr_cond (t);
344*e4b17023SJohn Marino if (!t)
345*e4b17023SJohn Marino return false;
346*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (inner_cond, t);
347*e4b17023SJohn Marino update_stmt (inner_cond);
348*e4b17023SJohn Marino
349*e4b17023SJohn Marino /* Leave CFG optimization to cfg_cleanup. */
350*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
351*e4b17023SJohn Marino update_stmt (outer_cond);
352*e4b17023SJohn Marino
353*e4b17023SJohn Marino if (dump_file)
354*e4b17023SJohn Marino {
355*e4b17023SJohn Marino fprintf (dump_file, "optimizing double bit test to ");
356*e4b17023SJohn Marino print_generic_expr (dump_file, name1, 0);
357*e4b17023SJohn Marino fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
358*e4b17023SJohn Marino print_generic_expr (dump_file, bit1, 0);
359*e4b17023SJohn Marino fprintf (dump_file, ") | (1 << ");
360*e4b17023SJohn Marino print_generic_expr (dump_file, bit2, 0);
361*e4b17023SJohn Marino fprintf (dump_file, ")\n");
362*e4b17023SJohn Marino }
363*e4b17023SJohn Marino
364*e4b17023SJohn Marino return true;
365*e4b17023SJohn Marino }
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino /* See if we have two comparisons that we can merge into one. */
368*e4b17023SJohn Marino else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
369*e4b17023SJohn Marino && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
370*e4b17023SJohn Marino {
371*e4b17023SJohn Marino tree t;
372*e4b17023SJohn Marino
373*e4b17023SJohn Marino if (!(t = maybe_fold_and_comparisons (gimple_cond_code (inner_cond),
374*e4b17023SJohn Marino gimple_cond_lhs (inner_cond),
375*e4b17023SJohn Marino gimple_cond_rhs (inner_cond),
376*e4b17023SJohn Marino gimple_cond_code (outer_cond),
377*e4b17023SJohn Marino gimple_cond_lhs (outer_cond),
378*e4b17023SJohn Marino gimple_cond_rhs (outer_cond))))
379*e4b17023SJohn Marino return false;
380*e4b17023SJohn Marino t = canonicalize_cond_expr_cond (t);
381*e4b17023SJohn Marino if (!t)
382*e4b17023SJohn Marino return false;
383*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (inner_cond, t);
384*e4b17023SJohn Marino update_stmt (inner_cond);
385*e4b17023SJohn Marino
386*e4b17023SJohn Marino /* Leave CFG optimization to cfg_cleanup. */
387*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
388*e4b17023SJohn Marino update_stmt (outer_cond);
389*e4b17023SJohn Marino
390*e4b17023SJohn Marino if (dump_file)
391*e4b17023SJohn Marino {
392*e4b17023SJohn Marino fprintf (dump_file, "optimizing two comparisons to ");
393*e4b17023SJohn Marino print_generic_expr (dump_file, t, 0);
394*e4b17023SJohn Marino fprintf (dump_file, "\n");
395*e4b17023SJohn Marino }
396*e4b17023SJohn Marino
397*e4b17023SJohn Marino return true;
398*e4b17023SJohn Marino }
399*e4b17023SJohn Marino
400*e4b17023SJohn Marino return false;
401*e4b17023SJohn Marino }
402*e4b17023SJohn Marino
403*e4b17023SJohn Marino /* If-convert on a or pattern with a common then block. The inner
404*e4b17023SJohn Marino if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
405*e4b17023SJohn Marino Returns true, if the edges leading to the common then basic-block
406*e4b17023SJohn Marino were merged. */
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino static bool
ifcombine_iforif(basic_block inner_cond_bb,basic_block outer_cond_bb)409*e4b17023SJohn Marino ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
410*e4b17023SJohn Marino {
411*e4b17023SJohn Marino gimple inner_cond, outer_cond;
412*e4b17023SJohn Marino tree name1, name2, bits1, bits2;
413*e4b17023SJohn Marino
414*e4b17023SJohn Marino inner_cond = last_stmt (inner_cond_bb);
415*e4b17023SJohn Marino if (!inner_cond
416*e4b17023SJohn Marino || gimple_code (inner_cond) != GIMPLE_COND)
417*e4b17023SJohn Marino return false;
418*e4b17023SJohn Marino
419*e4b17023SJohn Marino outer_cond = last_stmt (outer_cond_bb);
420*e4b17023SJohn Marino if (!outer_cond
421*e4b17023SJohn Marino || gimple_code (outer_cond) != GIMPLE_COND)
422*e4b17023SJohn Marino return false;
423*e4b17023SJohn Marino
424*e4b17023SJohn Marino /* See if we have two bit tests of the same name in both tests.
425*e4b17023SJohn Marino In that case remove the outer test and change the inner one to
426*e4b17023SJohn Marino test for name & (bits1 | bits2) != 0. */
427*e4b17023SJohn Marino if (recognize_bits_test (inner_cond, &name1, &bits1)
428*e4b17023SJohn Marino && recognize_bits_test (outer_cond, &name2, &bits2))
429*e4b17023SJohn Marino {
430*e4b17023SJohn Marino gimple_stmt_iterator gsi;
431*e4b17023SJohn Marino tree t;
432*e4b17023SJohn Marino
433*e4b17023SJohn Marino /* Find the common name which is bit-tested. */
434*e4b17023SJohn Marino if (name1 == name2)
435*e4b17023SJohn Marino ;
436*e4b17023SJohn Marino else if (bits1 == bits2)
437*e4b17023SJohn Marino {
438*e4b17023SJohn Marino t = name2;
439*e4b17023SJohn Marino name2 = bits2;
440*e4b17023SJohn Marino bits2 = t;
441*e4b17023SJohn Marino t = name1;
442*e4b17023SJohn Marino name1 = bits1;
443*e4b17023SJohn Marino bits1 = t;
444*e4b17023SJohn Marino }
445*e4b17023SJohn Marino else if (name1 == bits2)
446*e4b17023SJohn Marino {
447*e4b17023SJohn Marino t = name2;
448*e4b17023SJohn Marino name2 = bits2;
449*e4b17023SJohn Marino bits2 = t;
450*e4b17023SJohn Marino }
451*e4b17023SJohn Marino else if (bits1 == name2)
452*e4b17023SJohn Marino {
453*e4b17023SJohn Marino t = name1;
454*e4b17023SJohn Marino name1 = bits1;
455*e4b17023SJohn Marino bits1 = t;
456*e4b17023SJohn Marino }
457*e4b17023SJohn Marino else
458*e4b17023SJohn Marino return false;
459*e4b17023SJohn Marino
460*e4b17023SJohn Marino /* As we strip non-widening conversions in finding a common
461*e4b17023SJohn Marino name that is tested make sure to end up with an integral
462*e4b17023SJohn Marino type for building the bit operations. */
463*e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (bits1))
464*e4b17023SJohn Marino >= TYPE_PRECISION (TREE_TYPE (bits2)))
465*e4b17023SJohn Marino {
466*e4b17023SJohn Marino bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
467*e4b17023SJohn Marino name1 = fold_convert (TREE_TYPE (bits1), name1);
468*e4b17023SJohn Marino bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
469*e4b17023SJohn Marino bits2 = fold_convert (TREE_TYPE (bits1), bits2);
470*e4b17023SJohn Marino }
471*e4b17023SJohn Marino else
472*e4b17023SJohn Marino {
473*e4b17023SJohn Marino bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
474*e4b17023SJohn Marino name1 = fold_convert (TREE_TYPE (bits2), name1);
475*e4b17023SJohn Marino bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
476*e4b17023SJohn Marino bits1 = fold_convert (TREE_TYPE (bits2), bits1);
477*e4b17023SJohn Marino }
478*e4b17023SJohn Marino
479*e4b17023SJohn Marino /* Do it. */
480*e4b17023SJohn Marino gsi = gsi_for_stmt (inner_cond);
481*e4b17023SJohn Marino t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
482*e4b17023SJohn Marino t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
483*e4b17023SJohn Marino true, GSI_SAME_STMT);
484*e4b17023SJohn Marino t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
485*e4b17023SJohn Marino t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
486*e4b17023SJohn Marino true, GSI_SAME_STMT);
487*e4b17023SJohn Marino t = fold_build2 (NE_EXPR, boolean_type_node, t,
488*e4b17023SJohn Marino build_int_cst (TREE_TYPE (t), 0));
489*e4b17023SJohn Marino t = canonicalize_cond_expr_cond (t);
490*e4b17023SJohn Marino if (!t)
491*e4b17023SJohn Marino return false;
492*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (inner_cond, t);
493*e4b17023SJohn Marino update_stmt (inner_cond);
494*e4b17023SJohn Marino
495*e4b17023SJohn Marino /* Leave CFG optimization to cfg_cleanup. */
496*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
497*e4b17023SJohn Marino update_stmt (outer_cond);
498*e4b17023SJohn Marino
499*e4b17023SJohn Marino if (dump_file)
500*e4b17023SJohn Marino {
501*e4b17023SJohn Marino fprintf (dump_file, "optimizing bits or bits test to ");
502*e4b17023SJohn Marino print_generic_expr (dump_file, name1, 0);
503*e4b17023SJohn Marino fprintf (dump_file, " & T != 0\nwith temporary T = ");
504*e4b17023SJohn Marino print_generic_expr (dump_file, bits1, 0);
505*e4b17023SJohn Marino fprintf (dump_file, " | ");
506*e4b17023SJohn Marino print_generic_expr (dump_file, bits2, 0);
507*e4b17023SJohn Marino fprintf (dump_file, "\n");
508*e4b17023SJohn Marino }
509*e4b17023SJohn Marino
510*e4b17023SJohn Marino return true;
511*e4b17023SJohn Marino }
512*e4b17023SJohn Marino
513*e4b17023SJohn Marino /* See if we have two comparisons that we can merge into one.
514*e4b17023SJohn Marino This happens for C++ operator overloading where for example
515*e4b17023SJohn Marino GE_EXPR is implemented as GT_EXPR || EQ_EXPR. */
516*e4b17023SJohn Marino else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
517*e4b17023SJohn Marino && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
518*e4b17023SJohn Marino {
519*e4b17023SJohn Marino tree t;
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino if (!(t = maybe_fold_or_comparisons (gimple_cond_code (inner_cond),
522*e4b17023SJohn Marino gimple_cond_lhs (inner_cond),
523*e4b17023SJohn Marino gimple_cond_rhs (inner_cond),
524*e4b17023SJohn Marino gimple_cond_code (outer_cond),
525*e4b17023SJohn Marino gimple_cond_lhs (outer_cond),
526*e4b17023SJohn Marino gimple_cond_rhs (outer_cond))))
527*e4b17023SJohn Marino return false;
528*e4b17023SJohn Marino t = canonicalize_cond_expr_cond (t);
529*e4b17023SJohn Marino if (!t)
530*e4b17023SJohn Marino return false;
531*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (inner_cond, t);
532*e4b17023SJohn Marino update_stmt (inner_cond);
533*e4b17023SJohn Marino
534*e4b17023SJohn Marino /* Leave CFG optimization to cfg_cleanup. */
535*e4b17023SJohn Marino gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
536*e4b17023SJohn Marino update_stmt (outer_cond);
537*e4b17023SJohn Marino
538*e4b17023SJohn Marino if (dump_file)
539*e4b17023SJohn Marino {
540*e4b17023SJohn Marino fprintf (dump_file, "optimizing two comparisons to ");
541*e4b17023SJohn Marino print_generic_expr (dump_file, t, 0);
542*e4b17023SJohn Marino fprintf (dump_file, "\n");
543*e4b17023SJohn Marino }
544*e4b17023SJohn Marino
545*e4b17023SJohn Marino return true;
546*e4b17023SJohn Marino }
547*e4b17023SJohn Marino
548*e4b17023SJohn Marino return false;
549*e4b17023SJohn Marino }
550*e4b17023SJohn Marino
551*e4b17023SJohn Marino /* Recognize a CFG pattern and dispatch to the appropriate
552*e4b17023SJohn Marino if-conversion helper. We start with BB as the innermost
553*e4b17023SJohn Marino worker basic-block. Returns true if a transformation was done. */
554*e4b17023SJohn Marino
555*e4b17023SJohn Marino static bool
tree_ssa_ifcombine_bb(basic_block inner_cond_bb)556*e4b17023SJohn Marino tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
557*e4b17023SJohn Marino {
558*e4b17023SJohn Marino basic_block then_bb = NULL, else_bb = NULL;
559*e4b17023SJohn Marino
560*e4b17023SJohn Marino if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
561*e4b17023SJohn Marino return false;
562*e4b17023SJohn Marino
563*e4b17023SJohn Marino /* Recognize && and || of two conditions with a common
564*e4b17023SJohn Marino then/else block which entry edges we can merge. That is:
565*e4b17023SJohn Marino if (a || b)
566*e4b17023SJohn Marino ;
567*e4b17023SJohn Marino and
568*e4b17023SJohn Marino if (a && b)
569*e4b17023SJohn Marino ;
570*e4b17023SJohn Marino This requires a single predecessor of the inner cond_bb. */
571*e4b17023SJohn Marino if (single_pred_p (inner_cond_bb))
572*e4b17023SJohn Marino {
573*e4b17023SJohn Marino basic_block outer_cond_bb = single_pred (inner_cond_bb);
574*e4b17023SJohn Marino
575*e4b17023SJohn Marino /* The && form is characterized by a common else_bb with
576*e4b17023SJohn Marino the two edges leading to it mergable. The latter is
577*e4b17023SJohn Marino guaranteed by matching PHI arguments in the else_bb and
578*e4b17023SJohn Marino the inner cond_bb having no side-effects. */
579*e4b17023SJohn Marino if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
580*e4b17023SJohn Marino && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
581*e4b17023SJohn Marino && bb_no_side_effects_p (inner_cond_bb))
582*e4b17023SJohn Marino {
583*e4b17023SJohn Marino /* We have
584*e4b17023SJohn Marino <outer_cond_bb>
585*e4b17023SJohn Marino if (q) goto inner_cond_bb; else goto else_bb;
586*e4b17023SJohn Marino <inner_cond_bb>
587*e4b17023SJohn Marino if (p) goto ...; else goto else_bb;
588*e4b17023SJohn Marino ...
589*e4b17023SJohn Marino <else_bb>
590*e4b17023SJohn Marino ...
591*e4b17023SJohn Marino */
592*e4b17023SJohn Marino return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
593*e4b17023SJohn Marino }
594*e4b17023SJohn Marino
595*e4b17023SJohn Marino /* The || form is characterized by a common then_bb with the
596*e4b17023SJohn Marino two edges leading to it mergable. The latter is guaranteed
597*e4b17023SJohn Marino by matching PHI arguments in the then_bb and the inner cond_bb
598*e4b17023SJohn Marino having no side-effects. */
599*e4b17023SJohn Marino if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
600*e4b17023SJohn Marino && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
601*e4b17023SJohn Marino && bb_no_side_effects_p (inner_cond_bb))
602*e4b17023SJohn Marino {
603*e4b17023SJohn Marino /* We have
604*e4b17023SJohn Marino <outer_cond_bb>
605*e4b17023SJohn Marino if (q) goto then_bb; else goto inner_cond_bb;
606*e4b17023SJohn Marino <inner_cond_bb>
607*e4b17023SJohn Marino if (q) goto then_bb; else goto ...;
608*e4b17023SJohn Marino <then_bb>
609*e4b17023SJohn Marino ...
610*e4b17023SJohn Marino */
611*e4b17023SJohn Marino return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
612*e4b17023SJohn Marino }
613*e4b17023SJohn Marino }
614*e4b17023SJohn Marino
615*e4b17023SJohn Marino return false;
616*e4b17023SJohn Marino }
617*e4b17023SJohn Marino
618*e4b17023SJohn Marino /* Main entry for the tree if-conversion pass. */
619*e4b17023SJohn Marino
620*e4b17023SJohn Marino static unsigned int
tree_ssa_ifcombine(void)621*e4b17023SJohn Marino tree_ssa_ifcombine (void)
622*e4b17023SJohn Marino {
623*e4b17023SJohn Marino basic_block *bbs;
624*e4b17023SJohn Marino bool cfg_changed = false;
625*e4b17023SJohn Marino int i;
626*e4b17023SJohn Marino
627*e4b17023SJohn Marino bbs = blocks_in_phiopt_order ();
628*e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
629*e4b17023SJohn Marino
630*e4b17023SJohn Marino for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
631*e4b17023SJohn Marino {
632*e4b17023SJohn Marino basic_block bb = bbs[i];
633*e4b17023SJohn Marino gimple stmt = last_stmt (bb);
634*e4b17023SJohn Marino
635*e4b17023SJohn Marino if (stmt
636*e4b17023SJohn Marino && gimple_code (stmt) == GIMPLE_COND)
637*e4b17023SJohn Marino cfg_changed |= tree_ssa_ifcombine_bb (bb);
638*e4b17023SJohn Marino }
639*e4b17023SJohn Marino
640*e4b17023SJohn Marino free (bbs);
641*e4b17023SJohn Marino
642*e4b17023SJohn Marino return cfg_changed ? TODO_cleanup_cfg : 0;
643*e4b17023SJohn Marino }
644*e4b17023SJohn Marino
645*e4b17023SJohn Marino static bool
gate_ifcombine(void)646*e4b17023SJohn Marino gate_ifcombine (void)
647*e4b17023SJohn Marino {
648*e4b17023SJohn Marino return 1;
649*e4b17023SJohn Marino }
650*e4b17023SJohn Marino
651*e4b17023SJohn Marino struct gimple_opt_pass pass_tree_ifcombine =
652*e4b17023SJohn Marino {
653*e4b17023SJohn Marino {
654*e4b17023SJohn Marino GIMPLE_PASS,
655*e4b17023SJohn Marino "ifcombine", /* name */
656*e4b17023SJohn Marino gate_ifcombine, /* gate */
657*e4b17023SJohn Marino tree_ssa_ifcombine, /* execute */
658*e4b17023SJohn Marino NULL, /* sub */
659*e4b17023SJohn Marino NULL, /* next */
660*e4b17023SJohn Marino 0, /* static_pass_number */
661*e4b17023SJohn Marino TV_TREE_IFCOMBINE, /* tv_id */
662*e4b17023SJohn Marino PROP_cfg | PROP_ssa, /* properties_required */
663*e4b17023SJohn Marino 0, /* properties_provided */
664*e4b17023SJohn Marino 0, /* properties_destroyed */
665*e4b17023SJohn Marino 0, /* todo_flags_start */
666*e4b17023SJohn Marino TODO_ggc_collect
667*e4b17023SJohn Marino | TODO_update_ssa
668*e4b17023SJohn Marino | TODO_verify_ssa /* todo_flags_finish */
669*e4b17023SJohn Marino }
670*e4b17023SJohn Marino };
671