xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-ssa-ifcombine.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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