cgraphunit.c 56.1 KB
Newer Older
1
/* Callgraph based intraprocedural optimizations.
2
   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   Contributed by Jan Hubicka

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/* This module implements main driver of compilation process as well as
   few basic intraprocedural optimizers.

   The main scope of this file is to act as an interface in between
   tree based frontends and the backend (and middle end)

   The front-end is supposed to use following functionality:

    - cgraph_finalize_function

      This function is called once front-end has parsed whole body of function
      and it is certain that the function body nor the declaration will change.

      (There is one exception needed for implementing GCC extern inline function.)

    - cgraph_varpool_finalize_variable

39
      This function has same behavior as the above but is used for static
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
      variables.

    - cgraph_finalize_compilation_unit

      This function is called once compilation unit is finalized and it will
      no longer change.

      In the unit-at-a-time the call-graph construction and local function
      analysis takes place here.  Bodies of unreachable functions are released
      to conserve memory usage.

      ???  The compilation unit in this point of view should be compilation
      unit as defined by the language - for instance C frontend allows multiple
      compilation units to be parsed at once and it should call function each
      time parsing is done so we save memory.

    - cgraph_optimize

      In this unit-at-a-time compilation the intra procedural analysis takes
      place here.  In particular the static functions whose address is never
      taken are marked as local.  Backend can then use this information to
      modify calling conventions, do better inlining or similar optimizations.

    - cgraph_assemble_pending_functions
    - cgraph_varpool_assemble_pending_variables

      In non-unit-at-a-time mode these functions can be used to force compilation
      of functions or variables that are known to be needed at given stage
      of compilation

    - cgraph_mark_needed_node
    - cgraph_varpool_mark_needed_node

      When function or variable is referenced by some hidden way (for instance
      via assembly code and marked by attribute "used"), the call-graph data structure
      must be updated accordingly by this function.

    - analyze_expr callback

      This function is responsible for lowering tree nodes not understood by
      generic code into understandable ones or alternatively marking
      callgraph and varpool nodes referenced by the as needed.

      ??? On the tree-ssa genericizing should take place here and we will avoid
      need for these hooks (replacing them by genericizing hook)

    - expand_function callback

      This function is used to expand function and pass it into RTL back-end.
      Front-end should not make any assumptions about when this function can be
      called.  In particular cgraph_assemble_pending_functions,
      cgraph_varpool_assemble_pending_variables, cgraph_finalize_function,
      cgraph_varpool_finalize_function, cgraph_optimize can cause arbitrarily
      previously finalized functions to be expanded.

    We implement two compilation modes.

      - unit-at-a-time:  In this mode analyzing of all functions is deferred
	to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.

	In cgraph_finalize_compilation_unit the reachable functions are
	analyzed.  During analysis the call-graph edges from reachable
	functions are constructed and their destinations are marked as
	reachable.  References to functions and variables are discovered too
	and variables found to be needed output to the assembly file.  Via
	mark_referenced call in assemble_variable functions referenced by
	static variables are noticed too.

108
	The intra-procedural information is produced and its existence
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
	indicated by global_info_ready.  Once this flag is set it is impossible
	to change function from !reachable to reachable and thus
	assemble_variable no longer call mark_referenced.

	Finally the call-graph is topologically sorted and all reachable functions
	that has not been completely inlined or are not external are output.

	??? It is possible that reference to function or variable is optimized
	out.  We can not deal with this nicely because topological order is not
	suitable for it.  For tree-ssa we may consider another pass doing
	optimization and re-discovering reachable functions.

	??? Reorganize code so variables are output very last and only if they
	really has been referenced by produced code, so we catch more cases
	where reference has been optimized out.

      - non-unit-at-a-time

	All functions are variables are output as early as possible to conserve
	memory consumption.  This may or may not result in less memory used but
	it is still needed for some legacy code that rely on particular ordering
	of things output from the compiler.

	Varpool data structures are not used and variables are output directly.

	Functions are output early using call of
	cgraph_assemble_pending_function from cgraph_finalize_function.  The
	decision on whether function is needed is made more conservative so
	uninlininable static functions are needed too.  During the call-graph
	construction the edge destinations are not marked as reachable and it
	is completely relied upn assemble_variable to mark them.
	
     Inlining decision heuristics
        ??? Move this to separate file after tree-ssa merge.

	We separate inlining decisions from the inliner itself and store it
145
	inside callgraph as so called inline plan.  Refer to cgraph.c
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
	documentation about particular representation of inline plans in the
	callgraph

	The implementation of particular heuristics is separated from
	the rest of code to make it easier to replace it with more complicated
	implementation in the future.  The rest of inlining code acts as a
	library aimed to modify the callgraph and verify that the parameters
	on code size growth fits.

	To mark given call inline, use cgraph_mark_inline function, the
	verification is performed by cgraph_default_inline_p and
	cgraph_check_inline_limits.

	The heuristics implements simple knapsack style algorithm ordering
	all functions by their "profitability" (estimated by code size growth)
	and inlining them in priority order.

	cgraph_decide_inlining implements heuristics taking whole callgraph
	into account, while cgraph_decide_inlining_incrementally considers
	only one function at a time and is used in non-unit-at-a-time mode.  */
166

167

168 169 170 171 172
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
173
#include "rtl.h"
174
#include "tree-flow.h"
175 176
#include "tree-inline.h"
#include "langhooks.h"
177
#include "pointer-set.h"
178 179 180 181 182 183
#include "toplev.h"
#include "flags.h"
#include "ggc.h"
#include "debug.h"
#include "target.h"
#include "cgraph.h"
Jan Hubicka committed
184
#include "diagnostic.h"
185
#include "timevar.h"
186 187 188
#include "params.h"
#include "fibheap.h"
#include "c-common.h"
189
#include "intl.h"
190
#include "function.h"
191
#include "tree-gimple.h"
192 193

#define INSNS_PER_CALL 10
194

195
static void cgraph_expand_all_functions (void);
196 197 198
static void cgraph_mark_functions_to_output (void);
static void cgraph_expand_function (struct cgraph_node *);
static tree record_call_1 (tree *, int *, void *);
199
static void cgraph_mark_local_functions (void);
200 201
static bool cgraph_default_inline_p (struct cgraph_node *n);
static void cgraph_analyze_function (struct cgraph_node *node);
202
static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
203

204 205 206 207 208 209
/* Statistics we collect about inlining algorithm.  */
static int ncalls_inlined;
static int nfunctions_inlined;
static int initial_insns;
static int overall_insns;

210 211 212 213
/* Records tree nodes seen in cgraph_create_edges.  Simply using
   walk_tree_without_duplicates doesn't guarantee each node is visited
   once because it gets a new htab upon each recursive call from
   record_calls_1.  */
214
static struct pointer_set_t *visited_nodes;
215

216 217
static FILE *cgraph_dump_file;

218 219 220 221 222 223 224 225
/* Determine if function DECL is needed.  That is, visible to something
   either outside this translation unit, something magic in the system
   configury, or (if not doing unit-at-a-time) to something we havn't
   seen yet.  */

static bool
decide_is_function_needed (struct cgraph_node *node, tree decl)
{
226
  tree origin;
227

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
  /* If we decided it was needed before, but at the time we didn't have
     the body of the function available, then it's still needed.  We have
     to go back and re-check its dependencies now.  */
  if (node->needed)
    return true;

  /* Externally visible functions must be output.  The exception is
     COMDAT functions that must be output only when they are needed.  */
  if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
    return true;

  /* Constructors and destructors are reachable from the runtime by
     some mechanism.  */
  if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
    return true;

  /* If the user told us it is used, then it must be so.  */
  if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
    return true;

  /* ??? If the assembler name is set by hand, it is possible to assemble
     the name later after finalizing the function and the fact is noticed
     in assemble_name then.  This is arguably a bug.  */
  if (DECL_ASSEMBLER_NAME_SET_P (decl)
      && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
    return true;

  if (flag_unit_at_a_time)
    return false;

  /* If not doing unit at a time, then we'll only defer this function
     if its marked for inlining.  Otherwise we want to emit it now.  */

  /* "extern inline" functions are never output locally.  */
  if (DECL_EXTERNAL (decl))
    return false;
264 265
  /* Nested functions of extern inline function shall not be emit unless
     we inlined the origin.  */
266 267 268
  for (origin = decl_function_context (decl); origin;
       origin = decl_function_context (origin))
    if (DECL_EXTERNAL (origin))
269
      return false;
270
  /* We want to emit COMDAT functions only when absolutely necessary.  */
271
  if (DECL_COMDAT (decl))
272 273 274 275
    return false;
  if (!DECL_INLINE (decl)
      || (!node->local.disregard_inline_limits
	  /* When declared inline, defer even the uninlinable functions.
276
	     This allows them to be eliminated when unused.  */
277
	  && !DECL_DECLARED_INLINE_P (decl) 
278
	  && (!node->local.inlinable || !cgraph_default_inline_p (node))))
279 280 281 282 283
    return true;

  return false;
}

284 285


286 287
/* When not doing unit-at-a-time, output all functions enqueued.
   Return true when such a functions were found.  */
288 289

bool
290 291 292 293 294 295 296 297 298 299 300 301
cgraph_assemble_pending_functions (void)
{
  bool output = false;

  if (flag_unit_at_a_time)
    return false;

  while (cgraph_nodes_queue)
    {
      struct cgraph_node *n = cgraph_nodes_queue;

      cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
302
      n->next_needed = NULL;
303
      if (!n->global.inlined_to && !DECL_EXTERNAL (n->decl))
304 305 306 307
	{
	  cgraph_expand_function (n);
	  output = true;
	}
308
    }
309

310 311 312
  return output;
}

313 314 315 316
/* DECL has been parsed.  Take it, queue it, compile it at the whim of the
   logic in effect.  If NESTED is true, then our caller cannot stand to have
   the garbage collector run at the moment.  We would need to either create
   a new GC context, or just not compile right now.  */
317 318

void
319
cgraph_finalize_function (tree decl, bool nested)
320 321 322
{
  struct cgraph_node *node = cgraph_node (decl);

323 324 325
  if (node->local.finalized)
    {
      /* As an GCC extension we allow redefinition of the function.  The
326 327 328 329 330
	 semantics when both copies of bodies differ is not well defined.
	 We replace the old body with new body so in unit at a time mode
	 we always use new body, while in normal mode we may end up with
	 old body inlined into some functions and new body expanded and
	 inlined in others.
331
	 
332
	 ??? It may make more sense to use one body for inlining and other
333
	 body for expanding the function but this is difficult to do.  */
334

335 336 337 338 339 340
      /* If node->output is set, then this is a unit-at-a-time compilation
	 and we have already begun whole-unit analysis.  This is *not*
	 testing for whether we've already emitted the function.  That
	 case can be sort-of legitimately seen with real function 
	 redefinition errors.  I would argue that the front end should
	 never present us with such a case, but don't enforce that for now.  */
341
      gcc_assert (!node->output);
342

343
      /* Reset our data structures so we can analyze the function again.  */
344 345 346
      memset (&node->local, 0, sizeof (node->local));
      memset (&node->global, 0, sizeof (node->global));
      memset (&node->rtl, 0, sizeof (node->rtl));
347
      node->analyzed = false;
348
      node->local.redefined_extern_inline = true;
349 350 351 352 353 354 355 356 357 358

      if (!flag_unit_at_a_time)
	{
	  struct cgraph_node *n;

	  for (n = cgraph_nodes; n; n = n->next)
	    if (n->global.inlined_to == node)
	      cgraph_remove_node (n);
	}

359
      while (node->callees)
360
	cgraph_remove_edge (node->callees);
361

362 363 364
      /* We may need to re-queue the node for assembling in case
         we already proceeded it and ignored as not needed.  */
      if (node->reachable && !flag_unit_at_a_time)
365
	{
366 367 368 369 370 371 372
	  struct cgraph_node *n;

	  for (n = cgraph_nodes_queue; n; n = n->next_needed)
	    if (n == node)
	      break;
	  if (!n)
	    node->reachable = 0;
373 374
	}
    }
375

376
  notice_global_symbol (decl);
377
  node->decl = decl;
378
  node->local.finalized = true;
379 380 381
  if (node->nested)
    lower_nested_functions (decl);
  gcc_assert (!node->nested);
382

383 384
  /* If not unit at a time, then we need to create the call graph
     now, so that called functions can be queued and emitted now.  */
385
  if (!flag_unit_at_a_time)
386 387 388 389
    {
      cgraph_analyze_function (node);
      cgraph_decide_inlining_incrementally (node);
    }
390

391 392 393
  if (decide_is_function_needed (node, decl))
    cgraph_mark_needed_node (node);

394 395 396
  /* If not unit at a time, go ahead and emit everything we've found
     to be reachable at this time.  */
  if (!nested)
Jan Hubicka committed
397 398 399 400
    {
      if (!cgraph_assemble_pending_functions ())
	ggc_collect ();
    }
401

402
  /* If we've not yet emitted decl, tell the debug info about it.  */
403
  if (!TREE_ASM_WRITTEN (decl))
404
    (*debug_hooks->deferred_inline_function) (decl);
405

406 407 408
  /* Possibly warn about unused parameters.  */
  if (warn_unused_parameter)
    do_warn_unused_parameter (decl);
409 410 411 412
}

/* Walk tree and record all calls.  Called via walk_tree.  */
static tree
413
record_call_1 (tree *tp, int *walk_subtrees, void *data)
414
{
415 416 417
  tree t = *tp;

  switch (TREE_CODE (t))
418
    {
419 420 421 422 423
    case VAR_DECL:
      /* ??? Really, we should mark this decl as *potentially* referenced
	 by this function and re-examine whether the decl is actually used
	 after rtl has been generated.  */
      if (TREE_STATIC (t))
424 425 426 427 428 429
	{
	  cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
	  if (lang_hooks.callgraph.analyze_expr)
	    return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, 
						      data);
	}
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
      break;

    case ADDR_EXPR:
      if (flag_unit_at_a_time)
	{
	  /* Record dereferences to the functions.  This makes the
	     functions reachable unconditionally.  */
	  tree decl = TREE_OPERAND (*tp, 0);
	  if (TREE_CODE (decl) == FUNCTION_DECL)
	    cgraph_mark_needed_node (cgraph_node (decl));
	}
      break;

    case CALL_EXPR:
      {
	tree decl = get_callee_fndecl (*tp);
	if (decl && TREE_CODE (decl) == FUNCTION_DECL)
	  {
448
	    cgraph_create_edge (data, cgraph_node (decl), *tp);
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466

	    /* When we see a function call, we don't want to look at the
	       function reference in the ADDR_EXPR that is hanging from
	       the CALL_EXPR we're examining here, because we would
	       conclude incorrectly that the function's address could be
	       taken by something that is not a function call.  So only
	       walk the function parameter list, skip the other subtrees.  */

	    walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
		       visited_nodes);
	    *walk_subtrees = 0;
	  }
	break;
      }

    default:
      /* Save some cycles by not walking types and declaration as we
	 won't find anything useful there anyway.  */
467
      if (IS_TYPE_OR_DECL_P (*tp))
468 469
	{
	  *walk_subtrees = 0;
470
	  break;
471
	}
472 473

      if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
474
	return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees, data);
475
      break;
476
    }
477

478 479 480
  return NULL;
}

481
/* Create cgraph edges for function calls inside BODY from NODE.  */
482 483

void
484
cgraph_create_edges (struct cgraph_node *node, tree body)
485
{
486 487
  /* The nodes we're interested in are never shared, so walk
     the tree ignoring duplicates.  */
488
  visited_nodes = pointer_set_create ();
489
  walk_tree (&body, record_call_1, node, visited_nodes);
490
  pointer_set_destroy (visited_nodes);
491
  visited_nodes = NULL;
492 493
}

494 495
static bool error_found;

496 497
/* Callback of verify_cgraph_node.  Check that all call_exprs have
   cgraph nodes.  */
498

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
static tree
verify_cgraph_node_1 (tree *tp, int *walk_subtrees, void *data)
{
  tree t = *tp;
  tree decl;

  if (TREE_CODE (t) == CALL_EXPR && (decl = get_callee_fndecl (t)))
    {
      struct cgraph_edge *e = cgraph_edge (data, t);
      if (e)
	{
	  if (e->aux)
	    {
	      error ("Shared call_expr:");
	      debug_tree (t);
	      error_found = true;
	    }
	  if (e->callee->decl != cgraph_node (decl)->decl)
	    {
	      error ("Edge points to wrong declaration:");
	      debug_tree (e->callee->decl);
	      fprintf (stderr," Instead of:");
	      debug_tree (decl);
	    }
	  e->aux = (void *)1;
	}
      else
	{
	  error ("Missing callgraph edge for call expr:");
	  debug_tree (t);
	  error_found = true;
	}
    }
532

533 534
  /* Save some cycles by not walking types and declaration as we
     won't find anything useful there anyway.  */
535
  if (IS_TYPE_OR_DECL_P (*tp))
536 537
    *walk_subtrees = 0;

538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
  return NULL_TREE;
}

/* Verify cgraph nodes of given cgraph node.  */
void
verify_cgraph_node (struct cgraph_node *node)
{
  struct cgraph_edge *e;
  struct cgraph_node *main_clone;

  timevar_push (TV_CGRAPH_VERIFY);
  error_found = false;
  for (e = node->callees; e; e = e->next_callee)
    if (e->aux)
      {
	error ("Aux field set for edge %s->%s",
	       cgraph_node_name (e->caller), cgraph_node_name (e->callee));
	error_found = true;
      }
  for (e = node->callers; e; e = e->next_caller)
    {
      if (!e->inline_failed)
	{
	  if (node->global.inlined_to
	      != (e->caller->global.inlined_to
		  ? e->caller->global.inlined_to : e->caller))
	    {
	      error ("Inlined_to pointer is wrong");
	      error_found = true;
	    }
	  if (node->callers->next_caller)
	    {
	      error ("Multiple inline callers");
	      error_found = true;
	    }
	}
      else
	if (node->global.inlined_to)
	  {
	    error ("Inlined_to pointer set for noninline callers");
	    error_found = true;
	  }
    }
  if (!node->callers && node->global.inlined_to)
    {
      error ("Inlined_to pointer is set but no predecesors found");
      error_found = true;
    }
  if (node->global.inlined_to == node)
    {
      error ("Inlined_to pointer reffers to itself");
      error_found = true;
    }

  for (main_clone = cgraph_node (node->decl); main_clone;
       main_clone = main_clone->next_clone)
    if (main_clone == node)
      break;
  if (!node)
    {
      error ("Node not found in DECL_ASSEMBLER_NAME hash");
      error_found = true;
    }
  
  if (node->analyzed
      && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
      && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
    {
      walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl),
				    verify_cgraph_node_1, node);
      for (e = node->callees; e; e = e->next_callee)
	{
	  if (!e->aux)
	    {
	      error ("Edge %s->%s has no corresponding call_expr",
		     cgraph_node_name (e->caller),
		     cgraph_node_name (e->callee));
	      error_found = true;
	    }
	  e->aux = 0;
	}
    }
  if (error_found)
    {
      dump_cgraph_node (stderr, node);
      internal_error ("verify_cgraph_node failed.");
    }
  timevar_pop (TV_CGRAPH_VERIFY);
}

/* Verify whole cgraph structure.  */
void
verify_cgraph (void)
{
  struct cgraph_node *node;

634 635 636
  if (sorrycount || errorcount)
    return;

637 638 639 640
  for (node = cgraph_nodes; node; node = node->next)
    verify_cgraph_node (node);
}

641 642 643 644 645
/* Analyze the function scheduled to be output.  */
static void
cgraph_analyze_function (struct cgraph_node *node)
{
  tree decl = node->decl;
646
  struct cgraph_edge *e;
647

648
  current_function_decl = decl;
649 650

  /* First kill forward declaration so reverse inlining works properly.  */
651
  cgraph_create_edges (node, DECL_SAVED_TREE (decl));
652 653

  node->local.inlinable = tree_inlinable_function_p (decl);
654
  node->local.self_insns = estimate_num_insns (DECL_SAVED_TREE (decl));
655 656
  if (node->local.inlinable)
    node->local.disregard_inline_limits
657
      = lang_hooks.tree_inlining.disregard_inline_limits (decl);
658
  for (e = node->callers; e; e = e->next_caller)
659 660 661 662 663 664 665 666 667
    {
      if (node->local.redefined_extern_inline)
	e->inline_failed = N_("redefined extern inline functions are not "
			   "considered for inlining");
      else if (!node->local.inlinable)
	e->inline_failed = N_("function not inlinable");
      else
	e->inline_failed = N_("function not considered for inlining");
    }
668 669
  if (flag_really_no_inline && !node->local.disregard_inline_limits)
    node->local.inlinable = 0;
670 671 672
  /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
  node->global.insns = node->local.self_insns;

673
  node->analyzed = true;
674
  current_function_decl = NULL;
675 676
}

677 678 679
/* Analyze the whole compilation unit once it is parsed completely.  */

void
680
cgraph_finalize_compilation_unit (void)
681 682 683
{
  struct cgraph_node *node;

684
  if (!flag_unit_at_a_time)
685 686 687 688
    {
      cgraph_assemble_pending_functions ();
      return;
    }
689

690
  cgraph_varpool_assemble_pending_decls ();
691 692
  if (!quiet_flag)
    fprintf (stderr, "\nAnalyzing compilation unit\n");
693

694 695
  timevar_push (TV_CGRAPH);
  if (cgraph_dump_file)
696
    {
697
      fprintf (cgraph_dump_file, "Initial entry points:");
698 699
      for (node = cgraph_nodes; node; node = node->next)
	if (node->needed && DECL_SAVED_TREE (node->decl))
700 701
	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
      fprintf (cgraph_dump_file, "\n");
702 703
    }

704 705 706 707
  /* Propagate reachability flag and lower representation of all reachable
     functions.  In the future, lowering will introduce new functions and
     new entry points on the way (by template instantiation and virtual
     method table generation for instance).  */
708
  while (cgraph_nodes_queue)
709
    {
710
      struct cgraph_edge *edge;
711 712 713
      tree decl = cgraph_nodes_queue->decl;

      node = cgraph_nodes_queue;
714
      cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
715
      node->next_needed = NULL;
716

717
      /* ??? It is possible to create extern inline function and later using
718
	 weak alas attribute to kill its body. See
719 720 721 722
	 gcc.c-torture/compile/20011119-1.c  */
      if (!DECL_SAVED_TREE (decl))
	continue;

723 724
      gcc_assert (!node->analyzed && node->reachable);
      gcc_assert (DECL_SAVED_TREE (decl));
725

726
      cgraph_analyze_function (node);
727

728
      for (edge = node->callees; edge; edge = edge->next_callee)
729
	if (!edge->callee->reachable)
730 731
	  cgraph_mark_reachable_node (edge->callee);

732
      cgraph_varpool_assemble_pending_decls ();
733
    }
734

735 736
  /* Collect entry points to the unit.  */

737
  if (cgraph_dump_file)
738
    {
739
      fprintf (cgraph_dump_file, "Unit entry points:");
740 741
      for (node = cgraph_nodes; node; node = node->next)
	if (node->needed && DECL_SAVED_TREE (node->decl))
742
	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
743
      fprintf (cgraph_dump_file, "\n\nInitial ");
744
      dump_cgraph (cgraph_dump_file);
745
    }
746

747 748
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "\nReclaiming functions:");
749 750 751 752 753 754 755

  for (node = cgraph_nodes; node; node = node->next)
    {
      tree decl = node->decl;

      if (!node->reachable && DECL_SAVED_TREE (decl))
	{
756 757
	  if (cgraph_dump_file)
	    fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
758
	  cgraph_remove_node (node);
759
	}
760 761
      else
	node->next_needed = NULL;
762
    }
763
  if (cgraph_dump_file)
764 765 766 767
    {
      fprintf (cgraph_dump_file, "\n\nReclaimed ");
      dump_cgraph (cgraph_dump_file);
    }
768
  ggc_collect ();
769
  timevar_pop (TV_CGRAPH);
770 771 772 773
}
/* Figure out what functions we want to assemble.  */

static void
774
cgraph_mark_functions_to_output (void)
775 776 777 778 779 780
{
  struct cgraph_node *node;

  for (node = cgraph_nodes; node; node = node->next)
    {
      tree decl = node->decl;
781
      struct cgraph_edge *e;
782 783
      
      gcc_assert (!node->output);
784 785

      for (e = node->callers; e; e = e->next_caller)
786
	if (e->inline_failed)
787
	  break;
788

789 790 791
      /* We need to output all local functions that are used and not
	 always inlined, as well as those that are reachable from
	 outside the current compilation unit.  */
792
      if (DECL_SAVED_TREE (decl)
793
	  && !node->global.inlined_to
794
	  && (node->needed
795
	      || (e && node->reachable))
796
	  && !TREE_ASM_WRITTEN (decl)
797 798
	  && !DECL_EXTERNAL (decl))
	node->output = 1;
799
      else
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
	{
	  /* We should've reclaimed all functions that are not needed.  */
#ifdef ENABLE_CHECKING
	  if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
	      && !DECL_EXTERNAL (decl))
	    {
	      dump_cgraph_node (stderr, node);
	      internal_error ("failed to reclaim unneeded function");
	    }
#endif
	  gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
		      || DECL_EXTERNAL (decl));

	}
      
Jan Hubicka committed
815 816 817
    }
}

818
/* Expand function specified by NODE.  */
819

820
static void
821
cgraph_expand_function (struct cgraph_node *node)
822 823 824
{
  tree decl = node->decl;

825
  /* We ought to not compile any inline clones.  */
826
  gcc_assert (!node->global.inlined_to);
827

828 829
  if (flag_unit_at_a_time)
    announce_function (decl);
Jan Hubicka committed
830

831
  /* Generate RTL for the body of DECL.  */
832
  lang_hooks.callgraph.expand_function (decl);
Jan Hubicka committed
833

834 835
  /* Make sure that BE didn't give up on compiling.  */
  /* ??? Can happen with nested function of extern inline.  */
836
  gcc_assert (TREE_ASM_WRITTEN (node->decl));
837

838
  current_function_decl = NULL;
839
  if (!cgraph_preserve_function_body_p (node->decl))
840 841 842 843
    {
      DECL_SAVED_TREE (node->decl) = NULL;
      DECL_STRUCT_FUNCTION (node->decl) = NULL;
      DECL_INITIAL (node->decl) = error_mark_node;
844
      /* Eliminate all call edges.  This is important so the call_expr no longer
845 846 847
	 points to the dead function body.  */
      while (node->callees)
	cgraph_remove_edge (node->callees);
848
    }
849 850
}

851 852
/* Fill array order with all nodes with output flag set in the reverse
   topological order.  */
853

854 855
static int
cgraph_postorder (struct cgraph_node **order)
856 857 858 859 860 861
{
  struct cgraph_node *node, *node2;
  int stack_size = 0;
  int order_pos = 0;
  struct cgraph_edge *edge, last;

862
  struct cgraph_node **stack =
863
    xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
864

865 866 867
  /* We have to deal with cycles nicely, so use a depth first traversal
     output algorithm.  Ignore the fact that some functions won't need
     to be output and put them into order as well, so we get dependencies
868
     right through intline functions.  */
869 870 871
  for (node = cgraph_nodes; node; node = node->next)
    node->aux = NULL;
  for (node = cgraph_nodes; node; node = node->next)
872
    if (!node->aux)
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
      {
	node2 = node;
	if (!node->callers)
	  node->aux = &last;
	else
	  node->aux = node->callers;
	while (node2)
	  {
	    while (node2->aux != &last)
	      {
		edge = node2->aux;
		if (edge->next_caller)
		  node2->aux = edge->next_caller;
		else
		  node2->aux = &last;
		if (!edge->caller->aux)
		  {
		    if (!edge->caller->callers)
		      edge->caller->aux = &last;
		    else
		      edge->caller->aux = edge->caller->callers;
		    stack[stack_size++] = node2;
		    node2 = edge->caller;
		    break;
		  }
	      }
	    if (node2->aux == &last)
	      {
		order[order_pos++] = node2;
		if (stack_size)
		  node2 = stack[--stack_size];
		else
		  node2 = NULL;
	      }
	  }
      }
909 910 911 912
  free (stack);
  return order_pos;
}

913

914 915 916 917 918 919 920 921 922 923 924
/* Perform reachability analysis and reclaim all unreachable nodes.
   This function also remove unneeded bodies of extern inline functions
   and thus needs to be done only after inlining decisions has been made.  */
static bool
cgraph_remove_unreachable_nodes (void)
{
  struct cgraph_node *first = (void *) 1;
  struct cgraph_node *node;
  bool changed = false;
  int insns = 0;

925 926 927
#ifdef ENABLE_CHECKING
  verify_cgraph ();
#endif
928 929 930 931
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "\nReclaiming functions:");
#ifdef ENABLE_CHECKING
  for (node = cgraph_nodes; node; node = node->next)
932
    gcc_assert (!node->aux);
933 934
#endif
  for (node = cgraph_nodes; node; node = node->next)
935 936
    if (node->needed && !node->global.inlined_to
	&& (!DECL_EXTERNAL (node->decl) || !node->analyzed))
937 938 939 940
      {
	node->aux = first;
	first = node;
      }
941 942
    else
      gcc_assert (!node->aux);
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966

  /* Perform reachability analysis.  As a special case do not consider
     extern inline functions not inlined as live because we won't output
     them at all.  */
  while (first != (void *) 1)
    {
      struct cgraph_edge *e;
      node = first;
      first = first->aux;

      for (e = node->callees; e; e = e->next_callee)
	if (!e->callee->aux
	    && node->analyzed
	    && (!e->inline_failed || !e->callee->analyzed
		|| !DECL_EXTERNAL (e->callee->decl)))
	  {
	    e->callee->aux = first;
	    first = e->callee;
	  }
    }

  /* Remove unreachable nodes.  Extern inline functions need special care;
     Unreachable extern inline functions shall be removed.
     Reachable extern inline functions we never inlined shall get their bodies
967
     eliminated.
968 969
     Reachable extern inline functions we sometimes inlined will be turned into
     unanalyzed nodes so they look like for true extern functions to the rest
970
     of code.  Body of such functions is released via remove_node once the
971
     inline clones are eliminated.  */
972 973 974 975 976 977 978
  for (node = cgraph_nodes; node; node = node->next)
    {
      if (!node->aux)
	{
	  int local_insns;
	  tree decl = node->decl;

979
          node->global.inlined_to = NULL;
980
	  if (DECL_STRUCT_FUNCTION (decl))
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
	    local_insns = node->local.self_insns;
	  else
	    local_insns = 0;
	  if (cgraph_dump_file)
	    fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
	  if (!node->analyzed || !DECL_EXTERNAL (node->decl))
	    cgraph_remove_node (node);
	  else
	    {
	      struct cgraph_edge *e;

	      for (e = node->callers; e; e = e->next_caller)
		if (e->caller->aux)
		  break;
	      if (e || node->needed)
		{
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
		  struct cgraph_node *clone;

		  for (clone = node->next_clone; clone;
		       clone = clone->next_clone)
		    if (clone->aux)
		      break;
		  if (!clone)
		    {
		      DECL_SAVED_TREE (node->decl) = NULL;
		      DECL_STRUCT_FUNCTION (node->decl) = NULL;
		      DECL_INITIAL (node->decl) = error_mark_node;
		    }
1009
		  while (node->callees)
1010
		    cgraph_remove_edge (node->callees);
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
		  node->analyzed = false;
		}
	      else
		cgraph_remove_node (node);
	    }
	  if (!DECL_SAVED_TREE (decl))
	    insns += local_insns;
	  changed = true;
	}
    }
  for (node = cgraph_nodes; node; node = node->next)
    node->aux = NULL;
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "\nReclaimed %i insns", insns);
  return changed;
}

1028 1029 1030
/* Estimate size of the function after inlining WHAT into TO.  */

static int
1031
cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
1032 1033
				     struct cgraph_node *what)
{
1034
  return (what->global.insns - INSNS_PER_CALL) * times + to->global.insns;
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
}

/* Estimate the growth caused by inlining NODE into all callees.  */

static int
cgraph_estimate_growth (struct cgraph_node *node)
{
  int growth = 0;
  struct cgraph_edge *e;

  for (e = node->callers; e; e = e->next_caller)
1046
    if (e->inline_failed)
1047 1048
      growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
		 - e->caller->global.insns);
1049 1050 1051 1052

  /* ??? Wrong for self recursive functions or cases where we decide to not
     inline for different reasons, but it is not big deal as in that case
     we will keep the body around, but we will also avoid some inlining.  */
1053
  if (!node->needed && !DECL_EXTERNAL (node->decl))
1054
    growth -= node->global.insns;
1055 1056 1057 1058

  return growth;
}

1059 1060
/* E is expected to be an edge being inlined.  Clone destination node of
   the edge and redirect it to the new clone.
1061
   DUPLICATE is used for bookkeeping on whether we are actually creating new
1062 1063 1064 1065 1066 1067 1068
   clones or re-using node originally representing out-of-line function call.
   */
void
cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate)
{
  struct cgraph_node *n;

1069
  /* We may eliminate the need for out-of-line copy to be output.  In that
1070 1071 1072 1073 1074 1075
     case just go ahead and re-use it.  */
  if (!e->callee->callers->next_caller
      && (!e->callee->needed || DECL_EXTERNAL (e->callee->decl))
      && duplicate
      && flag_unit_at_a_time)
    {
1076
      gcc_assert (!e->callee->global.inlined_to);
1077 1078 1079 1080 1081 1082 1083 1084 1085
      if (!DECL_EXTERNAL (e->callee->decl))
        overall_insns -= e->callee->global.insns, nfunctions_inlined++;
      duplicate = 0;
    }
   else if (duplicate)
    {
      n = cgraph_clone_node (e->callee);
      cgraph_redirect_edge_callee (e, n);
    }
Jan Hubicka committed
1086

1087 1088 1089 1090 1091
  if (e->caller->global.inlined_to)
    e->callee->global.inlined_to = e->caller->global.inlined_to;
  else
    e->callee->global.inlined_to = e->caller;

1092
  /* Recursively clone all bodies.  */
1093 1094 1095 1096 1097 1098 1099 1100 1101
  for (e = e->callee->callees; e; e = e->next_callee)
    if (!e->inline_failed)
      cgraph_clone_inlined_nodes (e, duplicate);
}

/* Mark edge E as inlined and update callgraph accordingly.  */

void
cgraph_mark_inline_edge (struct cgraph_edge *e)
1102
{
1103 1104 1105
  int old_insns = 0, new_insns = 0;
  struct cgraph_node *to = NULL, *what;

1106
  gcc_assert (e->inline_failed);
1107
  e->inline_failed = NULL;
1108

1109
  if (!e->callee->global.inlined && flag_unit_at_a_time)
Zack Weinberg committed
1110
    DECL_POSSIBLY_INLINED (e->callee->decl) = true;
1111 1112 1113
  e->callee->global.inlined = true;

  cgraph_clone_inlined_nodes (e, true);
1114

1115
  what = e->callee;
1116

1117
  /* Now update size of caller and all functions caller is inlined into.  */
1118
  for (;e && !e->inline_failed; e = e->caller->callers)
1119
    {
1120 1121 1122
      old_insns = e->caller->global.insns;
      new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
						       what);
1123
      gcc_assert (new_insns >= 0);
1124 1125
      to = e->caller;
      to->global.insns = new_insns;
1126
    }
1127
  gcc_assert (what->global.inlined_to == to);
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
  overall_insns += new_insns - old_insns;
  ncalls_inlined++;
}

/* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER.
   Return following unredirected edge in the list of callers
   of EDGE->CALLEE  */

static struct cgraph_edge *
cgraph_mark_inline (struct cgraph_edge *edge)
{
  struct cgraph_node *to = edge->caller;
  struct cgraph_node *what = edge->callee;
  struct cgraph_edge *e, *next;
  int times = 0;

1144
  /* Look for all calls, mark them inline and clone recursively
1145 1146
     all inlined functions.  */
  for (e = what->callers; e; e = next)
1147
    {
1148 1149 1150 1151 1152 1153
      next = e->next_caller;
      if (e->caller == to && e->inline_failed)
	{
          cgraph_mark_inline_edge (e);
	  if (e == edge)
	    edge = next;
1154
	  times++;
1155
	}
1156
    }
1157
  gcc_assert (times);
1158
  return edge;
1159 1160
}

1161 1162
/* Return false when inlining WHAT into TO is not good idea
   as it would cause too large growth of function bodies.  */
1163 1164

static bool
1165
cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
1166
			    const char **reason)
Jan Hubicka committed
1167
{
1168 1169 1170 1171 1172
  int times = 0;
  struct cgraph_edge *e;
  int newsize;
  int limit;

1173 1174 1175
  if (to->global.inlined_to)
    to = to->global.inlined_to;

1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
  for (e = to->callees; e; e = e->next_callee)
    if (e->callee == what)
      times++;

  /* When inlining large function body called once into small function,
     take the inlined function as base for limiting the growth.  */
  if (to->local.self_insns > what->local.self_insns)
    limit = to->local.self_insns;
  else
    limit = what->local.self_insns;

  limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;

  newsize = cgraph_estimate_size_after_inlining (times, to, what);
  if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
      && newsize > limit)
1192
    {
1193 1194
      if (reason)
        *reason = N_("--param large-function-growth limit reached");
1195 1196
      return false;
    }
1197 1198 1199
  return true;
}

1200
/* Return true when function N is small enough to be inlined.  */
1201 1202 1203 1204 1205 1206

static bool
cgraph_default_inline_p (struct cgraph_node *n)
{
  if (!DECL_INLINE (n->decl) || !DECL_SAVED_TREE (n->decl))
    return false;
1207
  if (DECL_DECLARED_INLINE_P (n->decl))
1208
    return n->global.insns < MAX_INLINE_INSNS_SINGLE;
1209 1210
  else
    return n->global.insns < MAX_INLINE_INSNS_AUTO;
1211 1212
}

1213 1214
/* Return true when inlining WHAT would create recursive inlining.
   We call recursive inlining all cases where same function appears more than
1215
   once in the single recursion nest path in the inline graph.  */
1216 1217 1218 1219 1220 1221

static bool
cgraph_recursive_inlining_p (struct cgraph_node *to,
			     struct cgraph_node *what,
			     const char **reason)
{
1222 1223 1224 1225 1226
  bool recursive;
  if (to->global.inlined_to)
    recursive = what->decl == to->global.inlined_to->decl;
  else
    recursive = what->decl == to->decl;
1227
  /* Marking recursive function inline has sane semantic and thus we should
1228 1229
     not warn on it.  */
  if (recursive && reason)
1230 1231
    *reason = (what->local.disregard_inline_limits
	       ? N_("recursive inlining") : "");
1232
  return recursive;
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
}

/* Recompute heap nodes for each of callees.  */
static void
update_callee_keys (fibheap_t heap, struct fibnode **heap_node,
		    struct cgraph_node *node)
{
  struct cgraph_edge *e;

  for (e = node->callees; e; e = e->next_callee)
    if (e->inline_failed && heap_node[e->callee->uid])
      fibheap_replace_key (heap, heap_node[e->callee->uid],
			   cgraph_estimate_growth (e->callee));
    else if (!e->inline_failed)
      update_callee_keys (heap, heap_node, e->callee);
}

1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
/* Enqueue all recursive calls from NODE into queue linked via aux pointers
   in between FIRST and LAST.  WHERE is used for bookkeeping while looking
   int calls inlined within NODE.  */
static void
lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
			struct cgraph_edge **first, struct cgraph_edge **last)
{
  struct cgraph_edge *e;
  for (e = where->callees; e; e = e->next_callee)
    if (e->callee == node)
      {
	if (!*first)
	  *first = e;
	else
	  (*last)->aux = e;
	*last = e;
      }
  for (e = where->callees; e; e = e->next_callee)
    if (!e->inline_failed)
      lookup_recursive_calls (node, e->callee, first, last);
}

/* Decide on recursive inlining: in the case function has recursive calls,
   inline until body size reaches given argument.  */
static void
cgraph_decide_recursive_inlining (struct cgraph_node *node)
{
  int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
  int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
  struct cgraph_edge *first_call = NULL, *last_call = NULL;
  struct cgraph_edge *last_in_current_depth;
  struct cgraph_edge *e;
  struct cgraph_node *master_clone;
  int depth = 0;
  int n = 0;

  if (DECL_DECLARED_INLINE_P (node->decl))
    {
      limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
      max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
    }

1292
  /* Make sure that function is small enough to be considered for inlining.  */
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353
  if (!max_depth
      || cgraph_estimate_size_after_inlining (1, node, node)  >= limit)
    return;
  lookup_recursive_calls (node, node, &first_call, &last_call);
  if (!first_call)
    return;

  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, 
	     "\nPerforming recursive inlining on %s\n",
	     cgraph_node_name (node));

  /* We need original clone to copy around.  */
  master_clone = cgraph_clone_node (node);
  master_clone->needed = true;
  for (e = master_clone->callees; e; e = e->next_callee)
    if (!e->inline_failed)
      cgraph_clone_inlined_nodes (e, true);

  /* Do the inlining and update list of recursive call during process.  */
  last_in_current_depth = last_call;
  while (first_call
	 && cgraph_estimate_size_after_inlining (1, node, master_clone) <= limit)
    {
      struct cgraph_edge *curr = first_call;

      first_call = first_call->aux;
      curr->aux = NULL;

      cgraph_redirect_edge_callee (curr, master_clone);
      cgraph_mark_inline_edge (curr);
      lookup_recursive_calls (node, curr->callee, &first_call, &last_call);

      if (last_in_current_depth
	  && ++depth >= max_depth)
	break;
      n++;
    }

  /* Cleanup queue pointers.  */
  while (first_call)
    {
      struct cgraph_edge *next = first_call->aux;
      first_call->aux = NULL;
      first_call = next;
    }
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, 
	     "\n   Inlined %i times, body grown from %i to %i insns\n", n,
	     master_clone->global.insns, node->global.insns);

  /* Remove master clone we used for inlining.  We rely that clones inlined
     into master clone gets queued just before master clone so we don't
     need recursion.  */
  for (node = cgraph_nodes; node != master_clone;
       node = node->next)
    if (node->global.inlined_to == master_clone)
      cgraph_remove_node (node);
  cgraph_remove_node (master_clone);
}

1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
/* Set inline_failed for all callers of given function to REASON.  */

static void
cgraph_set_inline_failed (struct cgraph_node *node, const char *reason)
{
  struct cgraph_edge *e;

  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "Inlining failed: %s\n", reason);
  for (e = node->callers; e; e = e->next_caller)
    if (e->inline_failed)
      e->inline_failed = reason;
}

1368 1369 1370
/* We use greedy algorithm for inlining of small functions:
   All inline candidates are put into prioritized heap based on estimated
   growth of the overall number of instructions and then update the estimates.
1371

1372
   INLINED and INLINED_CALEES are just pointers to arrays large enough
1373 1374 1375
   to be passed to cgraph_inlined_into and cgraph_inlined_callees.  */

static void
1376
cgraph_decide_inlining_of_small_functions (void)
1377
{
Jan Hubicka committed
1378
  struct cgraph_node *node;
1379 1380
  fibheap_t heap = fibheap_new ();
  struct fibnode **heap_node =
1381
    xcalloc (cgraph_max_uid, sizeof (struct fibnode *));
1382 1383
  int max_insns = ((HOST_WIDEST_INT) initial_insns
		   * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
Jan Hubicka committed
1384

1385
  /* Put all inline candidates into the heap.  */
Jan Hubicka committed
1386 1387 1388

  for (node = cgraph_nodes; node; node = node->next)
    {
1389
      if (!node->local.inlinable || !node->callers
1390
	  || node->local.disregard_inline_limits)
1391 1392
	continue;

1393 1394 1395 1396 1397 1398
      if (!cgraph_default_inline_p (node))
	{
	  cgraph_set_inline_failed (node,
	    N_("--param max-inline-insns-single limit reached"));
	  continue;
	}
1399 1400
      heap_node[node->uid] =
	fibheap_insert (heap, cgraph_estimate_growth (node), node);
Jan Hubicka committed
1401
    }
1402

1403
  if (cgraph_dump_file)
1404
    fprintf (cgraph_dump_file, "\nDeciding on smaller functions:\n");
1405
  while (overall_insns <= max_insns && (node = fibheap_extract_min (heap)))
1406
    {
1407
      struct cgraph_edge *e, *next;
1408 1409 1410 1411
      int old_insns = overall_insns;

      heap_node[node->uid] = NULL;
      if (cgraph_dump_file)
1412 1413 1414
	fprintf (cgraph_dump_file, 
		 "\nConsidering %s with %i insns\n"
		 " Estimated growth is %+i insns.\n",
1415 1416 1417 1418
		 cgraph_node_name (node), node->global.insns,
		 cgraph_estimate_growth (node));
      if (!cgraph_default_inline_p (node))
	{
1419 1420
	  cgraph_set_inline_failed (node,
	    N_("--param max-inline-insns-single limit reached after inlining into the callee"));
1421 1422
	  continue;
	}
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
      for (e = node->callers; e; e = next)
	{
	  next = e->next_caller;
	  if (e->inline_failed)
	    {
	      struct cgraph_node *where;

	      if (cgraph_recursive_inlining_p (e->caller, e->callee,
				      	       &e->inline_failed)
		  || !cgraph_check_inline_limits (e->caller, e->callee,
			  			  &e->inline_failed))
		{
		  if (cgraph_dump_file)
		    fprintf (cgraph_dump_file, " Not inlining into %s:%s.\n",
			     cgraph_node_name (e->caller), e->inline_failed);
		  continue;
		}
	      next = cgraph_mark_inline (e);
	      where = e->caller;
	      if (where->global.inlined_to)
		where = where->global.inlined_to;

	      if (heap_node[where->uid])
		fibheap_replace_key (heap, heap_node[where->uid],
				     cgraph_estimate_growth (where));

	      if (cgraph_dump_file)
		fprintf (cgraph_dump_file, 
			 " Inlined into %s which now has %i insns.\n",
			 cgraph_node_name (e->caller),
			 e->caller->global.insns);
	    }
	}
1456

1457 1458
      cgraph_decide_recursive_inlining (node);

1459
      /* Similarly all functions called by the function we just inlined
1460
         are now called more times; update keys.  */
1461
      update_callee_keys (heap, heap_node, node);
1462 1463

      if (cgraph_dump_file)
1464
	fprintf (cgraph_dump_file, 
1465 1466
		 " Inlined for a net change of %+i insns.\n",
		 overall_insns - old_insns);
1467
    }
1468 1469 1470
  while ((node = fibheap_extract_min (heap)) != NULL)
    if (!node->local.disregard_inline_limits)
      cgraph_set_inline_failed (node, N_("--param inline-unit-growth limit reached"));
1471 1472
  fibheap_delete (heap);
  free (heap_node);
Jan Hubicka committed
1473 1474
}

1475
/* Decide on the inlining.  We do so in the topological order to avoid
1476
   expenses on updating data structures.  */
Jan Hubicka committed
1477 1478

static void
1479
cgraph_decide_inlining (void)
Jan Hubicka committed
1480
{
1481 1482 1483
  struct cgraph_node *node;
  int nnodes;
  struct cgraph_node **order =
1484
    xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1485
  int old_insns = 0;
1486
  int i;
Jan Hubicka committed
1487

1488
  for (node = cgraph_nodes; node; node = node->next)
1489
    initial_insns += node->local.self_insns;
1490 1491 1492
  overall_insns = initial_insns;

  nnodes = cgraph_postorder (order);
Jan Hubicka committed
1493

1494 1495 1496 1497 1498
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file,
	     "\nDeciding on inlining.  Starting with %i insns.\n",
	     initial_insns);

Jan Hubicka committed
1499
  for (node = cgraph_nodes; node; node = node->next)
1500 1501 1502
    node->aux = 0;

  if (cgraph_dump_file)
1503
    fprintf (cgraph_dump_file, "\nInlining always_inline functions:\n");
1504 1505

  /* In the first pass mark all always_inline edges.  Do this with a priority
1506
     so none of our later choices will make this impossible.  */
1507 1508
  for (i = nnodes - 1; i >= 0; i--)
    {
1509
      struct cgraph_edge *e, *next;
1510 1511 1512

      node = order[i];

1513
      if (!node->local.disregard_inline_limits)
1514 1515 1516
	continue;
      if (cgraph_dump_file)
	fprintf (cgraph_dump_file,
1517
		 "\nConsidering %s %i insns (always inline)\n",
1518
		 cgraph_node_name (node), node->global.insns);
1519 1520
      old_insns = overall_insns;
      for (e = node->callers; e; e = next)
1521
	{
1522 1523
	  next = e->next_caller;
	  if (!e->inline_failed)
1524
	    continue;
1525
	  if (cgraph_recursive_inlining_p (e->caller, e->callee,
1526 1527
				  	   &e->inline_failed))
	    continue;
1528
	  cgraph_mark_inline_edge (e);
1529
	  if (cgraph_dump_file)
1530 1531
	    fprintf (cgraph_dump_file, 
		     " Inlined into %s which now has %i insns.\n",
1532 1533
		     cgraph_node_name (e->caller),
		     e->caller->global.insns);
1534
	}
1535 1536 1537 1538
      if (cgraph_dump_file)
	fprintf (cgraph_dump_file, 
		 " Inlined for a net change of %+i insns.\n",
		 overall_insns - old_insns);
1539 1540
    }

1541 1542
  if (!flag_really_no_inline)
    {
1543
      cgraph_decide_inlining_of_small_functions ();
1544

1545 1546
      if (cgraph_dump_file)
	fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
1547

1548
      /* And finally decide what functions are called once.  */
1549

1550
      for (i = nnodes - 1; i >= 0; i--)
Jan Hubicka committed
1551
	{
1552 1553 1554
	  node = order[i];

	  if (node->callers && !node->callers->next_caller && !node->needed
1555
	      && node->local.inlinable && node->callers->inline_failed
1556
	      && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
Jan Hubicka committed
1557
	    {
1558 1559 1560 1561 1562
	      bool ok = true;
	      struct cgraph_node *node1;

	      /* Verify that we won't duplicate the caller.  */
	      for (node1 = node->callers->caller;
1563
		   node1->callers && !node1->callers->inline_failed
1564 1565 1566 1567
		   && ok; node1 = node1->callers->caller)
		if (node1->callers->next_caller || node1->needed)
		  ok = false;
	      if (ok)
1568 1569
		{
		  if (cgraph_dump_file)
1570
		    fprintf (cgraph_dump_file,
1571 1572 1573
			     "\nConsidering %s %i insns.\n"
			     " Called once from %s %i insns.\n",
			     cgraph_node_name (node), node->global.insns,
1574
			     cgraph_node_name (node->callers->caller),
1575
			     node->callers->caller->global.insns);
1576

1577
		  old_insns = overall_insns;
1578

1579 1580
		  if (cgraph_check_inline_limits (node->callers->caller, node,
					  	  NULL))
1581
		    {
1582
		      cgraph_mark_inline (node->callers);
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596
		      if (cgraph_dump_file)
			fprintf (cgraph_dump_file,
				 " Inlined into %s which now has %i insns"
				 " for a net change of %+i insns.\n",
				 cgraph_node_name (node->callers->caller),
				 node->callers->caller->global.insns,
				 overall_insns - old_insns);
		    }
		  else
		    {
		      if (cgraph_dump_file)
			fprintf (cgraph_dump_file,
				 " Inline limit reached, not inlined.\n");
		    }
1597
		}
Jan Hubicka committed
1598 1599
	    }
	}
1600
    }
1601 1602 1603 1604

  /* We will never output extern functions we didn't inline. 
     ??? Perhaps we can prevent accounting of growth of external
     inline functions.  */
1605
  cgraph_remove_unreachable_nodes ();
1606 1607 1608 1609 1610 1611 1612 1613

  if (cgraph_dump_file)
    fprintf (cgraph_dump_file,
	     "\nInlined %i calls, eliminated %i functions, "
	     "%i insns turned to %i insns.\n\n",
	     ncalls_inlined, nfunctions_inlined, initial_insns,
	     overall_insns);
  free (order);
Jan Hubicka committed
1614 1615
}

1616
/* Decide on the inlining.  We do so in the topological order to avoid
1617
   expenses on updating data structures.  */
1618 1619 1620 1621 1622 1623 1624 1625

static void
cgraph_decide_inlining_incrementally (struct cgraph_node *node)
{
  struct cgraph_edge *e;

  /* First of all look for always inline functions.  */
  for (e = node->callees; e; e = e->next_callee)
1626 1627 1628
    if (e->callee->local.disregard_inline_limits
	&& e->inline_failed
        && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
1629 1630 1631
	/* ??? It is possible that renaming variable removed the function body
	   in duplicate_decls. See gcc.c-torture/compile/20011119-2.c  */
	&& DECL_SAVED_TREE (e->callee->decl))
1632
      cgraph_mark_inline (e);
1633

1634
  /* Now do the automatic inlining.  */
1635
  if (!flag_really_no_inline)
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
    for (e = node->callees; e; e = e->next_callee)
      if (e->callee->local.inlinable
	  && e->inline_failed
	  && !e->callee->local.disregard_inline_limits
	  && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
	  && cgraph_check_inline_limits (node, e->callee, &e->inline_failed)
	  && DECL_SAVED_TREE (e->callee->decl))
	{
	  if (cgraph_default_inline_p (e->callee))
	    cgraph_mark_inline (e);
	  else
	    e->inline_failed
	      = N_("--param max-inline-insns-single limit reached");
	}
1650 1651 1652
}


1653
/* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
1654 1655

bool
1656
cgraph_inline_p (struct cgraph_edge *e, const char **reason)
1657
{
1658 1659
  *reason = e->inline_failed;
  return !e->inline_failed;
1660
}
1661

1662 1663


1664 1665
/* Expand all functions that must be output.

1666 1667
   Attempt to topologically sort the nodes so function is output when
   all called functions are already assembled to allow data to be
1668
   propagated across the callgraph.  Use a stack to get smaller distance
1669
   between a function and its callees (later we may choose to use a more
1670 1671 1672 1673 1674
   sophisticated algorithm for function reordering; we will likely want
   to use subsections to make the output functions appear in top-down
   order).  */

static void
1675
cgraph_expand_all_functions (void)
1676 1677 1678
{
  struct cgraph_node *node;
  struct cgraph_node **order =
1679
    xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
1680
  int order_pos = 0, new_order_pos = 0;
1681 1682 1683
  int i;

  order_pos = cgraph_postorder (order);
1684
  gcc_assert (order_pos == cgraph_n_nodes);
1685

1686
  /* Garbage collector may remove inline clones we eliminate during
1687 1688 1689 1690 1691 1692
     optimization.  So we must be sure to not reference them.  */
  for (i = 0; i < order_pos; i++)
    if (order[i]->output)
      order[new_order_pos++] = order[i];

  for (i = new_order_pos - 1; i >= 0; i--)
1693 1694 1695 1696
    {
      node = order[i];
      if (node->output)
	{
1697
	  gcc_assert (node->reachable);
1698 1699 1700 1701 1702 1703 1704
	  node->output = 0;
	  cgraph_expand_function (node);
	}
    }
  free (order);
}

1705
/* Mark all local functions.
1706 1707 1708 1709
   
   A local function is one whose calls can occur only in the current
   compilation unit and all its calls are explicit, so we can change
   its calling convention.  We simply mark all static functions whose
1710
   address is not taken as local.  */
1711 1712

static void
1713
cgraph_mark_local_functions (void)
1714 1715 1716 1717 1718 1719 1720 1721 1722 1723
{
  struct cgraph_node *node;

  /* Figure out functions we want to assemble.  */
  for (node = cgraph_nodes; node; node = node->next)
    {
      node->local.local = (!node->needed
		           && DECL_SAVED_TREE (node->decl)
		           && !TREE_PUBLIC (node->decl));
    }
1724

1725
  if (cgraph_dump_file)
1726 1727 1728 1729 1730 1731
    {
      fprintf (cgraph_dump_file, "\nMarking local functions:");
      for (node = cgraph_nodes; node; node = node->next)
	if (node->local.local)
	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
      fprintf (cgraph_dump_file, "\n\n");
1732
    }
1733
}
Jan Hubicka committed
1734

1735 1736 1737 1738 1739 1740 1741
/* Return true when function body of DECL still needs to be kept around
   for later re-use.  */
bool
cgraph_preserve_function_body_p (tree decl)
{
  struct cgraph_node *node;
  /* Keep the body; we're going to dump it.  */
1742
  if (dump_enabled_p (TDI_tree_all))
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
    return true;
  if (!cgraph_global_info_ready)
    return (DECL_INLINE (decl) && !flag_really_no_inline);
  /* Look if there is any clone around.  */
  for (node = cgraph_node (decl); node; node = node->next_clone)
    if (node->global.inlined_to)
      return true;
  return false;
}

1753 1754 1755
/* Perform simple optimizations based on callgraph.  */

void
1756
cgraph_optimize (void)
1757
{
1758 1759 1760
#ifdef ENABLE_CHECKING
  verify_cgraph ();
#endif
1761 1762
  if (!flag_unit_at_a_time)
    return;
1763 1764 1765

  process_pending_assemble_externals ();

1766
  timevar_push (TV_CGRAPHOPT);
1767 1768
  if (!quiet_flag)
    fprintf (stderr, "Performing intraprocedural optimizations\n");
1769

1770
  cgraph_mark_local_functions ();
1771 1772
  if (cgraph_dump_file)
    {
1773
      fprintf (cgraph_dump_file, "Marked ");
1774 1775
      dump_cgraph (cgraph_dump_file);
    }
Jan Hubicka committed
1776

1777 1778
  if (flag_inline_trees)
    cgraph_decide_inlining ();
Jan Hubicka committed
1779
  cgraph_global_info_ready = true;
1780 1781
  if (cgraph_dump_file)
    {
1782
      fprintf (cgraph_dump_file, "Optimized ");
1783 1784 1785
      dump_cgraph (cgraph_dump_file);
    }
  timevar_pop (TV_CGRAPHOPT);
1786

1787
  /* Output everything.  */
1788 1789
  if (!quiet_flag)
    fprintf (stderr, "Assembling functions:\n");
1790 1791 1792
#ifdef ENABLE_CHECKING
  verify_cgraph ();
#endif
1793 1794 1795
  
  cgraph_mark_functions_to_output ();
  
1796
  cgraph_expand_all_functions ();
1797 1798
  if (cgraph_dump_file)
    {
1799
      fprintf (cgraph_dump_file, "\nFinal ");
1800 1801
      dump_cgraph (cgraph_dump_file);
    }
1802 1803
#ifdef ENABLE_CHECKING
  verify_cgraph ();
1804 1805 1806
  /* Double check that all inline clones are gone and that all
     function bodies have been released from memory.  */
  if (flag_unit_at_a_time
1807
      && !dump_enabled_p (TDI_tree_all)
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823
      && !(sorrycount || errorcount))
    {
      struct cgraph_node *node;
      bool error_found = false;

      for (node = cgraph_nodes; node; node = node->next)
	if (node->analyzed
	    && (node->global.inlined_to
	        || DECL_SAVED_TREE (node->decl)))
	  {
	    error_found = true;
	    dump_cgraph_node (stderr, node);
 	  }
      if (error_found)
	internal_error ("Nodes with no released memory found.");
    }
1824
#endif
1825
}
1826 1827 1828 1829 1830 1831

/* Generate and emit a static constructor or destructor.  WHICH must be
   one of 'I' or 'D'.  BODY should be a STATEMENT_LIST containing 
   GENERIC statements.  */

void
Frank Ch. Eigler committed
1832
cgraph_build_static_cdtor (char which, tree body, int priority)
1833 1834 1835
{
  static int counter = 0;
  char which_buf[16];
1836
  tree decl, name, resdecl;
1837 1838 1839 1840 1841 1842 1843 1844

  sprintf (which_buf, "%c_%d", which, counter++);
  name = get_file_function_name_long (which_buf);

  decl = build_decl (FUNCTION_DECL, name,
		     build_function_type (void_type_node, void_list_node));
  current_function_decl = decl;

1845 1846 1847 1848 1849
  resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
  DECL_ARTIFICIAL (resdecl) = 1;
  DECL_IGNORED_P (resdecl) = 1;
  DECL_RESULT (decl) = resdecl;

1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866
  allocate_struct_function (decl);

  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
  DECL_SAVED_TREE (decl) = body;
  TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
  DECL_UNINLINABLE (decl) = 1;

  DECL_INITIAL (decl) = make_node (BLOCK);
  TREE_USED (DECL_INITIAL (decl)) = 1;

  DECL_SOURCE_LOCATION (decl) = input_location;
  cfun->function_end_locus = input_location;

1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877
  switch (which)
    {
    case 'I':
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
      break;
    case 'D':
      DECL_STATIC_DESTRUCTOR (decl) = 1;
      break;
    default:
      gcc_unreachable ();
    }
1878 1879 1880 1881 1882

  gimplify_function_tree (decl);

  /* ??? We will get called LATE in the compilation process.  */
  if (cgraph_global_info_ready)
1883
    tree_rest_of_compilation (decl);
1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894
  else
    cgraph_finalize_function (decl, 0);
  
  if (targetm.have_ctors_dtors)
    {
      void (*fn) (rtx, int);

      if (which == 'I')
	fn = targetm.asm_out.constructor;
      else
	fn = targetm.asm_out.destructor;
Frank Ch. Eigler committed
1895
      fn (XEXP (DECL_RTL (decl), 0), priority);
1896 1897
    }
}
1898 1899 1900 1901 1902 1903

void
init_cgraph (void)
{
  cgraph_dump_file = dump_begin (TDI_cgraph, NULL);
}