]> gcc.gnu.org Git - gcc.git/blob - gcc/tree-tailcall.c
tree-def (WITH_SIZE_EXPR): New.
[gcc.git] / gcc / tree-tailcall.c
1 /* Tail call optimization on trees.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30 #include "function.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
33 #include "diagnostic.h"
34 #include "except.h"
35 #include "tree-pass.h"
36 #include "flags.h"
37 #include "langhooks.h"
38
39 /* The file implements the tail recursion elimination. It is also used to
40 analyze the tail calls in general, passing the results to the rtl level
41 where they are used for sibcall optimization.
42
43 In addition to the standard tail recursion elimination, we handle the most
44 trivial cases of making the call tail recursive by creating accumulators.
45 For example the following function
46
47 int sum (int n)
48 {
49 if (n > 0)
50 return n + sum (n - 1);
51 else
52 return 0;
53 }
54
55 is transformed into
56
57 int sum (int n)
58 {
59 int acc = 0;
60
61 while (n > 0)
62 acc += n--;
63
64 return acc;
65 }
66
67 To do this, we maintain two accumulators (a_acc and m_acc) that indicate
68 when we reach the return x statement, we should return a_acc + x * m_acc
69 instead. They are initially initialized to 0 and 1, respectively,
70 so the semantics of the function is obviously preserved. If we are
71 guaranteed that the value of the accumulator never change, we
72 omit the accumulator.
73
74 There are three cases how the function may exit. The first one is
75 handled in adjust_return_value, the other two in adjust_accumulator_values
76 (the second case is actually a special case of the third one and we
77 present it separately just for clarity):
78
79 1) Just return x, where x is not in any of the remaining special shapes.
80 We rewrite this to a gimple equivalent of return m_acc * x + a_acc.
81
82 2) return f (...), where f is the current function, is rewritten in a
83 classical tail-recursion elimination way, into assignment of arguments
84 and jump to the start of the function. Values of the accumulators
85 are unchanged.
86
87 3) return a + m * f(...), where a and m do not depend on call to f.
88 To preserve the semantics described before we want this to be rewritten
89 in such a way that we finally return
90
91 a_acc + (a + m * f(...)) * m_acc = (a_acc + a * m_acc) + (m * m_acc) * f(...).
92
93 I.e. we increase a_acc by a * m_acc, multiply m_acc by m and
94 eliminate the tail call to f. Special cases when the value is just
95 added or just multiplied are obtained by setting a = 0 or m = 1.
96
97 TODO -- it is possible to do similar tricks for other operations. */
98
99 /* A structure that describes the tailcall. */
100
101 struct tailcall
102 {
103 /* The block in that the call occur. */
104 basic_block call_block;
105
106 /* The iterator pointing to the call statement. */
107 block_stmt_iterator call_bsi;
108
109 /* True if it is a call to the current function. */
110 bool tail_recursion;
111
112 /* The return value of the caller is mult * f + add, where f is the return
113 value of the call. */
114 tree mult, add;
115
116 /* Next tailcall in the chain. */
117 struct tailcall *next;
118 };
119
120 /* The variables holding the value of multiplicative and additive
121 accumulator. */
122 static tree m_acc, a_acc;
123
124 static bool suitable_for_tail_opt_p (void);
125 static bool optimize_tail_call (struct tailcall *, bool);
126 static void eliminate_tail_call (struct tailcall *);
127 static void find_tail_calls (basic_block, struct tailcall **);
128
129 /* Returns false when the function is not suitable for tail call optimization
130 from some reason (e.g. if it takes variable number of arguments). */
131
132 static bool
133 suitable_for_tail_opt_p (void)
134 {
135 int i;
136
137 if (current_function_stdarg)
138 return false;
139
140 /* No local variable should be call-clobbered. We ignore any kind
141 of memory tag, as these are not real variables. */
142 for (i = 0; i < (int) VARRAY_ACTIVE_SIZE (referenced_vars); i++)
143 {
144 tree var = VARRAY_TREE (referenced_vars, i);
145
146 if (decl_function_context (var) == current_function_decl
147 && !TREE_STATIC (var)
148 && var_ann (var)->mem_tag_kind == NOT_A_TAG
149 && is_call_clobbered (var))
150 return false;
151 }
152
153 return true;
154 }
155 /* Returns false when the function is not suitable for tail call optimization
156 from some reason (e.g. if it takes variable number of arguments).
157 This test must pass in addition to suitable_for_tail_opt_p in order to make
158 tail call discovery happen. */
159
160 static bool
161 suitable_for_tail_call_opt_p (void)
162 {
163 /* alloca (until we have stack slot life analysis) inhibits
164 sibling call optimizations, but not tail recursion. */
165 if (current_function_calls_alloca)
166 return false;
167
168 /* If we are using sjlj exceptions, we may need to add a call to
169 _Unwind_SjLj_Unregister at exit of the function. Which means
170 that we cannot do any sibcall transformations. */
171 if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers ())
172 return false;
173
174 /* Any function that calls setjmp might have longjmp called from
175 any called function. ??? We really should represent this
176 properly in the CFG so that this needn't be special cased. */
177 if (current_function_calls_setjmp)
178 return false;
179
180 return true;
181 }
182
183 /* Checks whether the expression EXPR in stmt AT is independent of the
184 statement pointed by BSI (in a sense that we already know EXPR's value
185 at BSI). We use the fact that we are only called from the chain of
186 basic blocks that have only single successor. Returns the expression
187 containing the value of EXPR at BSI. */
188
189 static tree
190 independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
191 {
192 basic_block bb, call_bb, at_bb;
193 edge e;
194
195 if (is_gimple_min_invariant (expr))
196 return expr;
197
198 if (TREE_CODE (expr) != SSA_NAME)
199 return NULL_TREE;
200
201 /* Mark the blocks in the chain leading to the end. */
202 at_bb = bb_for_stmt (at);
203 call_bb = bb_for_stmt (bsi_stmt (bsi));
204 for (bb = call_bb; bb != at_bb; bb = bb->succ->dest)
205 bb->aux = &bb->aux;
206 bb->aux = &bb->aux;
207
208 while (1)
209 {
210 at = SSA_NAME_DEF_STMT (expr);
211 bb = bb_for_stmt (at);
212
213 /* The default definition or defined before the chain. */
214 if (!bb || !bb->aux)
215 break;
216
217 if (bb == call_bb)
218 {
219 for (; !bsi_end_p (bsi); bsi_next (&bsi))
220 if (bsi_stmt (bsi) == at)
221 break;
222
223 if (!bsi_end_p (bsi))
224 expr = NULL_TREE;
225 break;
226 }
227
228 if (TREE_CODE (at) != PHI_NODE)
229 {
230 expr = NULL_TREE;
231 break;
232 }
233
234 for (e = bb->pred; e; e = e->pred_next)
235 if (e->src->aux)
236 break;
237 if (!e)
238 abort ();
239
240 expr = PHI_ARG_DEF_FROM_EDGE (at, e);
241 if (TREE_CODE (expr) != SSA_NAME)
242 {
243 /* The value is a constant. */
244 break;
245 }
246 }
247
248 /* Unmark the blocks. */
249 for (bb = call_bb; bb != at_bb; bb = bb->succ->dest)
250 bb->aux = NULL;
251 bb->aux = NULL;
252
253 return expr;
254 }
255
256 /* Simulates the effect of an assignment of ASS in STMT on the return value
257 of the tail recursive CALL passed in ASS_VAR. M and A are the
258 multiplicative and the additive factor for the real return value. */
259
260 static bool
261 process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
262 tree *a, tree *ass_var)
263 {
264 tree op0, op1, non_ass_var;
265 tree dest = TREE_OPERAND (ass, 0);
266 tree src = TREE_OPERAND (ass, 1);
267 enum tree_code code = TREE_CODE (src);
268 tree src_var = src;
269
270 /* See if this is a simple copy operation of an SSA name to the function
271 result. In that case we may have a simple tail call. Ignore type
272 conversions that can never produce extra code between the function
273 call and the function return. */
274 STRIP_NOPS (src_var);
275 if (TREE_CODE (src_var) == SSA_NAME)
276 {
277 if (src_var != *ass_var)
278 return false;
279
280 *ass_var = dest;
281 return true;
282 }
283
284 if (TREE_CODE_CLASS (code) != '2')
285 return false;
286
287 /* We only handle the code like
288
289 x = call ();
290 y = m * x;
291 z = y + a;
292 return z;
293
294 TODO -- Extend it for cases where the linear transformation of the output
295 is expressed in a more complicated way. */
296
297 op0 = TREE_OPERAND (src, 0);
298 op1 = TREE_OPERAND (src, 1);
299
300 if (op0 == *ass_var
301 && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
302 ;
303 else if (op1 == *ass_var
304 && (non_ass_var = independent_of_stmt_p (op0, stmt, call)))
305 ;
306 else
307 return false;
308
309 switch (code)
310 {
311 case PLUS_EXPR:
312 /* There should be no previous addition. TODO -- it should be fairly
313 straightforward to lift this restriction -- just allow storing
314 more complicated expressions in *A, and gimplify it in
315 adjust_accumulator_values. */
316 if (*a)
317 return false;
318 *a = non_ass_var;
319 *ass_var = dest;
320 return true;
321
322 case MULT_EXPR:
323 /* Similar remark applies here. Handling multiplication after addition
324 is just slightly more complicated -- we need to multiply both *A and
325 *M. */
326 if (*a || *m)
327 return false;
328 *m = non_ass_var;
329 *ass_var = dest;
330 return true;
331
332 /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR). */
333
334 default:
335 return false;
336 }
337 }
338
339 /* Propagate VAR through phis on edge E. */
340
341 static tree
342 propagate_through_phis (tree var, edge e)
343 {
344 basic_block dest = e->dest;
345 tree phi;
346
347 for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
348 if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var)
349 return PHI_RESULT (phi);
350
351 return var;
352 }
353
354 /* Finds tailcalls falling into basic block BB. The list of found tailcalls is
355 added to the start of RET. */
356
357 static void
358 find_tail_calls (basic_block bb, struct tailcall **ret)
359 {
360 tree ass_var, ret_var, stmt, func, param, args, call = NULL_TREE;
361 block_stmt_iterator bsi, absi;
362 bool tail_recursion;
363 struct tailcall *nw;
364 edge e;
365 tree m, a;
366 basic_block abb;
367 stmt_ann_t ann;
368
369 if (bb->succ->succ_next)
370 return;
371
372 for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
373 {
374 stmt = bsi_stmt (bsi);
375
376 /* Ignore labels. */
377 if (TREE_CODE (stmt) == LABEL_EXPR)
378 continue;
379
380 get_stmt_operands (stmt);
381
382 /* Check for a call. */
383 if (TREE_CODE (stmt) == MODIFY_EXPR)
384 {
385 ass_var = TREE_OPERAND (stmt, 0);
386 call = TREE_OPERAND (stmt, 1);
387 if (TREE_CODE (call) == WITH_SIZE_EXPR)
388 call = TREE_OPERAND (call, 0);
389 }
390 else
391 {
392 ass_var = NULL_TREE;
393 call = stmt;
394 }
395
396 if (TREE_CODE (call) == CALL_EXPR)
397 break;
398
399 /* If the statement has virtual operands, fail. */
400 ann = stmt_ann (stmt);
401 if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann))
402 || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann))
403 || NUM_VUSES (VUSE_OPS (ann)))
404 return;
405 }
406
407 if (bsi_end_p (bsi))
408 {
409 /* Recurse to the predecessors. */
410 for (e = bb->pred; e; e = e->pred_next)
411 find_tail_calls (e->src, ret);
412
413 return;
414 }
415
416 /* We found the call, check whether it is suitable. */
417 tail_recursion = false;
418 func = get_callee_fndecl (call);
419 if (func == current_function_decl)
420 {
421 for (param = DECL_ARGUMENTS (func), args = TREE_OPERAND (call, 1);
422 param && args;
423 param = TREE_CHAIN (param), args = TREE_CHAIN (args))
424 {
425 tree arg = TREE_VALUE (args);
426 if (param != arg
427 /* Make sure there are no problems with copying. Note we must
428 have a copyable type and the two arguments must have reasonably
429 equivalent types. The latter requirement could be relaxed if
430 we emitted a suitable type conversion statement. */
431 && (!is_gimple_reg_type (TREE_TYPE (param))
432 || !lang_hooks.types_compatible_p (TREE_TYPE (param),
433 TREE_TYPE (arg))))
434 break;
435 }
436 if (!args && !param)
437 tail_recursion = true;
438 }
439
440 /* Now check the statements after the call. None of them has virtual
441 operands, so they may only depend on the call through its return
442 value. The return value should also be dependent on each of them,
443 since we are running after dce. */
444 m = NULL_TREE;
445 a = NULL_TREE;
446
447 abb = bb;
448 absi = bsi;
449 while (1)
450 {
451 bsi_next (&absi);
452
453 while (bsi_end_p (absi))
454 {
455 ass_var = propagate_through_phis (ass_var, abb->succ);
456 abb = abb->succ->dest;
457 absi = bsi_start (abb);
458 }
459
460 stmt = bsi_stmt (absi);
461
462 if (TREE_CODE (stmt) == LABEL_EXPR)
463 continue;
464
465 if (TREE_CODE (stmt) == RETURN_EXPR)
466 break;
467
468 if (TREE_CODE (stmt) != MODIFY_EXPR)
469 return;
470
471 if (!process_assignment (stmt, stmt, bsi, &m, &a, &ass_var))
472 return;
473 }
474
475 /* See if this is a tail call we can handle. */
476 ret_var = TREE_OPERAND (stmt, 0);
477 if (ret_var
478 && TREE_CODE (ret_var) == MODIFY_EXPR)
479 {
480 tree ret_op = TREE_OPERAND (ret_var, 1);
481 STRIP_NOPS (ret_op);
482 if (!tail_recursion
483 && TREE_CODE (ret_op) != SSA_NAME)
484 return;
485
486 if (!process_assignment (ret_var, stmt, bsi, &m, &a, &ass_var))
487 return;
488 ret_var = TREE_OPERAND (ret_var, 0);
489 }
490
491 /* We may proceed if there either is no return value, or the return value
492 is identical to the call's return. */
493 if (ret_var
494 && (ret_var != ass_var))
495 return;
496
497 /* If this is not a tail recursive call, we cannot handle addends or
498 multiplicands. */
499 if (!tail_recursion && (m || a))
500 return;
501
502 nw = xmalloc (sizeof (struct tailcall));
503
504 nw->call_block = bb;
505 nw->call_bsi = bsi;
506
507 nw->tail_recursion = tail_recursion;
508
509 nw->mult = m;
510 nw->add = a;
511
512 nw->next = *ret;
513 *ret = nw;
514 }
515
516 /* Adjust the accumulator values according to A and M after BSI, and update
517 the phi nodes on edge BACK. */
518
519 static void
520 adjust_accumulator_values (block_stmt_iterator bsi, tree m, tree a, edge back)
521 {
522 tree stmt, var, phi, tmp;
523 tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
524 tree a_acc_arg = a_acc, m_acc_arg = m_acc;
525
526 if (a)
527 {
528 if (m_acc)
529 {
530 if (integer_onep (a))
531 var = m_acc;
532 else
533 {
534 stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
535 build (MULT_EXPR, ret_type, m_acc, a));
536
537 tmp = create_tmp_var (ret_type, "acc_tmp");
538 add_referenced_tmp_var (tmp);
539
540 var = make_ssa_name (tmp, stmt);
541 TREE_OPERAND (stmt, 0) = var;
542 bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
543 }
544 }
545 else
546 var = a;
547
548 stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
549 build (PLUS_EXPR, ret_type, a_acc, var));
550 var = make_ssa_name (SSA_NAME_VAR (a_acc), stmt);
551 TREE_OPERAND (stmt, 0) = var;
552 bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
553 a_acc_arg = var;
554 }
555
556 if (m)
557 {
558 stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
559 build (MULT_EXPR, ret_type, m_acc, m));
560 var = make_ssa_name (SSA_NAME_VAR (m_acc), stmt);
561 TREE_OPERAND (stmt, 0) = var;
562 bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
563 m_acc_arg = var;
564 }
565
566 if (a_acc)
567 {
568 for (phi = phi_nodes (back->dest); phi; phi = PHI_CHAIN (phi))
569 if (PHI_RESULT (phi) == a_acc)
570 break;
571
572 add_phi_arg (&phi, a_acc_arg, back);
573 }
574
575 if (m_acc)
576 {
577 for (phi = phi_nodes (back->dest); phi; phi = PHI_CHAIN (phi))
578 if (PHI_RESULT (phi) == m_acc)
579 break;
580
581 add_phi_arg (&phi, m_acc_arg, back);
582 }
583 }
584
585 /* Adjust value of the return at the end of BB according to M and A
586 accumulators. */
587
588 static void
589 adjust_return_value (basic_block bb, tree m, tree a)
590 {
591 tree ret_stmt = last_stmt (bb), ret_var, var, stmt, tmp;
592 tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
593 block_stmt_iterator bsi = bsi_last (bb);
594
595 if (TREE_CODE (ret_stmt) != RETURN_EXPR)
596 abort ();
597
598 ret_var = TREE_OPERAND (ret_stmt, 0);
599 if (!ret_var)
600 return;
601
602 if (TREE_CODE (ret_var) == MODIFY_EXPR)
603 {
604 ret_var->common.ann = (tree_ann_t) stmt_ann (ret_stmt);
605 bsi_replace (&bsi, ret_var, true);
606 SSA_NAME_DEF_STMT (TREE_OPERAND (ret_var, 0)) = ret_var;
607 ret_var = TREE_OPERAND (ret_var, 0);
608 ret_stmt = build1 (RETURN_EXPR, TREE_TYPE (ret_stmt), ret_var);
609 bsi_insert_after (&bsi, ret_stmt, BSI_NEW_STMT);
610 }
611
612 if (m)
613 {
614 stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
615 build (MULT_EXPR, ret_type, m_acc, ret_var));
616
617 tmp = create_tmp_var (ret_type, "acc_tmp");
618 add_referenced_tmp_var (tmp);
619
620 var = make_ssa_name (tmp, stmt);
621 TREE_OPERAND (stmt, 0) = var;
622 bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
623 }
624 else
625 var = ret_var;
626
627 if (a)
628 {
629 stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
630 build (PLUS_EXPR, ret_type, a_acc, var));
631
632 tmp = create_tmp_var (ret_type, "acc_tmp");
633 add_referenced_tmp_var (tmp);
634
635 var = make_ssa_name (tmp, stmt);
636 TREE_OPERAND (stmt, 0) = var;
637 bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
638 }
639
640 TREE_OPERAND (ret_stmt, 0) = var;
641 modify_stmt (ret_stmt);
642 }
643
644 /* Eliminates tail call described by T. TMP_VARS is a list of
645 temporary variables used to copy the function arguments. */
646
647 static void
648 eliminate_tail_call (struct tailcall *t)
649 {
650 tree param, stmt, args, rslt, call;
651 basic_block bb, first;
652 edge e;
653 tree phi;
654 stmt_ann_t ann;
655 v_may_def_optype v_may_defs;
656 unsigned i;
657 block_stmt_iterator bsi;
658
659 stmt = bsi_stmt (t->call_bsi);
660 get_stmt_operands (stmt);
661 ann = stmt_ann (stmt);
662 bb = t->call_block;
663
664 if (dump_file && (dump_flags & TDF_DETAILS))
665 {
666 fprintf (dump_file, "Eliminated tail recursion in bb %d : ",
667 bb->index);
668 print_generic_stmt (dump_file, stmt, TDF_SLIM);
669 fprintf (dump_file, "\n");
670 }
671
672 if (TREE_CODE (stmt) == MODIFY_EXPR)
673 stmt = TREE_OPERAND (stmt, 1);
674
675 first = ENTRY_BLOCK_PTR->succ->dest;
676
677 /* Remove the code after call_bsi that will become unreachable. The
678 possibly unreachable code in other blocks is removed later in
679 cfg cleanup. */
680 bsi = t->call_bsi;
681 bsi_next (&bsi);
682 while (!bsi_end_p (bsi))
683 {
684 /* Do not remove the return statement, so that redirect_edge_and_branch
685 sees how the block ends. */
686 if (TREE_CODE (bsi_stmt (bsi)) == RETURN_EXPR)
687 break;
688
689 bsi_remove (&bsi);
690 }
691
692 /* Replace the call by a jump to the start of function. */
693 e = redirect_edge_and_branch (t->call_block->succ, first);
694 if (!e)
695 abort ();
696 PENDING_STMT (e) = NULL_TREE;
697
698 /* Add phi node entries for arguments. Not every PHI node corresponds to
699 a function argument (there may be PHI nodes for virtual definitions of the
700 eliminated calls), so we search for a PHI corresponding to each argument
701 rather than searching for which argument a PHI node corresponds to. */
702
703 for (param = DECL_ARGUMENTS (current_function_decl),
704 args = TREE_OPERAND (stmt, 1);
705 param;
706 param = TREE_CHAIN (param),
707 args = TREE_CHAIN (args))
708 {
709
710 for (phi = phi_nodes (first); phi; phi = PHI_CHAIN (phi))
711 if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
712 break;
713
714 /* The phi node indeed does not have to be there, in case the operand is
715 invariant in the function. */
716 if (!phi)
717 continue;
718
719 add_phi_arg (&phi, TREE_VALUE (args), e);
720 }
721
722 /* Add phi nodes for the call clobbered variables. */
723 v_may_defs = V_MAY_DEF_OPS (ann);
724 for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
725 {
726 param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
727 for (phi = phi_nodes (first); phi; phi = PHI_CHAIN (phi))
728 if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
729 break;
730
731 if (!phi)
732 {
733 tree name = var_ann (param)->default_def;
734 tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name));
735
736 var_ann (param)->default_def = new_name;
737 phi = create_phi_node (name, first);
738 SSA_NAME_DEF_STMT (name) = phi;
739 add_phi_arg (&phi, new_name, ENTRY_BLOCK_PTR->succ);
740
741 /* For all calls the same set of variables should be clobbered. This
742 means that there always should be the appropriate phi node except
743 for the first time we eliminate the call. */
744 if (first->pred->pred_next->pred_next)
745 abort ();
746 }
747
748 add_phi_arg (&phi, V_MAY_DEF_OP (v_may_defs, i), e);
749 }
750
751 /* Update the values of accumulators. */
752 adjust_accumulator_values (t->call_bsi, t->mult, t->add, e);
753
754 call = bsi_stmt (t->call_bsi);
755 if (TREE_CODE (call) == MODIFY_EXPR)
756 {
757 rslt = TREE_OPERAND (call, 0);
758
759 /* Result of the call will no longer be defined. So adjust the
760 SSA_NAME_DEF_STMT accordingly. */
761 SSA_NAME_DEF_STMT (rslt) = build_empty_stmt ();
762 }
763
764 bsi_remove (&t->call_bsi);
765 }
766
767 /* Optimizes the tailcall described by T. If OPT_TAILCALLS is true, also
768 mark the tailcalls for the sibcall optimization. */
769
770 static bool
771 optimize_tail_call (struct tailcall *t, bool opt_tailcalls)
772 {
773 if (t->tail_recursion)
774 {
775 eliminate_tail_call (t);
776 return true;
777 }
778
779 if (opt_tailcalls)
780 {
781 tree stmt = bsi_stmt (t->call_bsi);
782
783 stmt = get_call_expr_in (stmt);
784 CALL_EXPR_TAILCALL (stmt) = 1;
785 if (dump_file && (dump_flags & TDF_DETAILS))
786 {
787 fprintf (dump_file, "Found tail call ");
788 print_generic_expr (dump_file, stmt, dump_flags);
789 fprintf (dump_file, " in bb %i\n", t->call_block->index);
790 }
791 }
792
793 return false;
794 }
795
796 /* Optimizes tail calls in the function, turning the tail recursion
797 into iteration. */
798
799 static void
800 tree_optimize_tail_calls_1 (bool opt_tailcalls)
801 {
802 edge e;
803 bool phis_constructed = false;
804 struct tailcall *tailcalls = NULL, *act, *next;
805 bool changed = false;
806 basic_block first = ENTRY_BLOCK_PTR->succ->dest;
807 tree stmt, param, ret_type, tmp, phi;
808
809 if (!suitable_for_tail_opt_p ())
810 return;
811 if (opt_tailcalls)
812 opt_tailcalls = suitable_for_tail_call_opt_p ();
813
814 for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
815 {
816 /* Only traverse the normal exits, i.e. those that end with return
817 statement. */
818 stmt = last_stmt (e->src);
819
820 if (stmt
821 && TREE_CODE (stmt) == RETURN_EXPR)
822 find_tail_calls (e->src, &tailcalls);
823 }
824
825 /* Construct the phi nodes and accumulators if necessary. */
826 a_acc = m_acc = NULL_TREE;
827 for (act = tailcalls; act; act = act->next)
828 {
829 if (!act->tail_recursion)
830 continue;
831
832 if (!phis_constructed)
833 {
834 /* Ensure that there is only one predecessor of the block. */
835 if (first->pred->pred_next)
836 first = split_edge (ENTRY_BLOCK_PTR->succ);
837
838 /* Copy the args if needed. */
839 for (param = DECL_ARGUMENTS (current_function_decl);
840 param;
841 param = TREE_CHAIN (param))
842 if (var_ann (param)
843 /* Also parameters that are only defined but never used need not
844 be copied. */
845 && (var_ann (param)->default_def
846 && TREE_CODE (var_ann (param)->default_def) == SSA_NAME))
847 {
848 tree name = var_ann (param)->default_def;
849 tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name));
850 tree phi;
851
852 var_ann (param)->default_def = new_name;
853 phi = create_phi_node (name, first);
854 SSA_NAME_DEF_STMT (name) = phi;
855 add_phi_arg (&phi, new_name, first->pred);
856 }
857 phis_constructed = true;
858 }
859
860 if (act->add && !a_acc)
861 {
862 ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
863
864 tmp = create_tmp_var (ret_type, "add_acc");
865 add_referenced_tmp_var (tmp);
866
867 phi = create_phi_node (tmp, first);
868 add_phi_arg (&phi, fold_convert (ret_type, integer_zero_node),
869 first->pred);
870 a_acc = PHI_RESULT (phi);
871 }
872
873 if (act->mult && !m_acc)
874 {
875 ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
876
877 tmp = create_tmp_var (ret_type, "mult_acc");
878 add_referenced_tmp_var (tmp);
879
880 phi = create_phi_node (tmp, first);
881 add_phi_arg (&phi, fold_convert (ret_type, integer_one_node),
882 first->pred);
883 m_acc = PHI_RESULT (phi);
884 }
885 }
886
887 for (; tailcalls; tailcalls = next)
888 {
889 next = tailcalls->next;
890 changed |= optimize_tail_call (tailcalls, opt_tailcalls);
891 free (tailcalls);
892 }
893
894 if (a_acc || m_acc)
895 {
896 /* Modify the remaining return statements. */
897 for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
898 {
899 stmt = last_stmt (e->src);
900
901 if (stmt
902 && TREE_CODE (stmt) == RETURN_EXPR)
903 adjust_return_value (e->src, m_acc, a_acc);
904 }
905 }
906
907 if (changed)
908 {
909 free_dominance_info (CDI_DOMINATORS);
910 cleanup_tree_cfg ();
911 }
912 }
913
914 static void
915 execute_tail_recursion (void)
916 {
917 tree_optimize_tail_calls_1 (false);
918 }
919
920 static bool
921 gate_tail_calls (void)
922 {
923 return flag_optimize_sibling_calls != 0;
924 }
925
926 static void
927 execute_tail_calls (void)
928 {
929 tree_optimize_tail_calls_1 (true);
930 }
931
932 struct tree_opt_pass pass_tail_recursion =
933 {
934 "tailr", /* name */
935 NULL, /* gate */
936 execute_tail_recursion, /* execute */
937 NULL, /* sub */
938 NULL, /* next */
939 0, /* static_pass_number */
940 0, /* tv_id */
941 PROP_cfg | PROP_ssa, /* properties_required */
942 0, /* properties_provided */
943 0, /* properties_destroyed */
944 0, /* todo_flags_start */
945 TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
946 };
947
948 struct tree_opt_pass pass_tail_calls =
949 {
950 "tailc", /* name */
951 gate_tail_calls, /* gate */
952 execute_tail_calls, /* execute */
953 NULL, /* sub */
954 NULL, /* next */
955 0, /* static_pass_number */
956 0, /* tv_id */
957 PROP_cfg | PROP_ssa, /* properties_required */
958 0, /* properties_provided */
959 0, /* properties_destroyed */
960 0, /* todo_flags_start */
961 TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
962 };
This page took 0.085563 seconds and 6 git commands to generate.