xref: /netbsd-src/external/gpl3/gcc/dist/gcc/tree-outof-ssa.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg /* Convert a program in SSA form into Normal form.
2*b1e83836Smrg    Copyright (C) 2004-2022 Free Software Foundation, Inc.
3*b1e83836Smrg    Contributed by Andrew Macleod <amacleod@redhat.com>
4*b1e83836Smrg 
5*b1e83836Smrg This file is part of GCC.
6*b1e83836Smrg 
7*b1e83836Smrg GCC is free software; you can redistribute it and/or modify
8*b1e83836Smrg it under the terms of the GNU General Public License as published by
9*b1e83836Smrg the Free Software Foundation; either version 3, or (at your option)
10*b1e83836Smrg any later version.
11*b1e83836Smrg 
12*b1e83836Smrg GCC is distributed in the hope that it will be useful,
13*b1e83836Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
14*b1e83836Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*b1e83836Smrg GNU General Public License for more details.
16*b1e83836Smrg 
17*b1e83836Smrg You should have received a copy of the GNU General Public License
18*b1e83836Smrg along with GCC; see the file COPYING3.  If not see
19*b1e83836Smrg <http://www.gnu.org/licenses/>.  */
20*b1e83836Smrg 
21*b1e83836Smrg #include "config.h"
22*b1e83836Smrg #include "system.h"
23*b1e83836Smrg #include "coretypes.h"
24*b1e83836Smrg #include "backend.h"
25*b1e83836Smrg #include "rtl.h"
26*b1e83836Smrg #include "tree.h"
27*b1e83836Smrg #include "gimple.h"
28*b1e83836Smrg #include "cfghooks.h"
29*b1e83836Smrg #include "ssa.h"
30*b1e83836Smrg #include "tree-ssa.h"
31*b1e83836Smrg #include "memmodel.h"
32*b1e83836Smrg #include "emit-rtl.h"
33*b1e83836Smrg #include "gimple-pretty-print.h"
34*b1e83836Smrg #include "diagnostic-core.h"
35*b1e83836Smrg #include "tree-dfa.h"
36*b1e83836Smrg #include "stor-layout.h"
37*b1e83836Smrg #include "cfgrtl.h"
38*b1e83836Smrg #include "cfganal.h"
39*b1e83836Smrg #include "tree-eh.h"
40*b1e83836Smrg #include "gimple-iterator.h"
41*b1e83836Smrg #include "tree-cfg.h"
42*b1e83836Smrg #include "dumpfile.h"
43*b1e83836Smrg #include "tree-ssa-live.h"
44*b1e83836Smrg #include "tree-ssa-ter.h"
45*b1e83836Smrg #include "tree-ssa-coalesce.h"
46*b1e83836Smrg #include "tree-outof-ssa.h"
47*b1e83836Smrg #include "dojump.h"
48*b1e83836Smrg 
49*b1e83836Smrg /* FIXME: A lot of code here deals with expanding to RTL.  All that code
50*b1e83836Smrg    should be in cfgexpand.cc.  */
51*b1e83836Smrg #include "explow.h"
52*b1e83836Smrg #include "expr.h"
53*b1e83836Smrg 
54*b1e83836Smrg /* Return TRUE if expression STMT is suitable for replacement.  */
55*b1e83836Smrg 
56*b1e83836Smrg bool
ssa_is_replaceable_p(gimple * stmt)57*b1e83836Smrg ssa_is_replaceable_p (gimple *stmt)
58*b1e83836Smrg {
59*b1e83836Smrg   use_operand_p use_p;
60*b1e83836Smrg   tree def;
61*b1e83836Smrg   gimple *use_stmt;
62*b1e83836Smrg 
63*b1e83836Smrg   /* Only consider modify stmts.  */
64*b1e83836Smrg   if (!is_gimple_assign (stmt))
65*b1e83836Smrg     return false;
66*b1e83836Smrg 
67*b1e83836Smrg   /* If the statement may throw an exception, it cannot be replaced.  */
68*b1e83836Smrg   if (stmt_could_throw_p (cfun, stmt))
69*b1e83836Smrg     return false;
70*b1e83836Smrg 
71*b1e83836Smrg   /* Punt if there is more than 1 def.  */
72*b1e83836Smrg   def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
73*b1e83836Smrg   if (!def)
74*b1e83836Smrg     return false;
75*b1e83836Smrg 
76*b1e83836Smrg   /* Only consider definitions which have a single use.  */
77*b1e83836Smrg   if (!single_imm_use (def, &use_p, &use_stmt))
78*b1e83836Smrg     return false;
79*b1e83836Smrg 
80*b1e83836Smrg   /* Used in this block, but at the TOP of the block, not the end.  */
81*b1e83836Smrg   if (gimple_code (use_stmt) == GIMPLE_PHI)
82*b1e83836Smrg     return false;
83*b1e83836Smrg 
84*b1e83836Smrg   /* There must be no VDEFs.  */
85*b1e83836Smrg   if (gimple_vdef (stmt))
86*b1e83836Smrg     return false;
87*b1e83836Smrg 
88*b1e83836Smrg   /* Float expressions must go through memory if float-store is on.  */
89*b1e83836Smrg   if (flag_float_store
90*b1e83836Smrg       && FLOAT_TYPE_P (TREE_TYPE (def)))
91*b1e83836Smrg     return false;
92*b1e83836Smrg 
93*b1e83836Smrg   /* An assignment with a register variable on the RHS is not
94*b1e83836Smrg      replaceable.  */
95*b1e83836Smrg   if (gimple_assign_rhs_code (stmt) == VAR_DECL
96*b1e83836Smrg       && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
97*b1e83836Smrg     return false;
98*b1e83836Smrg 
99*b1e83836Smrg   /* No function calls can be replaced.  */
100*b1e83836Smrg   if (is_gimple_call (stmt))
101*b1e83836Smrg     return false;
102*b1e83836Smrg 
103*b1e83836Smrg   /* Leave any stmt with volatile operands alone as well.  */
104*b1e83836Smrg   if (gimple_has_volatile_ops (stmt))
105*b1e83836Smrg     return false;
106*b1e83836Smrg 
107*b1e83836Smrg   return true;
108*b1e83836Smrg }
109*b1e83836Smrg 
110*b1e83836Smrg 
111*b1e83836Smrg /* Used to hold all the components required to do SSA PHI elimination.
112*b1e83836Smrg    The node and pred/succ list is a simple linear list of nodes and
113*b1e83836Smrg    edges represented as pairs of nodes.
114*b1e83836Smrg 
115*b1e83836Smrg    The predecessor and successor list:  Nodes are entered in pairs, where
116*b1e83836Smrg    [0] ->PRED, [1]->SUCC.  All the even indexes in the array represent
117*b1e83836Smrg    predecessors, all the odd elements are successors.
118*b1e83836Smrg 
119*b1e83836Smrg    Rationale:
120*b1e83836Smrg    When implemented as bitmaps, very large programs SSA->Normal times were
121*b1e83836Smrg    being dominated by clearing the interference graph.
122*b1e83836Smrg 
123*b1e83836Smrg    Typically this list of edges is extremely small since it only includes
124*b1e83836Smrg    PHI results and uses from a single edge which have not coalesced with
125*b1e83836Smrg    each other.  This means that no virtual PHI nodes are included, and
126*b1e83836Smrg    empirical evidence suggests that the number of edges rarely exceed
127*b1e83836Smrg    3, and in a bootstrap of GCC, the maximum size encountered was 7.
128*b1e83836Smrg    This also limits the number of possible nodes that are involved to
129*b1e83836Smrg    rarely more than 6, and in the bootstrap of gcc, the maximum number
130*b1e83836Smrg    of nodes encountered was 12.  */
131*b1e83836Smrg 
132*b1e83836Smrg class elim_graph
133*b1e83836Smrg {
134*b1e83836Smrg public:
135*b1e83836Smrg   elim_graph (var_map map);
136*b1e83836Smrg 
137*b1e83836Smrg   /* Size of the elimination vectors.  */
138*b1e83836Smrg   int size;
139*b1e83836Smrg 
140*b1e83836Smrg   /* List of nodes in the elimination graph.  */
141*b1e83836Smrg   auto_vec<int> nodes;
142*b1e83836Smrg 
143*b1e83836Smrg   /*  The predecessor and successor edge list.  */
144*b1e83836Smrg   auto_vec<int> edge_list;
145*b1e83836Smrg 
146*b1e83836Smrg   /* Source locus on each edge */
147*b1e83836Smrg   auto_vec<location_t> edge_locus;
148*b1e83836Smrg 
149*b1e83836Smrg   /* Visited vector.  */
150*b1e83836Smrg   auto_sbitmap visited;
151*b1e83836Smrg 
152*b1e83836Smrg   /* Stack for visited nodes.  */
153*b1e83836Smrg   auto_vec<int> stack;
154*b1e83836Smrg 
155*b1e83836Smrg   /* The variable partition map.  */
156*b1e83836Smrg   var_map map;
157*b1e83836Smrg 
158*b1e83836Smrg   /* Edge being eliminated by this graph.  */
159*b1e83836Smrg   edge e;
160*b1e83836Smrg 
161*b1e83836Smrg   /* List of constant copies to emit.  These are pushed on in pairs.  */
162*b1e83836Smrg   auto_vec<int> const_dests;
163*b1e83836Smrg   auto_vec<tree> const_copies;
164*b1e83836Smrg 
165*b1e83836Smrg   /* Source locations for any constant copies.  */
166*b1e83836Smrg   auto_vec<location_t> copy_locus;
167*b1e83836Smrg };
168*b1e83836Smrg 
169*b1e83836Smrg 
170*b1e83836Smrg /* For an edge E find out a good source location to associate with
171*b1e83836Smrg    instructions inserted on edge E.  If E has an implicit goto set,
172*b1e83836Smrg    use its location.  Otherwise search instructions in predecessors
173*b1e83836Smrg    of E for a location, and use that one.  That makes sense because
174*b1e83836Smrg    we insert on edges for PHI nodes, and effects of PHIs happen on
175*b1e83836Smrg    the end of the predecessor conceptually.  An exception is made
176*b1e83836Smrg    for EH edges because we don't want to drag the source location
177*b1e83836Smrg    of unrelated statements at the beginning of handlers; they would
178*b1e83836Smrg    be further reused for various EH constructs, which would damage
179*b1e83836Smrg    the coverage information.  */
180*b1e83836Smrg 
181*b1e83836Smrg static void
set_location_for_edge(edge e)182*b1e83836Smrg set_location_for_edge (edge e)
183*b1e83836Smrg {
184*b1e83836Smrg   if (e->goto_locus)
185*b1e83836Smrg     set_curr_insn_location (e->goto_locus);
186*b1e83836Smrg   else if (e->flags & EDGE_EH)
187*b1e83836Smrg     {
188*b1e83836Smrg       basic_block bb = e->dest;
189*b1e83836Smrg       gimple_stmt_iterator gsi;
190*b1e83836Smrg 
191*b1e83836Smrg       do
192*b1e83836Smrg 	{
193*b1e83836Smrg 	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
194*b1e83836Smrg 	    {
195*b1e83836Smrg 	      gimple *stmt = gsi_stmt (gsi);
196*b1e83836Smrg 	      if (is_gimple_debug (stmt))
197*b1e83836Smrg 		continue;
198*b1e83836Smrg 	      if (gimple_has_location (stmt) || gimple_block (stmt))
199*b1e83836Smrg 		{
200*b1e83836Smrg 		  set_curr_insn_location (gimple_location (stmt));
201*b1e83836Smrg 		  return;
202*b1e83836Smrg 		}
203*b1e83836Smrg 	    }
204*b1e83836Smrg 	  /* Nothing found in this basic block.  Make a half-assed attempt
205*b1e83836Smrg 	     to continue with another block.  */
206*b1e83836Smrg 	  if (single_succ_p (bb))
207*b1e83836Smrg 	    bb = single_succ (bb);
208*b1e83836Smrg 	  else
209*b1e83836Smrg 	    bb = e->dest;
210*b1e83836Smrg 	}
211*b1e83836Smrg       while (bb != e->dest);
212*b1e83836Smrg     }
213*b1e83836Smrg   else
214*b1e83836Smrg     {
215*b1e83836Smrg       basic_block bb = e->src;
216*b1e83836Smrg       gimple_stmt_iterator gsi;
217*b1e83836Smrg 
218*b1e83836Smrg       do
219*b1e83836Smrg 	{
220*b1e83836Smrg 	  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
221*b1e83836Smrg 	    {
222*b1e83836Smrg 	      gimple *stmt = gsi_stmt (gsi);
223*b1e83836Smrg 	      if (is_gimple_debug (stmt))
224*b1e83836Smrg 		continue;
225*b1e83836Smrg 	      if (gimple_has_location (stmt) || gimple_block (stmt))
226*b1e83836Smrg 		{
227*b1e83836Smrg 		  set_curr_insn_location (gimple_location (stmt));
228*b1e83836Smrg 		  return;
229*b1e83836Smrg 		}
230*b1e83836Smrg 	    }
231*b1e83836Smrg 	  /* Nothing found in this basic block.  Make a half-assed attempt
232*b1e83836Smrg 	     to continue with another block.  */
233*b1e83836Smrg 	  if (single_pred_p (bb))
234*b1e83836Smrg 	    bb = single_pred (bb);
235*b1e83836Smrg 	  else
236*b1e83836Smrg 	    bb = e->src;
237*b1e83836Smrg 	}
238*b1e83836Smrg       while (bb != e->src);
239*b1e83836Smrg     }
240*b1e83836Smrg }
241*b1e83836Smrg 
242*b1e83836Smrg /* Emit insns to copy SRC into DEST converting SRC if necessary.  As
243*b1e83836Smrg    SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from
244*b1e83836Smrg    which we deduce the size to copy in that case.  */
245*b1e83836Smrg 
246*b1e83836Smrg static inline rtx_insn *
emit_partition_copy(rtx dest,rtx src,int unsignedsrcp,tree sizeexp)247*b1e83836Smrg emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp)
248*b1e83836Smrg {
249*b1e83836Smrg   start_sequence ();
250*b1e83836Smrg 
251*b1e83836Smrg   if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest))
252*b1e83836Smrg     src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp);
253*b1e83836Smrg   if (GET_MODE (src) == BLKmode)
254*b1e83836Smrg     {
255*b1e83836Smrg       gcc_assert (GET_MODE (dest) == BLKmode);
256*b1e83836Smrg       emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL);
257*b1e83836Smrg     }
258*b1e83836Smrg   else
259*b1e83836Smrg     emit_move_insn (dest, src);
260*b1e83836Smrg   do_pending_stack_adjust ();
261*b1e83836Smrg 
262*b1e83836Smrg   rtx_insn *seq = get_insns ();
263*b1e83836Smrg   end_sequence ();
264*b1e83836Smrg 
265*b1e83836Smrg   return seq;
266*b1e83836Smrg }
267*b1e83836Smrg 
268*b1e83836Smrg /* Insert a copy instruction from partition SRC to DEST onto edge E.  */
269*b1e83836Smrg 
270*b1e83836Smrg static void
insert_partition_copy_on_edge(edge e,int dest,int src,location_t locus)271*b1e83836Smrg insert_partition_copy_on_edge (edge e, int dest, int src, location_t locus)
272*b1e83836Smrg {
273*b1e83836Smrg   tree var;
274*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
275*b1e83836Smrg     {
276*b1e83836Smrg       fprintf (dump_file,
277*b1e83836Smrg 	       "Inserting a partition copy on edge BB%d->BB%d : "
278*b1e83836Smrg 	       "PART.%d = PART.%d",
279*b1e83836Smrg 	       e->src->index,
280*b1e83836Smrg 	       e->dest->index, dest, src);
281*b1e83836Smrg       fprintf (dump_file, "\n");
282*b1e83836Smrg     }
283*b1e83836Smrg 
284*b1e83836Smrg   gcc_assert (SA.partition_to_pseudo[dest]);
285*b1e83836Smrg   gcc_assert (SA.partition_to_pseudo[src]);
286*b1e83836Smrg 
287*b1e83836Smrg   set_location_for_edge (e);
288*b1e83836Smrg   /* If a locus is provided, override the default.  */
289*b1e83836Smrg   if (locus)
290*b1e83836Smrg     set_curr_insn_location (locus);
291*b1e83836Smrg 
292*b1e83836Smrg   var = partition_to_var (SA.map, src);
293*b1e83836Smrg   rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]),
294*b1e83836Smrg 				       copy_rtx (SA.partition_to_pseudo[src]),
295*b1e83836Smrg 				       TYPE_UNSIGNED (TREE_TYPE (var)),
296*b1e83836Smrg 				       var);
297*b1e83836Smrg 
298*b1e83836Smrg   insert_insn_on_edge (seq, e);
299*b1e83836Smrg }
300*b1e83836Smrg 
301*b1e83836Smrg /* Insert a copy instruction from expression SRC to partition DEST
302*b1e83836Smrg    onto edge E.  */
303*b1e83836Smrg 
304*b1e83836Smrg static void
insert_value_copy_on_edge(edge e,int dest,tree src,location_t locus)305*b1e83836Smrg insert_value_copy_on_edge (edge e, int dest, tree src, location_t locus)
306*b1e83836Smrg {
307*b1e83836Smrg   rtx dest_rtx, seq, x;
308*b1e83836Smrg   machine_mode dest_mode, src_mode;
309*b1e83836Smrg   int unsignedp;
310*b1e83836Smrg 
311*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
312*b1e83836Smrg     {
313*b1e83836Smrg       fprintf (dump_file,
314*b1e83836Smrg 	       "Inserting a value copy on edge BB%d->BB%d : PART.%d = ",
315*b1e83836Smrg 	       e->src->index,
316*b1e83836Smrg 	       e->dest->index, dest);
317*b1e83836Smrg       print_generic_expr (dump_file, src, TDF_SLIM);
318*b1e83836Smrg       fprintf (dump_file, "\n");
319*b1e83836Smrg     }
320*b1e83836Smrg 
321*b1e83836Smrg   dest_rtx = copy_rtx (SA.partition_to_pseudo[dest]);
322*b1e83836Smrg   gcc_assert (dest_rtx);
323*b1e83836Smrg 
324*b1e83836Smrg   set_location_for_edge (e);
325*b1e83836Smrg   /* If a locus is provided, override the default.  */
326*b1e83836Smrg   if (locus)
327*b1e83836Smrg     set_curr_insn_location (locus);
328*b1e83836Smrg 
329*b1e83836Smrg   start_sequence ();
330*b1e83836Smrg 
331*b1e83836Smrg   tree name = partition_to_var (SA.map, dest);
332*b1e83836Smrg   src_mode = TYPE_MODE (TREE_TYPE (src));
333*b1e83836Smrg   dest_mode = GET_MODE (dest_rtx);
334*b1e83836Smrg   gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (name)));
335*b1e83836Smrg   gcc_assert (!REG_P (dest_rtx)
336*b1e83836Smrg 	      || dest_mode == promote_ssa_mode (name, &unsignedp));
337*b1e83836Smrg 
338*b1e83836Smrg   if (src_mode != dest_mode)
339*b1e83836Smrg     {
340*b1e83836Smrg       x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL);
341*b1e83836Smrg       x = convert_modes (dest_mode, src_mode, x, unsignedp);
342*b1e83836Smrg     }
343*b1e83836Smrg   else if (src_mode == BLKmode)
344*b1e83836Smrg     {
345*b1e83836Smrg       x = dest_rtx;
346*b1e83836Smrg       store_expr (src, x, 0, false, false);
347*b1e83836Smrg     }
348*b1e83836Smrg   else
349*b1e83836Smrg     x = expand_expr (src, dest_rtx, dest_mode, EXPAND_NORMAL);
350*b1e83836Smrg 
351*b1e83836Smrg   if (x != dest_rtx)
352*b1e83836Smrg     emit_move_insn (dest_rtx, x);
353*b1e83836Smrg   do_pending_stack_adjust ();
354*b1e83836Smrg 
355*b1e83836Smrg   seq = get_insns ();
356*b1e83836Smrg   end_sequence ();
357*b1e83836Smrg 
358*b1e83836Smrg   insert_insn_on_edge (seq, e);
359*b1e83836Smrg }
360*b1e83836Smrg 
361*b1e83836Smrg /* Insert a copy instruction from RTL expression SRC to partition DEST
362*b1e83836Smrg    onto edge E.  */
363*b1e83836Smrg 
364*b1e83836Smrg static void
insert_rtx_to_part_on_edge(edge e,int dest,rtx src,int unsignedsrcp,location_t locus)365*b1e83836Smrg insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
366*b1e83836Smrg 			    location_t locus)
367*b1e83836Smrg {
368*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
369*b1e83836Smrg     {
370*b1e83836Smrg       fprintf (dump_file,
371*b1e83836Smrg 	       "Inserting a temp copy on edge BB%d->BB%d : PART.%d = ",
372*b1e83836Smrg 	       e->src->index,
373*b1e83836Smrg 	       e->dest->index, dest);
374*b1e83836Smrg       print_simple_rtl (dump_file, src);
375*b1e83836Smrg       fprintf (dump_file, "\n");
376*b1e83836Smrg     }
377*b1e83836Smrg 
378*b1e83836Smrg   gcc_assert (SA.partition_to_pseudo[dest]);
379*b1e83836Smrg 
380*b1e83836Smrg   set_location_for_edge (e);
381*b1e83836Smrg   /* If a locus is provided, override the default.  */
382*b1e83836Smrg   if (locus)
383*b1e83836Smrg     set_curr_insn_location (locus);
384*b1e83836Smrg 
385*b1e83836Smrg   /* We give the destination as sizeexp in case src/dest are BLKmode
386*b1e83836Smrg      mems.  Usually we give the source.  As we result from SSA names
387*b1e83836Smrg      the left and right size should be the same (and no WITH_SIZE_EXPR
388*b1e83836Smrg      involved), so it doesn't matter.  */
389*b1e83836Smrg   rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]),
390*b1e83836Smrg 				       src, unsignedsrcp,
391*b1e83836Smrg 				       partition_to_var (SA.map, dest));
392*b1e83836Smrg 
393*b1e83836Smrg   insert_insn_on_edge (seq, e);
394*b1e83836Smrg }
395*b1e83836Smrg 
396*b1e83836Smrg /* Insert a copy instruction from partition SRC to RTL lvalue DEST
397*b1e83836Smrg    onto edge E.  */
398*b1e83836Smrg 
399*b1e83836Smrg static void
insert_part_to_rtx_on_edge(edge e,rtx dest,int src,location_t locus)400*b1e83836Smrg insert_part_to_rtx_on_edge (edge e, rtx dest, int src, location_t locus)
401*b1e83836Smrg {
402*b1e83836Smrg   tree var;
403*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
404*b1e83836Smrg     {
405*b1e83836Smrg       fprintf (dump_file,
406*b1e83836Smrg 	       "Inserting a temp copy on edge BB%d->BB%d : ",
407*b1e83836Smrg 	       e->src->index,
408*b1e83836Smrg 	       e->dest->index);
409*b1e83836Smrg       print_simple_rtl (dump_file, dest);
410*b1e83836Smrg       fprintf (dump_file, "= PART.%d\n", src);
411*b1e83836Smrg     }
412*b1e83836Smrg 
413*b1e83836Smrg   gcc_assert (SA.partition_to_pseudo[src]);
414*b1e83836Smrg 
415*b1e83836Smrg   set_location_for_edge (e);
416*b1e83836Smrg   /* If a locus is provided, override the default.  */
417*b1e83836Smrg   if (locus)
418*b1e83836Smrg     set_curr_insn_location (locus);
419*b1e83836Smrg 
420*b1e83836Smrg   var = partition_to_var (SA.map, src);
421*b1e83836Smrg   rtx_insn *seq = emit_partition_copy (dest,
422*b1e83836Smrg 				       copy_rtx (SA.partition_to_pseudo[src]),
423*b1e83836Smrg 				       TYPE_UNSIGNED (TREE_TYPE (var)),
424*b1e83836Smrg 				       var);
425*b1e83836Smrg 
426*b1e83836Smrg   insert_insn_on_edge (seq, e);
427*b1e83836Smrg }
428*b1e83836Smrg 
429*b1e83836Smrg 
430*b1e83836Smrg /* Create an elimination graph for map.  */
431*b1e83836Smrg 
elim_graph(var_map map)432*b1e83836Smrg elim_graph::elim_graph (var_map map) :
433*b1e83836Smrg   nodes (30), edge_list (20), edge_locus (10), visited (map->num_partitions),
434*b1e83836Smrg   stack (30), map (map), const_dests (20), const_copies (20), copy_locus (10)
435*b1e83836Smrg {
436*b1e83836Smrg }
437*b1e83836Smrg 
438*b1e83836Smrg 
439*b1e83836Smrg /* Empty elimination graph G.  */
440*b1e83836Smrg 
441*b1e83836Smrg static inline void
clear_elim_graph(elim_graph * g)442*b1e83836Smrg clear_elim_graph (elim_graph *g)
443*b1e83836Smrg {
444*b1e83836Smrg   g->nodes.truncate (0);
445*b1e83836Smrg   g->edge_list.truncate (0);
446*b1e83836Smrg   g->edge_locus.truncate (0);
447*b1e83836Smrg }
448*b1e83836Smrg 
449*b1e83836Smrg 
450*b1e83836Smrg /* Return the number of nodes in graph G.  */
451*b1e83836Smrg 
452*b1e83836Smrg static inline int
elim_graph_size(elim_graph * g)453*b1e83836Smrg elim_graph_size (elim_graph *g)
454*b1e83836Smrg {
455*b1e83836Smrg   return g->nodes.length ();
456*b1e83836Smrg }
457*b1e83836Smrg 
458*b1e83836Smrg 
459*b1e83836Smrg /* Add NODE to graph G, if it doesn't exist already.  */
460*b1e83836Smrg 
461*b1e83836Smrg static inline void
elim_graph_add_node(elim_graph * g,int node)462*b1e83836Smrg elim_graph_add_node (elim_graph *g, int node)
463*b1e83836Smrg {
464*b1e83836Smrg   int x;
465*b1e83836Smrg   int t;
466*b1e83836Smrg 
467*b1e83836Smrg   FOR_EACH_VEC_ELT (g->nodes, x, t)
468*b1e83836Smrg     if (t == node)
469*b1e83836Smrg       return;
470*b1e83836Smrg   g->nodes.safe_push (node);
471*b1e83836Smrg }
472*b1e83836Smrg 
473*b1e83836Smrg 
474*b1e83836Smrg /* Add the edge PRED->SUCC to graph G.  */
475*b1e83836Smrg 
476*b1e83836Smrg static inline void
elim_graph_add_edge(elim_graph * g,int pred,int succ,location_t locus)477*b1e83836Smrg elim_graph_add_edge (elim_graph *g, int pred, int succ, location_t locus)
478*b1e83836Smrg {
479*b1e83836Smrg   g->edge_list.safe_push (pred);
480*b1e83836Smrg   g->edge_list.safe_push (succ);
481*b1e83836Smrg   g->edge_locus.safe_push (locus);
482*b1e83836Smrg }
483*b1e83836Smrg 
484*b1e83836Smrg 
485*b1e83836Smrg /* Remove an edge from graph G for which NODE is the predecessor, and
486*b1e83836Smrg    return the successor node.  -1 is returned if there is no such edge.  */
487*b1e83836Smrg 
488*b1e83836Smrg static inline int
elim_graph_remove_succ_edge(elim_graph * g,int node,location_t * locus)489*b1e83836Smrg elim_graph_remove_succ_edge (elim_graph *g, int node, location_t *locus)
490*b1e83836Smrg {
491*b1e83836Smrg   int y;
492*b1e83836Smrg   unsigned x;
493*b1e83836Smrg   for (x = 0; x < g->edge_list.length (); x += 2)
494*b1e83836Smrg     if (g->edge_list[x] == node)
495*b1e83836Smrg       {
496*b1e83836Smrg         g->edge_list[x] = -1;
497*b1e83836Smrg 	y = g->edge_list[x + 1];
498*b1e83836Smrg 	g->edge_list[x + 1] = -1;
499*b1e83836Smrg 	*locus = g->edge_locus[x / 2];
500*b1e83836Smrg 	g->edge_locus[x / 2] = UNKNOWN_LOCATION;
501*b1e83836Smrg 	return y;
502*b1e83836Smrg       }
503*b1e83836Smrg   *locus = UNKNOWN_LOCATION;
504*b1e83836Smrg   return -1;
505*b1e83836Smrg }
506*b1e83836Smrg 
507*b1e83836Smrg 
508*b1e83836Smrg /* Find all the nodes in GRAPH which are successors to NODE in the
509*b1e83836Smrg    edge list.  VAR will hold the partition number found.  CODE is the
510*b1e83836Smrg    code fragment executed for every node found.  */
511*b1e83836Smrg 
512*b1e83836Smrg #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE)		\
513*b1e83836Smrg do {									\
514*b1e83836Smrg   unsigned x_;								\
515*b1e83836Smrg   int y_;								\
516*b1e83836Smrg   for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2)	\
517*b1e83836Smrg     {									\
518*b1e83836Smrg       y_ = (GRAPH)->edge_list[x_];					\
519*b1e83836Smrg       if (y_ != (NODE))							\
520*b1e83836Smrg         continue;							\
521*b1e83836Smrg       (void) ((VAR) = (GRAPH)->edge_list[x_ + 1]);			\
522*b1e83836Smrg       (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]);			\
523*b1e83836Smrg       CODE;								\
524*b1e83836Smrg     }									\
525*b1e83836Smrg } while (0)
526*b1e83836Smrg 
527*b1e83836Smrg 
528*b1e83836Smrg /* Find all the nodes which are predecessors of NODE in the edge list for
529*b1e83836Smrg    GRAPH.  VAR will hold the partition number found.  CODE is the
530*b1e83836Smrg    code fragment executed for every node found.  */
531*b1e83836Smrg 
532*b1e83836Smrg #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE)		\
533*b1e83836Smrg do {									\
534*b1e83836Smrg   unsigned x_;								\
535*b1e83836Smrg   int y_;								\
536*b1e83836Smrg   for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2)	\
537*b1e83836Smrg     {									\
538*b1e83836Smrg       y_ = (GRAPH)->edge_list[x_ + 1];					\
539*b1e83836Smrg       if (y_ != (NODE))							\
540*b1e83836Smrg         continue;							\
541*b1e83836Smrg       (void) ((VAR) = (GRAPH)->edge_list[x_]);				\
542*b1e83836Smrg       (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]);			\
543*b1e83836Smrg       CODE;								\
544*b1e83836Smrg     }									\
545*b1e83836Smrg } while (0)
546*b1e83836Smrg 
547*b1e83836Smrg 
548*b1e83836Smrg /* Add T to elimination graph G.  */
549*b1e83836Smrg 
550*b1e83836Smrg static inline void
eliminate_name(elim_graph * g,int T)551*b1e83836Smrg eliminate_name (elim_graph *g, int T)
552*b1e83836Smrg {
553*b1e83836Smrg   elim_graph_add_node (g, T);
554*b1e83836Smrg }
555*b1e83836Smrg 
556*b1e83836Smrg /* Return true if this phi argument T should have a copy queued when using
557*b1e83836Smrg    var_map MAP.  PHI nodes should contain only ssa_names and invariants.  A
558*b1e83836Smrg    test for ssa_name is definitely simpler, but don't let invalid contents
559*b1e83836Smrg    slip through in the meantime.  */
560*b1e83836Smrg 
561*b1e83836Smrg static inline bool
queue_phi_copy_p(var_map map,tree t)562*b1e83836Smrg queue_phi_copy_p (var_map map, tree t)
563*b1e83836Smrg {
564*b1e83836Smrg   if (TREE_CODE (t) == SSA_NAME)
565*b1e83836Smrg     {
566*b1e83836Smrg       if (var_to_partition (map, t) == NO_PARTITION)
567*b1e83836Smrg         return true;
568*b1e83836Smrg       return false;
569*b1e83836Smrg     }
570*b1e83836Smrg   gcc_checking_assert (is_gimple_min_invariant (t));
571*b1e83836Smrg   return true;
572*b1e83836Smrg }
573*b1e83836Smrg 
574*b1e83836Smrg /* Build elimination graph G for basic block BB on incoming PHI edge
575*b1e83836Smrg    G->e.  */
576*b1e83836Smrg 
577*b1e83836Smrg static void
eliminate_build(elim_graph * g)578*b1e83836Smrg eliminate_build (elim_graph *g)
579*b1e83836Smrg {
580*b1e83836Smrg   tree Ti;
581*b1e83836Smrg   int p0, pi;
582*b1e83836Smrg   gphi_iterator gsi;
583*b1e83836Smrg 
584*b1e83836Smrg   clear_elim_graph (g);
585*b1e83836Smrg 
586*b1e83836Smrg   for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
587*b1e83836Smrg     {
588*b1e83836Smrg       gphi *phi = gsi.phi ();
589*b1e83836Smrg       location_t locus;
590*b1e83836Smrg 
591*b1e83836Smrg       p0 = var_to_partition (g->map, gimple_phi_result (phi));
592*b1e83836Smrg       /* Ignore results which are not in partitions.  */
593*b1e83836Smrg       if (p0 == NO_PARTITION)
594*b1e83836Smrg 	continue;
595*b1e83836Smrg 
596*b1e83836Smrg       Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
597*b1e83836Smrg       /* See set_location_for_edge for the rationale.  */
598*b1e83836Smrg       if (g->e->flags & EDGE_EH)
599*b1e83836Smrg 	locus = UNKNOWN_LOCATION;
600*b1e83836Smrg       else
601*b1e83836Smrg 	locus = gimple_phi_arg_location_from_edge (phi, g->e);
602*b1e83836Smrg 
603*b1e83836Smrg       /* If this argument is a constant, or a SSA_NAME which is being
604*b1e83836Smrg 	 left in SSA form, just queue a copy to be emitted on this
605*b1e83836Smrg 	 edge.  */
606*b1e83836Smrg       if (queue_phi_copy_p (g->map, Ti))
607*b1e83836Smrg         {
608*b1e83836Smrg 	  /* Save constant copies until all other copies have been emitted
609*b1e83836Smrg 	     on this edge.  */
610*b1e83836Smrg 	  g->const_dests.safe_push (p0);
611*b1e83836Smrg 	  g->const_copies.safe_push (Ti);
612*b1e83836Smrg 	  g->copy_locus.safe_push (locus);
613*b1e83836Smrg 	}
614*b1e83836Smrg       else
615*b1e83836Smrg         {
616*b1e83836Smrg 	  pi = var_to_partition (g->map, Ti);
617*b1e83836Smrg 	  if (p0 != pi)
618*b1e83836Smrg 	    {
619*b1e83836Smrg 	      eliminate_name (g, p0);
620*b1e83836Smrg 	      eliminate_name (g, pi);
621*b1e83836Smrg 	      elim_graph_add_edge (g, p0, pi, locus);
622*b1e83836Smrg 	    }
623*b1e83836Smrg 	}
624*b1e83836Smrg     }
625*b1e83836Smrg }
626*b1e83836Smrg 
627*b1e83836Smrg 
628*b1e83836Smrg /* Push successors of T onto the elimination stack for G.  */
629*b1e83836Smrg 
630*b1e83836Smrg static void
elim_forward(elim_graph * g,int T)631*b1e83836Smrg elim_forward (elim_graph *g, int T)
632*b1e83836Smrg {
633*b1e83836Smrg   int S;
634*b1e83836Smrg   location_t locus;
635*b1e83836Smrg 
636*b1e83836Smrg   bitmap_set_bit (g->visited, T);
637*b1e83836Smrg   FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
638*b1e83836Smrg     {
639*b1e83836Smrg       if (!bitmap_bit_p (g->visited, S))
640*b1e83836Smrg         elim_forward (g, S);
641*b1e83836Smrg     });
642*b1e83836Smrg   g->stack.safe_push (T);
643*b1e83836Smrg }
644*b1e83836Smrg 
645*b1e83836Smrg 
646*b1e83836Smrg /* Return 1 if there unvisited predecessors of T in graph G.  */
647*b1e83836Smrg 
648*b1e83836Smrg static int
elim_unvisited_predecessor(elim_graph * g,int T)649*b1e83836Smrg elim_unvisited_predecessor (elim_graph *g, int T)
650*b1e83836Smrg {
651*b1e83836Smrg   int P;
652*b1e83836Smrg   location_t locus;
653*b1e83836Smrg 
654*b1e83836Smrg   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
655*b1e83836Smrg     {
656*b1e83836Smrg       if (!bitmap_bit_p (g->visited, P))
657*b1e83836Smrg         return 1;
658*b1e83836Smrg     });
659*b1e83836Smrg   return 0;
660*b1e83836Smrg }
661*b1e83836Smrg 
662*b1e83836Smrg /* Process predecessors first, and insert a copy.  */
663*b1e83836Smrg 
664*b1e83836Smrg static void
elim_backward(elim_graph * g,int T)665*b1e83836Smrg elim_backward (elim_graph *g, int T)
666*b1e83836Smrg {
667*b1e83836Smrg   int P;
668*b1e83836Smrg   location_t locus;
669*b1e83836Smrg 
670*b1e83836Smrg   bitmap_set_bit (g->visited, T);
671*b1e83836Smrg   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
672*b1e83836Smrg     {
673*b1e83836Smrg       if (!bitmap_bit_p (g->visited, P))
674*b1e83836Smrg         {
675*b1e83836Smrg 	  elim_backward (g, P);
676*b1e83836Smrg 	  insert_partition_copy_on_edge (g->e, P, T, locus);
677*b1e83836Smrg 	}
678*b1e83836Smrg     });
679*b1e83836Smrg }
680*b1e83836Smrg 
681*b1e83836Smrg /* Allocate a new pseudo register usable for storing values sitting
682*b1e83836Smrg    in NAME (a decl or SSA name), i.e. with matching mode and attributes.  */
683*b1e83836Smrg 
684*b1e83836Smrg static rtx
get_temp_reg(tree name)685*b1e83836Smrg get_temp_reg (tree name)
686*b1e83836Smrg {
687*b1e83836Smrg   tree type = TREE_TYPE (name);
688*b1e83836Smrg   int unsignedp;
689*b1e83836Smrg   machine_mode reg_mode = promote_ssa_mode (name, &unsignedp);
690*b1e83836Smrg   if (reg_mode == BLKmode)
691*b1e83836Smrg     return assign_temp (type, 0, 0);
692*b1e83836Smrg   rtx x = gen_reg_rtx (reg_mode);
693*b1e83836Smrg   if (POINTER_TYPE_P (type))
694*b1e83836Smrg     mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (type)));
695*b1e83836Smrg   return x;
696*b1e83836Smrg }
697*b1e83836Smrg 
698*b1e83836Smrg /* Insert required copies for T in graph G.  Check for a strongly connected
699*b1e83836Smrg    region, and create a temporary to break the cycle if one is found.  */
700*b1e83836Smrg 
701*b1e83836Smrg static void
elim_create(elim_graph * g,int T)702*b1e83836Smrg elim_create (elim_graph *g, int T)
703*b1e83836Smrg {
704*b1e83836Smrg   int P, S;
705*b1e83836Smrg   location_t locus;
706*b1e83836Smrg 
707*b1e83836Smrg   if (elim_unvisited_predecessor (g, T))
708*b1e83836Smrg     {
709*b1e83836Smrg       tree var = partition_to_var (g->map, T);
710*b1e83836Smrg       rtx U = get_temp_reg (var);
711*b1e83836Smrg       int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));
712*b1e83836Smrg 
713*b1e83836Smrg       insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION);
714*b1e83836Smrg       FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
715*b1e83836Smrg 	{
716*b1e83836Smrg 	  if (!bitmap_bit_p (g->visited, P))
717*b1e83836Smrg 	    {
718*b1e83836Smrg 	      elim_backward (g, P);
719*b1e83836Smrg 	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
720*b1e83836Smrg 	    }
721*b1e83836Smrg 	});
722*b1e83836Smrg     }
723*b1e83836Smrg   else
724*b1e83836Smrg     {
725*b1e83836Smrg       S = elim_graph_remove_succ_edge (g, T, &locus);
726*b1e83836Smrg       if (S != -1)
727*b1e83836Smrg 	{
728*b1e83836Smrg 	  bitmap_set_bit (g->visited, T);
729*b1e83836Smrg 	  insert_partition_copy_on_edge (g->e, T, S, locus);
730*b1e83836Smrg 	}
731*b1e83836Smrg     }
732*b1e83836Smrg }
733*b1e83836Smrg 
734*b1e83836Smrg 
735*b1e83836Smrg /* Eliminate all the phi nodes on edge E in graph G.  */
736*b1e83836Smrg 
737*b1e83836Smrg static void
eliminate_phi(edge e,elim_graph * g)738*b1e83836Smrg eliminate_phi (edge e, elim_graph *g)
739*b1e83836Smrg {
740*b1e83836Smrg   int x;
741*b1e83836Smrg 
742*b1e83836Smrg   gcc_assert (g->const_copies.length () == 0);
743*b1e83836Smrg   gcc_assert (g->copy_locus.length () == 0);
744*b1e83836Smrg 
745*b1e83836Smrg   /* Abnormal edges already have everything coalesced.  */
746*b1e83836Smrg   if (e->flags & EDGE_ABNORMAL)
747*b1e83836Smrg     return;
748*b1e83836Smrg 
749*b1e83836Smrg   g->e = e;
750*b1e83836Smrg 
751*b1e83836Smrg   eliminate_build (g);
752*b1e83836Smrg 
753*b1e83836Smrg   if (elim_graph_size (g) != 0)
754*b1e83836Smrg     {
755*b1e83836Smrg       int part;
756*b1e83836Smrg 
757*b1e83836Smrg       bitmap_clear (g->visited);
758*b1e83836Smrg       g->stack.truncate (0);
759*b1e83836Smrg 
760*b1e83836Smrg       FOR_EACH_VEC_ELT (g->nodes, x, part)
761*b1e83836Smrg         {
762*b1e83836Smrg 	  if (!bitmap_bit_p (g->visited, part))
763*b1e83836Smrg 	    elim_forward (g, part);
764*b1e83836Smrg 	}
765*b1e83836Smrg 
766*b1e83836Smrg       bitmap_clear (g->visited);
767*b1e83836Smrg       while (g->stack.length () > 0)
768*b1e83836Smrg 	{
769*b1e83836Smrg 	  x = g->stack.pop ();
770*b1e83836Smrg 	  if (!bitmap_bit_p (g->visited, x))
771*b1e83836Smrg 	    elim_create (g, x);
772*b1e83836Smrg 	}
773*b1e83836Smrg     }
774*b1e83836Smrg 
775*b1e83836Smrg   /* If there are any pending constant copies, issue them now.  */
776*b1e83836Smrg   while (g->const_copies.length () > 0)
777*b1e83836Smrg     {
778*b1e83836Smrg       int dest;
779*b1e83836Smrg       tree src;
780*b1e83836Smrg       location_t locus;
781*b1e83836Smrg 
782*b1e83836Smrg       src = g->const_copies.pop ();
783*b1e83836Smrg       dest = g->const_dests.pop ();
784*b1e83836Smrg       locus = g->copy_locus.pop ();
785*b1e83836Smrg       insert_value_copy_on_edge (e, dest, src, locus);
786*b1e83836Smrg     }
787*b1e83836Smrg }
788*b1e83836Smrg 
789*b1e83836Smrg 
790*b1e83836Smrg /* Remove each argument from PHI.  If an arg was the last use of an SSA_NAME,
791*b1e83836Smrg    check to see if this allows another PHI node to be removed.  */
792*b1e83836Smrg 
793*b1e83836Smrg static void
remove_gimple_phi_args(gphi * phi)794*b1e83836Smrg remove_gimple_phi_args (gphi *phi)
795*b1e83836Smrg {
796*b1e83836Smrg   use_operand_p arg_p;
797*b1e83836Smrg   ssa_op_iter iter;
798*b1e83836Smrg 
799*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
800*b1e83836Smrg     {
801*b1e83836Smrg       fprintf (dump_file, "Removing Dead PHI definition: ");
802*b1e83836Smrg       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
803*b1e83836Smrg     }
804*b1e83836Smrg 
805*b1e83836Smrg   FOR_EACH_PHI_ARG (arg_p, phi, iter, SSA_OP_USE)
806*b1e83836Smrg     {
807*b1e83836Smrg       tree arg = USE_FROM_PTR (arg_p);
808*b1e83836Smrg       if (TREE_CODE (arg) == SSA_NAME)
809*b1e83836Smrg         {
810*b1e83836Smrg 	  /* Remove the reference to the existing argument.  */
811*b1e83836Smrg 	  SET_USE (arg_p, NULL_TREE);
812*b1e83836Smrg 	  if (has_zero_uses (arg))
813*b1e83836Smrg 	    {
814*b1e83836Smrg 	      gimple *stmt;
815*b1e83836Smrg 	      gimple_stmt_iterator gsi;
816*b1e83836Smrg 
817*b1e83836Smrg 	      stmt = SSA_NAME_DEF_STMT (arg);
818*b1e83836Smrg 
819*b1e83836Smrg 	      /* Also remove the def if it is a PHI node.  */
820*b1e83836Smrg 	      if (gimple_code (stmt) == GIMPLE_PHI)
821*b1e83836Smrg 		{
822*b1e83836Smrg 		  remove_gimple_phi_args (as_a <gphi *> (stmt));
823*b1e83836Smrg 		  gsi = gsi_for_stmt (stmt);
824*b1e83836Smrg 		  remove_phi_node (&gsi, true);
825*b1e83836Smrg 		}
826*b1e83836Smrg 
827*b1e83836Smrg 	    }
828*b1e83836Smrg 	}
829*b1e83836Smrg     }
830*b1e83836Smrg }
831*b1e83836Smrg 
832*b1e83836Smrg /* Remove any PHI node which is a virtual PHI, or a PHI with no uses.  */
833*b1e83836Smrg 
834*b1e83836Smrg static void
eliminate_useless_phis(void)835*b1e83836Smrg eliminate_useless_phis (void)
836*b1e83836Smrg {
837*b1e83836Smrg   basic_block bb;
838*b1e83836Smrg   gphi_iterator gsi;
839*b1e83836Smrg   tree result;
840*b1e83836Smrg 
841*b1e83836Smrg   FOR_EACH_BB_FN (bb, cfun)
842*b1e83836Smrg     {
843*b1e83836Smrg       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
844*b1e83836Smrg         {
845*b1e83836Smrg 	  gphi *phi = gsi.phi ();
846*b1e83836Smrg 	  result = gimple_phi_result (phi);
847*b1e83836Smrg 	  if (virtual_operand_p (result))
848*b1e83836Smrg 	    remove_phi_node (&gsi, true);
849*b1e83836Smrg           else
850*b1e83836Smrg 	    {
851*b1e83836Smrg 	      /* Also remove real PHIs with no uses.  */
852*b1e83836Smrg 	      if (has_zero_uses (result))
853*b1e83836Smrg 	        {
854*b1e83836Smrg 		  remove_gimple_phi_args (phi);
855*b1e83836Smrg 		  remove_phi_node (&gsi, true);
856*b1e83836Smrg 		}
857*b1e83836Smrg 	      else
858*b1e83836Smrg 		gsi_next (&gsi);
859*b1e83836Smrg 	    }
860*b1e83836Smrg 	}
861*b1e83836Smrg     }
862*b1e83836Smrg }
863*b1e83836Smrg 
864*b1e83836Smrg 
865*b1e83836Smrg /* This function will rewrite the current program using the variable mapping
866*b1e83836Smrg    found in MAP.  If the replacement vector VALUES is provided, any
867*b1e83836Smrg    occurrences of partitions with non-null entries in the vector will be
868*b1e83836Smrg    replaced with the expression in the vector instead of its mapped
869*b1e83836Smrg    variable.  */
870*b1e83836Smrg 
871*b1e83836Smrg static void
rewrite_trees(var_map map)872*b1e83836Smrg rewrite_trees (var_map map)
873*b1e83836Smrg {
874*b1e83836Smrg   if (!flag_checking)
875*b1e83836Smrg     return;
876*b1e83836Smrg 
877*b1e83836Smrg   basic_block bb;
878*b1e83836Smrg   /* Search for PHIs where the destination has no partition, but one
879*b1e83836Smrg      or more arguments has a partition.  This should not happen and can
880*b1e83836Smrg      create incorrect code.  */
881*b1e83836Smrg   FOR_EACH_BB_FN (bb, cfun)
882*b1e83836Smrg     {
883*b1e83836Smrg       gphi_iterator gsi;
884*b1e83836Smrg       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
885*b1e83836Smrg 	{
886*b1e83836Smrg 	  gphi *phi = gsi.phi ();
887*b1e83836Smrg 	  tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi));
888*b1e83836Smrg 	  if (T0 == NULL_TREE)
889*b1e83836Smrg 	    {
890*b1e83836Smrg 	      size_t i;
891*b1e83836Smrg 	      for (i = 0; i < gimple_phi_num_args (phi); i++)
892*b1e83836Smrg 		{
893*b1e83836Smrg 		  tree arg = PHI_ARG_DEF (phi, i);
894*b1e83836Smrg 
895*b1e83836Smrg 		  if (TREE_CODE (arg) == SSA_NAME
896*b1e83836Smrg 		      && var_to_partition (map, arg) != NO_PARTITION)
897*b1e83836Smrg 		    {
898*b1e83836Smrg 		      fprintf (stderr, "Argument of PHI is in a partition :(");
899*b1e83836Smrg 		      print_generic_expr (stderr, arg, TDF_SLIM);
900*b1e83836Smrg 		      fprintf (stderr, "), but the result is not :");
901*b1e83836Smrg 		      print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
902*b1e83836Smrg 		      internal_error ("SSA corruption");
903*b1e83836Smrg 		    }
904*b1e83836Smrg 		}
905*b1e83836Smrg 	    }
906*b1e83836Smrg 	}
907*b1e83836Smrg     }
908*b1e83836Smrg }
909*b1e83836Smrg 
910*b1e83836Smrg /* Create a default def for VAR.  */
911*b1e83836Smrg 
912*b1e83836Smrg static void
create_default_def(tree var,void * arg ATTRIBUTE_UNUSED)913*b1e83836Smrg create_default_def (tree var, void *arg ATTRIBUTE_UNUSED)
914*b1e83836Smrg {
915*b1e83836Smrg   if (!is_gimple_reg (var))
916*b1e83836Smrg     return;
917*b1e83836Smrg 
918*b1e83836Smrg   tree ssa = get_or_create_ssa_default_def (cfun, var);
919*b1e83836Smrg   gcc_assert (ssa);
920*b1e83836Smrg }
921*b1e83836Smrg 
922*b1e83836Smrg /* Call CALLBACK for all PARM_DECLs and RESULT_DECLs for which
923*b1e83836Smrg    assign_parms may ask for a default partition.  */
924*b1e83836Smrg 
925*b1e83836Smrg static void
for_all_parms(void (* callback)(tree var,void * arg),void * arg)926*b1e83836Smrg for_all_parms (void (*callback)(tree var, void *arg), void *arg)
927*b1e83836Smrg {
928*b1e83836Smrg   for (tree var = DECL_ARGUMENTS (current_function_decl); var;
929*b1e83836Smrg        var = DECL_CHAIN (var))
930*b1e83836Smrg     callback (var, arg);
931*b1e83836Smrg   if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
932*b1e83836Smrg     callback (DECL_RESULT (current_function_decl), arg);
933*b1e83836Smrg   if (cfun->static_chain_decl)
934*b1e83836Smrg     callback (cfun->static_chain_decl, arg);
935*b1e83836Smrg }
936*b1e83836Smrg 
937*b1e83836Smrg /* We need to pass two arguments to set_parm_default_def_partition,
938*b1e83836Smrg    but for_all_parms only supports one.  Use a pair.  */
939*b1e83836Smrg 
940*b1e83836Smrg typedef std::pair<var_map, bitmap> parm_default_def_partition_arg;
941*b1e83836Smrg 
942*b1e83836Smrg /* Set in ARG's PARTS bitmap the bit corresponding to the partition in
943*b1e83836Smrg    ARG's MAP containing VAR's default def.  */
944*b1e83836Smrg 
945*b1e83836Smrg static void
set_parm_default_def_partition(tree var,void * arg_)946*b1e83836Smrg set_parm_default_def_partition (tree var, void *arg_)
947*b1e83836Smrg {
948*b1e83836Smrg   parm_default_def_partition_arg *arg = (parm_default_def_partition_arg *)arg_;
949*b1e83836Smrg   var_map map = arg->first;
950*b1e83836Smrg   bitmap parts = arg->second;
951*b1e83836Smrg 
952*b1e83836Smrg   if (!is_gimple_reg (var))
953*b1e83836Smrg     return;
954*b1e83836Smrg 
955*b1e83836Smrg   tree ssa = ssa_default_def (cfun, var);
956*b1e83836Smrg   gcc_assert (ssa);
957*b1e83836Smrg 
958*b1e83836Smrg   int version = var_to_partition (map, ssa);
959*b1e83836Smrg   gcc_assert (version != NO_PARTITION);
960*b1e83836Smrg 
961*b1e83836Smrg   bool changed = bitmap_set_bit (parts, version);
962*b1e83836Smrg   gcc_assert (changed);
963*b1e83836Smrg }
964*b1e83836Smrg 
965*b1e83836Smrg /* Allocate and return a bitmap that has a bit set for each partition
966*b1e83836Smrg    that contains a default def for a parameter.  */
967*b1e83836Smrg 
968*b1e83836Smrg static bitmap
get_parm_default_def_partitions(var_map map)969*b1e83836Smrg get_parm_default_def_partitions (var_map map)
970*b1e83836Smrg {
971*b1e83836Smrg   bitmap parm_default_def_parts = BITMAP_ALLOC (NULL);
972*b1e83836Smrg 
973*b1e83836Smrg   parm_default_def_partition_arg
974*b1e83836Smrg     arg = std::make_pair (map, parm_default_def_parts);
975*b1e83836Smrg 
976*b1e83836Smrg   for_all_parms (set_parm_default_def_partition, &arg);
977*b1e83836Smrg 
978*b1e83836Smrg   return parm_default_def_parts;
979*b1e83836Smrg }
980*b1e83836Smrg 
981*b1e83836Smrg /* Allocate and return a bitmap that has a bit set for each partition
982*b1e83836Smrg    that contains an undefined value.  */
983*b1e83836Smrg 
984*b1e83836Smrg static bitmap
get_undefined_value_partitions(var_map map)985*b1e83836Smrg get_undefined_value_partitions (var_map map)
986*b1e83836Smrg {
987*b1e83836Smrg   bitmap undefined_value_parts = BITMAP_ALLOC (NULL);
988*b1e83836Smrg 
989*b1e83836Smrg   for (unsigned int i = 1; i < num_ssa_names; i++)
990*b1e83836Smrg     {
991*b1e83836Smrg       tree var = ssa_name (i);
992*b1e83836Smrg       if (var
993*b1e83836Smrg 	  && !virtual_operand_p (var)
994*b1e83836Smrg 	  && !has_zero_uses (var)
995*b1e83836Smrg 	  && ssa_undefined_value_p (var))
996*b1e83836Smrg 	{
997*b1e83836Smrg 	  const int p = var_to_partition (map, var);
998*b1e83836Smrg 	  if (p != NO_PARTITION)
999*b1e83836Smrg 	    bitmap_set_bit (undefined_value_parts, p);
1000*b1e83836Smrg 	}
1001*b1e83836Smrg     }
1002*b1e83836Smrg 
1003*b1e83836Smrg   return undefined_value_parts;
1004*b1e83836Smrg }
1005*b1e83836Smrg 
1006*b1e83836Smrg /* Given the out-of-ssa info object SA (with prepared partitions)
1007*b1e83836Smrg    eliminate all phi nodes in all basic blocks.  Afterwards no
1008*b1e83836Smrg    basic block will have phi nodes anymore and there are possibly
1009*b1e83836Smrg    some RTL instructions inserted on edges.  */
1010*b1e83836Smrg 
1011*b1e83836Smrg void
expand_phi_nodes(struct ssaexpand * sa)1012*b1e83836Smrg expand_phi_nodes (struct ssaexpand *sa)
1013*b1e83836Smrg {
1014*b1e83836Smrg   basic_block bb;
1015*b1e83836Smrg   elim_graph g (sa->map);
1016*b1e83836Smrg 
1017*b1e83836Smrg   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb,
1018*b1e83836Smrg 		  EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
1019*b1e83836Smrg     if (!gimple_seq_empty_p (phi_nodes (bb)))
1020*b1e83836Smrg       {
1021*b1e83836Smrg 	edge e;
1022*b1e83836Smrg 	edge_iterator ei;
1023*b1e83836Smrg 	FOR_EACH_EDGE (e, ei, bb->preds)
1024*b1e83836Smrg 	  eliminate_phi (e, &g);
1025*b1e83836Smrg 	set_phi_nodes (bb, NULL);
1026*b1e83836Smrg 	/* We can't redirect EH edges in RTL land, so we need to do this
1027*b1e83836Smrg 	   here.  Redirection happens only when splitting is necessary,
1028*b1e83836Smrg 	   which it is only for critical edges, normally.  For EH edges
1029*b1e83836Smrg 	   it might also be necessary when the successor has more than
1030*b1e83836Smrg 	   one predecessor.  In that case the edge is either required to
1031*b1e83836Smrg 	   be fallthru (which EH edges aren't), or the predecessor needs
1032*b1e83836Smrg 	   to end with a jump (which again, isn't the case with EH edges).
1033*b1e83836Smrg 	   Hence, split all EH edges on which we inserted instructions
1034*b1e83836Smrg 	   and whose successor has multiple predecessors.  */
1035*b1e83836Smrg 	for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
1036*b1e83836Smrg 	  {
1037*b1e83836Smrg 	    if (e->insns.r && (e->flags & EDGE_EH)
1038*b1e83836Smrg 		&& !single_pred_p (e->dest))
1039*b1e83836Smrg 	      {
1040*b1e83836Smrg 		rtx_insn *insns = e->insns.r;
1041*b1e83836Smrg 		basic_block bb;
1042*b1e83836Smrg 		e->insns.r = NULL;
1043*b1e83836Smrg 		bb = split_edge (e);
1044*b1e83836Smrg 		single_pred_edge (bb)->insns.r = insns;
1045*b1e83836Smrg 	      }
1046*b1e83836Smrg 	    else
1047*b1e83836Smrg 	      ei_next (&ei);
1048*b1e83836Smrg 	  }
1049*b1e83836Smrg       }
1050*b1e83836Smrg }
1051*b1e83836Smrg 
1052*b1e83836Smrg 
1053*b1e83836Smrg /* Remove the ssa-names in the current function and translate them into normal
1054*b1e83836Smrg    compiler variables.  PERFORM_TER is true if Temporary Expression Replacement
1055*b1e83836Smrg    should also be used.  */
1056*b1e83836Smrg 
1057*b1e83836Smrg static void
remove_ssa_form(bool perform_ter,struct ssaexpand * sa)1058*b1e83836Smrg remove_ssa_form (bool perform_ter, struct ssaexpand *sa)
1059*b1e83836Smrg {
1060*b1e83836Smrg   bitmap values = NULL;
1061*b1e83836Smrg   var_map map;
1062*b1e83836Smrg 
1063*b1e83836Smrg   for_all_parms (create_default_def, NULL);
1064*b1e83836Smrg   map = init_var_map (num_ssa_names);
1065*b1e83836Smrg   coalesce_ssa_name (map);
1066*b1e83836Smrg 
1067*b1e83836Smrg   /* Return to viewing the variable list as just all reference variables after
1068*b1e83836Smrg      coalescing has been performed.  */
1069*b1e83836Smrg   partition_view_normal (map);
1070*b1e83836Smrg 
1071*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
1072*b1e83836Smrg     {
1073*b1e83836Smrg       fprintf (dump_file, "After Coalescing:\n");
1074*b1e83836Smrg       dump_var_map (dump_file, map);
1075*b1e83836Smrg     }
1076*b1e83836Smrg 
1077*b1e83836Smrg   if (perform_ter)
1078*b1e83836Smrg     {
1079*b1e83836Smrg       values = find_replaceable_exprs (map);
1080*b1e83836Smrg       if (values && dump_file && (dump_flags & TDF_DETAILS))
1081*b1e83836Smrg 	dump_replaceable_exprs (dump_file, values);
1082*b1e83836Smrg     }
1083*b1e83836Smrg 
1084*b1e83836Smrg   rewrite_trees (map);
1085*b1e83836Smrg 
1086*b1e83836Smrg   sa->map = map;
1087*b1e83836Smrg   sa->values = values;
1088*b1e83836Smrg   sa->partitions_for_parm_default_defs = get_parm_default_def_partitions (map);
1089*b1e83836Smrg   sa->partitions_for_undefined_values = get_undefined_value_partitions (map);
1090*b1e83836Smrg }
1091*b1e83836Smrg 
1092*b1e83836Smrg 
1093*b1e83836Smrg /* If not already done so for basic block BB, assign increasing uids
1094*b1e83836Smrg    to each of its instructions.  */
1095*b1e83836Smrg 
1096*b1e83836Smrg static void
maybe_renumber_stmts_bb(basic_block bb)1097*b1e83836Smrg maybe_renumber_stmts_bb (basic_block bb)
1098*b1e83836Smrg {
1099*b1e83836Smrg   unsigned i = 0;
1100*b1e83836Smrg   gimple_stmt_iterator gsi;
1101*b1e83836Smrg 
1102*b1e83836Smrg   if (!bb->aux)
1103*b1e83836Smrg     return;
1104*b1e83836Smrg   bb->aux = NULL;
1105*b1e83836Smrg   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1106*b1e83836Smrg     {
1107*b1e83836Smrg       gimple *stmt = gsi_stmt (gsi);
1108*b1e83836Smrg       gimple_set_uid (stmt, i);
1109*b1e83836Smrg       i++;
1110*b1e83836Smrg     }
1111*b1e83836Smrg }
1112*b1e83836Smrg 
1113*b1e83836Smrg 
1114*b1e83836Smrg /* Return true if we can determine that the SSA_NAMEs RESULT (a result
1115*b1e83836Smrg    of a PHI node) and ARG (one of its arguments) conflict.  Return false
1116*b1e83836Smrg    otherwise, also when we simply aren't sure.  */
1117*b1e83836Smrg 
1118*b1e83836Smrg static bool
trivially_conflicts_p(basic_block bb,tree result,tree arg)1119*b1e83836Smrg trivially_conflicts_p (basic_block bb, tree result, tree arg)
1120*b1e83836Smrg {
1121*b1e83836Smrg   use_operand_p use;
1122*b1e83836Smrg   imm_use_iterator imm_iter;
1123*b1e83836Smrg   gimple *defa = SSA_NAME_DEF_STMT (arg);
1124*b1e83836Smrg 
1125*b1e83836Smrg   /* If ARG isn't defined in the same block it's too complicated for
1126*b1e83836Smrg      our little mind.  */
1127*b1e83836Smrg   if (gimple_bb (defa) != bb)
1128*b1e83836Smrg     return false;
1129*b1e83836Smrg 
1130*b1e83836Smrg   FOR_EACH_IMM_USE_FAST (use, imm_iter, result)
1131*b1e83836Smrg     {
1132*b1e83836Smrg       gimple *use_stmt = USE_STMT (use);
1133*b1e83836Smrg       if (is_gimple_debug (use_stmt))
1134*b1e83836Smrg 	continue;
1135*b1e83836Smrg       /* Now, if there's a use of RESULT that lies outside this basic block,
1136*b1e83836Smrg 	 then there surely is a conflict with ARG.  */
1137*b1e83836Smrg       if (gimple_bb (use_stmt) != bb)
1138*b1e83836Smrg 	return true;
1139*b1e83836Smrg       if (gimple_code (use_stmt) == GIMPLE_PHI)
1140*b1e83836Smrg 	continue;
1141*b1e83836Smrg       /* The use now is in a real stmt of BB, so if ARG was defined
1142*b1e83836Smrg          in a PHI node (like RESULT) both conflict.  */
1143*b1e83836Smrg       if (gimple_code (defa) == GIMPLE_PHI)
1144*b1e83836Smrg 	return true;
1145*b1e83836Smrg       maybe_renumber_stmts_bb (bb);
1146*b1e83836Smrg       /* If the use of RESULT occurs after the definition of ARG,
1147*b1e83836Smrg          the two conflict too.  */
1148*b1e83836Smrg       if (gimple_uid (defa) < gimple_uid (use_stmt))
1149*b1e83836Smrg 	return true;
1150*b1e83836Smrg     }
1151*b1e83836Smrg 
1152*b1e83836Smrg   return false;
1153*b1e83836Smrg }
1154*b1e83836Smrg 
1155*b1e83836Smrg 
1156*b1e83836Smrg /* Search every PHI node for arguments associated with backedges which
1157*b1e83836Smrg    we can trivially determine will need a copy (the argument is either
1158*b1e83836Smrg    not an SSA_NAME or the argument has a different underlying variable
1159*b1e83836Smrg    than the PHI result).
1160*b1e83836Smrg 
1161*b1e83836Smrg    Insert a copy from the PHI argument to a new destination at the
1162*b1e83836Smrg    end of the block with the backedge to the top of the loop.  Update
1163*b1e83836Smrg    the PHI argument to reference this new destination.  */
1164*b1e83836Smrg 
1165*b1e83836Smrg static void
insert_backedge_copies(void)1166*b1e83836Smrg insert_backedge_copies (void)
1167*b1e83836Smrg {
1168*b1e83836Smrg   basic_block bb;
1169*b1e83836Smrg   gphi_iterator gsi;
1170*b1e83836Smrg 
1171*b1e83836Smrg   mark_dfs_back_edges ();
1172*b1e83836Smrg 
1173*b1e83836Smrg   FOR_EACH_BB_FN (bb, cfun)
1174*b1e83836Smrg     {
1175*b1e83836Smrg       /* Mark block as possibly needing calculation of UIDs.  */
1176*b1e83836Smrg       bb->aux = &bb->aux;
1177*b1e83836Smrg 
1178*b1e83836Smrg       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1179*b1e83836Smrg 	{
1180*b1e83836Smrg 	  gphi *phi = gsi.phi ();
1181*b1e83836Smrg 	  tree result = gimple_phi_result (phi);
1182*b1e83836Smrg 	  size_t i;
1183*b1e83836Smrg 
1184*b1e83836Smrg 	  if (virtual_operand_p (result))
1185*b1e83836Smrg 	    continue;
1186*b1e83836Smrg 
1187*b1e83836Smrg 	  for (i = 0; i < gimple_phi_num_args (phi); i++)
1188*b1e83836Smrg 	    {
1189*b1e83836Smrg 	      tree arg = gimple_phi_arg_def (phi, i);
1190*b1e83836Smrg 	      edge e = gimple_phi_arg_edge (phi, i);
1191*b1e83836Smrg 	      /* We are only interested in copies emitted on critical
1192*b1e83836Smrg                  backedges.  */
1193*b1e83836Smrg 	      if (!(e->flags & EDGE_DFS_BACK)
1194*b1e83836Smrg 		  || !EDGE_CRITICAL_P (e))
1195*b1e83836Smrg 		continue;
1196*b1e83836Smrg 
1197*b1e83836Smrg 	      /* If the argument is not an SSA_NAME, then we will need a
1198*b1e83836Smrg 		 constant initialization.  If the argument is an SSA_NAME then
1199*b1e83836Smrg 		 a copy statement may be needed.  First handle the case
1200*b1e83836Smrg 		 where we cannot insert before the argument definition.  */
1201*b1e83836Smrg 	      if (TREE_CODE (arg) != SSA_NAME
1202*b1e83836Smrg 		  || (gimple_code (SSA_NAME_DEF_STMT (arg)) == GIMPLE_PHI
1203*b1e83836Smrg 		      && trivially_conflicts_p (bb, result, arg)))
1204*b1e83836Smrg 		{
1205*b1e83836Smrg 		  tree name;
1206*b1e83836Smrg 		  gassign *stmt;
1207*b1e83836Smrg 		  gimple *last = NULL;
1208*b1e83836Smrg 		  gimple_stmt_iterator gsi2;
1209*b1e83836Smrg 
1210*b1e83836Smrg 		  gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src);
1211*b1e83836Smrg 		  if (!gsi_end_p (gsi2))
1212*b1e83836Smrg 		    last = gsi_stmt (gsi2);
1213*b1e83836Smrg 
1214*b1e83836Smrg 		  /* In theory the only way we ought to get back to the
1215*b1e83836Smrg 		     start of a loop should be with a COND_EXPR or GOTO_EXPR.
1216*b1e83836Smrg 		     However, better safe than sorry.
1217*b1e83836Smrg 		     If the block ends with a control statement or
1218*b1e83836Smrg 		     something that might throw, then we have to
1219*b1e83836Smrg 		     insert this assignment before the last
1220*b1e83836Smrg 		     statement.  Else insert it after the last statement.  */
1221*b1e83836Smrg 		  if (last && stmt_ends_bb_p (last))
1222*b1e83836Smrg 		    {
1223*b1e83836Smrg 		      /* If the last statement in the block is the definition
1224*b1e83836Smrg 			 site of the PHI argument, then we can't insert
1225*b1e83836Smrg 			 anything after it.  */
1226*b1e83836Smrg 		      if (TREE_CODE (arg) == SSA_NAME
1227*b1e83836Smrg 			  && SSA_NAME_DEF_STMT (arg) == last)
1228*b1e83836Smrg 			continue;
1229*b1e83836Smrg 		    }
1230*b1e83836Smrg 
1231*b1e83836Smrg 		  /* Create a new instance of the underlying variable of the
1232*b1e83836Smrg 		     PHI result.  */
1233*b1e83836Smrg 		  name = copy_ssa_name (result);
1234*b1e83836Smrg 		  stmt = gimple_build_assign (name,
1235*b1e83836Smrg 					      gimple_phi_arg_def (phi, i));
1236*b1e83836Smrg 
1237*b1e83836Smrg 		  /* copy location if present.  */
1238*b1e83836Smrg 		  if (gimple_phi_arg_has_location (phi, i))
1239*b1e83836Smrg 		    gimple_set_location (stmt,
1240*b1e83836Smrg 					 gimple_phi_arg_location (phi, i));
1241*b1e83836Smrg 
1242*b1e83836Smrg 		  /* Insert the new statement into the block and update
1243*b1e83836Smrg 		     the PHI node.  */
1244*b1e83836Smrg 		  if (last && stmt_ends_bb_p (last))
1245*b1e83836Smrg 		    gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
1246*b1e83836Smrg 		  else
1247*b1e83836Smrg 		    gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT);
1248*b1e83836Smrg 		  SET_PHI_ARG_DEF (phi, i, name);
1249*b1e83836Smrg 		}
1250*b1e83836Smrg 	      /* Insert a copy before the definition of the backedge value
1251*b1e83836Smrg 		 and adjust all conflicting uses.  */
1252*b1e83836Smrg 	      else if (trivially_conflicts_p (bb, result, arg))
1253*b1e83836Smrg 		{
1254*b1e83836Smrg 		  gimple *def = SSA_NAME_DEF_STMT (arg);
1255*b1e83836Smrg 		  if (gimple_nop_p (def)
1256*b1e83836Smrg 		      || gimple_code (def) == GIMPLE_PHI)
1257*b1e83836Smrg 		    continue;
1258*b1e83836Smrg 		  tree name = copy_ssa_name (result);
1259*b1e83836Smrg 		  gimple *stmt = gimple_build_assign (name, result);
1260*b1e83836Smrg 		  imm_use_iterator imm_iter;
1261*b1e83836Smrg 		  gimple *use_stmt;
1262*b1e83836Smrg 		  /* The following matches trivially_conflicts_p.  */
1263*b1e83836Smrg 		  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, result)
1264*b1e83836Smrg 		    {
1265*b1e83836Smrg 		      if (gimple_bb (use_stmt) != bb
1266*b1e83836Smrg 			  || (gimple_code (use_stmt) != GIMPLE_PHI
1267*b1e83836Smrg 			      && (maybe_renumber_stmts_bb (bb), true)
1268*b1e83836Smrg 			      && gimple_uid (use_stmt) > gimple_uid (def)))
1269*b1e83836Smrg 			{
1270*b1e83836Smrg 			  use_operand_p use;
1271*b1e83836Smrg 			  FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)
1272*b1e83836Smrg 			    SET_USE (use, name);
1273*b1e83836Smrg 			}
1274*b1e83836Smrg 		    }
1275*b1e83836Smrg 		  gimple_stmt_iterator gsi = gsi_for_stmt (def);
1276*b1e83836Smrg 		  gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1277*b1e83836Smrg 		}
1278*b1e83836Smrg 	    }
1279*b1e83836Smrg 	}
1280*b1e83836Smrg 
1281*b1e83836Smrg       /* Unmark this block again.  */
1282*b1e83836Smrg       bb->aux = NULL;
1283*b1e83836Smrg     }
1284*b1e83836Smrg }
1285*b1e83836Smrg 
1286*b1e83836Smrg /* Free all memory associated with going out of SSA form.  SA is
1287*b1e83836Smrg    the outof-SSA info object.  */
1288*b1e83836Smrg 
1289*b1e83836Smrg void
finish_out_of_ssa(struct ssaexpand * sa)1290*b1e83836Smrg finish_out_of_ssa (struct ssaexpand *sa)
1291*b1e83836Smrg {
1292*b1e83836Smrg   free (sa->partition_to_pseudo);
1293*b1e83836Smrg   if (sa->values)
1294*b1e83836Smrg     BITMAP_FREE (sa->values);
1295*b1e83836Smrg   delete_var_map (sa->map);
1296*b1e83836Smrg   BITMAP_FREE (sa->partitions_for_parm_default_defs);
1297*b1e83836Smrg   BITMAP_FREE (sa->partitions_for_undefined_values);
1298*b1e83836Smrg   memset (sa, 0, sizeof *sa);
1299*b1e83836Smrg }
1300*b1e83836Smrg 
1301*b1e83836Smrg /* Take the current function out of SSA form, translating PHIs as described in
1302*b1e83836Smrg    R. Morgan, ``Building an Optimizing Compiler'',
1303*b1e83836Smrg    Butterworth-Heinemann, Boston, MA, 1998. pp 176-186.  */
1304*b1e83836Smrg 
1305*b1e83836Smrg unsigned int
rewrite_out_of_ssa(struct ssaexpand * sa)1306*b1e83836Smrg rewrite_out_of_ssa (struct ssaexpand *sa)
1307*b1e83836Smrg {
1308*b1e83836Smrg   /* If elimination of a PHI requires inserting a copy on a backedge,
1309*b1e83836Smrg      then we will have to split the backedge which has numerous
1310*b1e83836Smrg      undesirable performance effects.
1311*b1e83836Smrg 
1312*b1e83836Smrg      A significant number of such cases can be handled here by inserting
1313*b1e83836Smrg      copies into the loop itself.  */
1314*b1e83836Smrg   insert_backedge_copies ();
1315*b1e83836Smrg 
1316*b1e83836Smrg 
1317*b1e83836Smrg   /* Eliminate PHIs which are of no use, such as virtual or dead phis.  */
1318*b1e83836Smrg   eliminate_useless_phis ();
1319*b1e83836Smrg 
1320*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
1321*b1e83836Smrg     gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
1322*b1e83836Smrg 
1323*b1e83836Smrg   remove_ssa_form (flag_tree_ter, sa);
1324*b1e83836Smrg 
1325*b1e83836Smrg   if (dump_file && (dump_flags & TDF_DETAILS))
1326*b1e83836Smrg     gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
1327*b1e83836Smrg 
1328*b1e83836Smrg   return 0;
1329*b1e83836Smrg }
1330