passes.c 41.1 KB
Newer Older
Richard Henderson committed
1 2
/* Top level of GCC compilers (cc1, cc1plus, etc.)
   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
   Free Software Foundation, Inc.
Richard Henderson committed
5 6 7 8 9

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
10
Software Foundation; either version 3, or (at your option) any later
Richard Henderson committed
11 12 13 14 15 16 17 18
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
19 20
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
Richard Henderson committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 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

/* This is the top level of cc1/c++.
   It parses command args, opens files, invokes the various passes
   in the proper order, and counts the time used by each.
   Error messages and low-level interface to malloc also handled here.  */

#include "config.h"
#undef FLOAT /* This is for hpux. They should change hpux.  */
#undef FFS  /* Some systems define this in param.h.  */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include <signal.h>

#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif

#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif

#include "line-map.h"
#include "input.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
#include "insn-attr.h"
#include "insn-config.h"
#include "insn-flags.h"
#include "hard-reg-set.h"
#include "recog.h"
#include "output.h"
#include "except.h"
#include "function.h"
#include "toplev.h"
#include "expr.h"
#include "basic-block.h"
#include "intl.h"
#include "ggc.h"
#include "graph.h"
#include "regs.h"
#include "timevar.h"
#include "diagnostic.h"
#include "params.h"
#include "reload.h"
#include "dwarf2asm.h"
#include "integrate.h"
#include "real.h"
#include "debug.h"
#include "target.h"
#include "langhooks.h"
#include "cfglayout.h"
#include "cfgloop.h"
#include "hosthooks.h"
#include "cgraph.h"
#include "opts.h"
#include "coverage.h"
#include "value-prof.h"
81 82
#include "tree-inline.h"
#include "tree-flow.h"
83
#include "tree-pass.h"
84
#include "tree-dump.h"
85
#include "df.h"
86
#include "predict.h"
Richard Henderson committed
87 88 89 90 91

#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
#endif

92
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
Richard Henderson committed
93 94 95 96 97 98 99 100 101 102 103 104
#include "dbxout.h"
#endif

#ifdef SDB_DEBUGGING_INFO
#include "sdbout.h"
#endif

#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"		/* Needed for external data
				   declarations for e.g. AIX 4.x.  */
#endif

105 106
/* This is used for debugging.  It allows the current pass to printed
   from anywhere in compilation.  */
107
struct opt_pass *current_pass;
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131

/* Call from anywhere to find out what pass this is.  Useful for
   printing out debugging information deep inside an service
   routine.  */
void
print_current_pass (FILE *file)
{
  if (current_pass)
    fprintf (file, "current pass = %s (%d)\n", 
	     current_pass->name, current_pass->static_pass_number);
  else
    fprintf (file, "no current pass.\n");
}


/* Call from the debugger to get the current pass name.  */
void
debug_pass (void)
{
  print_current_pass (stderr);
} 



132 133 134
/* Global variables used to communicate with passes.  */
int dump_flags;
bool in_gimple_form;
135
bool first_pass_instance;
Richard Henderson committed
136 137 138 139 140 141


/* This is called from various places for FUNCTION_DECL, VAR_DECL,
   and TYPE_DECL nodes.

   This does nothing for local (non-static) variables, unless the
142 143 144 145
   variable is a register variable with DECL_ASSEMBLER_NAME set.  In
   that case, or if the variable is not an automatic, it sets up the
   RTL and outputs any assembler code (label definition, storage
   allocation and initialization).
Richard Henderson committed
146

147
   DECL is the declaration.  TOP_LEVEL is nonzero
Richard Henderson committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
   if this declaration is not within a function.  */

void
rest_of_decl_compilation (tree decl,
			  int top_level,
			  int at_end)
{
  /* We deferred calling assemble_alias so that we could collect
     other attributes such as visibility.  Emit the alias now.  */
  {
    tree alias;
    alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
    if (alias)
      {
	alias = TREE_VALUE (TREE_VALUE (alias));
	alias = get_identifier (TREE_STRING_POINTER (alias));
	assemble_alias (decl, alias);
      }
  }

168 169
  /* Can't defer this, because it needs to happen before any
     later function definitions are processed.  */
170
  if (DECL_ASSEMBLER_NAME_SET_P (decl) && DECL_REGISTER (decl))
171 172
    make_decl_rtl (decl);

Richard Henderson committed
173 174 175 176 177 178 179 180 181 182
  /* Forward declarations for nested functions are not "external",
     but we need to treat them as if they were.  */
  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
      || TREE_CODE (decl) == FUNCTION_DECL)
    {
      timevar_push (TV_VARCONST);

      /* Don't output anything when a tentative file-scope definition
	 is seen.  But at end of compilation, do output code for them.

183
	 We do output all variables and rely on
Richard Henderson committed
184 185 186 187
	 callgraph code to defer them except for forward declarations
	 (see gcc.c-torture/compile/920624-1.c) */
      if ((at_end
	   || !DECL_DEFER_OUTPUT (decl)
Jan Hubicka committed
188
	   || DECL_INITIAL (decl))
Richard Henderson committed
189 190
	  && !DECL_EXTERNAL (decl))
	{
191
	  if (TREE_CODE (decl) != FUNCTION_DECL)
192
	    varpool_finalize_decl (decl);
Richard Henderson committed
193 194 195 196 197 198 199 200 201 202 203 204 205 206
	  else
	    assemble_variable (decl, top_level, at_end, 0);
	}

#ifdef ASM_FINISH_DECLARE_OBJECT
      if (decl == last_assemble_variable_decl)
	{
	  ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
				     top_level, at_end);
	}
#endif

      timevar_pop (TV_VARCONST);
    }
207 208 209 210
  else if (TREE_CODE (decl) == TYPE_DECL
	   /* Like in rest_of_type_compilation, avoid confusing the debug
	      information machinery when there are errors.  */
	   && !(sorrycount || errorcount))
Richard Henderson committed
211 212 213 214 215
    {
      timevar_push (TV_SYMOUT);
      debug_hooks->type_decl (decl, !top_level);
      timevar_pop (TV_SYMOUT);
    }
216

217
  /* Let cgraph know about the existence of variables.  */
218
  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
219
    varpool_node (decl);
Richard Henderson committed
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
}

/* Called after finishing a record, union or enumeral type.  */

void
rest_of_type_compilation (tree type, int toplev)
{
  /* Avoid confusing the debug information machinery when there are
     errors.  */
  if (errorcount != 0 || sorrycount != 0)
    return;

  timevar_push (TV_SYMOUT);
  debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev);
  timevar_pop (TV_SYMOUT);
}

237

Richard Henderson committed
238

239 240
void
finish_optimization_passes (void)
Richard Henderson committed
241
{
242
  int i;
243 244
  struct dump_file_info *dfi;
  char *name;
Richard Henderson committed
245

246 247
  timevar_push (TV_DUMP);
  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
Richard Henderson committed
248
    {
249
      dump_file = dump_begin (pass_profile.pass.static_pass_number, NULL);
250 251
      end_branch_prob ();
      if (dump_file)
252
	dump_end (pass_profile.pass.static_pass_number, dump_file);
Richard Henderson committed
253 254
    }

255
  if (optimize > 0)
Richard Henderson committed
256
    {
257
      dump_file = dump_begin (pass_combine.pass.static_pass_number, NULL);
258
      if (dump_file)
Richard Henderson committed
259
	{
260
	  dump_combine_total_stats (dump_file);
261
          dump_end (pass_combine.pass.static_pass_number, dump_file);
Richard Henderson committed
262 263 264
	}
    }

265 266 267 268
  /* Do whatever is necessary to finish printing the graphs.  */
  if (graph_dump_format != no_graph)
    for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
      if (dump_initialized_p (i)
269
	  && (dfi->flags & TDF_GRAPH) != 0
270
	  && (name = get_dump_file_name (i)) != NULL)
271 272 273 274
	{
	  finish_graph_dump_file (name);
	  free (name);
	}
Richard Henderson committed
275

276
  timevar_pop (TV_DUMP);
Richard Henderson committed
277 278
}

279 280
static bool
gate_rest_of_compilation (void)
Richard Henderson committed
281
{
282 283 284
  /* Early return if there were errors.  We can run afoul of our
     consistency checks, and there's not really much point in fixing them.  */
  return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount);
Richard Henderson committed
285 286
}

287
struct gimple_opt_pass pass_rest_of_compilation =
Richard Henderson committed
288
{
289 290
 {
  GIMPLE_PASS,
291
  "*rest_of_compilation",               /* name */
292 293 294 295 296 297 298 299 300 301
  gate_rest_of_compilation,             /* gate */
  NULL,                                 /* execute */
  NULL,                                 /* sub */
  NULL,                                 /* next */
  0,                                    /* static_pass_number */
  TV_REST_OF_COMPILATION,               /* tv_id */
  PROP_rtl,                             /* properties_required */
  0,                                    /* properties_provided */
  0,                                    /* properties_destroyed */
  0,                                    /* todo_flags_start */
302 303
  TODO_ggc_collect                      /* todo_flags_finish */
 }
304
};
Richard Henderson committed
305

306 307 308 309
static bool
gate_postreload (void)
{
  return reload_completed;
Richard Henderson committed
310 311
}

312
struct rtl_opt_pass pass_postreload =
Richard Henderson committed
313
{
314 315
 {
  RTL_PASS,
316 317 318 319 320 321
  NULL,                                 /* name */
  gate_postreload,                      /* gate */
  NULL,                                 /* execute */
  NULL,                                 /* sub */
  NULL,                                 /* next */
  0,                                    /* static_pass_number */
322
  TV_NONE,                              /* tv_id */
323 324 325 326
  PROP_rtl,                             /* properties_required */
  0,                                    /* properties_provided */
  0,                                    /* properties_destroyed */
  0,                                    /* todo_flags_start */
327 328
  TODO_ggc_collect | TODO_verify_rtl_sharing /* todo_flags_finish */
 }
329
};
Richard Henderson committed
330

331

Richard Henderson committed
332

333
/* The root of the compilation pass tree, once constructed.  */
334
struct opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
Richard Henderson committed
335

336 337 338 339 340 341 342 343 344 345 346 347 348
/* A map from static pass id to optimization pass.  */
struct opt_pass **passes_by_id;
int passes_by_id_size;

/* Set the static pass number of pass PASS to ID and record that
   in the mapping from static pass number to pass.  */

static void
set_pass_for_id (int id, struct opt_pass *pass)
{
  pass->static_pass_number = id;
  if (passes_by_id_size <= id)
    {
349
      passes_by_id = XRESIZEVEC (struct opt_pass *, passes_by_id, id + 1);
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
      memset (passes_by_id + passes_by_id_size, 0,
	      (id + 1 - passes_by_id_size) * sizeof (void *));
      passes_by_id_size = id + 1;
    }
  passes_by_id[id] = pass;
}

/* Return the pass with the static pass number ID.  */

struct opt_pass *
get_pass_for_id (int id)
{
  if (id >= passes_by_id_size)
    return NULL;
  return passes_by_id[id];
}

367 368 369
/* Iterate over the pass tree allocating dump file numbers.  We want
   to do this depth first, and independent of whether the pass is
   enabled or not.  */
Richard Henderson committed
370

Diego Novillo committed
371
void
372
register_one_dump_file (struct opt_pass *pass)
373 374
{
  char *dot_name, *flag_name, *glob_name;
375
  const char *prefix;
376
  char num[10];
377
  int flags, id;
Richard Henderson committed
378

379 380 381 382 383
  /* See below in next_pass_1.  */
  num[0] = '\0';
  if (pass->static_pass_number != -1)
    sprintf (num, "%d", ((int) pass->static_pass_number < 0
			 ? 1 : pass->static_pass_number));
Richard Henderson committed
384

385
  dot_name = concat (".", pass->name, num, NULL);
386
  if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
387
    prefix = "ipa-", flags = TDF_IPA;
388
  else if (pass->type == GIMPLE_PASS)
389
    prefix = "tree-", flags = TDF_TREE;
Richard Henderson committed
390
  else
391 392 393 394
    prefix = "rtl-", flags = TDF_RTL;

  flag_name = concat (prefix, pass->name, num, NULL);
  glob_name = concat (prefix, pass->name, NULL);
395 396
  id = dump_register (dot_name, flag_name, glob_name, flags);
  set_pass_for_id (id, pass);
397 398
}

399 400
/* Recursive worker function for register_dump_files.  */

401
static int 
402
register_dump_files_1 (struct opt_pass *pass, int properties)
403
{
404 405
  do
    {
406 407
      int new_properties = (properties | pass->properties_provided)
			   & ~pass->properties_destroyed;
Richard Henderson committed
408

409
      if (pass->name && pass->name[0] != '*')
410
        register_one_dump_file (pass);
Richard Henderson committed
411

412
      if (pass->sub)
413
        new_properties = register_dump_files_1 (pass->sub, new_properties);
Richard Henderson committed
414

415 416 417 418 419 420
      /* If we have a gate, combine the properties that we could have with
         and without the pass being examined.  */
      if (pass->gate)
        properties &= new_properties;
      else
        properties = new_properties;
Richard Henderson committed
421

422
      pass = pass->next;
Richard Henderson committed
423
    }
424
  while (pass);
Richard Henderson committed
425

426
  return properties;
Richard Henderson committed
427
}
428

429 430 431
/* Register the dump files for the pipeline starting at PASS. 
   PROPERTIES reflects the properties that are guaranteed to be available at
   the beginning of the pipeline.  */
432 433

static void 
434
register_dump_files (struct opt_pass *pass,int properties)
435 436
{
  pass->properties_required |= properties;
437
  register_dump_files_1 (pass, properties);
438 439
}

440 441
/* Add a pass to the pass list. Duplicate the pass if it's already
   in the list.  */
442

443 444
static struct opt_pass **
next_pass_1 (struct opt_pass **list, struct opt_pass *pass)
Richard Henderson committed
445
{
446 447 448 449
  /* A nonzero static_pass_number indicates that the
     pass is already in the list.  */
  if (pass->static_pass_number)
    {
450
      struct opt_pass *new_pass;
Richard Henderson committed
451

452 453 454
      new_pass = XNEW (struct opt_pass);
      memcpy (new_pass, pass, sizeof (*new_pass));
      new_pass->next = NULL;
Richard Henderson committed
455

456
      new_pass->todo_flags_start &= ~TODO_mark_first_instance;
457

458 459 460 461 462 463 464
      /* Indicate to register_dump_files that this pass has duplicates,
         and so it should rename the dump file.  The first instance will
         be -1, and be number of duplicates = -static_pass_number - 1.
         Subsequent instances will be > 0 and just the duplicate number.  */
      if (pass->name)
        {
          pass->static_pass_number -= 1;
465
          new_pass->static_pass_number = -pass->static_pass_number;
466 467
	}
      
468
      *list = new_pass;
469 470 471
    }
  else
    {
472
      pass->todo_flags_start |= TODO_mark_first_instance;
473 474 475 476 477 478
      pass->static_pass_number = -1;
      *list = pass;
    }  
  
  return &(*list)->next;
          
Richard Henderson committed
479 480
}

481

482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
/* Construct the pass tree.  The sequencing of passes is driven by
   the cgraph routines:

   cgraph_finalize_compilation_unit ()
       for each node N in the cgraph
	   cgraph_analyze_function (N)
	       cgraph_lower_function (N) -> all_lowering_passes

   If we are optimizing, cgraph_optimize is then invoked:

   cgraph_optimize ()
       ipa_passes () 			-> all_ipa_passes
       cgraph_expand_all_functions ()
           for each node N in the cgraph
	       cgraph_expand_function (N)
497
		  tree_rest_of_compilation (DECL (N))  -> all_passes
498
*/
499

500 501 502
void
init_optimization_passes (void)
{
503
  struct opt_pass **p;
504

505
#define NEXT_PASS(PASS)  (p = next_pass_1 (p, &((PASS).pass)))
506

507 508 509 510
 /* All passes needed to lower the function into shape optimizers can
    operate on.  These passes are always run first on the function, but
    backend might produce already lowered functions that are not processed
    by these passes.  */
511
  p = &all_lowering_passes;
512 513
  NEXT_PASS (pass_warn_unused_result);
  NEXT_PASS (pass_diagnose_omp_blocks);
514 515
  NEXT_PASS (pass_remove_useless_stmts);
  NEXT_PASS (pass_mudflap_1);
Diego Novillo committed
516
  NEXT_PASS (pass_lower_omp);
517
  NEXT_PASS (pass_lower_cf);
518
  NEXT_PASS (pass_refactor_eh);
519 520 521 522 523
  NEXT_PASS (pass_lower_eh);
  NEXT_PASS (pass_build_cfg);
  NEXT_PASS (pass_lower_complex_O0);
  NEXT_PASS (pass_lower_vector);
  NEXT_PASS (pass_warn_function_return);
524
  NEXT_PASS (pass_build_cgraph_edges);
525
  NEXT_PASS (pass_inline_parameters);
526 527
  *p = NULL;

528
  /* Interprocedural optimization passes.  */
529 530 531 532
  p = &all_ipa_passes;
  NEXT_PASS (pass_ipa_function_and_variable_visibility);
  NEXT_PASS (pass_ipa_early_inline);
    {
533
      struct opt_pass **p = &pass_ipa_early_inline.pass.sub;
534 535 536 537
      NEXT_PASS (pass_early_inline);
      NEXT_PASS (pass_inline_parameters);
      NEXT_PASS (pass_rebuild_cgraph_edges);
    }
Diego Novillo committed
538
  NEXT_PASS (pass_ipa_free_lang_data);
539 540
  NEXT_PASS (pass_early_local_passes);
    {
541
      struct opt_pass **p = &pass_early_local_passes.pass.sub;
542
      NEXT_PASS (pass_fixup_cfg);
543 544 545 546
      NEXT_PASS (pass_tree_profile);
      NEXT_PASS (pass_cleanup_cfg);
      NEXT_PASS (pass_init_datastructures);
      NEXT_PASS (pass_expand_omp);
547 548 549

      NEXT_PASS (pass_referenced_vars);
      NEXT_PASS (pass_build_ssa);
550
      NEXT_PASS (pass_early_warn_uninitialized);
551 552
      NEXT_PASS (pass_all_early_optimizations);
	{
553
	  struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
554 555
	  NEXT_PASS (pass_rebuild_cgraph_edges);
	  NEXT_PASS (pass_early_inline);
556
	  NEXT_PASS (pass_remove_cgraph_callee_edges);
557 558 559
	  NEXT_PASS (pass_rename_ssa_copies);
	  NEXT_PASS (pass_ccp);
	  NEXT_PASS (pass_forwprop);
560 561 562 563 564
	  /* pass_build_ealias is a dummy pass that ensures that we
	     execute TODO_rebuild_alias at this point.  Re-building
	     alias information also rewrites no longer addressed
	     locals into SSA form if possible.  */
	  NEXT_PASS (pass_build_ealias);
565
	  NEXT_PASS (pass_sra_early);
566 567
	  NEXT_PASS (pass_copy_prop);
	  NEXT_PASS (pass_merge_phi);
568
	  NEXT_PASS (pass_cd_dce);
569
	  NEXT_PASS (pass_early_ipa_sra);
570
	  NEXT_PASS (pass_tail_recursion);
571
	  NEXT_PASS (pass_convert_switch);
572
          NEXT_PASS (pass_cleanup_eh);
573
          NEXT_PASS (pass_profile);
574
          NEXT_PASS (pass_local_pure_const);
575
	}
576
      NEXT_PASS (pass_release_ssa_names);
577
      NEXT_PASS (pass_rebuild_cgraph_edges);
578
      NEXT_PASS (pass_inline_parameters);
579 580
    }
  NEXT_PASS (pass_ipa_increase_alignment);
581
  NEXT_PASS (pass_ipa_matrix_reorg);
582 583 584 585 586 587
  NEXT_PASS (pass_ipa_cp);
  NEXT_PASS (pass_ipa_inline);
  NEXT_PASS (pass_ipa_reference);
  NEXT_PASS (pass_ipa_pure_const); 
  NEXT_PASS (pass_ipa_type_escape);
  NEXT_PASS (pass_ipa_pta);
588
  NEXT_PASS (pass_ipa_struct_reorg);  
589 590
  *p = NULL;

591 592
  /* These passes are run after IPA passes on every function that is being
     output to the assembler file.  */
593
  p = &all_passes;
594
  NEXT_PASS (pass_lower_eh_dispatch);
595
  NEXT_PASS (pass_all_optimizations);
596
    {
597
      struct opt_pass **p = &pass_all_optimizations.pass.sub;
598
      NEXT_PASS (pass_remove_cgraph_callee_edges);
599 600
      /* Initial scalar cleanups before alias computation.
	 They ensure memory accesses are not indirect wherever possible.  */
601
      NEXT_PASS (pass_strip_predict_hints);
602
      NEXT_PASS (pass_update_address_taken);
603
      NEXT_PASS (pass_rename_ssa_copies);
604
      NEXT_PASS (pass_complete_unrolli);
605
      NEXT_PASS (pass_ccp);
606
      NEXT_PASS (pass_forwprop);
607 608 609 610 611 612 613
      NEXT_PASS (pass_call_cdce);
      /* pass_build_alias is a dummy pass that ensures that we
	 execute TODO_rebuild_alias at this point.  Re-building
	 alias information also rewrites no longer addressed
	 locals into SSA form if possible.  */
      NEXT_PASS (pass_build_alias);
      NEXT_PASS (pass_return_slot);
614
      NEXT_PASS (pass_phiprop);
615 616 617 618 619
      NEXT_PASS (pass_fre);
      NEXT_PASS (pass_copy_prop);
      NEXT_PASS (pass_merge_phi);
      NEXT_PASS (pass_vrp);
      NEXT_PASS (pass_dce);
620
      NEXT_PASS (pass_cselim);
621
      NEXT_PASS (pass_tree_ifcombine);
622 623 624 625 626 627 628 629 630 631 632 633 634 635
      NEXT_PASS (pass_phiopt);
      NEXT_PASS (pass_tail_recursion);
      NEXT_PASS (pass_ch);
      NEXT_PASS (pass_stdarg);
      NEXT_PASS (pass_lower_complex);
      NEXT_PASS (pass_sra);
      NEXT_PASS (pass_rename_ssa_copies);
      NEXT_PASS (pass_dominator);
      /* The only const/copy propagation opportunities left after
	 DOM should be due to degenerate PHI nodes.  So rather than
	 run the full propagators, run a specialized pass which
	 only examines PHIs to discover const/copy propagation
	 opportunities.  */
      NEXT_PASS (pass_phi_only_cprop);
636
      NEXT_PASS (pass_dse);
637 638 639 640 641
      NEXT_PASS (pass_reassoc);
      NEXT_PASS (pass_dce);
      NEXT_PASS (pass_forwprop);
      NEXT_PASS (pass_phiopt);
      NEXT_PASS (pass_object_sizes);
642
      NEXT_PASS (pass_ccp);
643
      NEXT_PASS (pass_copy_prop);
644 645
      NEXT_PASS (pass_fold_builtins);
      NEXT_PASS (pass_cse_sincos);
646
      NEXT_PASS (pass_optimize_bswap);
647 648 649 650 651
      NEXT_PASS (pass_split_crit_edges);
      NEXT_PASS (pass_pre);
      NEXT_PASS (pass_sink_code);
      NEXT_PASS (pass_tree_loop);
	{
652
	  struct opt_pass **p = &pass_tree_loop.pass.sub;
653 654
	  NEXT_PASS (pass_tree_loop_init);
	  NEXT_PASS (pass_copy_prop);
655
	  NEXT_PASS (pass_dce_loop);
656 657 658 659
	  NEXT_PASS (pass_lim);
	  NEXT_PASS (pass_tree_unswitch);
	  NEXT_PASS (pass_scev_cprop);
	  NEXT_PASS (pass_record_bounds);
660
	  NEXT_PASS (pass_check_data_deps);
661
	  NEXT_PASS (pass_loop_distribution);
662
	  NEXT_PASS (pass_linear_transform);
663
	  NEXT_PASS (pass_graphite_transforms);
664 665 666 667 668
	    {
	      struct opt_pass **p = &pass_graphite_transforms.pass.sub;
	      NEXT_PASS (pass_dce_loop);
	      NEXT_PASS (pass_lim);
	    }
669 670 671 672
	  NEXT_PASS (pass_iv_canon);
	  NEXT_PASS (pass_if_conversion);
	  NEXT_PASS (pass_vectorize);
	    {
673
	      struct opt_pass **p = &pass_vectorize.pass.sub;
674 675 676
	      NEXT_PASS (pass_lower_vector_ssa);
	      NEXT_PASS (pass_dce_loop);
	    }
677
          NEXT_PASS (pass_predcom);
678
	  NEXT_PASS (pass_complete_unroll);
679
	  NEXT_PASS (pass_slp_vectorize);
680
	  NEXT_PASS (pass_parallelize_loops);
681 682 683 684 685
	  NEXT_PASS (pass_loop_prefetch);
	  NEXT_PASS (pass_iv_optimize);
	  NEXT_PASS (pass_tree_loop_done);
	}
      NEXT_PASS (pass_cse_reciprocals);
686
      NEXT_PASS (pass_convert_to_rsqrt);
687 688 689 690 691 692 693 694 695 696
      NEXT_PASS (pass_reassoc);
      NEXT_PASS (pass_vrp);
      NEXT_PASS (pass_dominator);
      /* The only const/copy propagation opportunities left after
	 DOM should be due to degenerate PHI nodes.  So rather than
	 run the full propagators, run a specialized pass which
	 only examines PHIs to discover const/copy propagation
	 opportunities.  */
      NEXT_PASS (pass_phi_only_cprop);
      NEXT_PASS (pass_cd_dce);
697
      NEXT_PASS (pass_tracer);
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714

      /* FIXME: If DCE is not run before checking for uninitialized uses,
	 we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c).
	 However, this also causes us to misdiagnose cases that should be
	 real warnings (e.g., testsuite/gcc.dg/pr18501.c).
	 
	 To fix the false positives in uninit-5.c, we would have to
	 account for the predicates protecting the set and the use of each
	 variable.  Using a representation like Gated Single Assignment
	 may help.  */
      NEXT_PASS (pass_late_warn_uninitialized);
      NEXT_PASS (pass_dse);
      NEXT_PASS (pass_forwprop);
      NEXT_PASS (pass_phiopt);
      NEXT_PASS (pass_tail_calls);
      NEXT_PASS (pass_rename_ssa_copies);
      NEXT_PASS (pass_uncprop);
715
      NEXT_PASS (pass_local_pure_const);
716
    }
717
  NEXT_PASS (pass_cleanup_eh);
718
  NEXT_PASS (pass_lower_resx);
719
  NEXT_PASS (pass_nrv);
Michael Matz committed
720
  NEXT_PASS (pass_mudflap_2);
721
  NEXT_PASS (pass_cleanup_cfg_post_optimizing);
722
  NEXT_PASS (pass_warn_function_noreturn);
723

724
  NEXT_PASS (pass_expand);
Michael Matz committed
725

726
  NEXT_PASS (pass_rest_of_compilation);
727
    {
728
      struct opt_pass **p = &pass_rest_of_compilation.pass.sub;
729 730 731 732 733 734
      NEXT_PASS (pass_init_function);
      NEXT_PASS (pass_jump);
      NEXT_PASS (pass_rtl_eh);
      NEXT_PASS (pass_initial_value_sets);
      NEXT_PASS (pass_unshare_all_rtl);
      NEXT_PASS (pass_instantiate_virtual_regs);
735
      NEXT_PASS (pass_into_cfg_layout_mode);
736 737
      NEXT_PASS (pass_jump2);
      NEXT_PASS (pass_lower_subreg);
738
      NEXT_PASS (pass_df_initialize_opt);
739 740
      NEXT_PASS (pass_cse);
      NEXT_PASS (pass_rtl_fwprop);
741 742 743 744 745 746
      NEXT_PASS (pass_rtl_cprop);
      NEXT_PASS (pass_rtl_pre);
      NEXT_PASS (pass_rtl_hoist);
      NEXT_PASS (pass_rtl_cprop);
      NEXT_PASS (pass_rtl_store_motion);
      NEXT_PASS (pass_cse_after_global_opts);
747 748 749 750 751 752
      NEXT_PASS (pass_rtl_ifcvt);
      /* Perform loop optimizations.  It might be better to do them a bit
	 sooner, but we want the profile feedback to work more
	 efficiently.  */
      NEXT_PASS (pass_loop2);
	{
753
	  struct opt_pass **p = &pass_loop2.pass.sub;
754 755 756 757 758 759 760 761 762
	  NEXT_PASS (pass_rtl_loop_init);
	  NEXT_PASS (pass_rtl_move_loop_invariants);
	  NEXT_PASS (pass_rtl_unswitch);
	  NEXT_PASS (pass_rtl_unroll_and_peel_loops);
	  NEXT_PASS (pass_rtl_doloop);
	  NEXT_PASS (pass_rtl_loop_done);
	  *p = NULL;
	}
      NEXT_PASS (pass_web);
763
      NEXT_PASS (pass_rtl_cprop);
764
      NEXT_PASS (pass_cse2);
765
      NEXT_PASS (pass_rtl_dse1);
766
      NEXT_PASS (pass_rtl_fwprop_addr);
767
      NEXT_PASS (pass_reginfo_init);
768 769 770
      NEXT_PASS (pass_inc_dec);
      NEXT_PASS (pass_initialize_regs);
      NEXT_PASS (pass_ud_rtl_dce);
771 772 773 774
      NEXT_PASS (pass_combine);
      NEXT_PASS (pass_if_after_combine);
      NEXT_PASS (pass_partition_blocks);
      NEXT_PASS (pass_regmove);
775
      NEXT_PASS (pass_outof_cfg_layout_mode);
776 777
      NEXT_PASS (pass_split_all_insns);
      NEXT_PASS (pass_lower_subreg2);
778 779
      NEXT_PASS (pass_df_initialize_no_opt);
      NEXT_PASS (pass_stack_ptr_mod);
780
      NEXT_PASS (pass_mode_switching);
781
      NEXT_PASS (pass_match_asm_constraints);
782
      NEXT_PASS (pass_sms);
783
      NEXT_PASS (pass_subregs_of_mode_init);
784
      NEXT_PASS (pass_sched);
Vladimir Makarov committed
785
      NEXT_PASS (pass_ira);
786
      NEXT_PASS (pass_subregs_of_mode_finish);
787 788
      NEXT_PASS (pass_postreload);
	{
789
	  struct opt_pass **p = &pass_postreload.pass.sub;
790 791
	  NEXT_PASS (pass_postreload_cse);
	  NEXT_PASS (pass_gcse2);
792 793 794 795
	  NEXT_PASS (pass_split_after_reload);
	  NEXT_PASS (pass_branch_target_load_optimize1);
	  NEXT_PASS (pass_thread_prologue_and_epilogue);
	  NEXT_PASS (pass_rtl_dse2);
796 797 798 799
	  NEXT_PASS (pass_stack_adjustments);
	  NEXT_PASS (pass_peephole2);
	  NEXT_PASS (pass_if_after_reload);
	  NEXT_PASS (pass_regrename);
800 801
	  NEXT_PASS (pass_cprop_hardreg);
	  NEXT_PASS (pass_fast_rtl_dce);
802
	  NEXT_PASS (pass_reorder_blocks);
803
	  NEXT_PASS (pass_branch_target_load_optimize2);
804
	  NEXT_PASS (pass_leaf_regs);
805
	  NEXT_PASS (pass_split_before_sched2);
806 807
	  NEXT_PASS (pass_sched2);
	  NEXT_PASS (pass_stack_regs);
808
	    {
809
	      struct opt_pass **p = &pass_stack_regs.pass.sub;
810 811 812
	      NEXT_PASS (pass_split_before_regstack);
	      NEXT_PASS (pass_stack_regs_run);
	    }
813 814 815 816 817 818 819 820 821 822 823 824 825
	  NEXT_PASS (pass_compute_alignments);
	  NEXT_PASS (pass_duplicate_computed_gotos);
	  NEXT_PASS (pass_variable_tracking);
	  NEXT_PASS (pass_free_cfg);
	  NEXT_PASS (pass_machine_reorg);
	  NEXT_PASS (pass_cleanup_barriers);
	  NEXT_PASS (pass_delay_slots);
	  NEXT_PASS (pass_split_for_shorten_branches);
	  NEXT_PASS (pass_convert_to_eh_region_ranges);
	  NEXT_PASS (pass_shorten_branches);
	  NEXT_PASS (pass_set_nothrow_function_flags);
	  NEXT_PASS (pass_final);
	}
826
      NEXT_PASS (pass_df_finish);
827
    }
828 829 830 831 832 833
  NEXT_PASS (pass_clean_state);
  *p = NULL;

#undef NEXT_PASS

  /* Register the passes with the tree dump code.  */
834 835
  register_dump_files (all_lowering_passes, PROP_gimple_any);
  register_dump_files (all_ipa_passes, 
836 837
		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
		       | PROP_cfg);
838
  register_dump_files (all_passes, 
839 840
		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
		       | PROP_cfg);
841 842
}

843 844 845
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
   function CALLBACK for every function in the call graph.  Otherwise,
   call CALLBACK on the current function.  */ 
846

847
static void
848
do_per_function (void (*callback) (void *data), void *data)
849
{
850 851 852 853 854 855
  if (current_function_decl)
    callback (data);
  else
    {
      struct cgraph_node *node;
      for (node = cgraph_nodes; node; node = node->next)
856 857
	if (node->analyzed && gimple_has_body_p (node->decl)
	    && (!node->clone_of || node->decl != node->clone_of->decl))
858 859 860 861 862 863 864 865 866 867 868 869 870
	  {
	    push_cfun (DECL_STRUCT_FUNCTION (node->decl));
	    current_function_decl = node->decl;
	    callback (data);
	    free_dominance_info (CDI_DOMINATORS);
	    free_dominance_info (CDI_POST_DOMINATORS);
	    current_function_decl = NULL;
	    pop_cfun ();
	    ggc_collect ();
	  }
    }
}

871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
/* Because inlining might remove no-longer reachable nodes, we need to
   keep the array visible to garbage collector to avoid reading collected
   out nodes.  */
static int nnodes;
static GTY ((length ("nnodes"))) struct cgraph_node **order;

/* If we are in IPA mode (i.e., current_function_decl is NULL), call
   function CALLBACK for every function in the call graph.  Otherwise,
   call CALLBACK on the current function.  */ 

static void
do_per_function_toporder (void (*callback) (void *data), void *data)
{
  int i;

  if (current_function_decl)
    callback (data);
  else
    {
      gcc_assert (!order);
891
      order = GGC_NEWVEC (struct cgraph_node *, cgraph_n_nodes);
892 893
      nnodes = cgraph_postorder (order);
      for (i = nnodes - 1; i >= 0; i--)
894 895
        order[i]->process = 1;
      for (i = nnodes - 1; i >= 0; i--)
896 897 898 899 900
	{
	  struct cgraph_node *node = order[i];

	  /* Allow possibly removed nodes to be garbage collected.  */
	  order[i] = NULL;
901
	  node->process = 0;
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
	  if (node->analyzed && (node->needed || node->reachable))
	    {
	      push_cfun (DECL_STRUCT_FUNCTION (node->decl));
	      current_function_decl = node->decl;
	      callback (data);
	      free_dominance_info (CDI_DOMINATORS);
	      free_dominance_info (CDI_POST_DOMINATORS);
	      current_function_decl = NULL;
	      pop_cfun ();
	      ggc_collect ();
	    }
	}
    }
  ggc_free (order);
  order = NULL;
  nnodes = 0;
}

920
/* Perform all TODO actions that ought to be done on each function.  */
921

922 923 924 925 926
static void
execute_function_todo (void *data)
{
  unsigned int flags = (size_t)data;
  if (cfun->curr_properties & PROP_ssa)
927
    flags |= TODO_verify_ssa;
928
  flags &= ~cfun->last_verified;
929 930
  if (!flags)
    return;
931 932 933

  statistics_fini_pass ();

934
  /* Always cleanup the CFG before trying to update SSA.  */
935 936
  if (flags & TODO_cleanup_cfg)
    {
937
      bool cleanup = cleanup_tree_cfg ();
938

939 940 941
      if (cleanup && (cfun->curr_properties & PROP_ssa))
	flags |= TODO_remove_unused_locals;
	
942 943 944 945 946 947
      /* When cleanup_tree_cfg merges consecutive blocks, it may
	 perform some simplistic propagation when removing single
	 valued PHI nodes.  This propagation may, in turn, cause the
	 SSA form to become out-of-date (see PR 22037).  So, even
	 if the parent pass had not scheduled an SSA update, we may
	 still need to do one.  */
948
      if (!(flags & TODO_update_ssa_any) && need_ssa_update_p (cfun))
949
	flags |= TODO_update_ssa;
950
    }
Richard Henderson committed
951

952 953 954 955
  if (flags & TODO_update_ssa_any)
    {
      unsigned update_flags = flags & TODO_update_ssa_any;
      update_ssa (update_flags);
956
      cfun->last_verified &= ~TODO_verify_ssa;
957
    }
958
  
959 960 961
  if (flags & TODO_update_address_taken)
    execute_update_addresses_taken (true);

962 963
  if (flags & TODO_rebuild_alias)
    {
964 965
      if (!(flags & TODO_update_address_taken))
	execute_update_addresses_taken (true);
966 967 968
      compute_may_aliases ();
    }
  
969 970 971
  if (flags & TODO_remove_unused_locals)
    remove_unused_locals ();

972
  if ((flags & TODO_dump_func) && dump_file && current_function_decl)
973
    {
974
      if (cfun->curr_properties & PROP_trees)
975
        dump_function_to_file (current_function_decl, dump_file, dump_flags);
976
      else
977
	{
978 979
	  if (dump_flags & TDF_SLIM)
	    print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
980 981
	  else if ((cfun->curr_properties & PROP_cfg)
		   && (dump_flags & TDF_BLOCKS))
982 983 984 985
	    print_rtl_with_bb (dump_file, get_insns ());
          else
	    print_rtl (dump_file, get_insns ());

986
	  if ((cfun->curr_properties & PROP_cfg)
987
	      && graph_dump_format != no_graph
988 989 990
	      && (dump_flags & TDF_GRAPH))
	    print_rtl_graph_with_bb (dump_file_name, get_insns ());
	}
991 992 993 994 995

      /* Flush the file.  If verification fails, we won't be able to
	 close the file before aborting.  */
      fflush (dump_file);
    }
996

997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
  if (flags & TODO_rebuild_frequencies)
    {
      if (profile_status == PROFILE_GUESSED)
	{
	  loop_optimizer_init (0);
	  add_noreturn_fake_exit_edges ();
	  mark_irreducible_loops ();
	  connect_infinite_loops_to_exit ();
	  estimate_bb_frequencies ();
	  remove_fake_exit_edges ();
	  loop_optimizer_finalize ();
	}
      else if (profile_status == PROFILE_READ)
	counts_to_freqs ();
      else
	gcc_unreachable ();
    }

1015 1016 1017 1018 1019 1020 1021 1022 1023
#if defined ENABLE_CHECKING
  if (flags & TODO_verify_ssa)
    verify_ssa (true);
  if (flags & TODO_verify_flow)
    verify_flow_info ();
  if (flags & TODO_verify_stmts)
    verify_stmts ();
  if (flags & TODO_verify_loops)
    verify_loop_closed_ssa ();
1024 1025
  if (flags & TODO_verify_rtl_sharing)
    verify_rtl_sharing ();
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
#endif

  cfun->last_verified = flags & TODO_verify_all;
}

/* Perform all TODO actions.  */
static void
execute_todo (unsigned int flags)
{
#if defined ENABLE_CHECKING
1036 1037
  if (cfun
      && need_ssa_update_p (cfun))
1038 1039 1040
    gcc_assert (flags & TODO_update_ssa_any);
#endif

1041 1042 1043
  /* Inform the pass whether it is the first time it is run.  */
  first_pass_instance = (flags & TODO_mark_first_instance) != 0;

1044 1045
  do_per_function (execute_function_todo, (void *)(size_t) flags);

1046 1047 1048 1049 1050
  /* Always remove functions just as before inlining: IPA passes might be
     interested to see bodies of extern inline functions that are not inlined
     to analyze side effects.  The full removal is done just at the end
     of IPA pass queue.  */
  if (flags & TODO_remove_functions)
1051 1052 1053 1054
    {
      gcc_assert (!cfun);
      cgraph_remove_unreachable_nodes (true, dump_file);
    }
1055

1056
  if ((flags & TODO_dump_cgraph) && dump_file && !current_function_decl)
1057
    {
1058
      gcc_assert (!cfun);
1059 1060 1061 1062 1063
      dump_cgraph (dump_file);
      /* Flush the file.  If verification fails, we won't be able to
	 close the file before aborting.  */
      fflush (dump_file);
    }
Richard Henderson committed
1064

1065
  if (flags & TODO_ggc_collect)
1066
    ggc_collect ();
1067 1068 1069 1070

  /* Now that the dumping has been done, we can get rid of the optional 
     df problems.  */
  if (flags & TODO_df_finish)
1071
    df_finish_pass ((flags & TODO_df_verify) != 0);
1072
}
1073

1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
/* Verify invariants that should hold between passes.  This is a place
   to put simple sanity checks.  */

static void
verify_interpass_invariants (void)
{
#ifdef ENABLE_CHECKING
  gcc_assert (!fold_deferring_overflow_warnings_p ());
#endif
}

1085 1086 1087 1088 1089 1090 1091 1092 1093 1094
/* Clear the last verified flag.  */

static void
clear_last_verified (void *data ATTRIBUTE_UNUSED)
{
  cfun->last_verified = 0;
}

/* Helper function. Verify that the properties has been turn into the
   properties expected by the pass.  */
1095

1096
#ifdef ENABLE_CHECKING
1097 1098 1099 1100 1101 1102
static void
verify_curr_properties (void *data)
{
  unsigned int props = (size_t)data;
  gcc_assert ((cfun->curr_properties & props) == props);
}
1103
#endif
1104

1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
/* Initialize pass dump file.  */

static bool
pass_init_dump_file (struct opt_pass *pass)
{
  /* If a dump file name is present, open it if enabled.  */
  if (pass->static_pass_number != -1)
    {
      bool initializing_dump = !dump_initialized_p (pass->static_pass_number);
      dump_file_name = get_dump_file_name (pass->static_pass_number);
      dump_file = dump_begin (pass->static_pass_number, &dump_flags);
      if (dump_file && current_function_decl)
	{
	  const char *dname, *aname;
	  dname = lang_hooks.decl_printable_name (current_function_decl, 2);
	  aname = (IDENTIFIER_POINTER
		   (DECL_ASSEMBLER_NAME (current_function_decl)));
1122
	  fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
	     cfun->function_frequency == FUNCTION_FREQUENCY_HOT
	     ? " (hot)"
	     : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
	     ? " (unlikely executed)"
	     : "");
	}
      return initializing_dump;
    }
  else
    return false;
}

/* Flush PASS dump file.  */

static void
pass_fini_dump_file (struct opt_pass *pass)
{
  /* Flush and close dump file.  */
  if (dump_file_name)
    {
      free (CONST_CAST (char *, dump_file_name));
      dump_file_name = NULL;
    }

  if (dump_file)
    {
      dump_end (pass->static_pass_number, dump_file);
      dump_file = NULL;
    }
}

1154 1155
/* After executing the pass, apply expected changes to the function
   properties. */
1156

1157 1158 1159
static void
update_properties_after_pass (void *data)
{
1160
  struct opt_pass *pass = (struct opt_pass *) data;
1161 1162
  cfun->curr_properties = (cfun->curr_properties | pass->properties_provided)
		           & ~pass->properties_destroyed;
Richard Henderson committed
1163 1164
}

1165 1166 1167 1168 1169
/* Schedule IPA transform pass DATA for CFUN.  */

static void
add_ipa_transform_pass (void *data)
{
1170
  struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) data;
1171 1172 1173
  VEC_safe_push (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply, ipa_pass);
}

1174
/* Execute summary generation for all of the passes in IPA_PASS.  */
1175 1176

static void
1177
execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
1178
{
1179
  while (ipa_pass)
1180 1181
    {
      struct opt_pass *pass = &ipa_pass->pass;
1182 1183 1184 1185

      /* Execute all of the IPA_PASSes in the list.  */
      if (ipa_pass->pass.type == IPA_PASS 
	  && (!pass->gate || pass->gate ()))
1186 1187
	{
	  pass_init_dump_file (pass);
1188
	  ipa_pass->generate_summary ();
1189 1190
	  pass_fini_dump_file (pass);
	}
1191
      ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->pass.next;
1192 1193 1194 1195 1196 1197 1198
    }
}

/* Execute IPA_PASS function transform on NODE.  */

static void
execute_one_ipa_transform_pass (struct cgraph_node *node,
1199
				struct ipa_opt_pass_d *ipa_pass)
1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
{
  struct opt_pass *pass = &ipa_pass->pass;
  unsigned int todo_after = 0;

  current_pass = pass;
  if (!ipa_pass->function_transform)
    return;

  /* Note that the folders should only create gimple expressions.
     This is a hack until the new folder is ready.  */
  in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;

  pass_init_dump_file (pass);

  /* Run pre-pass verification.  */
1215
  execute_todo (ipa_pass->function_transform_todo_flags_start);
1216 1217

  /* If a timevar is present, start it.  */
1218
  if (pass->tv_id != TV_NONE)
1219 1220 1221 1222 1223 1224
    timevar_push (pass->tv_id);

  /* Do it!  */
  todo_after = ipa_pass->function_transform (node);

  /* Stop timevar.  */
1225
  if (pass->tv_id != TV_NONE)
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
    timevar_pop (pass->tv_id);

  /* Run post-pass cleanup and verification.  */
  execute_todo (todo_after);
  verify_interpass_invariants ();

  pass_fini_dump_file (pass);

  current_pass = NULL;
}

1237
static bool
1238
execute_one_pass (struct opt_pass *pass)
Richard Henderson committed
1239
{
1240
  bool initializing_dump;
1241
  unsigned int todo_after = 0;
1242

1243
  /* IPA passes are executed on whole program, so cfun should be NULL.
1244
     Other passes need function context set.  */
1245
  if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
1246 1247
    gcc_assert (!cfun && !current_function_decl);
  else
1248
    gcc_assert (cfun && current_function_decl);
1249

1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
  if (cfun && cfun->ipa_transforms_to_apply)
    {
      unsigned int i;
      struct cgraph_node *node = cgraph_node (current_function_decl);

      for (i = 0; i < VEC_length (ipa_opt_pass, cfun->ipa_transforms_to_apply);
	   i++)
	execute_one_ipa_transform_pass (node,
				        VEC_index (ipa_opt_pass,
						   cfun->ipa_transforms_to_apply,
						   i));
      VEC_free (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply);
      cfun->ipa_transforms_to_apply = NULL;
    }

1265
  current_pass = pass;
1266

1267 1268 1269
  /* See if we're supposed to run this pass.  */
  if (pass->gate && !pass->gate ())
    return false;
Richard Henderson committed
1270

1271
  if (!quiet_flag && !cfun)
1272 1273
    fprintf (stderr, " <%s>", pass->name ? pass->name : "");

1274 1275
  /* Note that the folders should only create gimple expressions.
     This is a hack until the new folder is ready.  */
1276
  in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
Richard Henderson committed
1277

1278 1279
  initializing_dump = pass_init_dump_file (pass);

1280
  /* Run pre-pass verification.  */
1281 1282
  execute_todo (pass->todo_flags_start);

1283 1284 1285 1286
#ifdef ENABLE_CHECKING
  do_per_function (verify_curr_properties,
		   (void *)(size_t)pass->properties_required);
#endif
Richard Henderson committed
1287

1288
  /* If a timevar is present, start it.  */
1289
  if (pass->tv_id != TV_NONE)
1290
    timevar_push (pass->tv_id);
Richard Henderson committed
1291

1292 1293
  /* Do it!  */
  if (pass->execute)
1294
    {
1295
      todo_after = pass->execute ();
1296
      do_per_function (clear_last_verified, NULL);
1297
    }
Richard Henderson committed
1298

1299
  /* Stop timevar.  */
1300
  if (pass->tv_id != TV_NONE)
1301
    timevar_pop (pass->tv_id);
Richard Henderson committed
1302

1303
  do_per_function (update_properties_after_pass, pass);
1304 1305 1306 1307

  if (initializing_dump
      && dump_file
      && graph_dump_format != no_graph
1308
      && cfun
1309 1310
      && (cfun->curr_properties & (PROP_cfg | PROP_rtl))
	  == (PROP_cfg | PROP_rtl))
1311 1312 1313 1314 1315 1316
    {
      get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH;
      dump_flags |= TDF_GRAPH;
      clean_graph_dump_file (dump_file_name);
    }

1317
  /* Run post-pass cleanup and verification.  */
1318
  execute_todo (todo_after | pass->todo_flags_finish);
1319
  verify_interpass_invariants ();
1320 1321
  if (pass->type == IPA_PASS)
    do_per_function (add_ipa_transform_pass, pass);
Richard Henderson committed
1322

1323 1324 1325
  if (!current_function_decl)
    cgraph_process_new_functions ();

1326
  pass_fini_dump_file (pass);
Richard Henderson committed
1327

1328
  if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS)
1329 1330 1331
    gcc_assert (!(cfun->curr_properties & PROP_trees)
		|| pass->type != RTL_PASS);

1332
  current_pass = NULL;
1333

1334
  return true;
Richard Henderson committed
1335 1336
}

1337
void
1338
execute_pass_list (struct opt_pass *pass)
Richard Henderson committed
1339
{
1340
  do
Richard Henderson committed
1341
    {
1342 1343
      gcc_assert (pass->type == GIMPLE_PASS
		  || pass->type == RTL_PASS);
1344 1345 1346
      if (execute_one_pass (pass) && pass->sub)
        execute_pass_list (pass->sub);
      pass = pass->next;
Richard Henderson committed
1347
    }
1348
  while (pass);
Richard Henderson committed
1349 1350
}

1351 1352 1353
/* Same as execute_pass_list but assume that subpasses of IPA passes
   are local passes.  */
void
1354
execute_ipa_pass_list (struct opt_pass *pass)
Richard Henderson committed
1355
{
1356
  bool summaries_generated = false;
1357
  do
Richard Henderson committed
1358
    {
1359 1360
      gcc_assert (!current_function_decl);
      gcc_assert (!cfun);
1361 1362 1363 1364 1365 1366 1367
      gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
      if (pass->type == IPA_PASS && (!pass->gate || pass->gate ()))
	{
	  if (!summaries_generated)
	    {
	      if (!quiet_flag && !cfun)
		fprintf (stderr, " <summary generate>");
1368
	      execute_ipa_summary_passes ((struct ipa_opt_pass_d *) pass);
1369 1370 1371
	    }
	  summaries_generated = true;
	}
1372
      if (execute_one_pass (pass) && pass->sub)
1373 1374 1375 1376
	{
	  if (pass->sub->type == GIMPLE_PASS)
	    do_per_function_toporder ((void (*)(void *))execute_pass_list,
				      pass->sub);
1377 1378
	  else if (pass->sub->type == SIMPLE_IPA_PASS
		   || pass->sub->type == IPA_PASS)
1379 1380 1381 1382
	    execute_ipa_pass_list (pass->sub);
	  else
	    gcc_unreachable ();
	}
1383 1384
      if (!current_function_decl)
	cgraph_process_new_functions ();
1385
      pass = pass->next;
Richard Henderson committed
1386
    }
1387
  while (pass);
1388
}
1389

1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415
/* Called by local passes to see if function is called by already processed nodes.
   Because we process nodes in topological order, this means that function is
   in recursive cycle or we introduced new direct calls.  */
bool
function_called_by_processed_nodes_p (void)
{
  struct cgraph_edge *e;
  for (e = cgraph_node (current_function_decl)->callers; e; e = e->next_caller)
    {
      if (e->caller->decl == current_function_decl)
        continue;
      if (!e->caller->analyzed || (!e->caller->needed && !e->caller->reachable))
        continue;
      if (TREE_ASM_WRITTEN (e->caller->decl))
        continue;
      if (!e->caller->process && !e->caller->global.inlined_to)
      	break;
    }
  if (dump_file && e)
    {
      fprintf (dump_file, "Already processed call to:\n");
      dump_cgraph_node (dump_file, e->caller);
    }
  return e != NULL;
}

1416
#include "gt-passes.h"