cgraph.c 16.9 KB
Newer Older
1
/* Callgraph handling code.
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 22 23 24 25 26 27 28 29 30 31 32 33
   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.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "langhooks.h"
#include "hashtab.h"
#include "toplev.h"
#include "flags.h"
#include "ggc.h"
#include "debug.h"
#include "target.h"
34
#include "cgraph.h"
35
#include "varray.h"
36
#include "output.h"
37
#include "intl.h"
38

39 40

/* Hash table used to convert declarations into nodes.  */
41
static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
42 43

/* The linked list of cgraph nodes.  */
44
struct cgraph_node *cgraph_nodes;
45

46 47 48
/* Queue of cgraph nodes scheduled to be lowered.  */
struct cgraph_node *cgraph_nodes_queue;

49
/* Number of nodes in existence.  */
50
int cgraph_n_nodes;
51

52 53 54
/* Maximal uid used in cgraph nodes.  */
int cgraph_max_uid;

Jan Hubicka committed
55 56 57
/* Set when whole unit has been analyzed so we can access global info.  */
bool cgraph_global_info_ready = false;

58
/* Hash table used to convert declarations into nodes.  */
59
static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
60 61 62 63 64 65 66

/* Queue of cgraph nodes scheduled to be lowered and output.  */
struct cgraph_varpool_node *cgraph_varpool_nodes_queue;

/* Number of nodes in existence.  */
int cgraph_varpool_n_nodes;

67 68 69
/* The linked list of cgraph varpool nodes.  */
static GTY(())  struct cgraph_varpool_node *cgraph_varpool_nodes;

70 71 72 73
static struct cgraph_edge *create_edge (struct cgraph_node *,
					struct cgraph_node *);
static hashval_t hash_node (const void *);
static int eq_node (const void *, const void *);
74 75 76 77

/* Returns a hash code for P.  */

static hashval_t
78
hash_node (const void *p)
79
{
80 81 82
  return ((hashval_t)
	  IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
				 (((struct cgraph_node *) p)->decl)));
83 84
}

85
/* Returns nonzero if P1 and P2 are equal.  */
86 87

static int
88
eq_node (const void *p1, const void *p2)
89 90
{
  return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
91
	  (tree) p2);
92 93 94
}

/* Return cgraph node assigned to DECL.  Create new one when needed.  */
95
struct cgraph_node *
96
cgraph_node (tree decl)
97 98 99 100
{
  struct cgraph_node *node;
  struct cgraph_node **slot;

101 102 103
  if (TREE_CODE (decl) != FUNCTION_DECL)
    abort ();

104
  if (!cgraph_hash)
105
    cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
106

107 108 109
  slot = (struct cgraph_node **)
    htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
			      IDENTIFIER_HASH_VALUE
110
			        (DECL_ASSEMBLER_NAME (decl)), INSERT);
111 112
  if (*slot)
    return *slot;
113
  node = ggc_alloc_cleared (sizeof (*node));
114 115
  node->decl = decl;
  node->next = cgraph_nodes;
116
  node->uid = cgraph_max_uid++;
Jan Hubicka committed
117 118 119
  if (cgraph_nodes)
    cgraph_nodes->previous = node;
  node->previous = NULL;
120 121 122
  cgraph_nodes = node;
  cgraph_n_nodes++;
  *slot = node;
123
  if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
124 125 126 127 128 129 130 131
    {
      node->origin = cgraph_node (DECL_CONTEXT (decl));
      node->next_nested = node->origin->nested;
      node->origin->nested = node;
    }
  return node;
}

132 133
/* Try to find existing function for identifier ID.  */
struct cgraph_node *
134
cgraph_node_for_identifier (tree id)
135 136 137 138 139 140 141
{
  struct cgraph_node **slot;

  if (TREE_CODE (id) != IDENTIFIER_NODE)
    abort ();

  if (!cgraph_hash)
142
    return NULL;
143

144 145
  slot = (struct cgraph_node **)
    htab_find_slot_with_hash (cgraph_hash, id,
146
			      IDENTIFIER_HASH_VALUE (id), NO_INSERT);
147 148 149 150 151
  if (!slot)
    return NULL;
  return *slot;
}

152 153 154
/* Create edge from CALLER to CALLEE in the cgraph.  */

static struct cgraph_edge *
155
create_edge (struct cgraph_node *caller, struct cgraph_node *callee)
156
{
157
  struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
158 159
  struct cgraph_edge *edge2;

160 161
  if (!DECL_SAVED_TREE (callee->decl))
    edge->inline_failed = N_("function body not available");
162 163 164
  else if (callee->local.redefined_extern_inline)
    edge->inline_failed = N_("redefined extern inline functions are not "
			     "considered for inlining");
165 166 167 168 169
  else if (callee->local.inlinable)
    edge->inline_failed = N_("function not considered for inlining");
  else
    edge->inline_failed = N_("function not inlinable");

170 171 172 173
  /* At the moment we don't associate calls with specific CALL_EXPRs
     as we probably ought to, so we must preserve inline_call flags to
     be the same in all copies of the same edge.  */
  if (cgraph_global_info_ready)
174
    for (edge2 = caller->callees; edge2; edge2 = edge2->next_callee)
175 176
      if (edge2->callee == callee)
	{
177
	  edge->inline_failed = edge2->inline_failed;
178 179
	  break;
	}
180 181 182 183 184 185 186 187 188 189 190 191

  edge->caller = caller;
  edge->callee = callee;
  edge->next_caller = callee->callers;
  edge->next_callee = caller->callees;
  caller->callees = edge;
  callee->callers = edge;
  return edge;
}

/* Remove the edge from CALLER to CALLEE in the cgraph.  */

192
void
193
cgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee)
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
{
  struct cgraph_edge **edge, **edge2;

  for (edge = &callee->callers; *edge && (*edge)->caller != caller;
       edge = &((*edge)->next_caller))
    continue;
  if (!*edge)
    abort ();
  *edge = (*edge)->next_caller;
  for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee;
       edge2 = &(*edge2)->next_callee)
    continue;
  if (!*edge2)
    abort ();
  *edge2 = (*edge2)->next_callee;
}

Jan Hubicka committed
211 212 213
/* Remove the node from cgraph.  */

void
214
cgraph_remove_node (struct cgraph_node *node)
Jan Hubicka committed
215
{
216
  void **slot;
Jan Hubicka committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
  while (node->callers)
    cgraph_remove_edge (node->callers->caller, node);
  while (node->callees)
    cgraph_remove_edge (node, node->callees->callee);
  while (node->nested)
    cgraph_remove_node (node->nested);
  if (node->origin)
    {
      struct cgraph_node **node2 = &node->origin->nested;

      while (*node2 != node)
	node2 = &(*node2)->next_nested;
      *node2 = node->next_nested;
    }
  if (node->previous)
    node->previous->next = node->next;
  else
234
    cgraph_nodes = node->next;
Jan Hubicka committed
235 236 237
  if (node->next)
    node->next->previous = node->previous;
  DECL_SAVED_TREE (node->decl) = NULL;
238 239 240
  DECL_SAVED_INSNS (node->decl) = NULL;
  DECL_ARGUMENTS (node->decl) = NULL;
  DECL_INITIAL (node->decl) = error_mark_node;
241 242 243
  slot = 
    htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl),
			      IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
244
						     (node->decl)), NO_INSERT);
245
  htab_clear_slot (cgraph_hash, slot);
Jan Hubicka committed
246 247 248
  /* Do not free the structure itself so the walk over chain can continue.  */
}

249 250
/* Notify finalize_compilation_unit that given node is reachable.  */

251
void
252
cgraph_mark_reachable_node (struct cgraph_node *node)
253
{
254
  if (!node->reachable && node->local.finalized)
255
    {
256
      notice_global_symbol (node->decl);
257
      node->reachable = 1;
258 259 260 261 262 263

      node->next_needed = cgraph_nodes_queue;
      cgraph_nodes_queue = node;

      /* At the moment frontend automatically emits all nested functions.  */
      if (node->nested)
264
	{
265 266 267 268
	  struct cgraph_node *node2;

	  for (node2 = node->nested; node2; node2 = node2->next_nested)
	    if (!node2->reachable)
269
	      cgraph_mark_reachable_node (node2);
270
	}
271 272 273
    }
}

274 275 276 277 278 279 280 281 282
/* Likewise indicate that a node is needed, i.e. reachable via some
   external means.  */

void
cgraph_mark_needed_node (struct cgraph_node *node)
{
  node->needed = 1;
  cgraph_mark_reachable_node (node);
}
Jan Hubicka committed
283

284
/* Record call from CALLER to CALLEE.  */
285

286
struct cgraph_edge *
287
cgraph_record_call (tree caller, tree callee)
288 289 290 291 292
{
  return create_edge (cgraph_node (caller), cgraph_node (callee));
}

void
293
cgraph_remove_call (tree caller, tree callee)
294
{
Jan Hubicka committed
295
  cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
296 297 298 299 300
}

/* Return true when CALLER_DECL calls CALLEE_DECL.  */

bool
301
cgraph_calls_p (tree caller_decl, tree callee_decl)
302 303 304 305 306 307 308 309 310 311 312
{
  struct cgraph_node *caller = cgraph_node (caller_decl);
  struct cgraph_node *callee = cgraph_node (callee_decl);
  struct cgraph_edge *edge;

  for (edge = callee->callers; edge && (edge)->caller != caller;
       edge = (edge->next_caller))
    continue;
  return edge != NULL;
}

Jan Hubicka committed
313 314 315
/* Return local info for the compiled function.  */

struct cgraph_local_info *
316
cgraph_local_info (tree decl)
Jan Hubicka committed
317 318 319 320 321 322 323 324 325 326 327
{
  struct cgraph_node *node;
  if (TREE_CODE (decl) != FUNCTION_DECL)
    abort ();
  node = cgraph_node (decl);
  return &node->local;
}

/* Return local info for the compiled function.  */

struct cgraph_global_info *
328
cgraph_global_info (tree decl)
Jan Hubicka committed
329 330 331 332 333 334 335 336
{
  struct cgraph_node *node;
  if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready)
    abort ();
  node = cgraph_node (decl);
  return &node->global;
}

337 338 339
/* Return local info for the compiled function.  */

struct cgraph_rtl_info *
340
cgraph_rtl_info (tree decl)
341 342 343 344 345 346 347 348 349 350 351
{
  struct cgraph_node *node;
  if (TREE_CODE (decl) != FUNCTION_DECL)
    abort ();
  node = cgraph_node (decl);
  if (decl != current_function_decl
      && !TREE_ASM_WRITTEN (node->decl))
    return NULL;
  return &node->rtl;
}

352 353
/* Return name of the node used in debug output.  */
const char *
354
cgraph_node_name (struct cgraph_node *node)
355 356 357
{
  return (*lang_hooks.decl_printable_name) (node->decl, 2);
}
Jan Hubicka committed
358

359 360 361
/* Dump the callgraph.  */

void
362
dump_cgraph (FILE *f)
363 364 365
{
  struct cgraph_node *node;

366
  fprintf (f, "callgraph:\n\n");
367 368 369
  for (node = cgraph_nodes; node; node = node->next)
    {
      struct cgraph_edge *edge;
370
      fprintf (f, "%s:", cgraph_node_name (node));
371 372
      if (node->local.self_insns)
        fprintf (f, " %i insns", node->local.self_insns);
373 374
      if (node->global.insns && node->global.insns != node->local.self_insns)
	fprintf (f, " (%i after inlining)", node->global.insns);
375
      if (node->origin)
376
	fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
377 378 379 380 381 382 383
      if (node->needed)
	fprintf (f, " needed");
      else if (node->reachable)
	fprintf (f, " reachable");
      if (DECL_SAVED_TREE (node->decl))
	fprintf (f, " tree");

384 385
      if (node->local.local)
	fprintf (f, " local");
386
      if (node->local.disregard_inline_limits)
387 388 389 390 391 392
	fprintf (f, " always_inline");
      else if (node->local.inlinable)
	fprintf (f, " inlinable");
      if (node->global.cloned_times > 1)
	fprintf (f, " cloned %ix", node->global.cloned_times);

393
      fprintf (f, "\n  called by: ");
394
      for (edge = node->callers; edge; edge = edge->next_caller)
395 396
	{
	  fprintf (f, "%s ", cgraph_node_name (edge->caller));
397
	  if (!edge->inline_failed)
398 399
	    fprintf(f, "(inlined) ");
	}
400 401 402

      fprintf (f, "\n  calls: ");
      for (edge = node->callees; edge; edge = edge->next_callee)
403 404
	{
	  fprintf (f, "%s ", cgraph_node_name (edge->callee));
405
	  if (!edge->inline_failed)
406 407
	    fprintf(f, "(inlined) ");
	}
408 409 410
      fprintf (f, "\n");
    }
}
411

412 413 414
/* Returns a hash code for P.  */

static hashval_t
415
cgraph_varpool_hash_node (const void *p)
416
{
417 418 419
  return ((hashval_t)
	  IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
				 (((struct cgraph_varpool_node *) p)->decl)));
420 421
}

422
/* Returns nonzero if P1 and P2 are equal.  */
423 424

static int
425
eq_cgraph_varpool_node (const void *p1, const void *p2)
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
{
  return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) ==
	  (tree) p2);
}

/* Return cgraph_varpool node assigned to DECL.  Create new one when needed.  */
struct cgraph_varpool_node *
cgraph_varpool_node (tree decl)
{
  struct cgraph_varpool_node *node;
  struct cgraph_varpool_node **slot;

  if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
    abort ();

  if (!cgraph_varpool_hash)
442 443 444 445 446
    cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node,
				           eq_cgraph_varpool_node, NULL);
  slot = (struct cgraph_varpool_node **)
    htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
			      IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
447
			      INSERT);
448 449
  if (*slot)
    return *slot;
450
  node = ggc_alloc_cleared (sizeof (*node));
451 452
  node->decl = decl;
  cgraph_varpool_n_nodes++;
453
  cgraph_varpool_nodes = node;
454 455 456 457
  *slot = node;
  return node;
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables.  */
void
change_decl_assembler_name (tree decl, tree name)
{
  struct cgraph_node *node = NULL;
  struct cgraph_varpool_node *vnode = NULL;
  void **slot;

  if (!DECL_ASSEMBLER_NAME_SET_P (decl))
    {
      SET_DECL_ASSEMBLER_NAME (decl, name);
      return;
    }
  if (name == DECL_ASSEMBLER_NAME (decl))
    return;

474 475
  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
      && DECL_RTL_SET_P (decl))
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 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 532 533 534 535 536
    warning ("%D renamed after being referenced in assembly", decl);

  if (TREE_CODE (decl) == FUNCTION_DECL && cgraph_hash)
    {
      /* Take a look whether declaration is in the cgraph structure.  */
      slot = 
	htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
				   IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
							  (decl)), NO_INSERT);
      if (slot)
	node = *slot;

      /* It is, verify that we are the canonical node for this decl.  */
      if (node && node->decl == decl)
	{
	  node = *slot;
	  htab_clear_slot (cgraph_hash, slot);
      	 }
       else
	 node = NULL;
    }
  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && cgraph_varpool_hash)
    {
      /* Take a look whether declaration is in the cgraph structure.  */
      slot = 
	htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
				   IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
							  (decl)), NO_INSERT);
      if (slot)
	vnode = *slot;

      /* It is, verify that we are the canonical vnode for this decl.  */
      if (vnode && vnode->decl == decl)
	{
	  vnode = *slot;
	  htab_clear_slot (cgraph_varpool_hash, slot);
      	 }
       else
	 vnode = NULL;
    }
  SET_DECL_ASSEMBLER_NAME (decl, name);
  if (node)
    {
      slot = 
	htab_find_slot_with_hash (cgraph_hash, name,
				  IDENTIFIER_HASH_VALUE (name), INSERT);
      if (*slot)
	abort ();
      *slot = node;
    }
  if (vnode)
    {
      slot = 
	htab_find_slot_with_hash (cgraph_varpool_hash, name,
				  IDENTIFIER_HASH_VALUE (name), INSERT);
      if (*slot)
	abort ();
      *slot = vnode;
    }
}

537 538 539 540 541 542 543 544 545 546 547 548
/* Try to find existing function for identifier ID.  */
struct cgraph_varpool_node *
cgraph_varpool_node_for_identifier (tree id)
{
  struct cgraph_varpool_node **slot;

  if (TREE_CODE (id) != IDENTIFIER_NODE)
    abort ();

  if (!cgraph_varpool_hash)
    return NULL;

549 550
  slot = (struct cgraph_varpool_node **)
    htab_find_slot_with_hash (cgraph_varpool_hash, id,
551
			      IDENTIFIER_HASH_VALUE (id), NO_INSERT);
552 553 554 555 556 557 558 559 560 561 562 563
  if (!slot)
    return NULL;
  return *slot;
}

/* Notify finalize_compilation_unit that given node is reachable
   or needed.  */
void
cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
{
  if (!node->needed && node->finalized)
    {
564
      node->next_needed = cgraph_varpool_nodes_queue;
565
      cgraph_varpool_nodes_queue = node;
566
      notice_global_symbol (node->decl);
567 568 569 570 571 572 573 574
    }
  node->needed = 1;
}

void
cgraph_varpool_finalize_decl (tree decl)
{
  struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
575 576 577 578 579 580 581 582
 
  /* The first declaration of a variable that comes through this function
     decides whether it is global (in C, has external linkage)
     or local (in C, has internal linkage).  So do nothing more
     if this function has already run.  */
  if (node->finalized)
    return;
  if (node->needed)
583
    {
584
      node->next_needed = cgraph_varpool_nodes_queue;
585
      cgraph_varpool_nodes_queue = node;
586
      notice_global_symbol (decl);
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
    }
  node->finalized = true;

  if (/* Externally visible variables must be output.  The exception are
	 COMDAT functions that must be output only when they are needed.  */
      (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
      /* Function whose name is output to the assembler file must be produced.
	 It is possible to assemble the name later after finalizing the function
	 and the fact is noticed in assemble_name then.  */
      || (DECL_ASSEMBLER_NAME_SET_P (decl)
	  && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
    {
      cgraph_varpool_mark_needed_node (node);
    }
}

bool
604
cgraph_varpool_assemble_pending_decls (void)
605 606 607 608 609 610 611 612
{
  bool changed = false;

  while (cgraph_varpool_nodes_queue)
    {
      tree decl = cgraph_varpool_nodes_queue->decl;
      struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;

613
      cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
614 615 616 617 618
      if (!TREE_ASM_WRITTEN (decl))
	{
	  assemble_variable (decl, 0, 1, 0);
	  changed = true;
	}
619
      node->next_needed = NULL;
620 621 622 623
    }
  return changed;
}

624 625 626 627 628
/* Return true when the DECL can possibly be inlined.  */
bool
cgraph_function_possibly_inlined_p (tree decl)
{
  if (!cgraph_global_info_ready)
629 630 631
    return (DECL_INLINE (decl)
	    && (!flag_really_no_inline
		|| (*lang_hooks.tree_inlining.disregard_inline_limits) (decl)));
632 633
  return cgraph_node (decl)->global.inlined;
}
634

635
#include "gt-cgraph.h"