1*e4b17023SJohn Marino /* Generic SSA value propagation engine.
2*e4b17023SJohn Marino    Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Diego Novillo <dnovillo@redhat.com>
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino    This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino    GCC is free software; you can redistribute it and/or modify it
9*e4b17023SJohn Marino    under the terms of the GNU General Public License as published by the
10*e4b17023SJohn Marino    Free Software Foundation; either version 3, or (at your option) any
11*e4b17023SJohn Marino    later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino    GCC is distributed in the hope that it will be useful, but WITHOUT
14*e4b17023SJohn Marino    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*e4b17023SJohn Marino    for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino    You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino    along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino    <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "tree.h"
27*e4b17023SJohn Marino #include "flags.h"
28*e4b17023SJohn Marino #include "tm_p.h"
29*e4b17023SJohn Marino #include "basic-block.h"
30*e4b17023SJohn Marino #include "output.h"
31*e4b17023SJohn Marino #include "function.h"
32*e4b17023SJohn Marino #include "gimple-pretty-print.h"
33*e4b17023SJohn Marino #include "timevar.h"
34*e4b17023SJohn Marino #include "tree-dump.h"
35*e4b17023SJohn Marino #include "tree-flow.h"
36*e4b17023SJohn Marino #include "tree-pass.h"
37*e4b17023SJohn Marino #include "tree-ssa-propagate.h"
38*e4b17023SJohn Marino #include "langhooks.h"
39*e4b17023SJohn Marino #include "vec.h"
40*e4b17023SJohn Marino #include "value-prof.h"
41*e4b17023SJohn Marino #include "gimple.h"
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino /* This file implements a generic value propagation engine based on
44*e4b17023SJohn Marino    the same propagation used by the SSA-CCP algorithm [1].
45*e4b17023SJohn Marino 
46*e4b17023SJohn Marino    Propagation is performed by simulating the execution of every
47*e4b17023SJohn Marino    statement that produces the value being propagated.  Simulation
48*e4b17023SJohn Marino    proceeds as follows:
49*e4b17023SJohn Marino 
50*e4b17023SJohn Marino    1- Initially, all edges of the CFG are marked not executable and
51*e4b17023SJohn Marino       the CFG worklist is seeded with all the statements in the entry
52*e4b17023SJohn Marino       basic block (block 0).
53*e4b17023SJohn Marino 
54*e4b17023SJohn Marino    2- Every statement S is simulated with a call to the call-back
55*e4b17023SJohn Marino       function SSA_PROP_VISIT_STMT.  This evaluation may produce 3
56*e4b17023SJohn Marino       results:
57*e4b17023SJohn Marino 
58*e4b17023SJohn Marino       	SSA_PROP_NOT_INTERESTING: Statement S produces nothing of
59*e4b17023SJohn Marino 	    interest and does not affect any of the work lists.
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino 	SSA_PROP_VARYING: The value produced by S cannot be determined
62*e4b17023SJohn Marino 	    at compile time.  Further simulation of S is not required.
63*e4b17023SJohn Marino 	    If S is a conditional jump, all the outgoing edges for the
64*e4b17023SJohn Marino 	    block are considered executable and added to the work
65*e4b17023SJohn Marino 	    list.
66*e4b17023SJohn Marino 
67*e4b17023SJohn Marino 	SSA_PROP_INTERESTING: S produces a value that can be computed
68*e4b17023SJohn Marino 	    at compile time.  Its result can be propagated into the
69*e4b17023SJohn Marino 	    statements that feed from S.  Furthermore, if S is a
70*e4b17023SJohn Marino 	    conditional jump, only the edge known to be taken is added
71*e4b17023SJohn Marino 	    to the work list.  Edges that are known not to execute are
72*e4b17023SJohn Marino 	    never simulated.
73*e4b17023SJohn Marino 
74*e4b17023SJohn Marino    3- PHI nodes are simulated with a call to SSA_PROP_VISIT_PHI.  The
75*e4b17023SJohn Marino       return value from SSA_PROP_VISIT_PHI has the same semantics as
76*e4b17023SJohn Marino       described in #2.
77*e4b17023SJohn Marino 
78*e4b17023SJohn Marino    4- Three work lists are kept.  Statements are only added to these
79*e4b17023SJohn Marino       lists if they produce one of SSA_PROP_INTERESTING or
80*e4b17023SJohn Marino       SSA_PROP_VARYING.
81*e4b17023SJohn Marino 
82*e4b17023SJohn Marino    	CFG_BLOCKS contains the list of blocks to be simulated.
83*e4b17023SJohn Marino 	    Blocks are added to this list if their incoming edges are
84*e4b17023SJohn Marino 	    found executable.
85*e4b17023SJohn Marino 
86*e4b17023SJohn Marino 	VARYING_SSA_EDGES contains the list of statements that feed
87*e4b17023SJohn Marino 	    from statements that produce an SSA_PROP_VARYING result.
88*e4b17023SJohn Marino 	    These are simulated first to speed up processing.
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino 	INTERESTING_SSA_EDGES contains the list of statements that
91*e4b17023SJohn Marino 	    feed from statements that produce an SSA_PROP_INTERESTING
92*e4b17023SJohn Marino 	    result.
93*e4b17023SJohn Marino 
94*e4b17023SJohn Marino    5- Simulation terminates when all three work lists are drained.
95*e4b17023SJohn Marino 
96*e4b17023SJohn Marino    Before calling ssa_propagate, it is important to clear
97*e4b17023SJohn Marino    prop_simulate_again_p for all the statements in the program that
98*e4b17023SJohn Marino    should be simulated.  This initialization allows an implementation
99*e4b17023SJohn Marino    to specify which statements should never be simulated.
100*e4b17023SJohn Marino 
101*e4b17023SJohn Marino    It is also important to compute def-use information before calling
102*e4b17023SJohn Marino    ssa_propagate.
103*e4b17023SJohn Marino 
104*e4b17023SJohn Marino    References:
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino      [1] Constant propagation with conditional branches,
107*e4b17023SJohn Marino          Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino      [2] Building an Optimizing Compiler,
110*e4b17023SJohn Marino 	 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino      [3] Advanced Compiler Design and Implementation,
113*e4b17023SJohn Marino 	 Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6  */
114*e4b17023SJohn Marino 
115*e4b17023SJohn Marino /* Function pointers used to parameterize the propagation engine.  */
116*e4b17023SJohn Marino static ssa_prop_visit_stmt_fn ssa_prop_visit_stmt;
117*e4b17023SJohn Marino static ssa_prop_visit_phi_fn ssa_prop_visit_phi;
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino /* Keep track of statements that have been added to one of the SSA
120*e4b17023SJohn Marino    edges worklists.  This flag is used to avoid visiting statements
121*e4b17023SJohn Marino    unnecessarily when draining an SSA edge worklist.  If while
122*e4b17023SJohn Marino    simulating a basic block, we find a statement with
123*e4b17023SJohn Marino    STMT_IN_SSA_EDGE_WORKLIST set, we clear it to prevent SSA edge
124*e4b17023SJohn Marino    processing from visiting it again.
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino    NOTE: users of the propagation engine are not allowed to use
127*e4b17023SJohn Marino    the GF_PLF_1 flag.  */
128*e4b17023SJohn Marino #define STMT_IN_SSA_EDGE_WORKLIST	GF_PLF_1
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino /* A bitmap to keep track of executable blocks in the CFG.  */
131*e4b17023SJohn Marino static sbitmap executable_blocks;
132*e4b17023SJohn Marino 
133*e4b17023SJohn Marino /* Array of control flow edges on the worklist.  */
134*e4b17023SJohn Marino static VEC(basic_block,heap) *cfg_blocks;
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino static unsigned int cfg_blocks_num = 0;
137*e4b17023SJohn Marino static int cfg_blocks_tail;
138*e4b17023SJohn Marino static int cfg_blocks_head;
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino static sbitmap bb_in_list;
141*e4b17023SJohn Marino 
142*e4b17023SJohn Marino /* Worklist of SSA edges which will need reexamination as their
143*e4b17023SJohn Marino    definition has changed.  SSA edges are def-use edges in the SSA
144*e4b17023SJohn Marino    web.  For each D-U edge, we store the target statement or PHI node
145*e4b17023SJohn Marino    U.  */
146*e4b17023SJohn Marino static GTY(()) VEC(gimple,gc) *interesting_ssa_edges;
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino /* Identical to INTERESTING_SSA_EDGES.  For performance reasons, the
149*e4b17023SJohn Marino    list of SSA edges is split into two.  One contains all SSA edges
150*e4b17023SJohn Marino    who need to be reexamined because their lattice value changed to
151*e4b17023SJohn Marino    varying (this worklist), and the other contains all other SSA edges
152*e4b17023SJohn Marino    to be reexamined (INTERESTING_SSA_EDGES).
153*e4b17023SJohn Marino 
154*e4b17023SJohn Marino    Since most values in the program are VARYING, the ideal situation
155*e4b17023SJohn Marino    is to move them to that lattice value as quickly as possible.
156*e4b17023SJohn Marino    Thus, it doesn't make sense to process any other type of lattice
157*e4b17023SJohn Marino    value until all VARYING values are propagated fully, which is one
158*e4b17023SJohn Marino    thing using the VARYING worklist achieves.  In addition, if we
159*e4b17023SJohn Marino    don't use a separate worklist for VARYING edges, we end up with
160*e4b17023SJohn Marino    situations where lattice values move from
161*e4b17023SJohn Marino    UNDEFINED->INTERESTING->VARYING instead of UNDEFINED->VARYING.  */
162*e4b17023SJohn Marino static GTY(()) VEC(gimple,gc) *varying_ssa_edges;
163*e4b17023SJohn Marino 
164*e4b17023SJohn Marino 
165*e4b17023SJohn Marino /* Return true if the block worklist empty.  */
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino static inline bool
cfg_blocks_empty_p(void)168*e4b17023SJohn Marino cfg_blocks_empty_p (void)
169*e4b17023SJohn Marino {
170*e4b17023SJohn Marino   return (cfg_blocks_num == 0);
171*e4b17023SJohn Marino }
172*e4b17023SJohn Marino 
173*e4b17023SJohn Marino 
174*e4b17023SJohn Marino /* Add a basic block to the worklist.  The block must not be already
175*e4b17023SJohn Marino    in the worklist, and it must not be the ENTRY or EXIT block.  */
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino static void
cfg_blocks_add(basic_block bb)178*e4b17023SJohn Marino cfg_blocks_add (basic_block bb)
179*e4b17023SJohn Marino {
180*e4b17023SJohn Marino   bool head = false;
181*e4b17023SJohn Marino 
182*e4b17023SJohn Marino   gcc_assert (bb != ENTRY_BLOCK_PTR && bb != EXIT_BLOCK_PTR);
183*e4b17023SJohn Marino   gcc_assert (!TEST_BIT (bb_in_list, bb->index));
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino   if (cfg_blocks_empty_p ())
186*e4b17023SJohn Marino     {
187*e4b17023SJohn Marino       cfg_blocks_tail = cfg_blocks_head = 0;
188*e4b17023SJohn Marino       cfg_blocks_num = 1;
189*e4b17023SJohn Marino     }
190*e4b17023SJohn Marino   else
191*e4b17023SJohn Marino     {
192*e4b17023SJohn Marino       cfg_blocks_num++;
193*e4b17023SJohn Marino       if (cfg_blocks_num > VEC_length (basic_block, cfg_blocks))
194*e4b17023SJohn Marino 	{
195*e4b17023SJohn Marino 	  /* We have to grow the array now.  Adjust to queue to occupy
196*e4b17023SJohn Marino 	     the full space of the original array.  We do not need to
197*e4b17023SJohn Marino 	     initialize the newly allocated portion of the array
198*e4b17023SJohn Marino 	     because we keep track of CFG_BLOCKS_HEAD and
199*e4b17023SJohn Marino 	     CFG_BLOCKS_HEAD.  */
200*e4b17023SJohn Marino 	  cfg_blocks_tail = VEC_length (basic_block, cfg_blocks);
201*e4b17023SJohn Marino 	  cfg_blocks_head = 0;
202*e4b17023SJohn Marino 	  VEC_safe_grow (basic_block, heap, cfg_blocks, 2 * cfg_blocks_tail);
203*e4b17023SJohn Marino 	}
204*e4b17023SJohn Marino       /* Minor optimization: we prefer to see blocks with more
205*e4b17023SJohn Marino 	 predecessors later, because there is more of a chance that
206*e4b17023SJohn Marino 	 the incoming edges will be executable.  */
207*e4b17023SJohn Marino       else if (EDGE_COUNT (bb->preds)
208*e4b17023SJohn Marino 	       >= EDGE_COUNT (VEC_index (basic_block, cfg_blocks,
209*e4b17023SJohn Marino 					 cfg_blocks_head)->preds))
210*e4b17023SJohn Marino 	cfg_blocks_tail = ((cfg_blocks_tail + 1)
211*e4b17023SJohn Marino 			   % VEC_length (basic_block, cfg_blocks));
212*e4b17023SJohn Marino       else
213*e4b17023SJohn Marino 	{
214*e4b17023SJohn Marino 	  if (cfg_blocks_head == 0)
215*e4b17023SJohn Marino 	    cfg_blocks_head = VEC_length (basic_block, cfg_blocks);
216*e4b17023SJohn Marino 	  --cfg_blocks_head;
217*e4b17023SJohn Marino 	  head = true;
218*e4b17023SJohn Marino 	}
219*e4b17023SJohn Marino     }
220*e4b17023SJohn Marino 
221*e4b17023SJohn Marino   VEC_replace (basic_block, cfg_blocks,
222*e4b17023SJohn Marino 	       head ? cfg_blocks_head : cfg_blocks_tail,
223*e4b17023SJohn Marino 	       bb);
224*e4b17023SJohn Marino   SET_BIT (bb_in_list, bb->index);
225*e4b17023SJohn Marino }
226*e4b17023SJohn Marino 
227*e4b17023SJohn Marino 
228*e4b17023SJohn Marino /* Remove a block from the worklist.  */
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino static basic_block
cfg_blocks_get(void)231*e4b17023SJohn Marino cfg_blocks_get (void)
232*e4b17023SJohn Marino {
233*e4b17023SJohn Marino   basic_block bb;
234*e4b17023SJohn Marino 
235*e4b17023SJohn Marino   bb = VEC_index (basic_block, cfg_blocks, cfg_blocks_head);
236*e4b17023SJohn Marino 
237*e4b17023SJohn Marino   gcc_assert (!cfg_blocks_empty_p ());
238*e4b17023SJohn Marino   gcc_assert (bb);
239*e4b17023SJohn Marino 
240*e4b17023SJohn Marino   cfg_blocks_head = ((cfg_blocks_head + 1)
241*e4b17023SJohn Marino 		     % VEC_length (basic_block, cfg_blocks));
242*e4b17023SJohn Marino   --cfg_blocks_num;
243*e4b17023SJohn Marino   RESET_BIT (bb_in_list, bb->index);
244*e4b17023SJohn Marino 
245*e4b17023SJohn Marino   return bb;
246*e4b17023SJohn Marino }
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino 
249*e4b17023SJohn Marino /* We have just defined a new value for VAR.  If IS_VARYING is true,
250*e4b17023SJohn Marino    add all immediate uses of VAR to VARYING_SSA_EDGES, otherwise add
251*e4b17023SJohn Marino    them to INTERESTING_SSA_EDGES.  */
252*e4b17023SJohn Marino 
253*e4b17023SJohn Marino static void
add_ssa_edge(tree var,bool is_varying)254*e4b17023SJohn Marino add_ssa_edge (tree var, bool is_varying)
255*e4b17023SJohn Marino {
256*e4b17023SJohn Marino   imm_use_iterator iter;
257*e4b17023SJohn Marino   use_operand_p use_p;
258*e4b17023SJohn Marino 
259*e4b17023SJohn Marino   FOR_EACH_IMM_USE_FAST (use_p, iter, var)
260*e4b17023SJohn Marino     {
261*e4b17023SJohn Marino       gimple use_stmt = USE_STMT (use_p);
262*e4b17023SJohn Marino 
263*e4b17023SJohn Marino       if (prop_simulate_again_p (use_stmt)
264*e4b17023SJohn Marino 	  && !gimple_plf (use_stmt, STMT_IN_SSA_EDGE_WORKLIST))
265*e4b17023SJohn Marino 	{
266*e4b17023SJohn Marino 	  gimple_set_plf (use_stmt, STMT_IN_SSA_EDGE_WORKLIST, true);
267*e4b17023SJohn Marino 	  if (is_varying)
268*e4b17023SJohn Marino 	    VEC_safe_push (gimple, gc, varying_ssa_edges, use_stmt);
269*e4b17023SJohn Marino 	  else
270*e4b17023SJohn Marino 	    VEC_safe_push (gimple, gc, interesting_ssa_edges, use_stmt);
271*e4b17023SJohn Marino 	}
272*e4b17023SJohn Marino     }
273*e4b17023SJohn Marino }
274*e4b17023SJohn Marino 
275*e4b17023SJohn Marino 
276*e4b17023SJohn Marino /* Add edge E to the control flow worklist.  */
277*e4b17023SJohn Marino 
278*e4b17023SJohn Marino static void
add_control_edge(edge e)279*e4b17023SJohn Marino add_control_edge (edge e)
280*e4b17023SJohn Marino {
281*e4b17023SJohn Marino   basic_block bb = e->dest;
282*e4b17023SJohn Marino   if (bb == EXIT_BLOCK_PTR)
283*e4b17023SJohn Marino     return;
284*e4b17023SJohn Marino 
285*e4b17023SJohn Marino   /* If the edge had already been executed, skip it.  */
286*e4b17023SJohn Marino   if (e->flags & EDGE_EXECUTABLE)
287*e4b17023SJohn Marino     return;
288*e4b17023SJohn Marino 
289*e4b17023SJohn Marino   e->flags |= EDGE_EXECUTABLE;
290*e4b17023SJohn Marino 
291*e4b17023SJohn Marino   /* If the block is already in the list, we're done.  */
292*e4b17023SJohn Marino   if (TEST_BIT (bb_in_list, bb->index))
293*e4b17023SJohn Marino     return;
294*e4b17023SJohn Marino 
295*e4b17023SJohn Marino   cfg_blocks_add (bb);
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
298*e4b17023SJohn Marino     fprintf (dump_file, "Adding Destination of edge (%d -> %d) to worklist\n\n",
299*e4b17023SJohn Marino 	e->src->index, e->dest->index);
300*e4b17023SJohn Marino }
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino 
303*e4b17023SJohn Marino /* Simulate the execution of STMT and update the work lists accordingly.  */
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino static void
simulate_stmt(gimple stmt)306*e4b17023SJohn Marino simulate_stmt (gimple stmt)
307*e4b17023SJohn Marino {
308*e4b17023SJohn Marino   enum ssa_prop_result val = SSA_PROP_NOT_INTERESTING;
309*e4b17023SJohn Marino   edge taken_edge = NULL;
310*e4b17023SJohn Marino   tree output_name = NULL_TREE;
311*e4b17023SJohn Marino 
312*e4b17023SJohn Marino   /* Don't bother visiting statements that are already
313*e4b17023SJohn Marino      considered varying by the propagator.  */
314*e4b17023SJohn Marino   if (!prop_simulate_again_p (stmt))
315*e4b17023SJohn Marino     return;
316*e4b17023SJohn Marino 
317*e4b17023SJohn Marino   if (gimple_code (stmt) == GIMPLE_PHI)
318*e4b17023SJohn Marino     {
319*e4b17023SJohn Marino       val = ssa_prop_visit_phi (stmt);
320*e4b17023SJohn Marino       output_name = gimple_phi_result (stmt);
321*e4b17023SJohn Marino     }
322*e4b17023SJohn Marino   else
323*e4b17023SJohn Marino     val = ssa_prop_visit_stmt (stmt, &taken_edge, &output_name);
324*e4b17023SJohn Marino 
325*e4b17023SJohn Marino   if (val == SSA_PROP_VARYING)
326*e4b17023SJohn Marino     {
327*e4b17023SJohn Marino       prop_set_simulate_again (stmt, false);
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino       /* If the statement produced a new varying value, add the SSA
330*e4b17023SJohn Marino 	 edges coming out of OUTPUT_NAME.  */
331*e4b17023SJohn Marino       if (output_name)
332*e4b17023SJohn Marino 	add_ssa_edge (output_name, true);
333*e4b17023SJohn Marino 
334*e4b17023SJohn Marino       /* If STMT transfers control out of its basic block, add
335*e4b17023SJohn Marino 	 all outgoing edges to the work list.  */
336*e4b17023SJohn Marino       if (stmt_ends_bb_p (stmt))
337*e4b17023SJohn Marino 	{
338*e4b17023SJohn Marino 	  edge e;
339*e4b17023SJohn Marino 	  edge_iterator ei;
340*e4b17023SJohn Marino 	  basic_block bb = gimple_bb (stmt);
341*e4b17023SJohn Marino 	  FOR_EACH_EDGE (e, ei, bb->succs)
342*e4b17023SJohn Marino 	    add_control_edge (e);
343*e4b17023SJohn Marino 	}
344*e4b17023SJohn Marino     }
345*e4b17023SJohn Marino   else if (val == SSA_PROP_INTERESTING)
346*e4b17023SJohn Marino     {
347*e4b17023SJohn Marino       /* If the statement produced new value, add the SSA edges coming
348*e4b17023SJohn Marino 	 out of OUTPUT_NAME.  */
349*e4b17023SJohn Marino       if (output_name)
350*e4b17023SJohn Marino 	add_ssa_edge (output_name, false);
351*e4b17023SJohn Marino 
352*e4b17023SJohn Marino       /* If we know which edge is going to be taken out of this block,
353*e4b17023SJohn Marino 	 add it to the CFG work list.  */
354*e4b17023SJohn Marino       if (taken_edge)
355*e4b17023SJohn Marino 	add_control_edge (taken_edge);
356*e4b17023SJohn Marino     }
357*e4b17023SJohn Marino }
358*e4b17023SJohn Marino 
359*e4b17023SJohn Marino /* Process an SSA edge worklist.  WORKLIST is the SSA edge worklist to
360*e4b17023SJohn Marino    drain.  This pops statements off the given WORKLIST and processes
361*e4b17023SJohn Marino    them until there are no more statements on WORKLIST.
362*e4b17023SJohn Marino    We take a pointer to WORKLIST because it may be reallocated when an
363*e4b17023SJohn Marino    SSA edge is added to it in simulate_stmt.  */
364*e4b17023SJohn Marino 
365*e4b17023SJohn Marino static void
process_ssa_edge_worklist(VEC (gimple,gc)** worklist)366*e4b17023SJohn Marino process_ssa_edge_worklist (VEC(gimple,gc) **worklist)
367*e4b17023SJohn Marino {
368*e4b17023SJohn Marino   /* Drain the entire worklist.  */
369*e4b17023SJohn Marino   while (VEC_length (gimple, *worklist) > 0)
370*e4b17023SJohn Marino     {
371*e4b17023SJohn Marino       basic_block bb;
372*e4b17023SJohn Marino 
373*e4b17023SJohn Marino       /* Pull the statement to simulate off the worklist.  */
374*e4b17023SJohn Marino       gimple stmt = VEC_pop (gimple, *worklist);
375*e4b17023SJohn Marino 
376*e4b17023SJohn Marino       /* If this statement was already visited by simulate_block, then
377*e4b17023SJohn Marino 	 we don't need to visit it again here.  */
378*e4b17023SJohn Marino       if (!gimple_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST))
379*e4b17023SJohn Marino 	continue;
380*e4b17023SJohn Marino 
381*e4b17023SJohn Marino       /* STMT is no longer in a worklist.  */
382*e4b17023SJohn Marino       gimple_set_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST, false);
383*e4b17023SJohn Marino 
384*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
385*e4b17023SJohn Marino 	{
386*e4b17023SJohn Marino 	  fprintf (dump_file, "\nSimulating statement (from ssa_edges): ");
387*e4b17023SJohn Marino 	  print_gimple_stmt (dump_file, stmt, 0, dump_flags);
388*e4b17023SJohn Marino 	}
389*e4b17023SJohn Marino 
390*e4b17023SJohn Marino       bb = gimple_bb (stmt);
391*e4b17023SJohn Marino 
392*e4b17023SJohn Marino       /* PHI nodes are always visited, regardless of whether or not
393*e4b17023SJohn Marino 	 the destination block is executable.  Otherwise, visit the
394*e4b17023SJohn Marino 	 statement only if its block is marked executable.  */
395*e4b17023SJohn Marino       if (gimple_code (stmt) == GIMPLE_PHI
396*e4b17023SJohn Marino 	  || TEST_BIT (executable_blocks, bb->index))
397*e4b17023SJohn Marino 	simulate_stmt (stmt);
398*e4b17023SJohn Marino     }
399*e4b17023SJohn Marino }
400*e4b17023SJohn Marino 
401*e4b17023SJohn Marino 
402*e4b17023SJohn Marino /* Simulate the execution of BLOCK.  Evaluate the statement associated
403*e4b17023SJohn Marino    with each variable reference inside the block.  */
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino static void
simulate_block(basic_block block)406*e4b17023SJohn Marino simulate_block (basic_block block)
407*e4b17023SJohn Marino {
408*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
409*e4b17023SJohn Marino 
410*e4b17023SJohn Marino   /* There is nothing to do for the exit block.  */
411*e4b17023SJohn Marino   if (block == EXIT_BLOCK_PTR)
412*e4b17023SJohn Marino     return;
413*e4b17023SJohn Marino 
414*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
415*e4b17023SJohn Marino     fprintf (dump_file, "\nSimulating block %d\n", block->index);
416*e4b17023SJohn Marino 
417*e4b17023SJohn Marino   /* Always simulate PHI nodes, even if we have simulated this block
418*e4b17023SJohn Marino      before.  */
419*e4b17023SJohn Marino   for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
420*e4b17023SJohn Marino     simulate_stmt (gsi_stmt (gsi));
421*e4b17023SJohn Marino 
422*e4b17023SJohn Marino   /* If this is the first time we've simulated this block, then we
423*e4b17023SJohn Marino      must simulate each of its statements.  */
424*e4b17023SJohn Marino   if (!TEST_BIT (executable_blocks, block->index))
425*e4b17023SJohn Marino     {
426*e4b17023SJohn Marino       gimple_stmt_iterator j;
427*e4b17023SJohn Marino       unsigned int normal_edge_count;
428*e4b17023SJohn Marino       edge e, normal_edge;
429*e4b17023SJohn Marino       edge_iterator ei;
430*e4b17023SJohn Marino 
431*e4b17023SJohn Marino       /* Note that we have simulated this block.  */
432*e4b17023SJohn Marino       SET_BIT (executable_blocks, block->index);
433*e4b17023SJohn Marino 
434*e4b17023SJohn Marino       for (j = gsi_start_bb (block); !gsi_end_p (j); gsi_next (&j))
435*e4b17023SJohn Marino 	{
436*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (j);
437*e4b17023SJohn Marino 
438*e4b17023SJohn Marino 	  /* If this statement is already in the worklist then
439*e4b17023SJohn Marino 	     "cancel" it.  The reevaluation implied by the worklist
440*e4b17023SJohn Marino 	     entry will produce the same value we generate here and
441*e4b17023SJohn Marino 	     thus reevaluating it again from the worklist is
442*e4b17023SJohn Marino 	     pointless.  */
443*e4b17023SJohn Marino 	  if (gimple_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST))
444*e4b17023SJohn Marino 	    gimple_set_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST, false);
445*e4b17023SJohn Marino 
446*e4b17023SJohn Marino 	  simulate_stmt (stmt);
447*e4b17023SJohn Marino 	}
448*e4b17023SJohn Marino 
449*e4b17023SJohn Marino       /* We can not predict when abnormal and EH edges will be executed, so
450*e4b17023SJohn Marino 	 once a block is considered executable, we consider any
451*e4b17023SJohn Marino 	 outgoing abnormal edges as executable.
452*e4b17023SJohn Marino 
453*e4b17023SJohn Marino 	 TODO: This is not exactly true.  Simplifying statement might
454*e4b17023SJohn Marino 	 prove it non-throwing and also computed goto can be handled
455*e4b17023SJohn Marino 	 when destination is known.
456*e4b17023SJohn Marino 
457*e4b17023SJohn Marino 	 At the same time, if this block has only one successor that is
458*e4b17023SJohn Marino 	 reached by non-abnormal edges, then add that successor to the
459*e4b17023SJohn Marino 	 worklist.  */
460*e4b17023SJohn Marino       normal_edge_count = 0;
461*e4b17023SJohn Marino       normal_edge = NULL;
462*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, block->succs)
463*e4b17023SJohn Marino 	{
464*e4b17023SJohn Marino 	  if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
465*e4b17023SJohn Marino 	    add_control_edge (e);
466*e4b17023SJohn Marino 	  else
467*e4b17023SJohn Marino 	    {
468*e4b17023SJohn Marino 	      normal_edge_count++;
469*e4b17023SJohn Marino 	      normal_edge = e;
470*e4b17023SJohn Marino 	    }
471*e4b17023SJohn Marino 	}
472*e4b17023SJohn Marino 
473*e4b17023SJohn Marino       if (normal_edge_count == 1)
474*e4b17023SJohn Marino 	add_control_edge (normal_edge);
475*e4b17023SJohn Marino     }
476*e4b17023SJohn Marino }
477*e4b17023SJohn Marino 
478*e4b17023SJohn Marino 
479*e4b17023SJohn Marino /* Initialize local data structures and work lists.  */
480*e4b17023SJohn Marino 
481*e4b17023SJohn Marino static void
ssa_prop_init(void)482*e4b17023SJohn Marino ssa_prop_init (void)
483*e4b17023SJohn Marino {
484*e4b17023SJohn Marino   edge e;
485*e4b17023SJohn Marino   edge_iterator ei;
486*e4b17023SJohn Marino   basic_block bb;
487*e4b17023SJohn Marino 
488*e4b17023SJohn Marino   /* Worklists of SSA edges.  */
489*e4b17023SJohn Marino   interesting_ssa_edges = VEC_alloc (gimple, gc, 20);
490*e4b17023SJohn Marino   varying_ssa_edges = VEC_alloc (gimple, gc, 20);
491*e4b17023SJohn Marino 
492*e4b17023SJohn Marino   executable_blocks = sbitmap_alloc (last_basic_block);
493*e4b17023SJohn Marino   sbitmap_zero (executable_blocks);
494*e4b17023SJohn Marino 
495*e4b17023SJohn Marino   bb_in_list = sbitmap_alloc (last_basic_block);
496*e4b17023SJohn Marino   sbitmap_zero (bb_in_list);
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
499*e4b17023SJohn Marino     dump_immediate_uses (dump_file);
500*e4b17023SJohn Marino 
501*e4b17023SJohn Marino   cfg_blocks = VEC_alloc (basic_block, heap, 20);
502*e4b17023SJohn Marino   VEC_safe_grow (basic_block, heap, cfg_blocks, 20);
503*e4b17023SJohn Marino 
504*e4b17023SJohn Marino   /* Initially assume that every edge in the CFG is not executable.
505*e4b17023SJohn Marino      (including the edges coming out of ENTRY_BLOCK_PTR).  */
506*e4b17023SJohn Marino   FOR_ALL_BB (bb)
507*e4b17023SJohn Marino     {
508*e4b17023SJohn Marino       gimple_stmt_iterator si;
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
511*e4b17023SJohn Marino 	gimple_set_plf (gsi_stmt (si), STMT_IN_SSA_EDGE_WORKLIST, false);
512*e4b17023SJohn Marino 
513*e4b17023SJohn Marino       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
514*e4b17023SJohn Marino 	gimple_set_plf (gsi_stmt (si), STMT_IN_SSA_EDGE_WORKLIST, false);
515*e4b17023SJohn Marino 
516*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->succs)
517*e4b17023SJohn Marino 	e->flags &= ~EDGE_EXECUTABLE;
518*e4b17023SJohn Marino     }
519*e4b17023SJohn Marino 
520*e4b17023SJohn Marino   /* Seed the algorithm by adding the successors of the entry block to the
521*e4b17023SJohn Marino      edge worklist.  */
522*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
523*e4b17023SJohn Marino     add_control_edge (e);
524*e4b17023SJohn Marino }
525*e4b17023SJohn Marino 
526*e4b17023SJohn Marino 
527*e4b17023SJohn Marino /* Free allocated storage.  */
528*e4b17023SJohn Marino 
529*e4b17023SJohn Marino static void
ssa_prop_fini(void)530*e4b17023SJohn Marino ssa_prop_fini (void)
531*e4b17023SJohn Marino {
532*e4b17023SJohn Marino   VEC_free (gimple, gc, interesting_ssa_edges);
533*e4b17023SJohn Marino   VEC_free (gimple, gc, varying_ssa_edges);
534*e4b17023SJohn Marino   VEC_free (basic_block, heap, cfg_blocks);
535*e4b17023SJohn Marino   cfg_blocks = NULL;
536*e4b17023SJohn Marino   sbitmap_free (bb_in_list);
537*e4b17023SJohn Marino   sbitmap_free (executable_blocks);
538*e4b17023SJohn Marino }
539*e4b17023SJohn Marino 
540*e4b17023SJohn Marino 
541*e4b17023SJohn Marino /* Return true if EXPR is an acceptable right-hand-side for a
542*e4b17023SJohn Marino    GIMPLE assignment.  We validate the entire tree, not just
543*e4b17023SJohn Marino    the root node, thus catching expressions that embed complex
544*e4b17023SJohn Marino    operands that are not permitted in GIMPLE.  This function
545*e4b17023SJohn Marino    is needed because the folding routines in fold-const.c
546*e4b17023SJohn Marino    may return such expressions in some cases, e.g., an array
547*e4b17023SJohn Marino    access with an embedded index addition.  It may make more
548*e4b17023SJohn Marino    sense to have folding routines that are sensitive to the
549*e4b17023SJohn Marino    constraints on GIMPLE operands, rather than abandoning any
550*e4b17023SJohn Marino    any attempt to fold if the usual folding turns out to be too
551*e4b17023SJohn Marino    aggressive.  */
552*e4b17023SJohn Marino 
553*e4b17023SJohn Marino bool
valid_gimple_rhs_p(tree expr)554*e4b17023SJohn Marino valid_gimple_rhs_p (tree expr)
555*e4b17023SJohn Marino {
556*e4b17023SJohn Marino   enum tree_code code = TREE_CODE (expr);
557*e4b17023SJohn Marino 
558*e4b17023SJohn Marino   switch (TREE_CODE_CLASS (code))
559*e4b17023SJohn Marino     {
560*e4b17023SJohn Marino     case tcc_declaration:
561*e4b17023SJohn Marino       if (!is_gimple_variable (expr))
562*e4b17023SJohn Marino 	return false;
563*e4b17023SJohn Marino       break;
564*e4b17023SJohn Marino 
565*e4b17023SJohn Marino     case tcc_constant:
566*e4b17023SJohn Marino       /* All constants are ok.  */
567*e4b17023SJohn Marino       break;
568*e4b17023SJohn Marino 
569*e4b17023SJohn Marino     case tcc_binary:
570*e4b17023SJohn Marino     case tcc_comparison:
571*e4b17023SJohn Marino       if (!is_gimple_val (TREE_OPERAND (expr, 0))
572*e4b17023SJohn Marino 	  || !is_gimple_val (TREE_OPERAND (expr, 1)))
573*e4b17023SJohn Marino 	return false;
574*e4b17023SJohn Marino       break;
575*e4b17023SJohn Marino 
576*e4b17023SJohn Marino     case tcc_unary:
577*e4b17023SJohn Marino       if (!is_gimple_val (TREE_OPERAND (expr, 0)))
578*e4b17023SJohn Marino 	return false;
579*e4b17023SJohn Marino       break;
580*e4b17023SJohn Marino 
581*e4b17023SJohn Marino     case tcc_expression:
582*e4b17023SJohn Marino       switch (code)
583*e4b17023SJohn Marino         {
584*e4b17023SJohn Marino         case ADDR_EXPR:
585*e4b17023SJohn Marino           {
586*e4b17023SJohn Marino 	    tree t;
587*e4b17023SJohn Marino 	    if (is_gimple_min_invariant (expr))
588*e4b17023SJohn Marino 	      return true;
589*e4b17023SJohn Marino             t = TREE_OPERAND (expr, 0);
590*e4b17023SJohn Marino             while (handled_component_p (t))
591*e4b17023SJohn Marino               {
592*e4b17023SJohn Marino                 /* ??? More checks needed, see the GIMPLE verifier.  */
593*e4b17023SJohn Marino                 if ((TREE_CODE (t) == ARRAY_REF
594*e4b17023SJohn Marino                      || TREE_CODE (t) == ARRAY_RANGE_REF)
595*e4b17023SJohn Marino                     && !is_gimple_val (TREE_OPERAND (t, 1)))
596*e4b17023SJohn Marino                   return false;
597*e4b17023SJohn Marino                 t = TREE_OPERAND (t, 0);
598*e4b17023SJohn Marino               }
599*e4b17023SJohn Marino             if (!is_gimple_id (t))
600*e4b17023SJohn Marino               return false;
601*e4b17023SJohn Marino           }
602*e4b17023SJohn Marino           break;
603*e4b17023SJohn Marino 
604*e4b17023SJohn Marino 	default:
605*e4b17023SJohn Marino 	  if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
606*e4b17023SJohn Marino 	    {
607*e4b17023SJohn Marino 	      if (((code == VEC_COND_EXPR || code == COND_EXPR)
608*e4b17023SJohn Marino 		   ? !is_gimple_condexpr (TREE_OPERAND (expr, 0))
609*e4b17023SJohn Marino 		   : !is_gimple_val (TREE_OPERAND (expr, 0)))
610*e4b17023SJohn Marino 		  || !is_gimple_val (TREE_OPERAND (expr, 1))
611*e4b17023SJohn Marino 		  || !is_gimple_val (TREE_OPERAND (expr, 2)))
612*e4b17023SJohn Marino 		return false;
613*e4b17023SJohn Marino 	      break;
614*e4b17023SJohn Marino 	    }
615*e4b17023SJohn Marino 	  return false;
616*e4b17023SJohn Marino 	}
617*e4b17023SJohn Marino       break;
618*e4b17023SJohn Marino 
619*e4b17023SJohn Marino     case tcc_vl_exp:
620*e4b17023SJohn Marino       return false;
621*e4b17023SJohn Marino 
622*e4b17023SJohn Marino     case tcc_exceptional:
623*e4b17023SJohn Marino       if (code != SSA_NAME)
624*e4b17023SJohn Marino         return false;
625*e4b17023SJohn Marino       break;
626*e4b17023SJohn Marino 
627*e4b17023SJohn Marino     default:
628*e4b17023SJohn Marino       return false;
629*e4b17023SJohn Marino     }
630*e4b17023SJohn Marino 
631*e4b17023SJohn Marino   return true;
632*e4b17023SJohn Marino }
633*e4b17023SJohn Marino 
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino /* Return true if EXPR is a CALL_EXPR suitable for representation
636*e4b17023SJohn Marino    as a single GIMPLE_CALL statement.  If the arguments require
637*e4b17023SJohn Marino    further gimplification, return false.  */
638*e4b17023SJohn Marino 
639*e4b17023SJohn Marino static bool
valid_gimple_call_p(tree expr)640*e4b17023SJohn Marino valid_gimple_call_p (tree expr)
641*e4b17023SJohn Marino {
642*e4b17023SJohn Marino   unsigned i, nargs;
643*e4b17023SJohn Marino 
644*e4b17023SJohn Marino   if (TREE_CODE (expr) != CALL_EXPR)
645*e4b17023SJohn Marino     return false;
646*e4b17023SJohn Marino 
647*e4b17023SJohn Marino   nargs = call_expr_nargs (expr);
648*e4b17023SJohn Marino   for (i = 0; i < nargs; i++)
649*e4b17023SJohn Marino     {
650*e4b17023SJohn Marino       tree arg = CALL_EXPR_ARG (expr, i);
651*e4b17023SJohn Marino       if (is_gimple_reg_type (arg))
652*e4b17023SJohn Marino 	{
653*e4b17023SJohn Marino 	  if (!is_gimple_val (arg))
654*e4b17023SJohn Marino 	    return false;
655*e4b17023SJohn Marino 	}
656*e4b17023SJohn Marino       else
657*e4b17023SJohn Marino 	if (!is_gimple_lvalue (arg))
658*e4b17023SJohn Marino 	  return false;
659*e4b17023SJohn Marino     }
660*e4b17023SJohn Marino 
661*e4b17023SJohn Marino   return true;
662*e4b17023SJohn Marino }
663*e4b17023SJohn Marino 
664*e4b17023SJohn Marino 
665*e4b17023SJohn Marino /* Make SSA names defined by OLD_STMT point to NEW_STMT
666*e4b17023SJohn Marino    as their defining statement.  */
667*e4b17023SJohn Marino 
668*e4b17023SJohn Marino void
move_ssa_defining_stmt_for_defs(gimple new_stmt,gimple old_stmt)669*e4b17023SJohn Marino move_ssa_defining_stmt_for_defs (gimple new_stmt, gimple old_stmt)
670*e4b17023SJohn Marino {
671*e4b17023SJohn Marino   tree var;
672*e4b17023SJohn Marino   ssa_op_iter iter;
673*e4b17023SJohn Marino 
674*e4b17023SJohn Marino   if (gimple_in_ssa_p (cfun))
675*e4b17023SJohn Marino     {
676*e4b17023SJohn Marino       /* Make defined SSA_NAMEs point to the new
677*e4b17023SJohn Marino          statement as their definition.  */
678*e4b17023SJohn Marino       FOR_EACH_SSA_TREE_OPERAND (var, old_stmt, iter, SSA_OP_ALL_DEFS)
679*e4b17023SJohn Marino         {
680*e4b17023SJohn Marino           if (TREE_CODE (var) == SSA_NAME)
681*e4b17023SJohn Marino             SSA_NAME_DEF_STMT (var) = new_stmt;
682*e4b17023SJohn Marino         }
683*e4b17023SJohn Marino     }
684*e4b17023SJohn Marino }
685*e4b17023SJohn Marino 
686*e4b17023SJohn Marino /* Helper function for update_gimple_call and update_call_from_tree.
687*e4b17023SJohn Marino    A GIMPLE_CALL STMT is being replaced with GIMPLE_CALL NEW_STMT.  */
688*e4b17023SJohn Marino 
689*e4b17023SJohn Marino static void
finish_update_gimple_call(gimple_stmt_iterator * si_p,gimple new_stmt,gimple stmt)690*e4b17023SJohn Marino finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple new_stmt,
691*e4b17023SJohn Marino 			   gimple stmt)
692*e4b17023SJohn Marino {
693*e4b17023SJohn Marino   gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
694*e4b17023SJohn Marino   move_ssa_defining_stmt_for_defs (new_stmt, stmt);
695*e4b17023SJohn Marino   gimple_set_vuse (new_stmt, gimple_vuse (stmt));
696*e4b17023SJohn Marino   gimple_set_vdef (new_stmt, gimple_vdef (stmt));
697*e4b17023SJohn Marino   gimple_set_location (new_stmt, gimple_location (stmt));
698*e4b17023SJohn Marino   if (gimple_block (new_stmt) == NULL_TREE)
699*e4b17023SJohn Marino     gimple_set_block (new_stmt, gimple_block (stmt));
700*e4b17023SJohn Marino   gsi_replace (si_p, new_stmt, false);
701*e4b17023SJohn Marino }
702*e4b17023SJohn Marino 
703*e4b17023SJohn Marino /* Update a GIMPLE_CALL statement at iterator *SI_P to call to FN
704*e4b17023SJohn Marino    with number of arguments NARGS, where the arguments in GIMPLE form
705*e4b17023SJohn Marino    follow NARGS argument.  */
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino bool
update_gimple_call(gimple_stmt_iterator * si_p,tree fn,int nargs,...)708*e4b17023SJohn Marino update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
709*e4b17023SJohn Marino {
710*e4b17023SJohn Marino   va_list ap;
711*e4b17023SJohn Marino   gimple new_stmt, stmt = gsi_stmt (*si_p);
712*e4b17023SJohn Marino 
713*e4b17023SJohn Marino   gcc_assert (is_gimple_call (stmt));
714*e4b17023SJohn Marino   va_start (ap, nargs);
715*e4b17023SJohn Marino   new_stmt = gimple_build_call_valist (fn, nargs, ap);
716*e4b17023SJohn Marino   finish_update_gimple_call (si_p, new_stmt, stmt);
717*e4b17023SJohn Marino   va_end (ap);
718*e4b17023SJohn Marino   return true;
719*e4b17023SJohn Marino }
720*e4b17023SJohn Marino 
721*e4b17023SJohn Marino /* Update a GIMPLE_CALL statement at iterator *SI_P to reflect the
722*e4b17023SJohn Marino    value of EXPR, which is expected to be the result of folding the
723*e4b17023SJohn Marino    call.  This can only be done if EXPR is a CALL_EXPR with valid
724*e4b17023SJohn Marino    GIMPLE operands as arguments, or if it is a suitable RHS expression
725*e4b17023SJohn Marino    for a GIMPLE_ASSIGN.  More complex expressions will require
726*e4b17023SJohn Marino    gimplification, which will introduce addtional statements.  In this
727*e4b17023SJohn Marino    event, no update is performed, and the function returns false.
728*e4b17023SJohn Marino    Note that we cannot mutate a GIMPLE_CALL in-place, so we always
729*e4b17023SJohn Marino    replace the statement at *SI_P with an entirely new statement.
730*e4b17023SJohn Marino    The new statement need not be a call, e.g., if the original call
731*e4b17023SJohn Marino    folded to a constant.  */
732*e4b17023SJohn Marino 
733*e4b17023SJohn Marino bool
update_call_from_tree(gimple_stmt_iterator * si_p,tree expr)734*e4b17023SJohn Marino update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
735*e4b17023SJohn Marino {
736*e4b17023SJohn Marino   gimple stmt = gsi_stmt (*si_p);
737*e4b17023SJohn Marino 
738*e4b17023SJohn Marino   if (valid_gimple_call_p (expr))
739*e4b17023SJohn Marino     {
740*e4b17023SJohn Marino       /* The call has simplified to another call.  */
741*e4b17023SJohn Marino       tree fn = CALL_EXPR_FN (expr);
742*e4b17023SJohn Marino       unsigned i;
743*e4b17023SJohn Marino       unsigned nargs = call_expr_nargs (expr);
744*e4b17023SJohn Marino       VEC(tree, heap) *args = NULL;
745*e4b17023SJohn Marino       gimple new_stmt;
746*e4b17023SJohn Marino 
747*e4b17023SJohn Marino       if (nargs > 0)
748*e4b17023SJohn Marino         {
749*e4b17023SJohn Marino           args = VEC_alloc (tree, heap, nargs);
750*e4b17023SJohn Marino           VEC_safe_grow (tree, heap, args, nargs);
751*e4b17023SJohn Marino 
752*e4b17023SJohn Marino           for (i = 0; i < nargs; i++)
753*e4b17023SJohn Marino             VEC_replace (tree, args, i, CALL_EXPR_ARG (expr, i));
754*e4b17023SJohn Marino         }
755*e4b17023SJohn Marino 
756*e4b17023SJohn Marino       new_stmt = gimple_build_call_vec (fn, args);
757*e4b17023SJohn Marino       finish_update_gimple_call (si_p, new_stmt, stmt);
758*e4b17023SJohn Marino       VEC_free (tree, heap, args);
759*e4b17023SJohn Marino 
760*e4b17023SJohn Marino       return true;
761*e4b17023SJohn Marino     }
762*e4b17023SJohn Marino   else if (valid_gimple_rhs_p (expr))
763*e4b17023SJohn Marino     {
764*e4b17023SJohn Marino       tree lhs = gimple_call_lhs (stmt);
765*e4b17023SJohn Marino       gimple new_stmt;
766*e4b17023SJohn Marino 
767*e4b17023SJohn Marino       /* The call has simplified to an expression
768*e4b17023SJohn Marino          that cannot be represented as a GIMPLE_CALL. */
769*e4b17023SJohn Marino       if (lhs)
770*e4b17023SJohn Marino         {
771*e4b17023SJohn Marino           /* A value is expected.
772*e4b17023SJohn Marino              Introduce a new GIMPLE_ASSIGN statement.  */
773*e4b17023SJohn Marino           STRIP_USELESS_TYPE_CONVERSION (expr);
774*e4b17023SJohn Marino           new_stmt = gimple_build_assign (lhs, expr);
775*e4b17023SJohn Marino           move_ssa_defining_stmt_for_defs (new_stmt, stmt);
776*e4b17023SJohn Marino 	  gimple_set_vuse (new_stmt, gimple_vuse (stmt));
777*e4b17023SJohn Marino 	  gimple_set_vdef (new_stmt, gimple_vdef (stmt));
778*e4b17023SJohn Marino         }
779*e4b17023SJohn Marino       else if (!TREE_SIDE_EFFECTS (expr))
780*e4b17023SJohn Marino         {
781*e4b17023SJohn Marino           /* No value is expected, and EXPR has no effect.
782*e4b17023SJohn Marino              Replace it with an empty statement.  */
783*e4b17023SJohn Marino           new_stmt = gimple_build_nop ();
784*e4b17023SJohn Marino 	  if (gimple_in_ssa_p (cfun))
785*e4b17023SJohn Marino 	    {
786*e4b17023SJohn Marino 	      unlink_stmt_vdef (stmt);
787*e4b17023SJohn Marino 	      release_defs (stmt);
788*e4b17023SJohn Marino 	    }
789*e4b17023SJohn Marino         }
790*e4b17023SJohn Marino       else
791*e4b17023SJohn Marino         {
792*e4b17023SJohn Marino           /* No value is expected, but EXPR has an effect,
793*e4b17023SJohn Marino              e.g., it could be a reference to a volatile
794*e4b17023SJohn Marino              variable.  Create an assignment statement
795*e4b17023SJohn Marino              with a dummy (unused) lhs variable.  */
796*e4b17023SJohn Marino           STRIP_USELESS_TYPE_CONVERSION (expr);
797*e4b17023SJohn Marino           lhs = create_tmp_var (TREE_TYPE (expr), NULL);
798*e4b17023SJohn Marino           new_stmt = gimple_build_assign (lhs, expr);
799*e4b17023SJohn Marino           add_referenced_var (lhs);
800*e4b17023SJohn Marino 	  if (gimple_in_ssa_p (cfun))
801*e4b17023SJohn Marino 	    lhs = make_ssa_name (lhs, new_stmt);
802*e4b17023SJohn Marino           gimple_assign_set_lhs (new_stmt, lhs);
803*e4b17023SJohn Marino 	  gimple_set_vuse (new_stmt, gimple_vuse (stmt));
804*e4b17023SJohn Marino 	  gimple_set_vdef (new_stmt, gimple_vdef (stmt));
805*e4b17023SJohn Marino           move_ssa_defining_stmt_for_defs (new_stmt, stmt);
806*e4b17023SJohn Marino         }
807*e4b17023SJohn Marino       gimple_set_location (new_stmt, gimple_location (stmt));
808*e4b17023SJohn Marino       gsi_replace (si_p, new_stmt, false);
809*e4b17023SJohn Marino       return true;
810*e4b17023SJohn Marino     }
811*e4b17023SJohn Marino   else
812*e4b17023SJohn Marino     /* The call simplified to an expression that is
813*e4b17023SJohn Marino        not a valid GIMPLE RHS.  */
814*e4b17023SJohn Marino     return false;
815*e4b17023SJohn Marino }
816*e4b17023SJohn Marino 
817*e4b17023SJohn Marino 
818*e4b17023SJohn Marino /* Entry point to the propagation engine.
819*e4b17023SJohn Marino 
820*e4b17023SJohn Marino    VISIT_STMT is called for every statement visited.
821*e4b17023SJohn Marino    VISIT_PHI is called for every PHI node visited.  */
822*e4b17023SJohn Marino 
823*e4b17023SJohn Marino void
ssa_propagate(ssa_prop_visit_stmt_fn visit_stmt,ssa_prop_visit_phi_fn visit_phi)824*e4b17023SJohn Marino ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt,
825*e4b17023SJohn Marino 	       ssa_prop_visit_phi_fn visit_phi)
826*e4b17023SJohn Marino {
827*e4b17023SJohn Marino   ssa_prop_visit_stmt = visit_stmt;
828*e4b17023SJohn Marino   ssa_prop_visit_phi = visit_phi;
829*e4b17023SJohn Marino 
830*e4b17023SJohn Marino   ssa_prop_init ();
831*e4b17023SJohn Marino 
832*e4b17023SJohn Marino   /* Iterate until the worklists are empty.  */
833*e4b17023SJohn Marino   while (!cfg_blocks_empty_p ()
834*e4b17023SJohn Marino 	 || VEC_length (gimple, interesting_ssa_edges) > 0
835*e4b17023SJohn Marino 	 || VEC_length (gimple, varying_ssa_edges) > 0)
836*e4b17023SJohn Marino     {
837*e4b17023SJohn Marino       if (!cfg_blocks_empty_p ())
838*e4b17023SJohn Marino 	{
839*e4b17023SJohn Marino 	  /* Pull the next block to simulate off the worklist.  */
840*e4b17023SJohn Marino 	  basic_block dest_block = cfg_blocks_get ();
841*e4b17023SJohn Marino 	  simulate_block (dest_block);
842*e4b17023SJohn Marino 	}
843*e4b17023SJohn Marino 
844*e4b17023SJohn Marino       /* In order to move things to varying as quickly as
845*e4b17023SJohn Marino 	 possible,process the VARYING_SSA_EDGES worklist first.  */
846*e4b17023SJohn Marino       process_ssa_edge_worklist (&varying_ssa_edges);
847*e4b17023SJohn Marino 
848*e4b17023SJohn Marino       /* Now process the INTERESTING_SSA_EDGES worklist.  */
849*e4b17023SJohn Marino       process_ssa_edge_worklist (&interesting_ssa_edges);
850*e4b17023SJohn Marino     }
851*e4b17023SJohn Marino 
852*e4b17023SJohn Marino   ssa_prop_fini ();
853*e4b17023SJohn Marino }
854*e4b17023SJohn Marino 
855*e4b17023SJohn Marino 
856*e4b17023SJohn Marino /* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref'
857*e4b17023SJohn Marino    is a non-volatile pointer dereference, a structure reference or a
858*e4b17023SJohn Marino    reference to a single _DECL.  Ignore volatile memory references
859*e4b17023SJohn Marino    because they are not interesting for the optimizers.  */
860*e4b17023SJohn Marino 
861*e4b17023SJohn Marino bool
stmt_makes_single_store(gimple stmt)862*e4b17023SJohn Marino stmt_makes_single_store (gimple stmt)
863*e4b17023SJohn Marino {
864*e4b17023SJohn Marino   tree lhs;
865*e4b17023SJohn Marino 
866*e4b17023SJohn Marino   if (gimple_code (stmt) != GIMPLE_ASSIGN
867*e4b17023SJohn Marino       && gimple_code (stmt) != GIMPLE_CALL)
868*e4b17023SJohn Marino     return false;
869*e4b17023SJohn Marino 
870*e4b17023SJohn Marino   if (!gimple_vdef (stmt))
871*e4b17023SJohn Marino     return false;
872*e4b17023SJohn Marino 
873*e4b17023SJohn Marino   lhs = gimple_get_lhs (stmt);
874*e4b17023SJohn Marino 
875*e4b17023SJohn Marino   /* A call statement may have a null LHS.  */
876*e4b17023SJohn Marino   if (!lhs)
877*e4b17023SJohn Marino     return false;
878*e4b17023SJohn Marino 
879*e4b17023SJohn Marino   return (!TREE_THIS_VOLATILE (lhs)
880*e4b17023SJohn Marino           && (DECL_P (lhs)
881*e4b17023SJohn Marino 	      || REFERENCE_CLASS_P (lhs)));
882*e4b17023SJohn Marino }
883*e4b17023SJohn Marino 
884*e4b17023SJohn Marino 
885*e4b17023SJohn Marino /* Propagation statistics.  */
886*e4b17023SJohn Marino struct prop_stats_d
887*e4b17023SJohn Marino {
888*e4b17023SJohn Marino   long num_const_prop;
889*e4b17023SJohn Marino   long num_copy_prop;
890*e4b17023SJohn Marino   long num_stmts_folded;
891*e4b17023SJohn Marino   long num_dce;
892*e4b17023SJohn Marino };
893*e4b17023SJohn Marino 
894*e4b17023SJohn Marino static struct prop_stats_d prop_stats;
895*e4b17023SJohn Marino 
896*e4b17023SJohn Marino /* Replace USE references in statement STMT with the values stored in
897*e4b17023SJohn Marino    PROP_VALUE. Return true if at least one reference was replaced.  */
898*e4b17023SJohn Marino 
899*e4b17023SJohn Marino static bool
replace_uses_in(gimple stmt,ssa_prop_get_value_fn get_value)900*e4b17023SJohn Marino replace_uses_in (gimple stmt, ssa_prop_get_value_fn get_value)
901*e4b17023SJohn Marino {
902*e4b17023SJohn Marino   bool replaced = false;
903*e4b17023SJohn Marino   use_operand_p use;
904*e4b17023SJohn Marino   ssa_op_iter iter;
905*e4b17023SJohn Marino 
906*e4b17023SJohn Marino   FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
907*e4b17023SJohn Marino     {
908*e4b17023SJohn Marino       tree tuse = USE_FROM_PTR (use);
909*e4b17023SJohn Marino       tree val = (*get_value) (tuse);
910*e4b17023SJohn Marino 
911*e4b17023SJohn Marino       if (val == tuse || val == NULL_TREE)
912*e4b17023SJohn Marino 	continue;
913*e4b17023SJohn Marino 
914*e4b17023SJohn Marino       if (gimple_code (stmt) == GIMPLE_ASM
915*e4b17023SJohn Marino 	  && !may_propagate_copy_into_asm (tuse))
916*e4b17023SJohn Marino 	continue;
917*e4b17023SJohn Marino 
918*e4b17023SJohn Marino       if (!may_propagate_copy (tuse, val))
919*e4b17023SJohn Marino 	continue;
920*e4b17023SJohn Marino 
921*e4b17023SJohn Marino       if (TREE_CODE (val) != SSA_NAME)
922*e4b17023SJohn Marino 	prop_stats.num_const_prop++;
923*e4b17023SJohn Marino       else
924*e4b17023SJohn Marino 	prop_stats.num_copy_prop++;
925*e4b17023SJohn Marino 
926*e4b17023SJohn Marino       propagate_value (use, val);
927*e4b17023SJohn Marino 
928*e4b17023SJohn Marino       replaced = true;
929*e4b17023SJohn Marino     }
930*e4b17023SJohn Marino 
931*e4b17023SJohn Marino   return replaced;
932*e4b17023SJohn Marino }
933*e4b17023SJohn Marino 
934*e4b17023SJohn Marino 
935*e4b17023SJohn Marino /* Replace propagated values into all the arguments for PHI using the
936*e4b17023SJohn Marino    values from PROP_VALUE.  */
937*e4b17023SJohn Marino 
938*e4b17023SJohn Marino static void
replace_phi_args_in(gimple phi,ssa_prop_get_value_fn get_value)939*e4b17023SJohn Marino replace_phi_args_in (gimple phi, ssa_prop_get_value_fn get_value)
940*e4b17023SJohn Marino {
941*e4b17023SJohn Marino   size_t i;
942*e4b17023SJohn Marino   bool replaced = false;
943*e4b17023SJohn Marino 
944*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
945*e4b17023SJohn Marino     {
946*e4b17023SJohn Marino       fprintf (dump_file, "Folding PHI node: ");
947*e4b17023SJohn Marino       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
948*e4b17023SJohn Marino     }
949*e4b17023SJohn Marino 
950*e4b17023SJohn Marino   for (i = 0; i < gimple_phi_num_args (phi); i++)
951*e4b17023SJohn Marino     {
952*e4b17023SJohn Marino       tree arg = gimple_phi_arg_def (phi, i);
953*e4b17023SJohn Marino 
954*e4b17023SJohn Marino       if (TREE_CODE (arg) == SSA_NAME)
955*e4b17023SJohn Marino 	{
956*e4b17023SJohn Marino 	  tree val = (*get_value) (arg);
957*e4b17023SJohn Marino 
958*e4b17023SJohn Marino 	  if (val && val != arg && may_propagate_copy (arg, val))
959*e4b17023SJohn Marino 	    {
960*e4b17023SJohn Marino 	      if (TREE_CODE (val) != SSA_NAME)
961*e4b17023SJohn Marino 		prop_stats.num_const_prop++;
962*e4b17023SJohn Marino 	      else
963*e4b17023SJohn Marino 		prop_stats.num_copy_prop++;
964*e4b17023SJohn Marino 
965*e4b17023SJohn Marino 	      propagate_value (PHI_ARG_DEF_PTR (phi, i), val);
966*e4b17023SJohn Marino 	      replaced = true;
967*e4b17023SJohn Marino 
968*e4b17023SJohn Marino 	      /* If we propagated a copy and this argument flows
969*e4b17023SJohn Marino 		 through an abnormal edge, update the replacement
970*e4b17023SJohn Marino 		 accordingly.  */
971*e4b17023SJohn Marino 	      if (TREE_CODE (val) == SSA_NAME
972*e4b17023SJohn Marino 		  && gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
973*e4b17023SJohn Marino 		SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
974*e4b17023SJohn Marino 	    }
975*e4b17023SJohn Marino 	}
976*e4b17023SJohn Marino     }
977*e4b17023SJohn Marino 
978*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
979*e4b17023SJohn Marino     {
980*e4b17023SJohn Marino       if (!replaced)
981*e4b17023SJohn Marino 	fprintf (dump_file, "No folding possible\n");
982*e4b17023SJohn Marino       else
983*e4b17023SJohn Marino 	{
984*e4b17023SJohn Marino 	  fprintf (dump_file, "Folded into: ");
985*e4b17023SJohn Marino 	  print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
986*e4b17023SJohn Marino 	  fprintf (dump_file, "\n");
987*e4b17023SJohn Marino 	}
988*e4b17023SJohn Marino     }
989*e4b17023SJohn Marino }
990*e4b17023SJohn Marino 
991*e4b17023SJohn Marino 
992*e4b17023SJohn Marino /* Perform final substitution and folding of propagated values.
993*e4b17023SJohn Marino 
994*e4b17023SJohn Marino    PROP_VALUE[I] contains the single value that should be substituted
995*e4b17023SJohn Marino    at every use of SSA name N_I.  If PROP_VALUE is NULL, no values are
996*e4b17023SJohn Marino    substituted.
997*e4b17023SJohn Marino 
998*e4b17023SJohn Marino    If FOLD_FN is non-NULL the function will be invoked on all statements
999*e4b17023SJohn Marino    before propagating values for pass specific simplification.
1000*e4b17023SJohn Marino 
1001*e4b17023SJohn Marino    DO_DCE is true if trivially dead stmts can be removed.
1002*e4b17023SJohn Marino 
1003*e4b17023SJohn Marino    If DO_DCE is true, the statements within a BB are walked from
1004*e4b17023SJohn Marino    last to first element.  Otherwise we scan from first to last element.
1005*e4b17023SJohn Marino 
1006*e4b17023SJohn Marino    Return TRUE when something changed.  */
1007*e4b17023SJohn Marino 
1008*e4b17023SJohn Marino bool
substitute_and_fold(ssa_prop_get_value_fn get_value_fn,ssa_prop_fold_stmt_fn fold_fn,bool do_dce)1009*e4b17023SJohn Marino substitute_and_fold (ssa_prop_get_value_fn get_value_fn,
1010*e4b17023SJohn Marino 		     ssa_prop_fold_stmt_fn fold_fn,
1011*e4b17023SJohn Marino 		     bool do_dce)
1012*e4b17023SJohn Marino {
1013*e4b17023SJohn Marino   basic_block bb;
1014*e4b17023SJohn Marino   bool something_changed = false;
1015*e4b17023SJohn Marino   unsigned i;
1016*e4b17023SJohn Marino 
1017*e4b17023SJohn Marino   if (!get_value_fn && !fold_fn)
1018*e4b17023SJohn Marino     return false;
1019*e4b17023SJohn Marino 
1020*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
1021*e4b17023SJohn Marino     fprintf (dump_file, "\nSubstituting values and folding statements\n\n");
1022*e4b17023SJohn Marino 
1023*e4b17023SJohn Marino   memset (&prop_stats, 0, sizeof (prop_stats));
1024*e4b17023SJohn Marino 
1025*e4b17023SJohn Marino   /* Substitute lattice values at definition sites.  */
1026*e4b17023SJohn Marino   if (get_value_fn)
1027*e4b17023SJohn Marino     for (i = 1; i < num_ssa_names; ++i)
1028*e4b17023SJohn Marino       {
1029*e4b17023SJohn Marino 	tree name = ssa_name (i);
1030*e4b17023SJohn Marino 	tree val;
1031*e4b17023SJohn Marino 	gimple def_stmt;
1032*e4b17023SJohn Marino 	gimple_stmt_iterator gsi;
1033*e4b17023SJohn Marino 
1034*e4b17023SJohn Marino 	if (!name
1035*e4b17023SJohn Marino 	    || !is_gimple_reg (name))
1036*e4b17023SJohn Marino 	  continue;
1037*e4b17023SJohn Marino 
1038*e4b17023SJohn Marino 	def_stmt = SSA_NAME_DEF_STMT (name);
1039*e4b17023SJohn Marino 	if (gimple_nop_p (def_stmt)
1040*e4b17023SJohn Marino 	    /* Do not substitute ASSERT_EXPR rhs, this will confuse VRP.  */
1041*e4b17023SJohn Marino 	    || (gimple_assign_single_p (def_stmt)
1042*e4b17023SJohn Marino 		&& gimple_assign_rhs_code (def_stmt) == ASSERT_EXPR)
1043*e4b17023SJohn Marino 	    || !(val = (*get_value_fn) (name))
1044*e4b17023SJohn Marino 	    || !may_propagate_copy (name, val))
1045*e4b17023SJohn Marino 	  continue;
1046*e4b17023SJohn Marino 
1047*e4b17023SJohn Marino 	gsi = gsi_for_stmt (def_stmt);
1048*e4b17023SJohn Marino 	if (is_gimple_assign (def_stmt))
1049*e4b17023SJohn Marino 	  {
1050*e4b17023SJohn Marino 	    gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val),
1051*e4b17023SJohn Marino 					    val, NULL_TREE);
1052*e4b17023SJohn Marino 	    gcc_assert (gsi_stmt (gsi) == def_stmt);
1053*e4b17023SJohn Marino 	    if (maybe_clean_eh_stmt (def_stmt))
1054*e4b17023SJohn Marino 	      gimple_purge_dead_eh_edges (gimple_bb (def_stmt));
1055*e4b17023SJohn Marino 	    update_stmt (def_stmt);
1056*e4b17023SJohn Marino 	  }
1057*e4b17023SJohn Marino 	else if (is_gimple_call (def_stmt))
1058*e4b17023SJohn Marino 	  {
1059*e4b17023SJohn Marino 	    int flags = gimple_call_flags (def_stmt);
1060*e4b17023SJohn Marino 
1061*e4b17023SJohn Marino 	    /* Don't optimize away calls that have side-effects.  */
1062*e4b17023SJohn Marino 	    if ((flags & (ECF_CONST|ECF_PURE)) == 0
1063*e4b17023SJohn Marino 		|| (flags & ECF_LOOPING_CONST_OR_PURE))
1064*e4b17023SJohn Marino 	      continue;
1065*e4b17023SJohn Marino 	    if (update_call_from_tree (&gsi, val)
1066*e4b17023SJohn Marino 		&& maybe_clean_or_replace_eh_stmt (def_stmt, gsi_stmt (gsi)))
1067*e4b17023SJohn Marino 	      gimple_purge_dead_eh_edges (gimple_bb (gsi_stmt (gsi)));
1068*e4b17023SJohn Marino 	  }
1069*e4b17023SJohn Marino 	else if (gimple_code (def_stmt) == GIMPLE_PHI)
1070*e4b17023SJohn Marino 	  {
1071*e4b17023SJohn Marino 	    gimple new_stmt = gimple_build_assign (name, val);
1072*e4b17023SJohn Marino 	    gimple_stmt_iterator gsi2;
1073*e4b17023SJohn Marino 	    SSA_NAME_DEF_STMT (name) = new_stmt;
1074*e4b17023SJohn Marino 	    gsi2 = gsi_after_labels (gimple_bb (def_stmt));
1075*e4b17023SJohn Marino 	    gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT);
1076*e4b17023SJohn Marino 	    remove_phi_node (&gsi, false);
1077*e4b17023SJohn Marino 	  }
1078*e4b17023SJohn Marino 
1079*e4b17023SJohn Marino 	something_changed = true;
1080*e4b17023SJohn Marino       }
1081*e4b17023SJohn Marino 
1082*e4b17023SJohn Marino   /* Propagate into all uses and fold.  */
1083*e4b17023SJohn Marino   FOR_EACH_BB (bb)
1084*e4b17023SJohn Marino     {
1085*e4b17023SJohn Marino       gimple_stmt_iterator i;
1086*e4b17023SJohn Marino 
1087*e4b17023SJohn Marino       /* Propagate known values into PHI nodes.  */
1088*e4b17023SJohn Marino       if (get_value_fn)
1089*e4b17023SJohn Marino 	for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
1090*e4b17023SJohn Marino 	  replace_phi_args_in (gsi_stmt (i), get_value_fn);
1091*e4b17023SJohn Marino 
1092*e4b17023SJohn Marino       /* Propagate known values into stmts.  Do a backward walk if
1093*e4b17023SJohn Marino          do_dce is true. In some case it exposes
1094*e4b17023SJohn Marino 	 more trivially deletable stmts to walk backward.  */
1095*e4b17023SJohn Marino       for (i = (do_dce ? gsi_last_bb (bb) : gsi_start_bb (bb)); !gsi_end_p (i);)
1096*e4b17023SJohn Marino 	{
1097*e4b17023SJohn Marino           bool did_replace;
1098*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (i);
1099*e4b17023SJohn Marino 	  gimple old_stmt;
1100*e4b17023SJohn Marino 	  enum gimple_code code = gimple_code (stmt);
1101*e4b17023SJohn Marino 	  gimple_stmt_iterator oldi;
1102*e4b17023SJohn Marino 
1103*e4b17023SJohn Marino 	  oldi = i;
1104*e4b17023SJohn Marino 	  if (do_dce)
1105*e4b17023SJohn Marino 	    gsi_prev (&i);
1106*e4b17023SJohn Marino 	  else
1107*e4b17023SJohn Marino 	    gsi_next (&i);
1108*e4b17023SJohn Marino 
1109*e4b17023SJohn Marino 	  /* Ignore ASSERT_EXPRs.  They are used by VRP to generate
1110*e4b17023SJohn Marino 	     range information for names and they are discarded
1111*e4b17023SJohn Marino 	     afterwards.  */
1112*e4b17023SJohn Marino 
1113*e4b17023SJohn Marino 	  if (code == GIMPLE_ASSIGN
1114*e4b17023SJohn Marino 	      && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
1115*e4b17023SJohn Marino 	    continue;
1116*e4b17023SJohn Marino 
1117*e4b17023SJohn Marino 	  /* No point propagating into a stmt whose result is not used,
1118*e4b17023SJohn Marino 	     but instead we might be able to remove a trivially dead stmt.
1119*e4b17023SJohn Marino 	     Don't do this when called from VRP, since the SSA_NAME which
1120*e4b17023SJohn Marino 	     is going to be released could be still referenced in VRP
1121*e4b17023SJohn Marino 	     ranges.  */
1122*e4b17023SJohn Marino 	  if (do_dce
1123*e4b17023SJohn Marino 	      && gimple_get_lhs (stmt)
1124*e4b17023SJohn Marino 	      && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
1125*e4b17023SJohn Marino 	      && has_zero_uses (gimple_get_lhs (stmt))
1126*e4b17023SJohn Marino 	      && !stmt_could_throw_p (stmt)
1127*e4b17023SJohn Marino 	      && !gimple_has_side_effects (stmt))
1128*e4b17023SJohn Marino 	    {
1129*e4b17023SJohn Marino 	      gimple_stmt_iterator i2;
1130*e4b17023SJohn Marino 
1131*e4b17023SJohn Marino 	      if (dump_file && dump_flags & TDF_DETAILS)
1132*e4b17023SJohn Marino 		{
1133*e4b17023SJohn Marino 		  fprintf (dump_file, "Removing dead stmt ");
1134*e4b17023SJohn Marino 		  print_gimple_stmt (dump_file, stmt, 0, 0);
1135*e4b17023SJohn Marino 		  fprintf (dump_file, "\n");
1136*e4b17023SJohn Marino 		}
1137*e4b17023SJohn Marino 	      prop_stats.num_dce++;
1138*e4b17023SJohn Marino 	      i2 = gsi_for_stmt (stmt);
1139*e4b17023SJohn Marino 	      gsi_remove (&i2, true);
1140*e4b17023SJohn Marino 	      release_defs (stmt);
1141*e4b17023SJohn Marino 	      continue;
1142*e4b17023SJohn Marino 	    }
1143*e4b17023SJohn Marino 
1144*e4b17023SJohn Marino 	  /* Replace the statement with its folded version and mark it
1145*e4b17023SJohn Marino 	     folded.  */
1146*e4b17023SJohn Marino 	  did_replace = false;
1147*e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
1148*e4b17023SJohn Marino 	    {
1149*e4b17023SJohn Marino 	      fprintf (dump_file, "Folding statement: ");
1150*e4b17023SJohn Marino 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1151*e4b17023SJohn Marino 	    }
1152*e4b17023SJohn Marino 
1153*e4b17023SJohn Marino 	  old_stmt = stmt;
1154*e4b17023SJohn Marino 
1155*e4b17023SJohn Marino 	  /* Some statements may be simplified using propagator
1156*e4b17023SJohn Marino 	     specific information.  Do this before propagating
1157*e4b17023SJohn Marino 	     into the stmt to not disturb pass specific information.  */
1158*e4b17023SJohn Marino 	  if (fold_fn
1159*e4b17023SJohn Marino 	      && (*fold_fn)(&oldi))
1160*e4b17023SJohn Marino 	    {
1161*e4b17023SJohn Marino 	      did_replace = true;
1162*e4b17023SJohn Marino 	      prop_stats.num_stmts_folded++;
1163*e4b17023SJohn Marino 	      stmt = gsi_stmt (oldi);
1164*e4b17023SJohn Marino 	      update_stmt (stmt);
1165*e4b17023SJohn Marino 	    }
1166*e4b17023SJohn Marino 
1167*e4b17023SJohn Marino 	  /* Replace real uses in the statement.  */
1168*e4b17023SJohn Marino 	  if (get_value_fn)
1169*e4b17023SJohn Marino 	    did_replace |= replace_uses_in (stmt, get_value_fn);
1170*e4b17023SJohn Marino 
1171*e4b17023SJohn Marino 	  /* If we made a replacement, fold the statement.  */
1172*e4b17023SJohn Marino 	  if (did_replace)
1173*e4b17023SJohn Marino 	    fold_stmt (&oldi);
1174*e4b17023SJohn Marino 
1175*e4b17023SJohn Marino 	  /* Now cleanup.  */
1176*e4b17023SJohn Marino 	  if (did_replace)
1177*e4b17023SJohn Marino 	    {
1178*e4b17023SJohn Marino 	      stmt = gsi_stmt (oldi);
1179*e4b17023SJohn Marino 
1180*e4b17023SJohn Marino               /* If we cleaned up EH information from the statement,
1181*e4b17023SJohn Marino                  remove EH edges.  */
1182*e4b17023SJohn Marino 	      if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
1183*e4b17023SJohn Marino 		gimple_purge_dead_eh_edges (bb);
1184*e4b17023SJohn Marino 
1185*e4b17023SJohn Marino               if (is_gimple_assign (stmt)
1186*e4b17023SJohn Marino                   && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
1187*e4b17023SJohn Marino                       == GIMPLE_SINGLE_RHS))
1188*e4b17023SJohn Marino               {
1189*e4b17023SJohn Marino                 tree rhs = gimple_assign_rhs1 (stmt);
1190*e4b17023SJohn Marino 
1191*e4b17023SJohn Marino                 if (TREE_CODE (rhs) == ADDR_EXPR)
1192*e4b17023SJohn Marino                   recompute_tree_invariant_for_addr_expr (rhs);
1193*e4b17023SJohn Marino               }
1194*e4b17023SJohn Marino 
1195*e4b17023SJohn Marino 	      /* Determine what needs to be done to update the SSA form.  */
1196*e4b17023SJohn Marino 	      update_stmt (stmt);
1197*e4b17023SJohn Marino 	      if (!is_gimple_debug (stmt))
1198*e4b17023SJohn Marino 		something_changed = true;
1199*e4b17023SJohn Marino 	    }
1200*e4b17023SJohn Marino 
1201*e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
1202*e4b17023SJohn Marino 	    {
1203*e4b17023SJohn Marino 	      if (did_replace)
1204*e4b17023SJohn Marino 		{
1205*e4b17023SJohn Marino 		  fprintf (dump_file, "Folded into: ");
1206*e4b17023SJohn Marino 		  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1207*e4b17023SJohn Marino 		  fprintf (dump_file, "\n");
1208*e4b17023SJohn Marino 		}
1209*e4b17023SJohn Marino 	      else
1210*e4b17023SJohn Marino 		fprintf (dump_file, "Not folded\n");
1211*e4b17023SJohn Marino 	    }
1212*e4b17023SJohn Marino 	}
1213*e4b17023SJohn Marino     }
1214*e4b17023SJohn Marino 
1215*e4b17023SJohn Marino   statistics_counter_event (cfun, "Constants propagated",
1216*e4b17023SJohn Marino 			    prop_stats.num_const_prop);
1217*e4b17023SJohn Marino   statistics_counter_event (cfun, "Copies propagated",
1218*e4b17023SJohn Marino 			    prop_stats.num_copy_prop);
1219*e4b17023SJohn Marino   statistics_counter_event (cfun, "Statements folded",
1220*e4b17023SJohn Marino 			    prop_stats.num_stmts_folded);
1221*e4b17023SJohn Marino   statistics_counter_event (cfun, "Statements deleted",
1222*e4b17023SJohn Marino 			    prop_stats.num_dce);
1223*e4b17023SJohn Marino   return something_changed;
1224*e4b17023SJohn Marino }
1225*e4b17023SJohn Marino 
1226*e4b17023SJohn Marino #include "gt-tree-ssa-propagate.h"
1227