xref: /dflybsd-src/contrib/gcc-4.7/gcc/ipa-split.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Function splitting pass
2*e4b17023SJohn Marino    Copyright (C) 2010, 2011, 2012
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Jan Hubicka  <jh@suse.cz>
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 under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino 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 /* The purpose of this pass is to split function bodies to improve
23*e4b17023SJohn Marino    inlining.  I.e. for function of the form:
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino    func (...)
26*e4b17023SJohn Marino      {
27*e4b17023SJohn Marino        if (cheap_test)
28*e4b17023SJohn Marino 	 something_small
29*e4b17023SJohn Marino        else
30*e4b17023SJohn Marino 	 something_big
31*e4b17023SJohn Marino      }
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino    Produce:
34*e4b17023SJohn Marino 
35*e4b17023SJohn Marino    func.part (...)
36*e4b17023SJohn Marino      {
37*e4b17023SJohn Marino 	something_big
38*e4b17023SJohn Marino      }
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino    func (...)
41*e4b17023SJohn Marino      {
42*e4b17023SJohn Marino        if (cheap_test)
43*e4b17023SJohn Marino 	 something_small
44*e4b17023SJohn Marino        else
45*e4b17023SJohn Marino 	 func.part (...);
46*e4b17023SJohn Marino      }
47*e4b17023SJohn Marino 
48*e4b17023SJohn Marino    When func becomes inlinable and when cheap_test is often true, inlining func,
49*e4b17023SJohn Marino    but not fund.part leads to performance improvement similar as inlining
50*e4b17023SJohn Marino    original func while the code size growth is smaller.
51*e4b17023SJohn Marino 
52*e4b17023SJohn Marino    The pass is organized in three stages:
53*e4b17023SJohn Marino    1) Collect local info about basic block into BB_INFO structure and
54*e4b17023SJohn Marino       compute function body estimated size and time.
55*e4b17023SJohn Marino    2) Via DFS walk find all possible basic blocks where we can split
56*e4b17023SJohn Marino       and chose best one.
57*e4b17023SJohn Marino    3) If split point is found, split at the specified BB by creating a clone
58*e4b17023SJohn Marino       and updating function to call it.
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino    The decisions what functions to split are in execute_split_functions
61*e4b17023SJohn Marino    and consider_split.
62*e4b17023SJohn Marino 
63*e4b17023SJohn Marino    There are several possible future improvements for this pass including:
64*e4b17023SJohn Marino 
65*e4b17023SJohn Marino    1) Splitting to break up large functions
66*e4b17023SJohn Marino    2) Splitting to reduce stack frame usage
67*e4b17023SJohn Marino    3) Allow split part of function to use values computed in the header part.
68*e4b17023SJohn Marino       The values needs to be passed to split function, perhaps via same
69*e4b17023SJohn Marino       interface as for nested functions or as argument.
70*e4b17023SJohn Marino    4) Support for simple rematerialization.  I.e. when split part use
71*e4b17023SJohn Marino       value computed in header from function parameter in very cheap way, we
72*e4b17023SJohn Marino       can just recompute it.
73*e4b17023SJohn Marino    5) Support splitting of nested functions.
74*e4b17023SJohn Marino    6) Support non-SSA arguments.
75*e4b17023SJohn Marino    7) There is nothing preventing us from producing multiple parts of single function
76*e4b17023SJohn Marino       when needed or splitting also the parts.  */
77*e4b17023SJohn Marino 
78*e4b17023SJohn Marino #include "config.h"
79*e4b17023SJohn Marino #include "system.h"
80*e4b17023SJohn Marino #include "coretypes.h"
81*e4b17023SJohn Marino #include "tree.h"
82*e4b17023SJohn Marino #include "target.h"
83*e4b17023SJohn Marino #include "cgraph.h"
84*e4b17023SJohn Marino #include "ipa-prop.h"
85*e4b17023SJohn Marino #include "tree-flow.h"
86*e4b17023SJohn Marino #include "tree-pass.h"
87*e4b17023SJohn Marino #include "flags.h"
88*e4b17023SJohn Marino #include "timevar.h"
89*e4b17023SJohn Marino #include "diagnostic.h"
90*e4b17023SJohn Marino #include "tree-dump.h"
91*e4b17023SJohn Marino #include "tree-inline.h"
92*e4b17023SJohn Marino #include "fibheap.h"
93*e4b17023SJohn Marino #include "params.h"
94*e4b17023SJohn Marino #include "gimple-pretty-print.h"
95*e4b17023SJohn Marino #include "ipa-inline.h"
96*e4b17023SJohn Marino 
97*e4b17023SJohn Marino /* Per basic block info.  */
98*e4b17023SJohn Marino 
99*e4b17023SJohn Marino typedef struct
100*e4b17023SJohn Marino {
101*e4b17023SJohn Marino   unsigned int size;
102*e4b17023SJohn Marino   unsigned int time;
103*e4b17023SJohn Marino } bb_info;
104*e4b17023SJohn Marino DEF_VEC_O(bb_info);
105*e4b17023SJohn Marino DEF_VEC_ALLOC_O(bb_info,heap);
106*e4b17023SJohn Marino 
VEC(bb_info,heap)107*e4b17023SJohn Marino static VEC(bb_info, heap) *bb_info_vec;
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino /* Description of split point.  */
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino struct split_point
112*e4b17023SJohn Marino {
113*e4b17023SJohn Marino   /* Size of the partitions.  */
114*e4b17023SJohn Marino   unsigned int header_time, header_size, split_time, split_size;
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino   /* SSA names that need to be passed into spit function.  */
117*e4b17023SJohn Marino   bitmap ssa_names_to_pass;
118*e4b17023SJohn Marino 
119*e4b17023SJohn Marino   /* Basic block where we split (that will become entry point of new function.  */
120*e4b17023SJohn Marino   basic_block entry_bb;
121*e4b17023SJohn Marino 
122*e4b17023SJohn Marino   /* Basic blocks we are splitting away.  */
123*e4b17023SJohn Marino   bitmap split_bbs;
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino   /* True when return value is computed on split part and thus it needs
126*e4b17023SJohn Marino      to be returned.  */
127*e4b17023SJohn Marino   bool split_part_set_retval;
128*e4b17023SJohn Marino };
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino /* Best split point found.  */
131*e4b17023SJohn Marino 
132*e4b17023SJohn Marino struct split_point best_split_point;
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino /* Set of basic blocks that are not allowed to dominate a split point.  */
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino static bitmap forbidden_dominators;
137*e4b17023SJohn Marino 
138*e4b17023SJohn Marino static tree find_retval (basic_block return_bb);
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino /* Callback for walk_stmt_load_store_addr_ops.  If T is non-SSA automatic
141*e4b17023SJohn Marino    variable, check it if it is present in bitmap passed via DATA.  */
142*e4b17023SJohn Marino 
143*e4b17023SJohn Marino static bool
test_nonssa_use(gimple stmt ATTRIBUTE_UNUSED,tree t,void * data)144*e4b17023SJohn Marino test_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
145*e4b17023SJohn Marino {
146*e4b17023SJohn Marino   t = get_base_address (t);
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino   if (!t || is_gimple_reg (t))
149*e4b17023SJohn Marino     return false;
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino   if (TREE_CODE (t) == PARM_DECL
152*e4b17023SJohn Marino       || (TREE_CODE (t) == VAR_DECL
153*e4b17023SJohn Marino 	  && auto_var_in_fn_p (t, current_function_decl))
154*e4b17023SJohn Marino       || TREE_CODE (t) == RESULT_DECL
155*e4b17023SJohn Marino       || TREE_CODE (t) == LABEL_DECL)
156*e4b17023SJohn Marino     return bitmap_bit_p ((bitmap)data, DECL_UID (t));
157*e4b17023SJohn Marino 
158*e4b17023SJohn Marino   /* For DECL_BY_REFERENCE, the return value is actually a pointer.  We want
159*e4b17023SJohn Marino      to pretend that the value pointed to is actual result decl.  */
160*e4b17023SJohn Marino   if ((TREE_CODE (t) == MEM_REF || INDIRECT_REF_P (t))
161*e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
162*e4b17023SJohn Marino       && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (t, 0))) == RESULT_DECL
163*e4b17023SJohn Marino       && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
164*e4b17023SJohn Marino     return
165*e4b17023SJohn Marino       bitmap_bit_p ((bitmap)data,
166*e4b17023SJohn Marino 		    DECL_UID (DECL_RESULT (current_function_decl)));
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino   return false;
169*e4b17023SJohn Marino }
170*e4b17023SJohn Marino 
171*e4b17023SJohn Marino /* Dump split point CURRENT.  */
172*e4b17023SJohn Marino 
173*e4b17023SJohn Marino static void
dump_split_point(FILE * file,struct split_point * current)174*e4b17023SJohn Marino dump_split_point (FILE * file, struct split_point *current)
175*e4b17023SJohn Marino {
176*e4b17023SJohn Marino   fprintf (file,
177*e4b17023SJohn Marino 	   "Split point at BB %i\n"
178*e4b17023SJohn Marino 	   "  header time: %i header size: %i\n"
179*e4b17023SJohn Marino 	   "  split time: %i split size: %i\n  bbs: ",
180*e4b17023SJohn Marino 	   current->entry_bb->index, current->header_time,
181*e4b17023SJohn Marino 	   current->header_size, current->split_time, current->split_size);
182*e4b17023SJohn Marino   dump_bitmap (file, current->split_bbs);
183*e4b17023SJohn Marino   fprintf (file, "  SSA names to pass: ");
184*e4b17023SJohn Marino   dump_bitmap (file, current->ssa_names_to_pass);
185*e4b17023SJohn Marino }
186*e4b17023SJohn Marino 
187*e4b17023SJohn Marino /* Look for all BBs in header that might lead to the split part and verify
188*e4b17023SJohn Marino    that they are not defining any non-SSA var used by the split part.
189*e4b17023SJohn Marino    Parameters are the same as for consider_split.  */
190*e4b17023SJohn Marino 
191*e4b17023SJohn Marino static bool
verify_non_ssa_vars(struct split_point * current,bitmap non_ssa_vars,basic_block return_bb)192*e4b17023SJohn Marino verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
193*e4b17023SJohn Marino 		     basic_block return_bb)
194*e4b17023SJohn Marino {
195*e4b17023SJohn Marino   bitmap seen = BITMAP_ALLOC (NULL);
196*e4b17023SJohn Marino   VEC (basic_block,heap) *worklist = NULL;
197*e4b17023SJohn Marino   edge e;
198*e4b17023SJohn Marino   edge_iterator ei;
199*e4b17023SJohn Marino   bool ok = true;
200*e4b17023SJohn Marino 
201*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
202*e4b17023SJohn Marino     if (e->src != ENTRY_BLOCK_PTR
203*e4b17023SJohn Marino 	&& !bitmap_bit_p (current->split_bbs, e->src->index))
204*e4b17023SJohn Marino       {
205*e4b17023SJohn Marino         VEC_safe_push (basic_block, heap, worklist, e->src);
206*e4b17023SJohn Marino 	bitmap_set_bit (seen, e->src->index);
207*e4b17023SJohn Marino       }
208*e4b17023SJohn Marino 
209*e4b17023SJohn Marino   while (!VEC_empty (basic_block, worklist))
210*e4b17023SJohn Marino     {
211*e4b17023SJohn Marino       gimple_stmt_iterator bsi;
212*e4b17023SJohn Marino       basic_block bb = VEC_pop (basic_block, worklist);
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->preds)
215*e4b17023SJohn Marino 	if (e->src != ENTRY_BLOCK_PTR
216*e4b17023SJohn Marino 	    && bitmap_set_bit (seen, e->src->index))
217*e4b17023SJohn Marino 	  {
218*e4b17023SJohn Marino 	    gcc_checking_assert (!bitmap_bit_p (current->split_bbs,
219*e4b17023SJohn Marino 					        e->src->index));
220*e4b17023SJohn Marino 	    VEC_safe_push (basic_block, heap, worklist, e->src);
221*e4b17023SJohn Marino 	  }
222*e4b17023SJohn Marino       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
223*e4b17023SJohn Marino 	{
224*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (bsi);
225*e4b17023SJohn Marino 	  if (is_gimple_debug (stmt))
226*e4b17023SJohn Marino 	    continue;
227*e4b17023SJohn Marino 	  if (walk_stmt_load_store_addr_ops
228*e4b17023SJohn Marino 	      (stmt, non_ssa_vars, test_nonssa_use, test_nonssa_use,
229*e4b17023SJohn Marino 	       test_nonssa_use))
230*e4b17023SJohn Marino 	    {
231*e4b17023SJohn Marino 	      ok = false;
232*e4b17023SJohn Marino 	      goto done;
233*e4b17023SJohn Marino 	    }
234*e4b17023SJohn Marino 	  if (gimple_code (stmt) == GIMPLE_LABEL
235*e4b17023SJohn Marino 	      && test_nonssa_use (stmt, gimple_label_label (stmt),
236*e4b17023SJohn Marino 				  non_ssa_vars))
237*e4b17023SJohn Marino 	  {
238*e4b17023SJohn Marino 	    ok = false;
239*e4b17023SJohn Marino 	    goto done;
240*e4b17023SJohn Marino 	  }
241*e4b17023SJohn Marino 	}
242*e4b17023SJohn Marino       for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
243*e4b17023SJohn Marino 	{
244*e4b17023SJohn Marino 	  if (walk_stmt_load_store_addr_ops
245*e4b17023SJohn Marino 	      (gsi_stmt (bsi), non_ssa_vars, test_nonssa_use, test_nonssa_use,
246*e4b17023SJohn Marino 	       test_nonssa_use))
247*e4b17023SJohn Marino 	    {
248*e4b17023SJohn Marino 	      ok = false;
249*e4b17023SJohn Marino 	      goto done;
250*e4b17023SJohn Marino 	    }
251*e4b17023SJohn Marino 	}
252*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->succs)
253*e4b17023SJohn Marino 	{
254*e4b17023SJohn Marino 	  if (e->dest != return_bb)
255*e4b17023SJohn Marino 	    continue;
256*e4b17023SJohn Marino 	  for (bsi = gsi_start_phis (return_bb); !gsi_end_p (bsi);
257*e4b17023SJohn Marino 	       gsi_next (&bsi))
258*e4b17023SJohn Marino 	    {
259*e4b17023SJohn Marino 	      gimple stmt = gsi_stmt (bsi);
260*e4b17023SJohn Marino 	      tree op = gimple_phi_arg_def (stmt, e->dest_idx);
261*e4b17023SJohn Marino 
262*e4b17023SJohn Marino 	      if (!is_gimple_reg (gimple_phi_result (stmt)))
263*e4b17023SJohn Marino 		continue;
264*e4b17023SJohn Marino 	      if (TREE_CODE (op) != SSA_NAME
265*e4b17023SJohn Marino 		  && test_nonssa_use (stmt, op, non_ssa_vars))
266*e4b17023SJohn Marino 		{
267*e4b17023SJohn Marino 		  ok = false;
268*e4b17023SJohn Marino 		  goto done;
269*e4b17023SJohn Marino 		}
270*e4b17023SJohn Marino 	    }
271*e4b17023SJohn Marino 	}
272*e4b17023SJohn Marino     }
273*e4b17023SJohn Marino done:
274*e4b17023SJohn Marino   BITMAP_FREE (seen);
275*e4b17023SJohn Marino   VEC_free (basic_block, heap, worklist);
276*e4b17023SJohn Marino   return ok;
277*e4b17023SJohn Marino }
278*e4b17023SJohn Marino 
279*e4b17023SJohn Marino /* If STMT is a call, check the callee against a list of forbidden
280*e4b17023SJohn Marino    predicate functions.  If a match is found, look for uses of the
281*e4b17023SJohn Marino    call result in condition statements that compare against zero.
282*e4b17023SJohn Marino    For each such use, find the block targeted by the condition
283*e4b17023SJohn Marino    statement for the nonzero result, and set the bit for this block
284*e4b17023SJohn Marino    in the forbidden dominators bitmap.  The purpose of this is to avoid
285*e4b17023SJohn Marino    selecting a split point where we are likely to lose the chance
286*e4b17023SJohn Marino    to optimize away an unused function call.  */
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino static void
check_forbidden_calls(gimple stmt)289*e4b17023SJohn Marino check_forbidden_calls (gimple stmt)
290*e4b17023SJohn Marino {
291*e4b17023SJohn Marino   imm_use_iterator use_iter;
292*e4b17023SJohn Marino   use_operand_p use_p;
293*e4b17023SJohn Marino   tree lhs;
294*e4b17023SJohn Marino 
295*e4b17023SJohn Marino   /* At the moment, __builtin_constant_p is the only forbidden
296*e4b17023SJohn Marino      predicate function call (see PR49642).  */
297*e4b17023SJohn Marino   if (!gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
298*e4b17023SJohn Marino     return;
299*e4b17023SJohn Marino 
300*e4b17023SJohn Marino   lhs = gimple_call_lhs (stmt);
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino   if (!lhs || TREE_CODE (lhs) != SSA_NAME)
303*e4b17023SJohn Marino     return;
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino   FOR_EACH_IMM_USE_FAST (use_p, use_iter, lhs)
306*e4b17023SJohn Marino     {
307*e4b17023SJohn Marino       tree op1;
308*e4b17023SJohn Marino       basic_block use_bb, forbidden_bb;
309*e4b17023SJohn Marino       enum tree_code code;
310*e4b17023SJohn Marino       edge true_edge, false_edge;
311*e4b17023SJohn Marino       gimple use_stmt = USE_STMT (use_p);
312*e4b17023SJohn Marino 
313*e4b17023SJohn Marino       if (gimple_code (use_stmt) != GIMPLE_COND)
314*e4b17023SJohn Marino 	continue;
315*e4b17023SJohn Marino 
316*e4b17023SJohn Marino       /* Assuming canonical form for GIMPLE_COND here, with constant
317*e4b17023SJohn Marino 	 in second position.  */
318*e4b17023SJohn Marino       op1 = gimple_cond_rhs (use_stmt);
319*e4b17023SJohn Marino       code = gimple_cond_code (use_stmt);
320*e4b17023SJohn Marino       use_bb = gimple_bb (use_stmt);
321*e4b17023SJohn Marino 
322*e4b17023SJohn Marino       extract_true_false_edges_from_block (use_bb, &true_edge, &false_edge);
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino       /* We're only interested in comparisons that distinguish
325*e4b17023SJohn Marino 	 unambiguously from zero.  */
326*e4b17023SJohn Marino       if (!integer_zerop (op1) || code == LE_EXPR || code == GE_EXPR)
327*e4b17023SJohn Marino 	continue;
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino       if (code == EQ_EXPR)
330*e4b17023SJohn Marino 	forbidden_bb = false_edge->dest;
331*e4b17023SJohn Marino       else
332*e4b17023SJohn Marino 	forbidden_bb = true_edge->dest;
333*e4b17023SJohn Marino 
334*e4b17023SJohn Marino       bitmap_set_bit (forbidden_dominators, forbidden_bb->index);
335*e4b17023SJohn Marino     }
336*e4b17023SJohn Marino }
337*e4b17023SJohn Marino 
338*e4b17023SJohn Marino /* If BB is dominated by any block in the forbidden dominators set,
339*e4b17023SJohn Marino    return TRUE; else FALSE.  */
340*e4b17023SJohn Marino 
341*e4b17023SJohn Marino static bool
dominated_by_forbidden(basic_block bb)342*e4b17023SJohn Marino dominated_by_forbidden (basic_block bb)
343*e4b17023SJohn Marino {
344*e4b17023SJohn Marino   unsigned dom_bb;
345*e4b17023SJohn Marino   bitmap_iterator bi;
346*e4b17023SJohn Marino 
347*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (forbidden_dominators, 1, dom_bb, bi)
348*e4b17023SJohn Marino     {
349*e4b17023SJohn Marino       if (dominated_by_p (CDI_DOMINATORS, bb, BASIC_BLOCK (dom_bb)))
350*e4b17023SJohn Marino 	return true;
351*e4b17023SJohn Marino     }
352*e4b17023SJohn Marino 
353*e4b17023SJohn Marino   return false;
354*e4b17023SJohn Marino }
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino /* We found an split_point CURRENT.  NON_SSA_VARS is bitmap of all non ssa
357*e4b17023SJohn Marino    variables used and RETURN_BB is return basic block.
358*e4b17023SJohn Marino    See if we can split function here.  */
359*e4b17023SJohn Marino 
360*e4b17023SJohn Marino static void
consider_split(struct split_point * current,bitmap non_ssa_vars,basic_block return_bb)361*e4b17023SJohn Marino consider_split (struct split_point *current, bitmap non_ssa_vars,
362*e4b17023SJohn Marino 		basic_block return_bb)
363*e4b17023SJohn Marino {
364*e4b17023SJohn Marino   tree parm;
365*e4b17023SJohn Marino   unsigned int num_args = 0;
366*e4b17023SJohn Marino   unsigned int call_overhead;
367*e4b17023SJohn Marino   edge e;
368*e4b17023SJohn Marino   edge_iterator ei;
369*e4b17023SJohn Marino   gimple_stmt_iterator bsi;
370*e4b17023SJohn Marino   unsigned int i;
371*e4b17023SJohn Marino   int incoming_freq = 0;
372*e4b17023SJohn Marino   tree retval;
373*e4b17023SJohn Marino 
374*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
375*e4b17023SJohn Marino     dump_split_point (dump_file, current);
376*e4b17023SJohn Marino 
377*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
378*e4b17023SJohn Marino     if (!bitmap_bit_p (current->split_bbs, e->src->index))
379*e4b17023SJohn Marino       incoming_freq += EDGE_FREQUENCY (e);
380*e4b17023SJohn Marino 
381*e4b17023SJohn Marino   /* Do not split when we would end up calling function anyway.  */
382*e4b17023SJohn Marino   if (incoming_freq
383*e4b17023SJohn Marino       >= (ENTRY_BLOCK_PTR->frequency
384*e4b17023SJohn Marino 	  * PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
385*e4b17023SJohn Marino     {
386*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
387*e4b17023SJohn Marino 	fprintf (dump_file,
388*e4b17023SJohn Marino 		 "  Refused: incoming frequency is too large.\n");
389*e4b17023SJohn Marino       return;
390*e4b17023SJohn Marino     }
391*e4b17023SJohn Marino 
392*e4b17023SJohn Marino   if (!current->header_size)
393*e4b17023SJohn Marino     {
394*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
395*e4b17023SJohn Marino 	fprintf (dump_file, "  Refused: header empty\n");
396*e4b17023SJohn Marino       return;
397*e4b17023SJohn Marino     }
398*e4b17023SJohn Marino 
399*e4b17023SJohn Marino   /* Verify that PHI args on entry are either virtual or all their operands
400*e4b17023SJohn Marino      incoming from header are the same.  */
401*e4b17023SJohn Marino   for (bsi = gsi_start_phis (current->entry_bb); !gsi_end_p (bsi); gsi_next (&bsi))
402*e4b17023SJohn Marino     {
403*e4b17023SJohn Marino       gimple stmt = gsi_stmt (bsi);
404*e4b17023SJohn Marino       tree val = NULL;
405*e4b17023SJohn Marino 
406*e4b17023SJohn Marino       if (!is_gimple_reg (gimple_phi_result (stmt)))
407*e4b17023SJohn Marino 	continue;
408*e4b17023SJohn Marino       for (i = 0; i < gimple_phi_num_args (stmt); i++)
409*e4b17023SJohn Marino 	{
410*e4b17023SJohn Marino 	  edge e = gimple_phi_arg_edge (stmt, i);
411*e4b17023SJohn Marino 	  if (!bitmap_bit_p (current->split_bbs, e->src->index))
412*e4b17023SJohn Marino 	    {
413*e4b17023SJohn Marino 	      tree edge_val = gimple_phi_arg_def (stmt, i);
414*e4b17023SJohn Marino 	      if (val && edge_val != val)
415*e4b17023SJohn Marino 	        {
416*e4b17023SJohn Marino 		  if (dump_file && (dump_flags & TDF_DETAILS))
417*e4b17023SJohn Marino 		    fprintf (dump_file,
418*e4b17023SJohn Marino 			     "  Refused: entry BB has PHI with multiple variants\n");
419*e4b17023SJohn Marino 		  return;
420*e4b17023SJohn Marino 	        }
421*e4b17023SJohn Marino 	      val = edge_val;
422*e4b17023SJohn Marino 	    }
423*e4b17023SJohn Marino 	}
424*e4b17023SJohn Marino     }
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino 
427*e4b17023SJohn Marino   /* See what argument we will pass to the split function and compute
428*e4b17023SJohn Marino      call overhead.  */
429*e4b17023SJohn Marino   call_overhead = eni_size_weights.call_cost;
430*e4b17023SJohn Marino   for (parm = DECL_ARGUMENTS (current_function_decl); parm;
431*e4b17023SJohn Marino        parm = DECL_CHAIN (parm))
432*e4b17023SJohn Marino     {
433*e4b17023SJohn Marino       if (!is_gimple_reg (parm))
434*e4b17023SJohn Marino 	{
435*e4b17023SJohn Marino 	  if (bitmap_bit_p (non_ssa_vars, DECL_UID (parm)))
436*e4b17023SJohn Marino 	    {
437*e4b17023SJohn Marino 	      if (dump_file && (dump_flags & TDF_DETAILS))
438*e4b17023SJohn Marino 		fprintf (dump_file,
439*e4b17023SJohn Marino 			 "  Refused: need to pass non-ssa param values\n");
440*e4b17023SJohn Marino 	      return;
441*e4b17023SJohn Marino 	    }
442*e4b17023SJohn Marino 	}
443*e4b17023SJohn Marino       else if (gimple_default_def (cfun, parm)
444*e4b17023SJohn Marino 	       && bitmap_bit_p (current->ssa_names_to_pass,
445*e4b17023SJohn Marino 				SSA_NAME_VERSION (gimple_default_def
446*e4b17023SJohn Marino 						  (cfun, parm))))
447*e4b17023SJohn Marino 	{
448*e4b17023SJohn Marino 	  if (!VOID_TYPE_P (TREE_TYPE (parm)))
449*e4b17023SJohn Marino 	    call_overhead += estimate_move_cost (TREE_TYPE (parm));
450*e4b17023SJohn Marino 	  num_args++;
451*e4b17023SJohn Marino 	}
452*e4b17023SJohn Marino     }
453*e4b17023SJohn Marino   if (!VOID_TYPE_P (TREE_TYPE (current_function_decl)))
454*e4b17023SJohn Marino     call_overhead += estimate_move_cost (TREE_TYPE (current_function_decl));
455*e4b17023SJohn Marino 
456*e4b17023SJohn Marino   if (current->split_size <= call_overhead)
457*e4b17023SJohn Marino     {
458*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
459*e4b17023SJohn Marino 	fprintf (dump_file,
460*e4b17023SJohn Marino 		 "  Refused: split size is smaller than call overhead\n");
461*e4b17023SJohn Marino       return;
462*e4b17023SJohn Marino     }
463*e4b17023SJohn Marino   if (current->header_size + call_overhead
464*e4b17023SJohn Marino       >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl)
465*e4b17023SJohn Marino 			? MAX_INLINE_INSNS_SINGLE
466*e4b17023SJohn Marino 			: MAX_INLINE_INSNS_AUTO))
467*e4b17023SJohn Marino     {
468*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
469*e4b17023SJohn Marino 	fprintf (dump_file,
470*e4b17023SJohn Marino 		 "  Refused: header size is too large for inline candidate\n");
471*e4b17023SJohn Marino       return;
472*e4b17023SJohn Marino     }
473*e4b17023SJohn Marino 
474*e4b17023SJohn Marino   /* FIXME: we currently can pass only SSA function parameters to the split
475*e4b17023SJohn Marino      arguments.  Once parm_adjustment infrastructure is supported by cloning,
476*e4b17023SJohn Marino      we can pass more than that.  */
477*e4b17023SJohn Marino   if (num_args != bitmap_count_bits (current->ssa_names_to_pass))
478*e4b17023SJohn Marino     {
479*e4b17023SJohn Marino 
480*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
481*e4b17023SJohn Marino 	fprintf (dump_file,
482*e4b17023SJohn Marino 		 "  Refused: need to pass non-param values\n");
483*e4b17023SJohn Marino       return;
484*e4b17023SJohn Marino     }
485*e4b17023SJohn Marino 
486*e4b17023SJohn Marino   /* When there are non-ssa vars used in the split region, see if they
487*e4b17023SJohn Marino      are used in the header region.  If so, reject the split.
488*e4b17023SJohn Marino      FIXME: we can use nested function support to access both.  */
489*e4b17023SJohn Marino   if (!bitmap_empty_p (non_ssa_vars)
490*e4b17023SJohn Marino       && !verify_non_ssa_vars (current, non_ssa_vars, return_bb))
491*e4b17023SJohn Marino     {
492*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
493*e4b17023SJohn Marino 	fprintf (dump_file,
494*e4b17023SJohn Marino 		 "  Refused: split part has non-ssa uses\n");
495*e4b17023SJohn Marino       return;
496*e4b17023SJohn Marino     }
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino   /* If the split point is dominated by a forbidden block, reject
499*e4b17023SJohn Marino      the split.  */
500*e4b17023SJohn Marino   if (!bitmap_empty_p (forbidden_dominators)
501*e4b17023SJohn Marino       && dominated_by_forbidden (current->entry_bb))
502*e4b17023SJohn Marino     {
503*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
504*e4b17023SJohn Marino 	fprintf (dump_file,
505*e4b17023SJohn Marino 		 "  Refused: split point dominated by forbidden block\n");
506*e4b17023SJohn Marino       return;
507*e4b17023SJohn Marino     }
508*e4b17023SJohn Marino 
509*e4b17023SJohn Marino   /* See if retval used by return bb is computed by header or split part.
510*e4b17023SJohn Marino      When it is computed by split part, we need to produce return statement
511*e4b17023SJohn Marino      in the split part and add code to header to pass it around.
512*e4b17023SJohn Marino 
513*e4b17023SJohn Marino      This is bit tricky to test:
514*e4b17023SJohn Marino        1) When there is no return_bb or no return value, we always pass
515*e4b17023SJohn Marino           value around.
516*e4b17023SJohn Marino        2) Invariants are always computed by caller.
517*e4b17023SJohn Marino        3) For SSA we need to look if defining statement is in header or split part
518*e4b17023SJohn Marino        4) For non-SSA we need to look where the var is computed. */
519*e4b17023SJohn Marino   retval = find_retval (return_bb);
520*e4b17023SJohn Marino   if (!retval)
521*e4b17023SJohn Marino     current->split_part_set_retval = true;
522*e4b17023SJohn Marino   else if (is_gimple_min_invariant (retval))
523*e4b17023SJohn Marino     current->split_part_set_retval = false;
524*e4b17023SJohn Marino   /* Special case is value returned by reference we record as if it was non-ssa
525*e4b17023SJohn Marino      set to result_decl.  */
526*e4b17023SJohn Marino   else if (TREE_CODE (retval) == SSA_NAME
527*e4b17023SJohn Marino 	   && TREE_CODE (SSA_NAME_VAR (retval)) == RESULT_DECL
528*e4b17023SJohn Marino 	   && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
529*e4b17023SJohn Marino     current->split_part_set_retval
530*e4b17023SJohn Marino        = bitmap_bit_p (non_ssa_vars, DECL_UID (SSA_NAME_VAR (retval)));
531*e4b17023SJohn Marino   else if (TREE_CODE (retval) == SSA_NAME)
532*e4b17023SJohn Marino     current->split_part_set_retval
533*e4b17023SJohn Marino       = (!SSA_NAME_IS_DEFAULT_DEF (retval)
534*e4b17023SJohn Marino 	 && (bitmap_bit_p (current->split_bbs,
535*e4b17023SJohn Marino 			  gimple_bb (SSA_NAME_DEF_STMT (retval))->index)
536*e4b17023SJohn Marino 	     || gimple_bb (SSA_NAME_DEF_STMT (retval)) == return_bb));
537*e4b17023SJohn Marino   else if (TREE_CODE (retval) == PARM_DECL)
538*e4b17023SJohn Marino     current->split_part_set_retval = false;
539*e4b17023SJohn Marino   else if (TREE_CODE (retval) == VAR_DECL
540*e4b17023SJohn Marino 	   || TREE_CODE (retval) == RESULT_DECL)
541*e4b17023SJohn Marino     current->split_part_set_retval
542*e4b17023SJohn Marino       = bitmap_bit_p (non_ssa_vars, DECL_UID (retval));
543*e4b17023SJohn Marino   else
544*e4b17023SJohn Marino     current->split_part_set_retval = true;
545*e4b17023SJohn Marino 
546*e4b17023SJohn Marino   /* split_function fixes up at most one PHI non-virtual PHI node in return_bb,
547*e4b17023SJohn Marino      for the return value.  If there are other PHIs, give up.  */
548*e4b17023SJohn Marino   if (return_bb != EXIT_BLOCK_PTR)
549*e4b17023SJohn Marino     {
550*e4b17023SJohn Marino       gimple_stmt_iterator psi;
551*e4b17023SJohn Marino 
552*e4b17023SJohn Marino       for (psi = gsi_start_phis (return_bb); !gsi_end_p (psi); gsi_next (&psi))
553*e4b17023SJohn Marino 	if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi)))
554*e4b17023SJohn Marino 	    && !(retval
555*e4b17023SJohn Marino 		 && current->split_part_set_retval
556*e4b17023SJohn Marino 		 && TREE_CODE (retval) == SSA_NAME
557*e4b17023SJohn Marino 		 && !DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))
558*e4b17023SJohn Marino 		 && SSA_NAME_DEF_STMT (retval) == gsi_stmt (psi)))
559*e4b17023SJohn Marino 	  {
560*e4b17023SJohn Marino 	    if (dump_file && (dump_flags & TDF_DETAILS))
561*e4b17023SJohn Marino 	      fprintf (dump_file,
562*e4b17023SJohn Marino 		       "  Refused: return bb has extra PHIs\n");
563*e4b17023SJohn Marino 	    return;
564*e4b17023SJohn Marino 	  }
565*e4b17023SJohn Marino     }
566*e4b17023SJohn Marino 
567*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
568*e4b17023SJohn Marino     fprintf (dump_file, "  Accepted!\n");
569*e4b17023SJohn Marino 
570*e4b17023SJohn Marino   /* At the moment chose split point with lowest frequency and that leaves
571*e4b17023SJohn Marino      out smallest size of header.
572*e4b17023SJohn Marino      In future we might re-consider this heuristics.  */
573*e4b17023SJohn Marino   if (!best_split_point.split_bbs
574*e4b17023SJohn Marino       || best_split_point.entry_bb->frequency > current->entry_bb->frequency
575*e4b17023SJohn Marino       || (best_split_point.entry_bb->frequency == current->entry_bb->frequency
576*e4b17023SJohn Marino 	  && best_split_point.split_size < current->split_size))
577*e4b17023SJohn Marino 
578*e4b17023SJohn Marino     {
579*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
580*e4b17023SJohn Marino 	fprintf (dump_file, "  New best split point!\n");
581*e4b17023SJohn Marino       if (best_split_point.ssa_names_to_pass)
582*e4b17023SJohn Marino 	{
583*e4b17023SJohn Marino 	  BITMAP_FREE (best_split_point.ssa_names_to_pass);
584*e4b17023SJohn Marino 	  BITMAP_FREE (best_split_point.split_bbs);
585*e4b17023SJohn Marino 	}
586*e4b17023SJohn Marino       best_split_point = *current;
587*e4b17023SJohn Marino       best_split_point.ssa_names_to_pass = BITMAP_ALLOC (NULL);
588*e4b17023SJohn Marino       bitmap_copy (best_split_point.ssa_names_to_pass,
589*e4b17023SJohn Marino 		   current->ssa_names_to_pass);
590*e4b17023SJohn Marino       best_split_point.split_bbs = BITMAP_ALLOC (NULL);
591*e4b17023SJohn Marino       bitmap_copy (best_split_point.split_bbs, current->split_bbs);
592*e4b17023SJohn Marino     }
593*e4b17023SJohn Marino }
594*e4b17023SJohn Marino 
595*e4b17023SJohn Marino /* Return basic block containing RETURN statement.  We allow basic blocks
596*e4b17023SJohn Marino    of the form:
597*e4b17023SJohn Marino    <retval> = tmp_var;
598*e4b17023SJohn Marino    return <retval>
599*e4b17023SJohn Marino    but return_bb can not be more complex than this.
600*e4b17023SJohn Marino    If nothing is found, return EXIT_BLOCK_PTR.
601*e4b17023SJohn Marino 
602*e4b17023SJohn Marino    When there are multiple RETURN statement, chose one with return value,
603*e4b17023SJohn Marino    since that one is more likely shared by multiple code paths.
604*e4b17023SJohn Marino 
605*e4b17023SJohn Marino    Return BB is special, because for function splitting it is the only
606*e4b17023SJohn Marino    basic block that is duplicated in between header and split part of the
607*e4b17023SJohn Marino    function.
608*e4b17023SJohn Marino 
609*e4b17023SJohn Marino    TODO: We might support multiple return blocks.  */
610*e4b17023SJohn Marino 
611*e4b17023SJohn Marino static basic_block
find_return_bb(void)612*e4b17023SJohn Marino find_return_bb (void)
613*e4b17023SJohn Marino {
614*e4b17023SJohn Marino   edge e;
615*e4b17023SJohn Marino   basic_block return_bb = EXIT_BLOCK_PTR;
616*e4b17023SJohn Marino   gimple_stmt_iterator bsi;
617*e4b17023SJohn Marino   bool found_return = false;
618*e4b17023SJohn Marino   tree retval = NULL_TREE;
619*e4b17023SJohn Marino 
620*e4b17023SJohn Marino   if (!single_pred_p (EXIT_BLOCK_PTR))
621*e4b17023SJohn Marino     return return_bb;
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino   e = single_pred_edge (EXIT_BLOCK_PTR);
624*e4b17023SJohn Marino   for (bsi = gsi_last_bb (e->src); !gsi_end_p (bsi); gsi_prev (&bsi))
625*e4b17023SJohn Marino     {
626*e4b17023SJohn Marino       gimple stmt = gsi_stmt (bsi);
627*e4b17023SJohn Marino       if (gimple_code (stmt) == GIMPLE_LABEL
628*e4b17023SJohn Marino 	  || is_gimple_debug (stmt)
629*e4b17023SJohn Marino 	  || gimple_clobber_p (stmt))
630*e4b17023SJohn Marino 	;
631*e4b17023SJohn Marino       else if (gimple_code (stmt) == GIMPLE_ASSIGN
632*e4b17023SJohn Marino 	       && found_return
633*e4b17023SJohn Marino 	       && gimple_assign_single_p (stmt)
634*e4b17023SJohn Marino 	       && (auto_var_in_fn_p (gimple_assign_rhs1 (stmt),
635*e4b17023SJohn Marino 				     current_function_decl)
636*e4b17023SJohn Marino 		   || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
637*e4b17023SJohn Marino 	       && retval == gimple_assign_lhs (stmt))
638*e4b17023SJohn Marino 	;
639*e4b17023SJohn Marino       else if (gimple_code (stmt) == GIMPLE_RETURN)
640*e4b17023SJohn Marino 	{
641*e4b17023SJohn Marino 	  found_return = true;
642*e4b17023SJohn Marino 	  retval = gimple_return_retval (stmt);
643*e4b17023SJohn Marino 	}
644*e4b17023SJohn Marino       else
645*e4b17023SJohn Marino 	break;
646*e4b17023SJohn Marino     }
647*e4b17023SJohn Marino   if (gsi_end_p (bsi) && found_return)
648*e4b17023SJohn Marino     return_bb = e->src;
649*e4b17023SJohn Marino 
650*e4b17023SJohn Marino   return return_bb;
651*e4b17023SJohn Marino }
652*e4b17023SJohn Marino 
653*e4b17023SJohn Marino /* Given return basic block RETURN_BB, see where return value is really
654*e4b17023SJohn Marino    stored.  */
655*e4b17023SJohn Marino static tree
find_retval(basic_block return_bb)656*e4b17023SJohn Marino find_retval (basic_block return_bb)
657*e4b17023SJohn Marino {
658*e4b17023SJohn Marino   gimple_stmt_iterator bsi;
659*e4b17023SJohn Marino   for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi); gsi_next (&bsi))
660*e4b17023SJohn Marino     if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN)
661*e4b17023SJohn Marino       return gimple_return_retval (gsi_stmt (bsi));
662*e4b17023SJohn Marino     else if (gimple_code (gsi_stmt (bsi)) == GIMPLE_ASSIGN
663*e4b17023SJohn Marino 	     && !gimple_clobber_p (gsi_stmt (bsi)))
664*e4b17023SJohn Marino       return gimple_assign_rhs1 (gsi_stmt (bsi));
665*e4b17023SJohn Marino   return NULL;
666*e4b17023SJohn Marino }
667*e4b17023SJohn Marino 
668*e4b17023SJohn Marino /* Callback for walk_stmt_load_store_addr_ops.  If T is non-SSA automatic
669*e4b17023SJohn Marino    variable, mark it as used in bitmap passed via DATA.
670*e4b17023SJohn Marino    Return true when access to T prevents splitting the function.  */
671*e4b17023SJohn Marino 
672*e4b17023SJohn Marino static bool
mark_nonssa_use(gimple stmt ATTRIBUTE_UNUSED,tree t,void * data)673*e4b17023SJohn Marino mark_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
674*e4b17023SJohn Marino {
675*e4b17023SJohn Marino   t = get_base_address (t);
676*e4b17023SJohn Marino 
677*e4b17023SJohn Marino   if (!t || is_gimple_reg (t))
678*e4b17023SJohn Marino     return false;
679*e4b17023SJohn Marino 
680*e4b17023SJohn Marino   /* At present we can't pass non-SSA arguments to split function.
681*e4b17023SJohn Marino      FIXME: this can be relaxed by passing references to arguments.  */
682*e4b17023SJohn Marino   if (TREE_CODE (t) == PARM_DECL)
683*e4b17023SJohn Marino     {
684*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
685*e4b17023SJohn Marino 	fprintf (dump_file,
686*e4b17023SJohn Marino 		 "Cannot split: use of non-ssa function parameter.\n");
687*e4b17023SJohn Marino       return true;
688*e4b17023SJohn Marino     }
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino   if ((TREE_CODE (t) == VAR_DECL
691*e4b17023SJohn Marino        && auto_var_in_fn_p (t, current_function_decl))
692*e4b17023SJohn Marino       || TREE_CODE (t) == RESULT_DECL
693*e4b17023SJohn Marino       || TREE_CODE (t) == LABEL_DECL)
694*e4b17023SJohn Marino     bitmap_set_bit ((bitmap)data, DECL_UID (t));
695*e4b17023SJohn Marino 
696*e4b17023SJohn Marino   /* For DECL_BY_REFERENCE, the return value is actually a pointer.  We want
697*e4b17023SJohn Marino      to pretend that the value pointed to is actual result decl.  */
698*e4b17023SJohn Marino   if ((TREE_CODE (t) == MEM_REF || INDIRECT_REF_P (t))
699*e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
700*e4b17023SJohn Marino       && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (t, 0))) == RESULT_DECL
701*e4b17023SJohn Marino       && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
702*e4b17023SJohn Marino     return
703*e4b17023SJohn Marino       bitmap_bit_p ((bitmap)data,
704*e4b17023SJohn Marino 		    DECL_UID (DECL_RESULT (current_function_decl)));
705*e4b17023SJohn Marino 
706*e4b17023SJohn Marino   return false;
707*e4b17023SJohn Marino }
708*e4b17023SJohn Marino 
709*e4b17023SJohn Marino /* Compute local properties of basic block BB we collect when looking for
710*e4b17023SJohn Marino    split points.  We look for ssa defs and store them in SET_SSA_NAMES,
711*e4b17023SJohn Marino    for ssa uses and store them in USED_SSA_NAMES and for any non-SSA automatic
712*e4b17023SJohn Marino    vars stored in NON_SSA_VARS.
713*e4b17023SJohn Marino 
714*e4b17023SJohn Marino    When BB has edge to RETURN_BB, collect uses in RETURN_BB too.
715*e4b17023SJohn Marino 
716*e4b17023SJohn Marino    Return false when BB contains something that prevents it from being put into
717*e4b17023SJohn Marino    split function.  */
718*e4b17023SJohn Marino 
719*e4b17023SJohn Marino static bool
visit_bb(basic_block bb,basic_block return_bb,bitmap set_ssa_names,bitmap used_ssa_names,bitmap non_ssa_vars)720*e4b17023SJohn Marino visit_bb (basic_block bb, basic_block return_bb,
721*e4b17023SJohn Marino 	  bitmap set_ssa_names, bitmap used_ssa_names,
722*e4b17023SJohn Marino 	  bitmap non_ssa_vars)
723*e4b17023SJohn Marino {
724*e4b17023SJohn Marino   gimple_stmt_iterator bsi;
725*e4b17023SJohn Marino   edge e;
726*e4b17023SJohn Marino   edge_iterator ei;
727*e4b17023SJohn Marino   bool can_split = true;
728*e4b17023SJohn Marino 
729*e4b17023SJohn Marino   for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
730*e4b17023SJohn Marino     {
731*e4b17023SJohn Marino       gimple stmt = gsi_stmt (bsi);
732*e4b17023SJohn Marino       tree op;
733*e4b17023SJohn Marino       ssa_op_iter iter;
734*e4b17023SJohn Marino       tree decl;
735*e4b17023SJohn Marino 
736*e4b17023SJohn Marino       if (is_gimple_debug (stmt))
737*e4b17023SJohn Marino 	continue;
738*e4b17023SJohn Marino 
739*e4b17023SJohn Marino       if (gimple_clobber_p (stmt))
740*e4b17023SJohn Marino 	continue;
741*e4b17023SJohn Marino 
742*e4b17023SJohn Marino       /* FIXME: We can split regions containing EH.  We can not however
743*e4b17023SJohn Marino 	 split RESX, EH_DISPATCH and EH_POINTER referring to same region
744*e4b17023SJohn Marino 	 into different partitions.  This would require tracking of
745*e4b17023SJohn Marino 	 EH regions and checking in consider_split_point if they
746*e4b17023SJohn Marino 	 are not used elsewhere.  */
747*e4b17023SJohn Marino       if (gimple_code (stmt) == GIMPLE_RESX)
748*e4b17023SJohn Marino 	{
749*e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
750*e4b17023SJohn Marino 	    fprintf (dump_file, "Cannot split: resx.\n");
751*e4b17023SJohn Marino 	  can_split = false;
752*e4b17023SJohn Marino 	}
753*e4b17023SJohn Marino       if (gimple_code (stmt) == GIMPLE_EH_DISPATCH)
754*e4b17023SJohn Marino 	{
755*e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
756*e4b17023SJohn Marino 	    fprintf (dump_file, "Cannot split: eh dispatch.\n");
757*e4b17023SJohn Marino 	  can_split = false;
758*e4b17023SJohn Marino 	}
759*e4b17023SJohn Marino 
760*e4b17023SJohn Marino       /* Check builtins that prevent splitting.  */
761*e4b17023SJohn Marino       if (gimple_code (stmt) == GIMPLE_CALL
762*e4b17023SJohn Marino 	  && (decl = gimple_call_fndecl (stmt)) != NULL_TREE
763*e4b17023SJohn Marino 	  && DECL_BUILT_IN (decl)
764*e4b17023SJohn Marino 	  && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
765*e4b17023SJohn Marino 	switch (DECL_FUNCTION_CODE (decl))
766*e4b17023SJohn Marino 	  {
767*e4b17023SJohn Marino 	  /* FIXME: once we will allow passing non-parm values to split part,
768*e4b17023SJohn Marino 	     we need to be sure to handle correct builtin_stack_save and
769*e4b17023SJohn Marino 	     builtin_stack_restore.  At the moment we are safe; there is no
770*e4b17023SJohn Marino 	     way to store builtin_stack_save result in non-SSA variable
771*e4b17023SJohn Marino 	     since all calls to those are compiler generated.  */
772*e4b17023SJohn Marino 	  case BUILT_IN_APPLY:
773*e4b17023SJohn Marino 	  case BUILT_IN_APPLY_ARGS:
774*e4b17023SJohn Marino 	  case BUILT_IN_VA_START:
775*e4b17023SJohn Marino 	    if (dump_file && (dump_flags & TDF_DETAILS))
776*e4b17023SJohn Marino 	      fprintf (dump_file,
777*e4b17023SJohn Marino 		       "Cannot split: builtin_apply and va_start.\n");
778*e4b17023SJohn Marino 	    can_split = false;
779*e4b17023SJohn Marino 	    break;
780*e4b17023SJohn Marino 	  case BUILT_IN_EH_POINTER:
781*e4b17023SJohn Marino 	    if (dump_file && (dump_flags & TDF_DETAILS))
782*e4b17023SJohn Marino 	      fprintf (dump_file, "Cannot split: builtin_eh_pointer.\n");
783*e4b17023SJohn Marino 	    can_split = false;
784*e4b17023SJohn Marino 	    break;
785*e4b17023SJohn Marino 	  default:
786*e4b17023SJohn Marino 	    break;
787*e4b17023SJohn Marino 	  }
788*e4b17023SJohn Marino 
789*e4b17023SJohn Marino       FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
790*e4b17023SJohn Marino 	bitmap_set_bit (set_ssa_names, SSA_NAME_VERSION (op));
791*e4b17023SJohn Marino       FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
792*e4b17023SJohn Marino 	bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op));
793*e4b17023SJohn Marino       can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars,
794*e4b17023SJohn Marino 						   mark_nonssa_use,
795*e4b17023SJohn Marino 						   mark_nonssa_use,
796*e4b17023SJohn Marino 						   mark_nonssa_use);
797*e4b17023SJohn Marino     }
798*e4b17023SJohn Marino   for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
799*e4b17023SJohn Marino     {
800*e4b17023SJohn Marino       gimple stmt = gsi_stmt (bsi);
801*e4b17023SJohn Marino       unsigned int i;
802*e4b17023SJohn Marino 
803*e4b17023SJohn Marino       if (is_gimple_debug (stmt))
804*e4b17023SJohn Marino 	continue;
805*e4b17023SJohn Marino       if (!is_gimple_reg (gimple_phi_result (stmt)))
806*e4b17023SJohn Marino 	continue;
807*e4b17023SJohn Marino       bitmap_set_bit (set_ssa_names,
808*e4b17023SJohn Marino 		      SSA_NAME_VERSION (gimple_phi_result (stmt)));
809*e4b17023SJohn Marino       for (i = 0; i < gimple_phi_num_args (stmt); i++)
810*e4b17023SJohn Marino 	{
811*e4b17023SJohn Marino 	  tree op = gimple_phi_arg_def (stmt, i);
812*e4b17023SJohn Marino 	  if (TREE_CODE (op) == SSA_NAME)
813*e4b17023SJohn Marino 	    bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op));
814*e4b17023SJohn Marino 	}
815*e4b17023SJohn Marino       can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars,
816*e4b17023SJohn Marino 						   mark_nonssa_use,
817*e4b17023SJohn Marino 						   mark_nonssa_use,
818*e4b17023SJohn Marino 						   mark_nonssa_use);
819*e4b17023SJohn Marino     }
820*e4b17023SJohn Marino   /* Record also uses coming from PHI operand in return BB.  */
821*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb->succs)
822*e4b17023SJohn Marino     if (e->dest == return_bb)
823*e4b17023SJohn Marino       {
824*e4b17023SJohn Marino 	for (bsi = gsi_start_phis (return_bb); !gsi_end_p (bsi); gsi_next (&bsi))
825*e4b17023SJohn Marino 	  {
826*e4b17023SJohn Marino 	    gimple stmt = gsi_stmt (bsi);
827*e4b17023SJohn Marino 	    tree op = gimple_phi_arg_def (stmt, e->dest_idx);
828*e4b17023SJohn Marino 
829*e4b17023SJohn Marino 	    if (is_gimple_debug (stmt))
830*e4b17023SJohn Marino 	      continue;
831*e4b17023SJohn Marino 	    if (!is_gimple_reg (gimple_phi_result (stmt)))
832*e4b17023SJohn Marino 	      continue;
833*e4b17023SJohn Marino 	    if (TREE_CODE (op) == SSA_NAME)
834*e4b17023SJohn Marino 	      bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op));
835*e4b17023SJohn Marino 	    else
836*e4b17023SJohn Marino 	      can_split &= !mark_nonssa_use (stmt, op, non_ssa_vars);
837*e4b17023SJohn Marino 	  }
838*e4b17023SJohn Marino       }
839*e4b17023SJohn Marino   return can_split;
840*e4b17023SJohn Marino }
841*e4b17023SJohn Marino 
842*e4b17023SJohn Marino /* Stack entry for recursive DFS walk in find_split_point.  */
843*e4b17023SJohn Marino 
844*e4b17023SJohn Marino typedef struct
845*e4b17023SJohn Marino {
846*e4b17023SJohn Marino   /* Basic block we are examining.  */
847*e4b17023SJohn Marino   basic_block bb;
848*e4b17023SJohn Marino 
849*e4b17023SJohn Marino   /* SSA names set and used by the BB and all BBs reachable
850*e4b17023SJohn Marino      from it via DFS walk.  */
851*e4b17023SJohn Marino   bitmap set_ssa_names, used_ssa_names;
852*e4b17023SJohn Marino   bitmap non_ssa_vars;
853*e4b17023SJohn Marino 
854*e4b17023SJohn Marino   /* All BBS visited from this BB via DFS walk.  */
855*e4b17023SJohn Marino   bitmap bbs_visited;
856*e4b17023SJohn Marino 
857*e4b17023SJohn Marino   /* Last examined edge in DFS walk.  Since we walk unoriented graph,
858*e4b17023SJohn Marino      the value is up to sum of incoming and outgoing edges of BB.  */
859*e4b17023SJohn Marino   unsigned int edge_num;
860*e4b17023SJohn Marino 
861*e4b17023SJohn Marino   /* Stack entry index of earliest BB reachable from current BB
862*e4b17023SJohn Marino      or any BB visited later in DFS walk.  */
863*e4b17023SJohn Marino   int earliest;
864*e4b17023SJohn Marino 
865*e4b17023SJohn Marino   /* Overall time and size of all BBs reached from this BB in DFS walk.  */
866*e4b17023SJohn Marino   int overall_time, overall_size;
867*e4b17023SJohn Marino 
868*e4b17023SJohn Marino   /* When false we can not split on this BB.  */
869*e4b17023SJohn Marino   bool can_split;
870*e4b17023SJohn Marino } stack_entry;
871*e4b17023SJohn Marino DEF_VEC_O(stack_entry);
872*e4b17023SJohn Marino DEF_VEC_ALLOC_O(stack_entry,heap);
873*e4b17023SJohn Marino 
874*e4b17023SJohn Marino 
875*e4b17023SJohn Marino /* Find all articulations and call consider_split on them.
876*e4b17023SJohn Marino    OVERALL_TIME and OVERALL_SIZE is time and size of the function.
877*e4b17023SJohn Marino 
878*e4b17023SJohn Marino    We perform basic algorithm for finding an articulation in a graph
879*e4b17023SJohn Marino    created from CFG by considering it to be an unoriented graph.
880*e4b17023SJohn Marino 
881*e4b17023SJohn Marino    The articulation is discovered via DFS walk. We collect earliest
882*e4b17023SJohn Marino    basic block on stack that is reachable via backward edge.  Articulation
883*e4b17023SJohn Marino    is any basic block such that there is no backward edge bypassing it.
884*e4b17023SJohn Marino    To reduce stack usage we maintain heap allocated stack in STACK vector.
885*e4b17023SJohn Marino    AUX pointer of BB is set to index it appears in the stack or -1 once
886*e4b17023SJohn Marino    it is visited and popped off the stack.
887*e4b17023SJohn Marino 
888*e4b17023SJohn Marino    The algorithm finds articulation after visiting the whole component
889*e4b17023SJohn Marino    reachable by it.  This makes it convenient to collect information about
890*e4b17023SJohn Marino    the component used by consider_split.  */
891*e4b17023SJohn Marino 
892*e4b17023SJohn Marino static void
find_split_points(int overall_time,int overall_size)893*e4b17023SJohn Marino find_split_points (int overall_time, int overall_size)
894*e4b17023SJohn Marino {
895*e4b17023SJohn Marino   stack_entry first;
896*e4b17023SJohn Marino   VEC(stack_entry, heap) *stack = NULL;
897*e4b17023SJohn Marino   basic_block bb;
898*e4b17023SJohn Marino   basic_block return_bb = find_return_bb ();
899*e4b17023SJohn Marino   struct split_point current;
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino   current.header_time = overall_time;
902*e4b17023SJohn Marino   current.header_size = overall_size;
903*e4b17023SJohn Marino   current.split_time = 0;
904*e4b17023SJohn Marino   current.split_size = 0;
905*e4b17023SJohn Marino   current.ssa_names_to_pass = BITMAP_ALLOC (NULL);
906*e4b17023SJohn Marino 
907*e4b17023SJohn Marino   first.bb = ENTRY_BLOCK_PTR;
908*e4b17023SJohn Marino   first.edge_num = 0;
909*e4b17023SJohn Marino   first.overall_time = 0;
910*e4b17023SJohn Marino   first.overall_size = 0;
911*e4b17023SJohn Marino   first.earliest = INT_MAX;
912*e4b17023SJohn Marino   first.set_ssa_names = 0;
913*e4b17023SJohn Marino   first.used_ssa_names = 0;
914*e4b17023SJohn Marino   first.bbs_visited = 0;
915*e4b17023SJohn Marino   VEC_safe_push (stack_entry, heap, stack, &first);
916*e4b17023SJohn Marino   ENTRY_BLOCK_PTR->aux = (void *)(intptr_t)-1;
917*e4b17023SJohn Marino 
918*e4b17023SJohn Marino   while (!VEC_empty (stack_entry, stack))
919*e4b17023SJohn Marino     {
920*e4b17023SJohn Marino       stack_entry *entry = VEC_last (stack_entry, stack);
921*e4b17023SJohn Marino 
922*e4b17023SJohn Marino       /* We are walking an acyclic graph, so edge_num counts
923*e4b17023SJohn Marino 	 succ and pred edges together.  However when considering
924*e4b17023SJohn Marino          articulation, we want to have processed everything reachable
925*e4b17023SJohn Marino 	 from articulation but nothing that reaches into it.  */
926*e4b17023SJohn Marino       if (entry->edge_num == EDGE_COUNT (entry->bb->succs)
927*e4b17023SJohn Marino 	  && entry->bb != ENTRY_BLOCK_PTR)
928*e4b17023SJohn Marino 	{
929*e4b17023SJohn Marino 	  int pos = VEC_length (stack_entry, stack);
930*e4b17023SJohn Marino 	  entry->can_split &= visit_bb (entry->bb, return_bb,
931*e4b17023SJohn Marino 					entry->set_ssa_names,
932*e4b17023SJohn Marino 					entry->used_ssa_names,
933*e4b17023SJohn Marino 					entry->non_ssa_vars);
934*e4b17023SJohn Marino 	  if (pos <= entry->earliest && !entry->can_split
935*e4b17023SJohn Marino 	      && dump_file && (dump_flags & TDF_DETAILS))
936*e4b17023SJohn Marino 	    fprintf (dump_file,
937*e4b17023SJohn Marino 		     "found articulation at bb %i but can not split\n",
938*e4b17023SJohn Marino 		     entry->bb->index);
939*e4b17023SJohn Marino 	  if (pos <= entry->earliest && entry->can_split)
940*e4b17023SJohn Marino 	     {
941*e4b17023SJohn Marino 	       if (dump_file && (dump_flags & TDF_DETAILS))
942*e4b17023SJohn Marino 		 fprintf (dump_file, "found articulation at bb %i\n",
943*e4b17023SJohn Marino 			  entry->bb->index);
944*e4b17023SJohn Marino 	       current.entry_bb = entry->bb;
945*e4b17023SJohn Marino 	       current.ssa_names_to_pass = BITMAP_ALLOC (NULL);
946*e4b17023SJohn Marino 	       bitmap_and_compl (current.ssa_names_to_pass,
947*e4b17023SJohn Marino 				 entry->used_ssa_names, entry->set_ssa_names);
948*e4b17023SJohn Marino 	       current.header_time = overall_time - entry->overall_time;
949*e4b17023SJohn Marino 	       current.header_size = overall_size - entry->overall_size;
950*e4b17023SJohn Marino 	       current.split_time = entry->overall_time;
951*e4b17023SJohn Marino 	       current.split_size = entry->overall_size;
952*e4b17023SJohn Marino 	       current.split_bbs = entry->bbs_visited;
953*e4b17023SJohn Marino 	       consider_split (&current, entry->non_ssa_vars, return_bb);
954*e4b17023SJohn Marino 	       BITMAP_FREE (current.ssa_names_to_pass);
955*e4b17023SJohn Marino 	     }
956*e4b17023SJohn Marino 	}
957*e4b17023SJohn Marino       /* Do actual DFS walk.  */
958*e4b17023SJohn Marino       if (entry->edge_num
959*e4b17023SJohn Marino 	  < (EDGE_COUNT (entry->bb->succs)
960*e4b17023SJohn Marino 	     + EDGE_COUNT (entry->bb->preds)))
961*e4b17023SJohn Marino 	{
962*e4b17023SJohn Marino           edge e;
963*e4b17023SJohn Marino 	  basic_block dest;
964*e4b17023SJohn Marino 	  if (entry->edge_num < EDGE_COUNT (entry->bb->succs))
965*e4b17023SJohn Marino 	    {
966*e4b17023SJohn Marino 	      e = EDGE_SUCC (entry->bb, entry->edge_num);
967*e4b17023SJohn Marino 	      dest = e->dest;
968*e4b17023SJohn Marino 	    }
969*e4b17023SJohn Marino 	  else
970*e4b17023SJohn Marino 	    {
971*e4b17023SJohn Marino 	      e = EDGE_PRED (entry->bb, entry->edge_num
972*e4b17023SJohn Marino 			     - EDGE_COUNT (entry->bb->succs));
973*e4b17023SJohn Marino 	      dest = e->src;
974*e4b17023SJohn Marino 	    }
975*e4b17023SJohn Marino 
976*e4b17023SJohn Marino 	  entry->edge_num++;
977*e4b17023SJohn Marino 
978*e4b17023SJohn Marino 	  /* New BB to visit, push it to the stack.  */
979*e4b17023SJohn Marino 	  if (dest != return_bb && dest != EXIT_BLOCK_PTR
980*e4b17023SJohn Marino 	      && !dest->aux)
981*e4b17023SJohn Marino 	    {
982*e4b17023SJohn Marino 	      stack_entry new_entry;
983*e4b17023SJohn Marino 
984*e4b17023SJohn Marino 	      new_entry.bb = dest;
985*e4b17023SJohn Marino 	      new_entry.edge_num = 0;
986*e4b17023SJohn Marino 	      new_entry.overall_time
987*e4b17023SJohn Marino 		 = VEC_index (bb_info, bb_info_vec, dest->index)->time;
988*e4b17023SJohn Marino 	      new_entry.overall_size
989*e4b17023SJohn Marino 		 = VEC_index (bb_info, bb_info_vec, dest->index)->size;
990*e4b17023SJohn Marino 	      new_entry.earliest = INT_MAX;
991*e4b17023SJohn Marino 	      new_entry.set_ssa_names = BITMAP_ALLOC (NULL);
992*e4b17023SJohn Marino 	      new_entry.used_ssa_names = BITMAP_ALLOC (NULL);
993*e4b17023SJohn Marino 	      new_entry.bbs_visited = BITMAP_ALLOC (NULL);
994*e4b17023SJohn Marino 	      new_entry.non_ssa_vars = BITMAP_ALLOC (NULL);
995*e4b17023SJohn Marino 	      new_entry.can_split = true;
996*e4b17023SJohn Marino 	      bitmap_set_bit (new_entry.bbs_visited, dest->index);
997*e4b17023SJohn Marino 	      VEC_safe_push (stack_entry, heap, stack, &new_entry);
998*e4b17023SJohn Marino 	      dest->aux = (void *)(intptr_t)VEC_length (stack_entry, stack);
999*e4b17023SJohn Marino 	    }
1000*e4b17023SJohn Marino 	  /* Back edge found, record the earliest point.  */
1001*e4b17023SJohn Marino 	  else if ((intptr_t)dest->aux > 0
1002*e4b17023SJohn Marino 		   && (intptr_t)dest->aux < entry->earliest)
1003*e4b17023SJohn Marino 	    entry->earliest = (intptr_t)dest->aux;
1004*e4b17023SJohn Marino 	}
1005*e4b17023SJohn Marino       /* We are done with examining the edges.  Pop off the value from stack
1006*e4b17023SJohn Marino 	 and merge stuff we accumulate during the walk.  */
1007*e4b17023SJohn Marino       else if (entry->bb != ENTRY_BLOCK_PTR)
1008*e4b17023SJohn Marino 	{
1009*e4b17023SJohn Marino 	  stack_entry *prev = VEC_index (stack_entry, stack,
1010*e4b17023SJohn Marino 					 VEC_length (stack_entry, stack) - 2);
1011*e4b17023SJohn Marino 
1012*e4b17023SJohn Marino 	  entry->bb->aux = (void *)(intptr_t)-1;
1013*e4b17023SJohn Marino 	  prev->can_split &= entry->can_split;
1014*e4b17023SJohn Marino 	  if (prev->set_ssa_names)
1015*e4b17023SJohn Marino 	    {
1016*e4b17023SJohn Marino 	      bitmap_ior_into (prev->set_ssa_names, entry->set_ssa_names);
1017*e4b17023SJohn Marino 	      bitmap_ior_into (prev->used_ssa_names, entry->used_ssa_names);
1018*e4b17023SJohn Marino 	      bitmap_ior_into (prev->bbs_visited, entry->bbs_visited);
1019*e4b17023SJohn Marino 	      bitmap_ior_into (prev->non_ssa_vars, entry->non_ssa_vars);
1020*e4b17023SJohn Marino 	    }
1021*e4b17023SJohn Marino 	  if (prev->earliest > entry->earliest)
1022*e4b17023SJohn Marino 	    prev->earliest = entry->earliest;
1023*e4b17023SJohn Marino 	  prev->overall_time += entry->overall_time;
1024*e4b17023SJohn Marino 	  prev->overall_size += entry->overall_size;
1025*e4b17023SJohn Marino 	  BITMAP_FREE (entry->set_ssa_names);
1026*e4b17023SJohn Marino 	  BITMAP_FREE (entry->used_ssa_names);
1027*e4b17023SJohn Marino 	  BITMAP_FREE (entry->bbs_visited);
1028*e4b17023SJohn Marino 	  BITMAP_FREE (entry->non_ssa_vars);
1029*e4b17023SJohn Marino 	  VEC_pop (stack_entry, stack);
1030*e4b17023SJohn Marino 	}
1031*e4b17023SJohn Marino       else
1032*e4b17023SJohn Marino         VEC_pop (stack_entry, stack);
1033*e4b17023SJohn Marino     }
1034*e4b17023SJohn Marino   ENTRY_BLOCK_PTR->aux = NULL;
1035*e4b17023SJohn Marino   FOR_EACH_BB (bb)
1036*e4b17023SJohn Marino     bb->aux = NULL;
1037*e4b17023SJohn Marino   VEC_free (stack_entry, heap, stack);
1038*e4b17023SJohn Marino   BITMAP_FREE (current.ssa_names_to_pass);
1039*e4b17023SJohn Marino }
1040*e4b17023SJohn Marino 
1041*e4b17023SJohn Marino /* Split function at SPLIT_POINT.  */
1042*e4b17023SJohn Marino 
1043*e4b17023SJohn Marino static void
split_function(struct split_point * split_point)1044*e4b17023SJohn Marino split_function (struct split_point *split_point)
1045*e4b17023SJohn Marino {
1046*e4b17023SJohn Marino   VEC (tree, heap) *args_to_pass = NULL;
1047*e4b17023SJohn Marino   bitmap args_to_skip;
1048*e4b17023SJohn Marino   tree parm;
1049*e4b17023SJohn Marino   int num = 0;
1050*e4b17023SJohn Marino   struct cgraph_node *node, *cur_node = cgraph_get_node (current_function_decl);
1051*e4b17023SJohn Marino   basic_block return_bb = find_return_bb ();
1052*e4b17023SJohn Marino   basic_block call_bb;
1053*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
1054*e4b17023SJohn Marino   gimple call;
1055*e4b17023SJohn Marino   edge e;
1056*e4b17023SJohn Marino   edge_iterator ei;
1057*e4b17023SJohn Marino   tree retval = NULL, real_retval = NULL;
1058*e4b17023SJohn Marino   bool split_part_return_p = false;
1059*e4b17023SJohn Marino   gimple last_stmt = NULL;
1060*e4b17023SJohn Marino   unsigned int i;
1061*e4b17023SJohn Marino   tree arg;
1062*e4b17023SJohn Marino 
1063*e4b17023SJohn Marino   if (dump_file)
1064*e4b17023SJohn Marino     {
1065*e4b17023SJohn Marino       fprintf (dump_file, "\n\nSplitting function at:\n");
1066*e4b17023SJohn Marino       dump_split_point (dump_file, split_point);
1067*e4b17023SJohn Marino     }
1068*e4b17023SJohn Marino 
1069*e4b17023SJohn Marino   if (cur_node->local.can_change_signature)
1070*e4b17023SJohn Marino     args_to_skip = BITMAP_ALLOC (NULL);
1071*e4b17023SJohn Marino   else
1072*e4b17023SJohn Marino     args_to_skip = NULL;
1073*e4b17023SJohn Marino 
1074*e4b17023SJohn Marino   /* Collect the parameters of new function and args_to_skip bitmap.  */
1075*e4b17023SJohn Marino   for (parm = DECL_ARGUMENTS (current_function_decl);
1076*e4b17023SJohn Marino        parm; parm = DECL_CHAIN (parm), num++)
1077*e4b17023SJohn Marino     if (args_to_skip
1078*e4b17023SJohn Marino 	&& (!is_gimple_reg (parm)
1079*e4b17023SJohn Marino 	    || !gimple_default_def (cfun, parm)
1080*e4b17023SJohn Marino 	    || !bitmap_bit_p (split_point->ssa_names_to_pass,
1081*e4b17023SJohn Marino 			      SSA_NAME_VERSION (gimple_default_def (cfun,
1082*e4b17023SJohn Marino 								    parm)))))
1083*e4b17023SJohn Marino       bitmap_set_bit (args_to_skip, num);
1084*e4b17023SJohn Marino     else
1085*e4b17023SJohn Marino       {
1086*e4b17023SJohn Marino 	/* This parm might not have been used up to now, but is going to be
1087*e4b17023SJohn Marino 	   used, hence register it.  */
1088*e4b17023SJohn Marino 	add_referenced_var (parm);
1089*e4b17023SJohn Marino 	if (is_gimple_reg (parm))
1090*e4b17023SJohn Marino 	  {
1091*e4b17023SJohn Marino 	    arg = gimple_default_def (cfun, parm);
1092*e4b17023SJohn Marino 	    if (!arg)
1093*e4b17023SJohn Marino 	      {
1094*e4b17023SJohn Marino 		arg = make_ssa_name (parm, gimple_build_nop ());
1095*e4b17023SJohn Marino 		set_default_def (parm, arg);
1096*e4b17023SJohn Marino 	      }
1097*e4b17023SJohn Marino 	  }
1098*e4b17023SJohn Marino 	else
1099*e4b17023SJohn Marino 	  arg = parm;
1100*e4b17023SJohn Marino 
1101*e4b17023SJohn Marino 	if (!useless_type_conversion_p (DECL_ARG_TYPE (parm), TREE_TYPE (arg)))
1102*e4b17023SJohn Marino 	  arg = fold_convert (DECL_ARG_TYPE (parm), arg);
1103*e4b17023SJohn Marino 	VEC_safe_push (tree, heap, args_to_pass, arg);
1104*e4b17023SJohn Marino       }
1105*e4b17023SJohn Marino 
1106*e4b17023SJohn Marino   /* See if the split function will return.  */
1107*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, return_bb->preds)
1108*e4b17023SJohn Marino     if (bitmap_bit_p (split_point->split_bbs, e->src->index))
1109*e4b17023SJohn Marino       break;
1110*e4b17023SJohn Marino   if (e)
1111*e4b17023SJohn Marino     split_part_return_p = true;
1112*e4b17023SJohn Marino 
1113*e4b17023SJohn Marino   /* Add return block to what will become the split function.
1114*e4b17023SJohn Marino      We do not return; no return block is needed.  */
1115*e4b17023SJohn Marino   if (!split_part_return_p)
1116*e4b17023SJohn Marino     ;
1117*e4b17023SJohn Marino   /* We have no return block, so nothing is needed.  */
1118*e4b17023SJohn Marino   else if (return_bb == EXIT_BLOCK_PTR)
1119*e4b17023SJohn Marino     ;
1120*e4b17023SJohn Marino   /* When we do not want to return value, we need to construct
1121*e4b17023SJohn Marino      new return block with empty return statement.
1122*e4b17023SJohn Marino      FIXME: Once we are able to change return type, we should change function
1123*e4b17023SJohn Marino      to return void instead of just outputting function with undefined return
1124*e4b17023SJohn Marino      value.  For structures this affects quality of codegen.  */
1125*e4b17023SJohn Marino   else if (!split_point->split_part_set_retval
1126*e4b17023SJohn Marino            && find_retval (return_bb))
1127*e4b17023SJohn Marino     {
1128*e4b17023SJohn Marino       bool redirected = true;
1129*e4b17023SJohn Marino       basic_block new_return_bb = create_basic_block (NULL, 0, return_bb);
1130*e4b17023SJohn Marino       gimple_stmt_iterator gsi = gsi_start_bb (new_return_bb);
1131*e4b17023SJohn Marino       gsi_insert_after (&gsi, gimple_build_return (NULL), GSI_NEW_STMT);
1132*e4b17023SJohn Marino       while (redirected)
1133*e4b17023SJohn Marino 	{
1134*e4b17023SJohn Marino 	  redirected = false;
1135*e4b17023SJohn Marino 	  FOR_EACH_EDGE (e, ei, return_bb->preds)
1136*e4b17023SJohn Marino 	    if (bitmap_bit_p (split_point->split_bbs, e->src->index))
1137*e4b17023SJohn Marino 	      {
1138*e4b17023SJohn Marino 		new_return_bb->count += e->count;
1139*e4b17023SJohn Marino 		new_return_bb->frequency += EDGE_FREQUENCY (e);
1140*e4b17023SJohn Marino 		redirect_edge_and_branch (e, new_return_bb);
1141*e4b17023SJohn Marino 		redirected = true;
1142*e4b17023SJohn Marino 		break;
1143*e4b17023SJohn Marino 	      }
1144*e4b17023SJohn Marino 	}
1145*e4b17023SJohn Marino       e = make_edge (new_return_bb, EXIT_BLOCK_PTR, 0);
1146*e4b17023SJohn Marino       e->probability = REG_BR_PROB_BASE;
1147*e4b17023SJohn Marino       e->count = new_return_bb->count;
1148*e4b17023SJohn Marino       bitmap_set_bit (split_point->split_bbs, new_return_bb->index);
1149*e4b17023SJohn Marino     }
1150*e4b17023SJohn Marino   /* When we pass around the value, use existing return block.  */
1151*e4b17023SJohn Marino   else
1152*e4b17023SJohn Marino     bitmap_set_bit (split_point->split_bbs, return_bb->index);
1153*e4b17023SJohn Marino 
1154*e4b17023SJohn Marino   /* If RETURN_BB has virtual operand PHIs, they must be removed and the
1155*e4b17023SJohn Marino      virtual operand marked for renaming as we change the CFG in a way that
1156*e4b17023SJohn Marino      tree-inline is not able to compensate for.
1157*e4b17023SJohn Marino 
1158*e4b17023SJohn Marino      Note this can happen whether or not we have a return value.  If we have
1159*e4b17023SJohn Marino      a return value, then RETURN_BB may have PHIs for real operands too.  */
1160*e4b17023SJohn Marino   if (return_bb != EXIT_BLOCK_PTR)
1161*e4b17023SJohn Marino     {
1162*e4b17023SJohn Marino       bool phi_p = false;
1163*e4b17023SJohn Marino       for (gsi = gsi_start_phis (return_bb); !gsi_end_p (gsi);)
1164*e4b17023SJohn Marino 	{
1165*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (gsi);
1166*e4b17023SJohn Marino 	  if (is_gimple_reg (gimple_phi_result (stmt)))
1167*e4b17023SJohn Marino 	    {
1168*e4b17023SJohn Marino 	      gsi_next (&gsi);
1169*e4b17023SJohn Marino 	      continue;
1170*e4b17023SJohn Marino 	    }
1171*e4b17023SJohn Marino 	  mark_virtual_phi_result_for_renaming (stmt);
1172*e4b17023SJohn Marino 	  remove_phi_node (&gsi, true);
1173*e4b17023SJohn Marino 	  phi_p = true;
1174*e4b17023SJohn Marino 	}
1175*e4b17023SJohn Marino       /* In reality we have to rename the reaching definition of the
1176*e4b17023SJohn Marino 	 virtual operand at return_bb as we will eventually release it
1177*e4b17023SJohn Marino 	 when we remove the code region we outlined.
1178*e4b17023SJohn Marino 	 So we have to rename all immediate virtual uses of that region
1179*e4b17023SJohn Marino 	 if we didn't see a PHI definition yet.  */
1180*e4b17023SJohn Marino       /* ???  In real reality we want to set the reaching vdef of the
1181*e4b17023SJohn Marino          entry of the SESE region as the vuse of the call and the reaching
1182*e4b17023SJohn Marino 	 vdef of the exit of the SESE region as the vdef of the call.  */
1183*e4b17023SJohn Marino       if (!phi_p)
1184*e4b17023SJohn Marino 	for (gsi = gsi_start_bb (return_bb); !gsi_end_p (gsi); gsi_next (&gsi))
1185*e4b17023SJohn Marino 	  {
1186*e4b17023SJohn Marino 	    gimple stmt = gsi_stmt (gsi);
1187*e4b17023SJohn Marino 	    if (gimple_vuse (stmt))
1188*e4b17023SJohn Marino 	      {
1189*e4b17023SJohn Marino 		gimple_set_vuse (stmt, NULL_TREE);
1190*e4b17023SJohn Marino 		update_stmt (stmt);
1191*e4b17023SJohn Marino 	      }
1192*e4b17023SJohn Marino 	    if (gimple_vdef (stmt))
1193*e4b17023SJohn Marino 	      break;
1194*e4b17023SJohn Marino 	  }
1195*e4b17023SJohn Marino     }
1196*e4b17023SJohn Marino 
1197*e4b17023SJohn Marino   /* Now create the actual clone.  */
1198*e4b17023SJohn Marino   rebuild_cgraph_edges ();
1199*e4b17023SJohn Marino   node = cgraph_function_versioning (cur_node, NULL, NULL, args_to_skip,
1200*e4b17023SJohn Marino 				     !split_part_return_p,
1201*e4b17023SJohn Marino 				     split_point->split_bbs,
1202*e4b17023SJohn Marino 				     split_point->entry_bb, "part");
1203*e4b17023SJohn Marino   /* For usual cloning it is enough to clear builtin only when signature
1204*e4b17023SJohn Marino      changes.  For partial inlining we however can not expect the part
1205*e4b17023SJohn Marino      of builtin implementation to have same semantic as the whole.  */
1206*e4b17023SJohn Marino   if (DECL_BUILT_IN (node->decl))
1207*e4b17023SJohn Marino     {
1208*e4b17023SJohn Marino       DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN;
1209*e4b17023SJohn Marino       DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
1210*e4b17023SJohn Marino     }
1211*e4b17023SJohn Marino   cgraph_node_remove_callees (cur_node);
1212*e4b17023SJohn Marino   if (!split_part_return_p)
1213*e4b17023SJohn Marino     TREE_THIS_VOLATILE (node->decl) = 1;
1214*e4b17023SJohn Marino   if (dump_file)
1215*e4b17023SJohn Marino     dump_function_to_file (node->decl, dump_file, dump_flags);
1216*e4b17023SJohn Marino 
1217*e4b17023SJohn Marino   /* Create the basic block we place call into.  It is the entry basic block
1218*e4b17023SJohn Marino      split after last label.  */
1219*e4b17023SJohn Marino   call_bb = split_point->entry_bb;
1220*e4b17023SJohn Marino   for (gsi = gsi_start_bb (call_bb); !gsi_end_p (gsi);)
1221*e4b17023SJohn Marino     if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
1222*e4b17023SJohn Marino       {
1223*e4b17023SJohn Marino 	last_stmt = gsi_stmt (gsi);
1224*e4b17023SJohn Marino 	gsi_next (&gsi);
1225*e4b17023SJohn Marino       }
1226*e4b17023SJohn Marino     else
1227*e4b17023SJohn Marino       break;
1228*e4b17023SJohn Marino   e = split_block (split_point->entry_bb, last_stmt);
1229*e4b17023SJohn Marino   remove_edge (e);
1230*e4b17023SJohn Marino 
1231*e4b17023SJohn Marino   /* Produce the call statement.  */
1232*e4b17023SJohn Marino   gsi = gsi_last_bb (call_bb);
1233*e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, args_to_pass, i, arg)
1234*e4b17023SJohn Marino     if (!is_gimple_val (arg))
1235*e4b17023SJohn Marino       {
1236*e4b17023SJohn Marino 	arg = force_gimple_operand_gsi (&gsi, arg, true, NULL_TREE,
1237*e4b17023SJohn Marino 					false, GSI_CONTINUE_LINKING);
1238*e4b17023SJohn Marino 	VEC_replace (tree, args_to_pass, i, arg);
1239*e4b17023SJohn Marino       }
1240*e4b17023SJohn Marino   call = gimple_build_call_vec (node->decl, args_to_pass);
1241*e4b17023SJohn Marino   gimple_set_block (call, DECL_INITIAL (current_function_decl));
1242*e4b17023SJohn Marino   VEC_free (tree, heap, args_to_pass);
1243*e4b17023SJohn Marino 
1244*e4b17023SJohn Marino   /* We avoid address being taken on any variable used by split part,
1245*e4b17023SJohn Marino      so return slot optimization is always possible.  Moreover this is
1246*e4b17023SJohn Marino      required to make DECL_BY_REFERENCE work.  */
1247*e4b17023SJohn Marino   if (aggregate_value_p (DECL_RESULT (current_function_decl),
1248*e4b17023SJohn Marino 			 TREE_TYPE (current_function_decl)))
1249*e4b17023SJohn Marino     gimple_call_set_return_slot_opt (call, true);
1250*e4b17023SJohn Marino 
1251*e4b17023SJohn Marino   /* Update return value.  This is bit tricky.  When we do not return,
1252*e4b17023SJohn Marino      do nothing.  When we return we might need to update return_bb
1253*e4b17023SJohn Marino      or produce a new return statement.  */
1254*e4b17023SJohn Marino   if (!split_part_return_p)
1255*e4b17023SJohn Marino     gsi_insert_after (&gsi, call, GSI_NEW_STMT);
1256*e4b17023SJohn Marino   else
1257*e4b17023SJohn Marino     {
1258*e4b17023SJohn Marino       e = make_edge (call_bb, return_bb,
1259*e4b17023SJohn Marino 		     return_bb == EXIT_BLOCK_PTR ? 0 : EDGE_FALLTHRU);
1260*e4b17023SJohn Marino       e->count = call_bb->count;
1261*e4b17023SJohn Marino       e->probability = REG_BR_PROB_BASE;
1262*e4b17023SJohn Marino 
1263*e4b17023SJohn Marino       /* If there is return basic block, see what value we need to store
1264*e4b17023SJohn Marino          return value into and put call just before it.  */
1265*e4b17023SJohn Marino       if (return_bb != EXIT_BLOCK_PTR)
1266*e4b17023SJohn Marino 	{
1267*e4b17023SJohn Marino 	  real_retval = retval = find_retval (return_bb);
1268*e4b17023SJohn Marino 
1269*e4b17023SJohn Marino 	  if (real_retval && split_point->split_part_set_retval)
1270*e4b17023SJohn Marino 	    {
1271*e4b17023SJohn Marino 	      gimple_stmt_iterator psi;
1272*e4b17023SJohn Marino 
1273*e4b17023SJohn Marino 	      /* See if we need new SSA_NAME for the result.
1274*e4b17023SJohn Marino 		 When DECL_BY_REFERENCE is true, retval is actually pointer to
1275*e4b17023SJohn Marino 		 return value and it is constant in whole function.  */
1276*e4b17023SJohn Marino 	      if (TREE_CODE (retval) == SSA_NAME
1277*e4b17023SJohn Marino 		  && !DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
1278*e4b17023SJohn Marino 		{
1279*e4b17023SJohn Marino 		  retval = make_ssa_name (SSA_NAME_VAR (retval), call);
1280*e4b17023SJohn Marino 
1281*e4b17023SJohn Marino 		  /* See if there is PHI defining return value.  */
1282*e4b17023SJohn Marino 		  for (psi = gsi_start_phis (return_bb);
1283*e4b17023SJohn Marino 		       !gsi_end_p (psi); gsi_next (&psi))
1284*e4b17023SJohn Marino 		    if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi))))
1285*e4b17023SJohn Marino 		      break;
1286*e4b17023SJohn Marino 
1287*e4b17023SJohn Marino 		  /* When there is PHI, just update its value.  */
1288*e4b17023SJohn Marino 		  if (TREE_CODE (retval) == SSA_NAME
1289*e4b17023SJohn Marino 		      && !gsi_end_p (psi))
1290*e4b17023SJohn Marino 		    add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION);
1291*e4b17023SJohn Marino 		  /* Otherwise update the return BB itself.
1292*e4b17023SJohn Marino 		     find_return_bb allows at most one assignment to return value,
1293*e4b17023SJohn Marino 		     so update first statement.  */
1294*e4b17023SJohn Marino 		  else
1295*e4b17023SJohn Marino 		    {
1296*e4b17023SJohn Marino 		      gimple_stmt_iterator bsi;
1297*e4b17023SJohn Marino 		      for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi);
1298*e4b17023SJohn Marino 			   gsi_next (&bsi))
1299*e4b17023SJohn Marino 			if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN)
1300*e4b17023SJohn Marino 			  {
1301*e4b17023SJohn Marino 			    gimple_return_set_retval (gsi_stmt (bsi), retval);
1302*e4b17023SJohn Marino 			    break;
1303*e4b17023SJohn Marino 			  }
1304*e4b17023SJohn Marino 			else if (gimple_code (gsi_stmt (bsi)) == GIMPLE_ASSIGN
1305*e4b17023SJohn Marino 				 && !gimple_clobber_p (gsi_stmt (bsi)))
1306*e4b17023SJohn Marino 			  {
1307*e4b17023SJohn Marino 			    gimple_assign_set_rhs1 (gsi_stmt (bsi), retval);
1308*e4b17023SJohn Marino 			    break;
1309*e4b17023SJohn Marino 			  }
1310*e4b17023SJohn Marino 		      update_stmt (gsi_stmt (bsi));
1311*e4b17023SJohn Marino 		    }
1312*e4b17023SJohn Marino 		}
1313*e4b17023SJohn Marino 	      if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
1314*e4b17023SJohn Marino 		{
1315*e4b17023SJohn Marino 		  gimple_call_set_lhs (call, build_simple_mem_ref (retval));
1316*e4b17023SJohn Marino 		  gsi_insert_after (&gsi, call, GSI_NEW_STMT);
1317*e4b17023SJohn Marino 		}
1318*e4b17023SJohn Marino 	      else
1319*e4b17023SJohn Marino 		{
1320*e4b17023SJohn Marino 		  tree restype;
1321*e4b17023SJohn Marino 		  restype = TREE_TYPE (DECL_RESULT (current_function_decl));
1322*e4b17023SJohn Marino 		  gsi_insert_after (&gsi, call, GSI_NEW_STMT);
1323*e4b17023SJohn Marino 		  if (!useless_type_conversion_p (TREE_TYPE (retval), restype))
1324*e4b17023SJohn Marino 		    {
1325*e4b17023SJohn Marino 		      gimple cpy;
1326*e4b17023SJohn Marino 		      tree tem = create_tmp_reg (restype, NULL);
1327*e4b17023SJohn Marino 		      tem = make_ssa_name (tem, call);
1328*e4b17023SJohn Marino 		      cpy = gimple_build_assign_with_ops (NOP_EXPR, retval,
1329*e4b17023SJohn Marino 							  tem, NULL_TREE);
1330*e4b17023SJohn Marino 		      gsi_insert_after (&gsi, cpy, GSI_NEW_STMT);
1331*e4b17023SJohn Marino 		      retval = tem;
1332*e4b17023SJohn Marino 		    }
1333*e4b17023SJohn Marino 		  gimple_call_set_lhs (call, retval);
1334*e4b17023SJohn Marino 		  update_stmt (call);
1335*e4b17023SJohn Marino 		}
1336*e4b17023SJohn Marino 	    }
1337*e4b17023SJohn Marino 	  else
1338*e4b17023SJohn Marino 	    gsi_insert_after (&gsi, call, GSI_NEW_STMT);
1339*e4b17023SJohn Marino 	}
1340*e4b17023SJohn Marino       /* We don't use return block (there is either no return in function or
1341*e4b17023SJohn Marino 	 multiple of them).  So create new basic block with return statement.
1342*e4b17023SJohn Marino 	 */
1343*e4b17023SJohn Marino       else
1344*e4b17023SJohn Marino 	{
1345*e4b17023SJohn Marino 	  gimple ret;
1346*e4b17023SJohn Marino 	  if (split_point->split_part_set_retval
1347*e4b17023SJohn Marino 	      && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1348*e4b17023SJohn Marino 	    {
1349*e4b17023SJohn Marino 	      retval = DECL_RESULT (current_function_decl);
1350*e4b17023SJohn Marino 
1351*e4b17023SJohn Marino 	      /* We use temporary register to hold value when aggregate_value_p
1352*e4b17023SJohn Marino 		 is false.  Similarly for DECL_BY_REFERENCE we must avoid extra
1353*e4b17023SJohn Marino 		 copy.  */
1354*e4b17023SJohn Marino 	      if (!aggregate_value_p (retval, TREE_TYPE (current_function_decl))
1355*e4b17023SJohn Marino 		  && !DECL_BY_REFERENCE (retval))
1356*e4b17023SJohn Marino 		retval = create_tmp_reg (TREE_TYPE (retval), NULL);
1357*e4b17023SJohn Marino 	      if (is_gimple_reg (retval))
1358*e4b17023SJohn Marino 		{
1359*e4b17023SJohn Marino 		  /* When returning by reference, there is only one SSA name
1360*e4b17023SJohn Marino 		     assigned to RESULT_DECL (that is pointer to return value).
1361*e4b17023SJohn Marino 		     Look it up or create new one if it is missing.  */
1362*e4b17023SJohn Marino 		  if (DECL_BY_REFERENCE (retval))
1363*e4b17023SJohn Marino 		    {
1364*e4b17023SJohn Marino 		      tree retval_name;
1365*e4b17023SJohn Marino 		      if ((retval_name = gimple_default_def (cfun, retval))
1366*e4b17023SJohn Marino 			  != NULL)
1367*e4b17023SJohn Marino 			retval = retval_name;
1368*e4b17023SJohn Marino 		      else
1369*e4b17023SJohn Marino 			{
1370*e4b17023SJohn Marino 		          retval_name = make_ssa_name (retval,
1371*e4b17023SJohn Marino 						       gimple_build_nop ());
1372*e4b17023SJohn Marino 			  set_default_def (retval, retval_name);
1373*e4b17023SJohn Marino 			  retval = retval_name;
1374*e4b17023SJohn Marino 			}
1375*e4b17023SJohn Marino 		    }
1376*e4b17023SJohn Marino 		  /* Otherwise produce new SSA name for return value.  */
1377*e4b17023SJohn Marino 		  else
1378*e4b17023SJohn Marino 		    retval = make_ssa_name (retval, call);
1379*e4b17023SJohn Marino 		}
1380*e4b17023SJohn Marino 	      if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
1381*e4b17023SJohn Marino 	        gimple_call_set_lhs (call, build_simple_mem_ref (retval));
1382*e4b17023SJohn Marino 	      else
1383*e4b17023SJohn Marino 	        gimple_call_set_lhs (call, retval);
1384*e4b17023SJohn Marino 	    }
1385*e4b17023SJohn Marino           gsi_insert_after (&gsi, call, GSI_NEW_STMT);
1386*e4b17023SJohn Marino 	  ret = gimple_build_return (retval);
1387*e4b17023SJohn Marino 	  gsi_insert_after (&gsi, ret, GSI_NEW_STMT);
1388*e4b17023SJohn Marino 	}
1389*e4b17023SJohn Marino     }
1390*e4b17023SJohn Marino   free_dominance_info (CDI_DOMINATORS);
1391*e4b17023SJohn Marino   free_dominance_info (CDI_POST_DOMINATORS);
1392*e4b17023SJohn Marino   compute_inline_parameters (node, true);
1393*e4b17023SJohn Marino }
1394*e4b17023SJohn Marino 
1395*e4b17023SJohn Marino /* Execute function splitting pass.  */
1396*e4b17023SJohn Marino 
1397*e4b17023SJohn Marino static unsigned int
execute_split_functions(void)1398*e4b17023SJohn Marino execute_split_functions (void)
1399*e4b17023SJohn Marino {
1400*e4b17023SJohn Marino   gimple_stmt_iterator bsi;
1401*e4b17023SJohn Marino   basic_block bb;
1402*e4b17023SJohn Marino   int overall_time = 0, overall_size = 0;
1403*e4b17023SJohn Marino   int todo = 0;
1404*e4b17023SJohn Marino   struct cgraph_node *node = cgraph_get_node (current_function_decl);
1405*e4b17023SJohn Marino 
1406*e4b17023SJohn Marino   if (flags_from_decl_or_type (current_function_decl)
1407*e4b17023SJohn Marino       & (ECF_NORETURN|ECF_MALLOC))
1408*e4b17023SJohn Marino     {
1409*e4b17023SJohn Marino       if (dump_file)
1410*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: noreturn/malloc function.\n");
1411*e4b17023SJohn Marino       return 0;
1412*e4b17023SJohn Marino     }
1413*e4b17023SJohn Marino   if (MAIN_NAME_P (DECL_NAME (current_function_decl)))
1414*e4b17023SJohn Marino     {
1415*e4b17023SJohn Marino       if (dump_file)
1416*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: main function.\n");
1417*e4b17023SJohn Marino       return 0;
1418*e4b17023SJohn Marino     }
1419*e4b17023SJohn Marino   /* This can be relaxed; function might become inlinable after splitting
1420*e4b17023SJohn Marino      away the uninlinable part.  */
1421*e4b17023SJohn Marino   if (!inline_summary (node)->inlinable)
1422*e4b17023SJohn Marino     {
1423*e4b17023SJohn Marino       if (dump_file)
1424*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: not inlinable.\n");
1425*e4b17023SJohn Marino       return 0;
1426*e4b17023SJohn Marino     }
1427*e4b17023SJohn Marino   if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
1428*e4b17023SJohn Marino     {
1429*e4b17023SJohn Marino       if (dump_file)
1430*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: disregarding inline limits.\n");
1431*e4b17023SJohn Marino       return 0;
1432*e4b17023SJohn Marino     }
1433*e4b17023SJohn Marino   /* This can be relaxed; most of versioning tests actually prevents
1434*e4b17023SJohn Marino      a duplication.  */
1435*e4b17023SJohn Marino   if (!tree_versionable_function_p (current_function_decl))
1436*e4b17023SJohn Marino     {
1437*e4b17023SJohn Marino       if (dump_file)
1438*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: not versionable.\n");
1439*e4b17023SJohn Marino       return 0;
1440*e4b17023SJohn Marino     }
1441*e4b17023SJohn Marino   /* FIXME: we could support this.  */
1442*e4b17023SJohn Marino   if (DECL_STRUCT_FUNCTION (current_function_decl)->static_chain_decl)
1443*e4b17023SJohn Marino     {
1444*e4b17023SJohn Marino       if (dump_file)
1445*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: nested function.\n");
1446*e4b17023SJohn Marino       return 0;
1447*e4b17023SJohn Marino     }
1448*e4b17023SJohn Marino 
1449*e4b17023SJohn Marino   /* See if it makes sense to try to split.
1450*e4b17023SJohn Marino      It makes sense to split if we inline, that is if we have direct calls to
1451*e4b17023SJohn Marino      handle or direct calls are possibly going to appear as result of indirect
1452*e4b17023SJohn Marino      inlining or LTO.  Also handle -fprofile-generate as LTO to allow non-LTO
1453*e4b17023SJohn Marino      training for LTO -fprofile-use build.
1454*e4b17023SJohn Marino 
1455*e4b17023SJohn Marino      Note that we are not completely conservative about disqualifying functions
1456*e4b17023SJohn Marino      called once.  It is possible that the caller is called more then once and
1457*e4b17023SJohn Marino      then inlining would still benefit.  */
1458*e4b17023SJohn Marino   if ((!node->callers || !node->callers->next_caller)
1459*e4b17023SJohn Marino       && !node->address_taken
1460*e4b17023SJohn Marino       && (!flag_lto || !node->local.externally_visible))
1461*e4b17023SJohn Marino     {
1462*e4b17023SJohn Marino       if (dump_file)
1463*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: not called directly "
1464*e4b17023SJohn Marino 		 "or called once.\n");
1465*e4b17023SJohn Marino       return 0;
1466*e4b17023SJohn Marino     }
1467*e4b17023SJohn Marino 
1468*e4b17023SJohn Marino   /* FIXME: We can actually split if splitting reduces call overhead.  */
1469*e4b17023SJohn Marino   if (!flag_inline_small_functions
1470*e4b17023SJohn Marino       && !DECL_DECLARED_INLINE_P (current_function_decl))
1471*e4b17023SJohn Marino     {
1472*e4b17023SJohn Marino       if (dump_file)
1473*e4b17023SJohn Marino 	fprintf (dump_file, "Not splitting: not autoinlining and function"
1474*e4b17023SJohn Marino 		 " is not inline.\n");
1475*e4b17023SJohn Marino       return 0;
1476*e4b17023SJohn Marino     }
1477*e4b17023SJohn Marino 
1478*e4b17023SJohn Marino   /* Initialize bitmap to track forbidden calls.  */
1479*e4b17023SJohn Marino   forbidden_dominators = BITMAP_ALLOC (NULL);
1480*e4b17023SJohn Marino   calculate_dominance_info (CDI_DOMINATORS);
1481*e4b17023SJohn Marino 
1482*e4b17023SJohn Marino   /* Compute local info about basic blocks and determine function size/time.  */
1483*e4b17023SJohn Marino   VEC_safe_grow_cleared (bb_info, heap, bb_info_vec, last_basic_block + 1);
1484*e4b17023SJohn Marino   memset (&best_split_point, 0, sizeof (best_split_point));
1485*e4b17023SJohn Marino   FOR_EACH_BB (bb)
1486*e4b17023SJohn Marino     {
1487*e4b17023SJohn Marino       int time = 0;
1488*e4b17023SJohn Marino       int size = 0;
1489*e4b17023SJohn Marino       int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
1490*e4b17023SJohn Marino 
1491*e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
1492*e4b17023SJohn Marino 	fprintf (dump_file, "Basic block %i\n", bb->index);
1493*e4b17023SJohn Marino 
1494*e4b17023SJohn Marino       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
1495*e4b17023SJohn Marino 	{
1496*e4b17023SJohn Marino 	  int this_time, this_size;
1497*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (bsi);
1498*e4b17023SJohn Marino 
1499*e4b17023SJohn Marino 	  this_size = estimate_num_insns (stmt, &eni_size_weights);
1500*e4b17023SJohn Marino 	  this_time = estimate_num_insns (stmt, &eni_time_weights) * freq;
1501*e4b17023SJohn Marino 	  size += this_size;
1502*e4b17023SJohn Marino 	  time += this_time;
1503*e4b17023SJohn Marino 	  check_forbidden_calls (stmt);
1504*e4b17023SJohn Marino 
1505*e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
1506*e4b17023SJohn Marino 	    {
1507*e4b17023SJohn Marino 	      fprintf (dump_file, "  freq:%6i size:%3i time:%3i ",
1508*e4b17023SJohn Marino 		       freq, this_size, this_time);
1509*e4b17023SJohn Marino 	      print_gimple_stmt (dump_file, stmt, 0, 0);
1510*e4b17023SJohn Marino 	    }
1511*e4b17023SJohn Marino 	}
1512*e4b17023SJohn Marino       overall_time += time;
1513*e4b17023SJohn Marino       overall_size += size;
1514*e4b17023SJohn Marino       VEC_index (bb_info, bb_info_vec, bb->index)->time = time;
1515*e4b17023SJohn Marino       VEC_index (bb_info, bb_info_vec, bb->index)->size = size;
1516*e4b17023SJohn Marino     }
1517*e4b17023SJohn Marino   find_split_points (overall_time, overall_size);
1518*e4b17023SJohn Marino   if (best_split_point.split_bbs)
1519*e4b17023SJohn Marino     {
1520*e4b17023SJohn Marino       split_function (&best_split_point);
1521*e4b17023SJohn Marino       BITMAP_FREE (best_split_point.ssa_names_to_pass);
1522*e4b17023SJohn Marino       BITMAP_FREE (best_split_point.split_bbs);
1523*e4b17023SJohn Marino       todo = TODO_update_ssa | TODO_cleanup_cfg;
1524*e4b17023SJohn Marino     }
1525*e4b17023SJohn Marino   BITMAP_FREE (forbidden_dominators);
1526*e4b17023SJohn Marino   VEC_free (bb_info, heap, bb_info_vec);
1527*e4b17023SJohn Marino   bb_info_vec = NULL;
1528*e4b17023SJohn Marino   return todo;
1529*e4b17023SJohn Marino }
1530*e4b17023SJohn Marino 
1531*e4b17023SJohn Marino /* Gate function splitting pass.  When doing profile feedback, we want
1532*e4b17023SJohn Marino    to execute the pass after profiling is read.  So disable one in
1533*e4b17023SJohn Marino    early optimization.  */
1534*e4b17023SJohn Marino 
1535*e4b17023SJohn Marino static bool
gate_split_functions(void)1536*e4b17023SJohn Marino gate_split_functions (void)
1537*e4b17023SJohn Marino {
1538*e4b17023SJohn Marino   return (flag_partial_inlining
1539*e4b17023SJohn Marino 	  && !profile_arc_flag && !flag_branch_probabilities);
1540*e4b17023SJohn Marino }
1541*e4b17023SJohn Marino 
1542*e4b17023SJohn Marino struct gimple_opt_pass pass_split_functions =
1543*e4b17023SJohn Marino {
1544*e4b17023SJohn Marino  {
1545*e4b17023SJohn Marino   GIMPLE_PASS,
1546*e4b17023SJohn Marino   "fnsplit",				/* name */
1547*e4b17023SJohn Marino   gate_split_functions,			/* gate */
1548*e4b17023SJohn Marino   execute_split_functions,		/* execute */
1549*e4b17023SJohn Marino   NULL,					/* sub */
1550*e4b17023SJohn Marino   NULL,					/* next */
1551*e4b17023SJohn Marino   0,					/* static_pass_number */
1552*e4b17023SJohn Marino   TV_IPA_FNSPLIT,			/* tv_id */
1553*e4b17023SJohn Marino   PROP_cfg,				/* properties_required */
1554*e4b17023SJohn Marino   0,					/* properties_provided */
1555*e4b17023SJohn Marino   0,					/* properties_destroyed */
1556*e4b17023SJohn Marino   0,					/* todo_flags_start */
1557*e4b17023SJohn Marino   TODO_verify_all      			/* todo_flags_finish */
1558*e4b17023SJohn Marino  }
1559*e4b17023SJohn Marino };
1560*e4b17023SJohn Marino 
1561*e4b17023SJohn Marino /* Gate feedback driven function splitting pass.
1562*e4b17023SJohn Marino    We don't need to split when profiling at all, we are producing
1563*e4b17023SJohn Marino    lousy code anyway.  */
1564*e4b17023SJohn Marino 
1565*e4b17023SJohn Marino static bool
gate_feedback_split_functions(void)1566*e4b17023SJohn Marino gate_feedback_split_functions (void)
1567*e4b17023SJohn Marino {
1568*e4b17023SJohn Marino   return (flag_partial_inlining
1569*e4b17023SJohn Marino 	  && flag_branch_probabilities);
1570*e4b17023SJohn Marino }
1571*e4b17023SJohn Marino 
1572*e4b17023SJohn Marino /* Execute function splitting pass.  */
1573*e4b17023SJohn Marino 
1574*e4b17023SJohn Marino static unsigned int
execute_feedback_split_functions(void)1575*e4b17023SJohn Marino execute_feedback_split_functions (void)
1576*e4b17023SJohn Marino {
1577*e4b17023SJohn Marino   unsigned int retval = execute_split_functions ();
1578*e4b17023SJohn Marino   if (retval)
1579*e4b17023SJohn Marino     retval |= TODO_rebuild_cgraph_edges;
1580*e4b17023SJohn Marino   return retval;
1581*e4b17023SJohn Marino }
1582*e4b17023SJohn Marino 
1583*e4b17023SJohn Marino struct gimple_opt_pass pass_feedback_split_functions =
1584*e4b17023SJohn Marino {
1585*e4b17023SJohn Marino  {
1586*e4b17023SJohn Marino   GIMPLE_PASS,
1587*e4b17023SJohn Marino   "feedback_fnsplit",			/* name */
1588*e4b17023SJohn Marino   gate_feedback_split_functions,	/* gate */
1589*e4b17023SJohn Marino   execute_feedback_split_functions,	/* execute */
1590*e4b17023SJohn Marino   NULL,					/* sub */
1591*e4b17023SJohn Marino   NULL,					/* next */
1592*e4b17023SJohn Marino   0,					/* static_pass_number */
1593*e4b17023SJohn Marino   TV_IPA_FNSPLIT,			/* tv_id */
1594*e4b17023SJohn Marino   PROP_cfg,				/* properties_required */
1595*e4b17023SJohn Marino   0,					/* properties_provided */
1596*e4b17023SJohn Marino   0,					/* properties_destroyed */
1597*e4b17023SJohn Marino   0,					/* todo_flags_start */
1598*e4b17023SJohn Marino   TODO_verify_all      			/* todo_flags_finish */
1599*e4b17023SJohn Marino  }
1600*e4b17023SJohn Marino };
1601