1*e4b17023SJohn Marino /* Generic routines for manipulating PHIs
2*e4b17023SJohn Marino    Copyright (C) 2003, 2005, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino 
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino any later version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*e4b17023SJohn Marino GNU General Public License for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "tm.h"
25*e4b17023SJohn Marino #include "tree.h"
26*e4b17023SJohn Marino #include "rtl.h"	/* FIXME: Only for ceil_log2, of all things...  */
27*e4b17023SJohn Marino #include "ggc.h"
28*e4b17023SJohn Marino #include "basic-block.h"
29*e4b17023SJohn Marino #include "tree-flow.h"
30*e4b17023SJohn Marino #include "diagnostic-core.h"
31*e4b17023SJohn Marino #include "gimple.h"
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino /* Rewriting a function into SSA form can create a huge number of PHIs
34*e4b17023SJohn Marino    many of which may be thrown away shortly after their creation if jumps
35*e4b17023SJohn Marino    were threaded through PHI nodes.
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino    While our garbage collection mechanisms will handle this situation, it
38*e4b17023SJohn Marino    is extremely wasteful to create nodes and throw them away, especially
39*e4b17023SJohn Marino    when the nodes can be reused.
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino    For PR 8361, we can significantly reduce the number of nodes allocated
42*e4b17023SJohn Marino    and thus the total amount of memory allocated by managing PHIs a
43*e4b17023SJohn Marino    little.  This additionally helps reduce the amount of work done by the
44*e4b17023SJohn Marino    garbage collector.  Similar results have been seen on a wider variety
45*e4b17023SJohn Marino    of tests (such as the compiler itself).
46*e4b17023SJohn Marino 
47*e4b17023SJohn Marino    Right now we maintain our free list on a per-function basis.  It may
48*e4b17023SJohn Marino    or may not make sense to maintain the free list for the duration of
49*e4b17023SJohn Marino    a compilation unit.
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino    We could also use a zone allocator for these objects since they have
52*e4b17023SJohn Marino    a very well defined lifetime.  If someone wants to experiment with that
53*e4b17023SJohn Marino    this is the place to try it.
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino    PHI nodes have different sizes, so we can't have a single list of all
56*e4b17023SJohn Marino    the PHI nodes as it would be too expensive to walk down that list to
57*e4b17023SJohn Marino    find a PHI of a suitable size.
58*e4b17023SJohn Marino 
59*e4b17023SJohn Marino    Instead we have an array of lists of free PHI nodes.  The array is
60*e4b17023SJohn Marino    indexed by the number of PHI alternatives that PHI node can hold.
61*e4b17023SJohn Marino    Except for the last array member, which holds all remaining PHI
62*e4b17023SJohn Marino    nodes.
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino    So to find a free PHI node, we compute its index into the free PHI
65*e4b17023SJohn Marino    node array and see if there are any elements with an exact match.
66*e4b17023SJohn Marino    If so, then we are done.  Otherwise, we test the next larger size
67*e4b17023SJohn Marino    up and continue until we are in the last array element.
68*e4b17023SJohn Marino 
69*e4b17023SJohn Marino    We do not actually walk members of the last array element.  While it
70*e4b17023SJohn Marino    might allow us to pick up a few reusable PHI nodes, it could potentially
71*e4b17023SJohn Marino    be very expensive if the program has released a bunch of large PHI nodes,
72*e4b17023SJohn Marino    but keeps asking for even larger PHI nodes.  Experiments have shown that
73*e4b17023SJohn Marino    walking the elements of the last array entry would result in finding less
74*e4b17023SJohn Marino    than .1% additional reusable PHI nodes.
75*e4b17023SJohn Marino 
76*e4b17023SJohn Marino    Note that we can never have less than two PHI argument slots.  Thus,
77*e4b17023SJohn Marino    the -2 on all the calculations below.  */
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino #define NUM_BUCKETS 10
80*e4b17023SJohn Marino static GTY ((deletable (""))) VEC(gimple,gc) *free_phinodes[NUM_BUCKETS - 2];
81*e4b17023SJohn Marino static unsigned long free_phinode_count;
82*e4b17023SJohn Marino 
83*e4b17023SJohn Marino static int ideal_phi_node_len (int);
84*e4b17023SJohn Marino 
85*e4b17023SJohn Marino #ifdef GATHER_STATISTICS
86*e4b17023SJohn Marino unsigned int phi_nodes_reused;
87*e4b17023SJohn Marino unsigned int phi_nodes_created;
88*e4b17023SJohn Marino #endif
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino /* Initialize management of PHIs.  */
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino void
init_phinodes(void)93*e4b17023SJohn Marino init_phinodes (void)
94*e4b17023SJohn Marino {
95*e4b17023SJohn Marino   int i;
96*e4b17023SJohn Marino 
97*e4b17023SJohn Marino   for (i = 0; i < NUM_BUCKETS - 2; i++)
98*e4b17023SJohn Marino     free_phinodes[i] = NULL;
99*e4b17023SJohn Marino   free_phinode_count = 0;
100*e4b17023SJohn Marino }
101*e4b17023SJohn Marino 
102*e4b17023SJohn Marino /* Finalize management of PHIs.  */
103*e4b17023SJohn Marino 
104*e4b17023SJohn Marino void
fini_phinodes(void)105*e4b17023SJohn Marino fini_phinodes (void)
106*e4b17023SJohn Marino {
107*e4b17023SJohn Marino   int i;
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino   for (i = 0; i < NUM_BUCKETS - 2; i++)
110*e4b17023SJohn Marino     free_phinodes[i] = NULL;
111*e4b17023SJohn Marino   free_phinode_count = 0;
112*e4b17023SJohn Marino }
113*e4b17023SJohn Marino 
114*e4b17023SJohn Marino /* Dump some simple statistics regarding the re-use of PHI nodes.  */
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino #ifdef GATHER_STATISTICS
117*e4b17023SJohn Marino void
phinodes_print_statistics(void)118*e4b17023SJohn Marino phinodes_print_statistics (void)
119*e4b17023SJohn Marino {
120*e4b17023SJohn Marino   fprintf (stderr, "PHI nodes allocated: %u\n", phi_nodes_created);
121*e4b17023SJohn Marino   fprintf (stderr, "PHI nodes reused: %u\n", phi_nodes_reused);
122*e4b17023SJohn Marino }
123*e4b17023SJohn Marino #endif
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino /* Allocate a PHI node with at least LEN arguments.  If the free list
126*e4b17023SJohn Marino    happens to contain a PHI node with LEN arguments or more, return
127*e4b17023SJohn Marino    that one.  */
128*e4b17023SJohn Marino 
129*e4b17023SJohn Marino static inline gimple
allocate_phi_node(size_t len)130*e4b17023SJohn Marino allocate_phi_node (size_t len)
131*e4b17023SJohn Marino {
132*e4b17023SJohn Marino   gimple phi;
133*e4b17023SJohn Marino   size_t bucket = NUM_BUCKETS - 2;
134*e4b17023SJohn Marino   size_t size = sizeof (struct gimple_statement_phi)
135*e4b17023SJohn Marino 	        + (len - 1) * sizeof (struct phi_arg_d);
136*e4b17023SJohn Marino 
137*e4b17023SJohn Marino   if (free_phinode_count)
138*e4b17023SJohn Marino     for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
139*e4b17023SJohn Marino       if (free_phinodes[bucket])
140*e4b17023SJohn Marino 	break;
141*e4b17023SJohn Marino 
142*e4b17023SJohn Marino   /* If our free list has an element, then use it.  */
143*e4b17023SJohn Marino   if (bucket < NUM_BUCKETS - 2
144*e4b17023SJohn Marino       && gimple_phi_capacity (VEC_index (gimple, free_phinodes[bucket], 0))
145*e4b17023SJohn Marino 	 >= len)
146*e4b17023SJohn Marino     {
147*e4b17023SJohn Marino       free_phinode_count--;
148*e4b17023SJohn Marino       phi = VEC_pop (gimple, free_phinodes[bucket]);
149*e4b17023SJohn Marino       if (VEC_empty (gimple, free_phinodes[bucket]))
150*e4b17023SJohn Marino 	VEC_free (gimple, gc, free_phinodes[bucket]);
151*e4b17023SJohn Marino #ifdef GATHER_STATISTICS
152*e4b17023SJohn Marino       phi_nodes_reused++;
153*e4b17023SJohn Marino #endif
154*e4b17023SJohn Marino     }
155*e4b17023SJohn Marino   else
156*e4b17023SJohn Marino     {
157*e4b17023SJohn Marino       phi = ggc_alloc_gimple_statement_d (size);
158*e4b17023SJohn Marino #ifdef GATHER_STATISTICS
159*e4b17023SJohn Marino       phi_nodes_created++;
160*e4b17023SJohn Marino 	{
161*e4b17023SJohn Marino 	  enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI);
162*e4b17023SJohn Marino           gimple_alloc_counts[(int) kind]++;
163*e4b17023SJohn Marino           gimple_alloc_sizes[(int) kind] += size;
164*e4b17023SJohn Marino 	}
165*e4b17023SJohn Marino #endif
166*e4b17023SJohn Marino     }
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino   return phi;
169*e4b17023SJohn Marino }
170*e4b17023SJohn Marino 
171*e4b17023SJohn Marino /* Given LEN, the original number of requested PHI arguments, return
172*e4b17023SJohn Marino    a new, "ideal" length for the PHI node.  The "ideal" length rounds
173*e4b17023SJohn Marino    the total size of the PHI node up to the next power of two bytes.
174*e4b17023SJohn Marino 
175*e4b17023SJohn Marino    Rounding up will not result in wasting any memory since the size request
176*e4b17023SJohn Marino    will be rounded up by the GC system anyway.  [ Note this is not entirely
177*e4b17023SJohn Marino    true since the original length might have fit on one of the special
178*e4b17023SJohn Marino    GC pages. ]  By rounding up, we may avoid the need to reallocate the
179*e4b17023SJohn Marino    PHI node later if we increase the number of arguments for the PHI.  */
180*e4b17023SJohn Marino 
181*e4b17023SJohn Marino static int
ideal_phi_node_len(int len)182*e4b17023SJohn Marino ideal_phi_node_len (int len)
183*e4b17023SJohn Marino {
184*e4b17023SJohn Marino   size_t size, new_size;
185*e4b17023SJohn Marino   int log2, new_len;
186*e4b17023SJohn Marino 
187*e4b17023SJohn Marino   /* We do not support allocations of less than two PHI argument slots.  */
188*e4b17023SJohn Marino   if (len < 2)
189*e4b17023SJohn Marino     len = 2;
190*e4b17023SJohn Marino 
191*e4b17023SJohn Marino   /* Compute the number of bytes of the original request.  */
192*e4b17023SJohn Marino   size = sizeof (struct gimple_statement_phi)
193*e4b17023SJohn Marino 	 + (len - 1) * sizeof (struct phi_arg_d);
194*e4b17023SJohn Marino 
195*e4b17023SJohn Marino   /* Round it up to the next power of two.  */
196*e4b17023SJohn Marino   log2 = ceil_log2 (size);
197*e4b17023SJohn Marino   new_size = 1 << log2;
198*e4b17023SJohn Marino 
199*e4b17023SJohn Marino   /* Now compute and return the number of PHI argument slots given an
200*e4b17023SJohn Marino      ideal size allocation.  */
201*e4b17023SJohn Marino   new_len = len + (new_size - size) / sizeof (struct phi_arg_d);
202*e4b17023SJohn Marino   return new_len;
203*e4b17023SJohn Marino }
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino /* Return a PHI node with LEN argument slots for variable VAR.  */
206*e4b17023SJohn Marino 
207*e4b17023SJohn Marino static gimple
make_phi_node(tree var,int len)208*e4b17023SJohn Marino make_phi_node (tree var, int len)
209*e4b17023SJohn Marino {
210*e4b17023SJohn Marino   gimple phi;
211*e4b17023SJohn Marino   int capacity, i;
212*e4b17023SJohn Marino 
213*e4b17023SJohn Marino   capacity = ideal_phi_node_len (len);
214*e4b17023SJohn Marino 
215*e4b17023SJohn Marino   phi = allocate_phi_node (capacity);
216*e4b17023SJohn Marino 
217*e4b17023SJohn Marino   /* We need to clear the entire PHI node, including the argument
218*e4b17023SJohn Marino      portion, because we represent a "missing PHI argument" by placing
219*e4b17023SJohn Marino      NULL_TREE in PHI_ARG_DEF.  */
220*e4b17023SJohn Marino   memset (phi, 0, (sizeof (struct gimple_statement_phi)
221*e4b17023SJohn Marino 		   - sizeof (struct phi_arg_d)
222*e4b17023SJohn Marino 		   + sizeof (struct phi_arg_d) * len));
223*e4b17023SJohn Marino   phi->gsbase.code = GIMPLE_PHI;
224*e4b17023SJohn Marino   phi->gimple_phi.nargs = len;
225*e4b17023SJohn Marino   phi->gimple_phi.capacity = capacity;
226*e4b17023SJohn Marino   if (TREE_CODE (var) == SSA_NAME)
227*e4b17023SJohn Marino     gimple_phi_set_result (phi, var);
228*e4b17023SJohn Marino   else
229*e4b17023SJohn Marino     gimple_phi_set_result (phi, make_ssa_name (var, phi));
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino   for (i = 0; i < capacity; i++)
232*e4b17023SJohn Marino     {
233*e4b17023SJohn Marino       use_operand_p  imm;
234*e4b17023SJohn Marino 
235*e4b17023SJohn Marino       gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
236*e4b17023SJohn Marino       imm = gimple_phi_arg_imm_use_ptr (phi, i);
237*e4b17023SJohn Marino       imm->use = gimple_phi_arg_def_ptr (phi, i);
238*e4b17023SJohn Marino       imm->prev = NULL;
239*e4b17023SJohn Marino       imm->next = NULL;
240*e4b17023SJohn Marino       imm->loc.stmt = phi;
241*e4b17023SJohn Marino     }
242*e4b17023SJohn Marino 
243*e4b17023SJohn Marino   return phi;
244*e4b17023SJohn Marino }
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino /* We no longer need PHI, release it so that it may be reused.  */
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino void
release_phi_node(gimple phi)249*e4b17023SJohn Marino release_phi_node (gimple phi)
250*e4b17023SJohn Marino {
251*e4b17023SJohn Marino   size_t bucket;
252*e4b17023SJohn Marino   size_t len = gimple_phi_capacity (phi);
253*e4b17023SJohn Marino   size_t x;
254*e4b17023SJohn Marino 
255*e4b17023SJohn Marino   for (x = 0; x < gimple_phi_num_args (phi); x++)
256*e4b17023SJohn Marino     {
257*e4b17023SJohn Marino       use_operand_p  imm;
258*e4b17023SJohn Marino       imm = gimple_phi_arg_imm_use_ptr (phi, x);
259*e4b17023SJohn Marino       delink_imm_use (imm);
260*e4b17023SJohn Marino     }
261*e4b17023SJohn Marino 
262*e4b17023SJohn Marino   bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len;
263*e4b17023SJohn Marino   bucket -= 2;
264*e4b17023SJohn Marino   VEC_safe_push (gimple, gc, free_phinodes[bucket], phi);
265*e4b17023SJohn Marino   free_phinode_count++;
266*e4b17023SJohn Marino }
267*e4b17023SJohn Marino 
268*e4b17023SJohn Marino 
269*e4b17023SJohn Marino /* Resize an existing PHI node.  The only way is up.  Return the
270*e4b17023SJohn Marino    possibly relocated phi.  */
271*e4b17023SJohn Marino 
272*e4b17023SJohn Marino static void
resize_phi_node(gimple * phi,size_t len)273*e4b17023SJohn Marino resize_phi_node (gimple *phi, size_t len)
274*e4b17023SJohn Marino {
275*e4b17023SJohn Marino   size_t old_size, i;
276*e4b17023SJohn Marino   gimple new_phi;
277*e4b17023SJohn Marino 
278*e4b17023SJohn Marino   gcc_assert (len > gimple_phi_capacity (*phi));
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino   /* The garbage collector will not look at the PHI node beyond the
281*e4b17023SJohn Marino      first PHI_NUM_ARGS elements.  Therefore, all we have to copy is a
282*e4b17023SJohn Marino      portion of the PHI node currently in use.  */
283*e4b17023SJohn Marino   old_size = sizeof (struct gimple_statement_phi)
284*e4b17023SJohn Marino 	     + (gimple_phi_num_args (*phi) - 1) * sizeof (struct phi_arg_d);
285*e4b17023SJohn Marino 
286*e4b17023SJohn Marino   new_phi = allocate_phi_node (len);
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino   memcpy (new_phi, *phi, old_size);
289*e4b17023SJohn Marino 
290*e4b17023SJohn Marino   for (i = 0; i < gimple_phi_num_args (new_phi); i++)
291*e4b17023SJohn Marino     {
292*e4b17023SJohn Marino       use_operand_p imm, old_imm;
293*e4b17023SJohn Marino       imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
294*e4b17023SJohn Marino       old_imm = gimple_phi_arg_imm_use_ptr (*phi, i);
295*e4b17023SJohn Marino       imm->use = gimple_phi_arg_def_ptr (new_phi, i);
296*e4b17023SJohn Marino       relink_imm_use_stmt (imm, old_imm, new_phi);
297*e4b17023SJohn Marino     }
298*e4b17023SJohn Marino 
299*e4b17023SJohn Marino   new_phi->gimple_phi.capacity = len;
300*e4b17023SJohn Marino 
301*e4b17023SJohn Marino   for (i = gimple_phi_num_args (new_phi); i < len; i++)
302*e4b17023SJohn Marino     {
303*e4b17023SJohn Marino       use_operand_p imm;
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino       gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
306*e4b17023SJohn Marino       imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
307*e4b17023SJohn Marino       imm->use = gimple_phi_arg_def_ptr (new_phi, i);
308*e4b17023SJohn Marino       imm->prev = NULL;
309*e4b17023SJohn Marino       imm->next = NULL;
310*e4b17023SJohn Marino       imm->loc.stmt = new_phi;
311*e4b17023SJohn Marino     }
312*e4b17023SJohn Marino 
313*e4b17023SJohn Marino   *phi = new_phi;
314*e4b17023SJohn Marino }
315*e4b17023SJohn Marino 
316*e4b17023SJohn Marino /* Reserve PHI arguments for a new edge to basic block BB.  */
317*e4b17023SJohn Marino 
318*e4b17023SJohn Marino void
reserve_phi_args_for_new_edge(basic_block bb)319*e4b17023SJohn Marino reserve_phi_args_for_new_edge (basic_block bb)
320*e4b17023SJohn Marino {
321*e4b17023SJohn Marino   size_t len = EDGE_COUNT (bb->preds);
322*e4b17023SJohn Marino   size_t cap = ideal_phi_node_len (len + 4);
323*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
324*e4b17023SJohn Marino 
325*e4b17023SJohn Marino   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
326*e4b17023SJohn Marino     {
327*e4b17023SJohn Marino       gimple *loc = gsi_stmt_ptr (&gsi);
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino       if (len > gimple_phi_capacity (*loc))
330*e4b17023SJohn Marino 	{
331*e4b17023SJohn Marino 	  gimple old_phi = *loc;
332*e4b17023SJohn Marino 
333*e4b17023SJohn Marino 	  resize_phi_node (loc, cap);
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino 	  /* The result of the PHI is defined by this PHI node.  */
336*e4b17023SJohn Marino 	  SSA_NAME_DEF_STMT (gimple_phi_result (*loc)) = *loc;
337*e4b17023SJohn Marino 
338*e4b17023SJohn Marino 	  release_phi_node (old_phi);
339*e4b17023SJohn Marino 	}
340*e4b17023SJohn Marino 
341*e4b17023SJohn Marino       /* We represent a "missing PHI argument" by placing NULL_TREE in
342*e4b17023SJohn Marino 	 the corresponding slot.  If PHI arguments were added
343*e4b17023SJohn Marino 	 immediately after an edge is created, this zeroing would not
344*e4b17023SJohn Marino 	 be necessary, but unfortunately this is not the case.  For
345*e4b17023SJohn Marino 	 example, the loop optimizer duplicates several basic blocks,
346*e4b17023SJohn Marino 	 redirects edges, and then fixes up PHI arguments later in
347*e4b17023SJohn Marino 	 batch.  */
348*e4b17023SJohn Marino       SET_PHI_ARG_DEF (*loc, len - 1, NULL_TREE);
349*e4b17023SJohn Marino 
350*e4b17023SJohn Marino       (*loc)->gimple_phi.nargs++;
351*e4b17023SJohn Marino     }
352*e4b17023SJohn Marino }
353*e4b17023SJohn Marino 
354*e4b17023SJohn Marino /* Adds PHI to BB.  */
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino void
add_phi_node_to_bb(gimple phi,basic_block bb)357*e4b17023SJohn Marino add_phi_node_to_bb (gimple phi, basic_block bb)
358*e4b17023SJohn Marino {
359*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
360*e4b17023SJohn Marino   /* Add the new PHI node to the list of PHI nodes for block BB.  */
361*e4b17023SJohn Marino   if (phi_nodes (bb) == NULL)
362*e4b17023SJohn Marino     set_phi_nodes (bb, gimple_seq_alloc ());
363*e4b17023SJohn Marino 
364*e4b17023SJohn Marino   gsi = gsi_last (phi_nodes (bb));
365*e4b17023SJohn Marino   gsi_insert_after (&gsi, phi, GSI_NEW_STMT);
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino   /* Associate BB to the PHI node.  */
368*e4b17023SJohn Marino   gimple_set_bb (phi, bb);
369*e4b17023SJohn Marino 
370*e4b17023SJohn Marino }
371*e4b17023SJohn Marino 
372*e4b17023SJohn Marino /* Create a new PHI node for variable VAR at basic block BB.  */
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino gimple
create_phi_node(tree var,basic_block bb)375*e4b17023SJohn Marino create_phi_node (tree var, basic_block bb)
376*e4b17023SJohn Marino {
377*e4b17023SJohn Marino   gimple phi = make_phi_node (var, EDGE_COUNT (bb->preds));
378*e4b17023SJohn Marino 
379*e4b17023SJohn Marino   add_phi_node_to_bb (phi, bb);
380*e4b17023SJohn Marino   return phi;
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino 
384*e4b17023SJohn Marino /* Add a new argument to PHI node PHI.  DEF is the incoming reaching
385*e4b17023SJohn Marino    definition and E is the edge through which DEF reaches PHI.  The new
386*e4b17023SJohn Marino    argument is added at the end of the argument list.
387*e4b17023SJohn Marino    If PHI has reached its maximum capacity, add a few slots.  In this case,
388*e4b17023SJohn Marino    PHI points to the reallocated phi node when we return.  */
389*e4b17023SJohn Marino 
390*e4b17023SJohn Marino void
add_phi_arg(gimple phi,tree def,edge e,source_location locus)391*e4b17023SJohn Marino add_phi_arg (gimple phi, tree def, edge e, source_location locus)
392*e4b17023SJohn Marino {
393*e4b17023SJohn Marino   basic_block bb = e->dest;
394*e4b17023SJohn Marino 
395*e4b17023SJohn Marino   gcc_assert (bb == gimple_bb (phi));
396*e4b17023SJohn Marino 
397*e4b17023SJohn Marino   /* We resize PHI nodes upon edge creation.  We should always have
398*e4b17023SJohn Marino      enough room at this point.  */
399*e4b17023SJohn Marino   gcc_assert (gimple_phi_num_args (phi) <= gimple_phi_capacity (phi));
400*e4b17023SJohn Marino 
401*e4b17023SJohn Marino   /* We resize PHI nodes upon edge creation.  We should always have
402*e4b17023SJohn Marino      enough room at this point.  */
403*e4b17023SJohn Marino   gcc_assert (e->dest_idx < gimple_phi_num_args (phi));
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino   /* Copy propagation needs to know what object occur in abnormal
406*e4b17023SJohn Marino      PHI nodes.  This is a convenient place to record such information.  */
407*e4b17023SJohn Marino   if (e->flags & EDGE_ABNORMAL)
408*e4b17023SJohn Marino     {
409*e4b17023SJohn Marino       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) = 1;
410*e4b17023SJohn Marino       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)) = 1;
411*e4b17023SJohn Marino     }
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino   SET_PHI_ARG_DEF (phi, e->dest_idx, def);
414*e4b17023SJohn Marino   gimple_phi_arg_set_location (phi, e->dest_idx, locus);
415*e4b17023SJohn Marino }
416*e4b17023SJohn Marino 
417*e4b17023SJohn Marino 
418*e4b17023SJohn Marino /* Remove the Ith argument from PHI's argument list.  This routine
419*e4b17023SJohn Marino    implements removal by swapping the last alternative with the
420*e4b17023SJohn Marino    alternative we want to delete and then shrinking the vector, which
421*e4b17023SJohn Marino    is consistent with how we remove an edge from the edge vector.  */
422*e4b17023SJohn Marino 
423*e4b17023SJohn Marino static void
remove_phi_arg_num(gimple phi,int i)424*e4b17023SJohn Marino remove_phi_arg_num (gimple phi, int i)
425*e4b17023SJohn Marino {
426*e4b17023SJohn Marino   int num_elem = gimple_phi_num_args (phi);
427*e4b17023SJohn Marino 
428*e4b17023SJohn Marino   gcc_assert (i < num_elem);
429*e4b17023SJohn Marino 
430*e4b17023SJohn Marino   /* Delink the item which is being removed.  */
431*e4b17023SJohn Marino   delink_imm_use (gimple_phi_arg_imm_use_ptr (phi, i));
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino   /* If it is not the last element, move the last element
434*e4b17023SJohn Marino      to the element we want to delete, resetting all the links. */
435*e4b17023SJohn Marino   if (i != num_elem - 1)
436*e4b17023SJohn Marino     {
437*e4b17023SJohn Marino       use_operand_p old_p, new_p;
438*e4b17023SJohn Marino       old_p = gimple_phi_arg_imm_use_ptr (phi, num_elem - 1);
439*e4b17023SJohn Marino       new_p = gimple_phi_arg_imm_use_ptr (phi, i);
440*e4b17023SJohn Marino       /* Set use on new node, and link into last element's place.  */
441*e4b17023SJohn Marino       *(new_p->use) = *(old_p->use);
442*e4b17023SJohn Marino       relink_imm_use (new_p, old_p);
443*e4b17023SJohn Marino       /* Move the location as well.  */
444*e4b17023SJohn Marino       gimple_phi_arg_set_location (phi, i,
445*e4b17023SJohn Marino 				   gimple_phi_arg_location (phi, num_elem - 1));
446*e4b17023SJohn Marino     }
447*e4b17023SJohn Marino 
448*e4b17023SJohn Marino   /* Shrink the vector and return.  Note that we do not have to clear
449*e4b17023SJohn Marino      PHI_ARG_DEF because the garbage collector will not look at those
450*e4b17023SJohn Marino      elements beyond the first PHI_NUM_ARGS elements of the array.  */
451*e4b17023SJohn Marino   phi->gimple_phi.nargs--;
452*e4b17023SJohn Marino }
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino 
455*e4b17023SJohn Marino /* Remove all PHI arguments associated with edge E.  */
456*e4b17023SJohn Marino 
457*e4b17023SJohn Marino void
remove_phi_args(edge e)458*e4b17023SJohn Marino remove_phi_args (edge e)
459*e4b17023SJohn Marino {
460*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
461*e4b17023SJohn Marino 
462*e4b17023SJohn Marino   for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
463*e4b17023SJohn Marino     remove_phi_arg_num (gsi_stmt (gsi), e->dest_idx);
464*e4b17023SJohn Marino }
465*e4b17023SJohn Marino 
466*e4b17023SJohn Marino 
467*e4b17023SJohn Marino /* Remove the PHI node pointed-to by iterator GSI from basic block BB.  After
468*e4b17023SJohn Marino    removal, iterator GSI is updated to point to the next PHI node in the
469*e4b17023SJohn Marino    sequence. If RELEASE_LHS_P is true, the LHS of this PHI node is released
470*e4b17023SJohn Marino    into the free pool of SSA names.  */
471*e4b17023SJohn Marino 
472*e4b17023SJohn Marino void
remove_phi_node(gimple_stmt_iterator * gsi,bool release_lhs_p)473*e4b17023SJohn Marino remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p)
474*e4b17023SJohn Marino {
475*e4b17023SJohn Marino   gimple phi = gsi_stmt (*gsi);
476*e4b17023SJohn Marino 
477*e4b17023SJohn Marino   if (release_lhs_p)
478*e4b17023SJohn Marino     insert_debug_temps_for_defs (gsi);
479*e4b17023SJohn Marino 
480*e4b17023SJohn Marino   gsi_remove (gsi, false);
481*e4b17023SJohn Marino 
482*e4b17023SJohn Marino   /* If we are deleting the PHI node, then we should release the
483*e4b17023SJohn Marino      SSA_NAME node so that it can be reused.  */
484*e4b17023SJohn Marino   release_phi_node (phi);
485*e4b17023SJohn Marino   if (release_lhs_p)
486*e4b17023SJohn Marino     release_ssa_name (gimple_phi_result (phi));
487*e4b17023SJohn Marino }
488*e4b17023SJohn Marino 
489*e4b17023SJohn Marino /* Remove all the phi nodes from BB.  */
490*e4b17023SJohn Marino 
491*e4b17023SJohn Marino void
remove_phi_nodes(basic_block bb)492*e4b17023SJohn Marino remove_phi_nodes (basic_block bb)
493*e4b17023SJohn Marino {
494*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
495*e4b17023SJohn Marino 
496*e4b17023SJohn Marino   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
497*e4b17023SJohn Marino     remove_phi_node (&gsi, true);
498*e4b17023SJohn Marino 
499*e4b17023SJohn Marino   set_phi_nodes (bb, NULL);
500*e4b17023SJohn Marino }
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino #include "gt-tree-phinodes.h"
503