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 (¤t, 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