passes.c 39.6 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
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 243 244
  enum tree_dump_index i;
  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 292 293 294 295 296 297 298 299 300 301
  NULL,                                 /* name */
  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 322 323 324 325 326
  NULL,                                 /* name */
  gate_postreload,                      /* gate */
  NULL,                                 /* execute */
  NULL,                                 /* sub */
  NULL,                                 /* next */
  0,                                    /* static_pass_number */
  0,                                    /* tv_id */
  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

371
static 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 512 513
  p = &all_lowering_passes;
  NEXT_PASS (pass_remove_useless_stmts);
  NEXT_PASS (pass_mudflap_1);
Diego Novillo committed
514
  NEXT_PASS (pass_lower_omp);
515
  NEXT_PASS (pass_lower_cf);
516
  NEXT_PASS (pass_refactor_eh);
517 518 519 520 521
  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);
522
  NEXT_PASS (pass_build_cgraph_edges);
523
  NEXT_PASS (pass_inline_parameters);
524 525
  *p = NULL;

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

      NEXT_PASS (pass_referenced_vars);
      NEXT_PASS (pass_reset_cc_flags);
      NEXT_PASS (pass_build_ssa);
547
      NEXT_PASS (pass_early_warn_uninitialized);
548 549
      NEXT_PASS (pass_all_early_optimizations);
	{
550
	  struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
551 552 553 554 555
	  NEXT_PASS (pass_rebuild_cgraph_edges);
	  NEXT_PASS (pass_early_inline);
	  NEXT_PASS (pass_rename_ssa_copies);
	  NEXT_PASS (pass_ccp);
	  NEXT_PASS (pass_forwprop);
556
	  NEXT_PASS (pass_update_address_taken);
557
	  NEXT_PASS (pass_sra_early);
558 559
	  NEXT_PASS (pass_copy_prop);
	  NEXT_PASS (pass_merge_phi);
560
	  NEXT_PASS (pass_cd_dce);
561
	  NEXT_PASS (pass_simple_dse);
562
	  NEXT_PASS (pass_tail_recursion);
563
	  NEXT_PASS (pass_convert_switch);
564
          NEXT_PASS (pass_profile);
565
	}
566
      NEXT_PASS (pass_release_ssa_names);
567
      NEXT_PASS (pass_rebuild_cgraph_edges);
568
      NEXT_PASS (pass_inline_parameters);
569 570
    }
  NEXT_PASS (pass_ipa_increase_alignment);
571
  NEXT_PASS (pass_ipa_matrix_reorg);
572 573 574 575 576 577
  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);
578
  NEXT_PASS (pass_ipa_struct_reorg);  
579 580
  *p = NULL;

581 582
  /* These passes are run after IPA passes on every function that is being
     output to the assembler file.  */
583 584
  p = &all_passes;
  NEXT_PASS (pass_all_optimizations);
585
    {
586
      struct opt_pass **p = &pass_all_optimizations.pass.sub;
587 588
      /* Initial scalar cleanups before alias computation.
	 They ensure memory accesses are not indirect wherever possible.  */
589
      NEXT_PASS (pass_strip_predict_hints);
590
      NEXT_PASS (pass_update_address_taken);
591
      NEXT_PASS (pass_rename_ssa_copies);
592
      NEXT_PASS (pass_complete_unrolli);
593
      NEXT_PASS (pass_ccp);
594
      NEXT_PASS (pass_forwprop);
595 596 597 598 599 600 601 602 603 604 605 606 607 608
      /* Ideally the function call conditional
	 dead code elimination phase can be delayed
	 till later where potentially more opportunities
	 can be found.  Due to lack of good ways to
	 update VDEFs associated with the shrink-wrapped
	 calls, it is better to do the transformation
	 here where memory SSA is not built yet.  */
      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);
609
      NEXT_PASS (pass_phiprop);
610 611 612 613 614
      NEXT_PASS (pass_fre);
      NEXT_PASS (pass_copy_prop);
      NEXT_PASS (pass_merge_phi);
      NEXT_PASS (pass_vrp);
      NEXT_PASS (pass_dce);
615
      NEXT_PASS (pass_cselim);
616
      NEXT_PASS (pass_tree_ifcombine);
617 618 619 620 621 622 623 624 625 626 627 628 629 630
      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);
631
      NEXT_PASS (pass_dse);
632 633 634 635 636
      NEXT_PASS (pass_reassoc);
      NEXT_PASS (pass_dce);
      NEXT_PASS (pass_forwprop);
      NEXT_PASS (pass_phiopt);
      NEXT_PASS (pass_object_sizes);
637
      NEXT_PASS (pass_ccp);
638
      NEXT_PASS (pass_copy_prop);
639 640 641 642 643 644 645
      NEXT_PASS (pass_fold_builtins);
      NEXT_PASS (pass_cse_sincos);
      NEXT_PASS (pass_split_crit_edges);
      NEXT_PASS (pass_pre);
      NEXT_PASS (pass_sink_code);
      NEXT_PASS (pass_tree_loop);
	{
646
	  struct opt_pass **p = &pass_tree_loop.pass.sub;
647 648
	  NEXT_PASS (pass_tree_loop_init);
	  NEXT_PASS (pass_copy_prop);
649
	  NEXT_PASS (pass_dce_loop);
650
	  NEXT_PASS (pass_lim);
651
	  NEXT_PASS (pass_predcom);
652 653 654 655
	  NEXT_PASS (pass_tree_unswitch);
	  NEXT_PASS (pass_scev_cprop);
	  NEXT_PASS (pass_empty_loop);
	  NEXT_PASS (pass_record_bounds);
656
	  NEXT_PASS (pass_check_data_deps);
657
	  NEXT_PASS (pass_loop_distribution);
658
	  NEXT_PASS (pass_linear_transform);
659
	  NEXT_PASS (pass_graphite_transforms);
660 661 662 663
	  NEXT_PASS (pass_iv_canon);
	  NEXT_PASS (pass_if_conversion);
	  NEXT_PASS (pass_vectorize);
	    {
664
	      struct opt_pass **p = &pass_vectorize.pass.sub;
665 666 667 668
	      NEXT_PASS (pass_lower_vector_ssa);
	      NEXT_PASS (pass_dce_loop);
	    }
	  NEXT_PASS (pass_complete_unroll);
669
	  NEXT_PASS (pass_parallelize_loops);
670 671 672 673 674
	  NEXT_PASS (pass_loop_prefetch);
	  NEXT_PASS (pass_iv_optimize);
	  NEXT_PASS (pass_tree_loop_done);
	}
      NEXT_PASS (pass_cse_reciprocals);
675
      NEXT_PASS (pass_convert_to_rsqrt);
676 677 678 679 680 681 682 683 684 685
      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);
686
      NEXT_PASS (pass_tracer);
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704

      /* 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);
    }
705 706 707 708 709
  NEXT_PASS (pass_del_ssa);
  NEXT_PASS (pass_nrv);
  NEXT_PASS (pass_mark_used_blocks);
  NEXT_PASS (pass_cleanup_cfg_post_optimizing);

710 711
  NEXT_PASS (pass_warn_function_noreturn);
  NEXT_PASS (pass_free_datastructures);
712
  NEXT_PASS (pass_mudflap_2);
713

714 715 716
  NEXT_PASS (pass_free_cfg_annotations);
  NEXT_PASS (pass_expand);
  NEXT_PASS (pass_rest_of_compilation);
717
    {
718
      struct opt_pass **p = &pass_rest_of_compilation.pass.sub;
719 720 721 722 723 724
      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);
725
      NEXT_PASS (pass_into_cfg_layout_mode);
726 727
      NEXT_PASS (pass_jump2);
      NEXT_PASS (pass_lower_subreg);
728
      NEXT_PASS (pass_df_initialize_opt);
729 730 731 732 733 734 735 736 737
      NEXT_PASS (pass_cse);
      NEXT_PASS (pass_rtl_fwprop);
      NEXT_PASS (pass_gcse);
      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);
	{
738
	  struct opt_pass **p = &pass_loop2.pass.sub;
739 740 741 742 743 744 745 746 747
	  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);
748
      NEXT_PASS (pass_jump_bypass);
749
      NEXT_PASS (pass_cse2);
750
      NEXT_PASS (pass_rtl_dse1);
751
      NEXT_PASS (pass_rtl_fwprop_addr);
752 753 754
      NEXT_PASS (pass_regclass_init);
      NEXT_PASS (pass_inc_dec);
      NEXT_PASS (pass_initialize_regs);
755
      NEXT_PASS (pass_outof_cfg_layout_mode);
756
      NEXT_PASS (pass_ud_rtl_dce);
757 758 759 760 761 762
      NEXT_PASS (pass_combine);
      NEXT_PASS (pass_if_after_combine);
      NEXT_PASS (pass_partition_blocks);
      NEXT_PASS (pass_regmove);
      NEXT_PASS (pass_split_all_insns);
      NEXT_PASS (pass_lower_subreg2);
763 764
      NEXT_PASS (pass_df_initialize_no_opt);
      NEXT_PASS (pass_stack_ptr_mod);
765 766
      NEXT_PASS (pass_mode_switching);
      NEXT_PASS (pass_see);
767
      NEXT_PASS (pass_match_asm_constraints);
768 769
      NEXT_PASS (pass_sms);
      NEXT_PASS (pass_sched);
770
      NEXT_PASS (pass_subregs_of_mode_init);
771 772
      NEXT_PASS (pass_local_alloc);
      NEXT_PASS (pass_global_alloc);
Vladimir Makarov committed
773
      NEXT_PASS (pass_ira);
774
      NEXT_PASS (pass_subregs_of_mode_finish);
775 776
      NEXT_PASS (pass_postreload);
	{
777
	  struct opt_pass **p = &pass_postreload.pass.sub;
778 779
	  NEXT_PASS (pass_postreload_cse);
	  NEXT_PASS (pass_gcse2);
780 781 782 783
	  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);
784 785 786 787 788
	  NEXT_PASS (pass_rtl_seqabstr);
	  NEXT_PASS (pass_stack_adjustments);
	  NEXT_PASS (pass_peephole2);
	  NEXT_PASS (pass_if_after_reload);
	  NEXT_PASS (pass_regrename);
789 790
	  NEXT_PASS (pass_cprop_hardreg);
	  NEXT_PASS (pass_fast_rtl_dce);
791
	  NEXT_PASS (pass_reorder_blocks);
792
	  NEXT_PASS (pass_branch_target_load_optimize2);
793
	  NEXT_PASS (pass_leaf_regs);
794
	  NEXT_PASS (pass_split_before_sched2);
795 796
	  NEXT_PASS (pass_sched2);
	  NEXT_PASS (pass_stack_regs);
797
	    {
798
	      struct opt_pass **p = &pass_stack_regs.pass.sub;
799 800 801
	      NEXT_PASS (pass_split_before_regstack);
	      NEXT_PASS (pass_stack_regs_run);
	    }
802 803 804 805 806 807 808 809 810 811 812 813 814
	  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);
	}
815
      NEXT_PASS (pass_df_finish);
816
    }
817 818 819 820 821 822
  NEXT_PASS (pass_clean_state);
  *p = NULL;

#undef NEXT_PASS

  /* Register the passes with the tree dump code.  */
823
  register_dump_files (all_lowering_passes, PROP_gimple_any);
824
  all_lowering_passes->todo_flags_start |= TODO_set_props;
825
  register_dump_files (all_ipa_passes, 
826 827
		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
		       | PROP_cfg);
828
  register_dump_files (all_passes, 
829 830
		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
		       | PROP_cfg);
831 832
}

833 834 835
/* 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.  */ 
836

837
static void
838
do_per_function (void (*callback) (void *data), void *data)
839
{
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
  if (current_function_decl)
    callback (data);
  else
    {
      struct cgraph_node *node;
      for (node = cgraph_nodes; node; node = node->next)
	if (node->analyzed)
	  {
	    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 ();
	  }
    }
}

860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
/* 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);
880
      order = GGC_NEWVEC (struct cgraph_node *, cgraph_n_nodes);
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
      nnodes = cgraph_postorder (order);
      for (i = nnodes - 1; i >= 0; i--)
	{
	  struct cgraph_node *node = order[i];

	  /* Allow possibly removed nodes to be garbage collected.  */
	  order[i] = NULL;
	  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;
}

906
/* Perform all TODO actions that ought to be done on each function.  */
907

908 909 910 911 912
static void
execute_function_todo (void *data)
{
  unsigned int flags = (size_t)data;
  if (cfun->curr_properties & PROP_ssa)
913
    flags |= TODO_verify_ssa;
914
  flags &= ~cfun->last_verified;
915 916
  if (!flags)
    return;
917 918 919

  statistics_fini_pass ();

920
  /* Always cleanup the CFG before trying to update SSA.  */
921 922
  if (flags & TODO_cleanup_cfg)
    {
923
      bool cleanup = cleanup_tree_cfg ();
924

925 926 927
      if (cleanup && (cfun->curr_properties & PROP_ssa))
	flags |= TODO_remove_unused_locals;
	
928 929 930 931 932 933 934 935
      /* 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.  */
      if (!(flags & TODO_update_ssa_any) && need_ssa_update_p ())
	flags |= TODO_update_ssa;
936
    }
Richard Henderson committed
937

938 939 940 941
  if (flags & TODO_update_ssa_any)
    {
      unsigned update_flags = flags & TODO_update_ssa_any;
      update_ssa (update_flags);
942
      cfun->last_verified &= ~TODO_verify_ssa;
943
    }
944 945 946 947 948 949 950
  
  if (flags & TODO_rebuild_alias)
    {
      compute_may_aliases ();
      cfun->curr_properties |= PROP_alias;
    }
  
951 952 953
  if (flags & TODO_remove_unused_locals)
    remove_unused_locals ();

954
  if ((flags & TODO_dump_func) && dump_file && current_function_decl)
955
    {
956
      if (cfun->curr_properties & PROP_trees)
957
        dump_function_to_file (current_function_decl, dump_file, dump_flags);
958
      else
959
	{
960 961
	  if (dump_flags & TDF_SLIM)
	    print_rtl_slim_with_bb (dump_file, get_insns (), dump_flags);
962 963
	  else if ((cfun->curr_properties & PROP_cfg)
		   && (dump_flags & TDF_BLOCKS))
964 965 966 967
	    print_rtl_with_bb (dump_file, get_insns ());
          else
	    print_rtl (dump_file, get_insns ());

968
	  if ((cfun->curr_properties & PROP_cfg)
969
	      && graph_dump_format != no_graph
970 971 972
	      && (dump_flags & TDF_GRAPH))
	    print_rtl_graph_with_bb (dump_file_name, get_insns ());
	}
973 974 975 976 977

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

979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
  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 ();
    }

997 998 999 1000 1001 1002 1003 1004 1005
#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 ();
1006 1007
  if (flags & TODO_verify_rtl_sharing)
    verify_rtl_sharing ();
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
#endif

  cfun->last_verified = flags & TODO_verify_all;
}

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

1022 1023 1024
  /* Inform the pass whether it is the first time it is run.  */
  first_pass_instance = (flags & TODO_mark_first_instance) != 0;

1025 1026
  do_per_function (execute_function_todo, (void *)(size_t) flags);

1027 1028 1029 1030 1031
  /* 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)
1032 1033 1034 1035
    {
      gcc_assert (!cfun);
      cgraph_remove_unreachable_nodes (true, dump_file);
    }
1036

1037
  if ((flags & TODO_dump_cgraph) && dump_file && !current_function_decl)
1038
    {
1039
      gcc_assert (!cfun);
1040 1041 1042 1043 1044
      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
1045

1046
  if (flags & TODO_ggc_collect)
1047
    ggc_collect ();
1048 1049 1050 1051

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

1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
/* 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
}

1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
/* 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.  */
1076

1077
#ifdef ENABLE_CHECKING
1078 1079 1080 1081 1082 1083
static void
verify_curr_properties (void *data)
{
  unsigned int props = (size_t)data;
  gcc_assert ((cfun->curr_properties & props) == props);
}
1084
#endif
1085

1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
/* 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)));
1103
	  fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
	     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;
    }
}

1135 1136
/* After executing the pass, apply expected changes to the function
   properties. */
1137

1138 1139 1140
static void
update_properties_after_pass (void *data)
{
1141
  struct opt_pass *pass = (struct opt_pass *) data;
1142 1143
  cfun->curr_properties = (cfun->curr_properties | pass->properties_provided)
		           & ~pass->properties_destroyed;
Richard Henderson committed
1144 1145
}

1146 1147 1148 1149 1150 1151 1152 1153 1154
/* Schedule IPA transform pass DATA for CFUN.  */

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

1155
/* Execute summary generation for all of the passes in IPA_PASS.  */
1156 1157

static void
1158
execute_ipa_summary_passes (struct ipa_opt_pass *ipa_pass)
1159
{
1160
  while (ipa_pass)
1161 1162
    {
      struct opt_pass *pass = &ipa_pass->pass;
1163 1164 1165 1166

      /* Execute all of the IPA_PASSes in the list.  */
      if (ipa_pass->pass.type == IPA_PASS 
	  && (!pass->gate || pass->gate ()))
1167 1168
	{
	  pass_init_dump_file (pass);
1169
	  ipa_pass->generate_summary ();
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
	  pass_fini_dump_file (pass);
	}
      ipa_pass = (struct ipa_opt_pass *)ipa_pass->pass.next;
    }
}

/* Execute IPA_PASS function transform on NODE.  */

static void
execute_one_ipa_transform_pass (struct cgraph_node *node,
				struct ipa_opt_pass *ipa_pass)
{
  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.  */
1196
  execute_todo (ipa_pass->function_transform_todo_flags_start);
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217

  /* If a timevar is present, start it.  */
  if (pass->tv_id)
    timevar_push (pass->tv_id);

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

  /* Stop timevar.  */
  if (pass->tv_id)
    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;
}

1218
static bool
1219
execute_one_pass (struct opt_pass *pass)
Richard Henderson committed
1220
{
1221
  bool initializing_dump;
1222
  unsigned int todo_after = 0;
1223

1224
  /* IPA passes are executed on whole program, so cfun should be NULL.
1225
     Other passes need function context set.  */
1226
  if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
1227 1228
    gcc_assert (!cfun && !current_function_decl);
  else
1229
    gcc_assert (cfun && current_function_decl);
1230

1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
  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;
    }

1246
  current_pass = pass;
1247

1248 1249 1250
  /* See if we're supposed to run this pass.  */
  if (pass->gate && !pass->gate ())
    return false;
Richard Henderson committed
1251

1252 1253 1254
  if (!quiet_flag && !cfun)
    fprintf (stderr, " <%s>", pass->name ? pass->name : "");

1255
  if (pass->todo_flags_start & TODO_set_props)
1256
    cfun->curr_properties = pass->properties_required;
1257

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

1262
  /* Run pre-pass verification.  */
1263 1264
  execute_todo (pass->todo_flags_start);

1265 1266 1267 1268
#ifdef ENABLE_CHECKING
  do_per_function (verify_curr_properties,
		   (void *)(size_t)pass->properties_required);
#endif
Richard Henderson committed
1269

1270
  initializing_dump = pass_init_dump_file (pass);
Richard Henderson committed
1271

1272 1273 1274
  /* If a timevar is present, start it.  */
  if (pass->tv_id)
    timevar_push (pass->tv_id);
Richard Henderson committed
1275

1276 1277
  /* Do it!  */
  if (pass->execute)
1278
    {
1279
      todo_after = pass->execute ();
1280
      do_per_function (clear_last_verified, NULL);
1281
    }
Richard Henderson committed
1282

1283 1284 1285
  /* Stop timevar.  */
  if (pass->tv_id)
    timevar_pop (pass->tv_id);
Richard Henderson committed
1286

1287
  do_per_function (update_properties_after_pass, pass);
1288 1289 1290 1291

  if (initializing_dump
      && dump_file
      && graph_dump_format != no_graph
1292
      && cfun
1293 1294
      && (cfun->curr_properties & (PROP_cfg | PROP_rtl))
	  == (PROP_cfg | PROP_rtl))
1295 1296 1297 1298 1299 1300
    {
      get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH;
      dump_flags |= TDF_GRAPH;
      clean_graph_dump_file (dump_file_name);
    }

1301
  /* Run post-pass cleanup and verification.  */
1302
  execute_todo (todo_after | pass->todo_flags_finish);
1303
  verify_interpass_invariants ();
1304 1305
  if (pass->type == IPA_PASS)
    do_per_function (add_ipa_transform_pass, pass);
Richard Henderson committed
1306

1307 1308 1309
  if (!current_function_decl)
    cgraph_process_new_functions ();

1310
  pass_fini_dump_file (pass);
Richard Henderson committed
1311

1312
  if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS)
1313 1314 1315
    gcc_assert (!(cfun->curr_properties & PROP_trees)
		|| pass->type != RTL_PASS);

1316
  current_pass = NULL;
1317

1318
  return true;
Richard Henderson committed
1319 1320
}

1321
void
1322
execute_pass_list (struct opt_pass *pass)
Richard Henderson committed
1323
{
1324
  do
Richard Henderson committed
1325
    {
1326 1327
      gcc_assert (pass->type == GIMPLE_PASS
		  || pass->type == RTL_PASS);
1328 1329 1330
      if (execute_one_pass (pass) && pass->sub)
        execute_pass_list (pass->sub);
      pass = pass->next;
Richard Henderson committed
1331
    }
1332
  while (pass);
Richard Henderson committed
1333 1334
}

1335 1336 1337
/* Same as execute_pass_list but assume that subpasses of IPA passes
   are local passes.  */
void
1338
execute_ipa_pass_list (struct opt_pass *pass)
Richard Henderson committed
1339
{
1340
  bool summaries_generated = false;
1341
  do
Richard Henderson committed
1342
    {
1343 1344
      gcc_assert (!current_function_decl);
      gcc_assert (!cfun);
1345 1346 1347 1348 1349 1350 1351
      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>");
1352
	      execute_ipa_summary_passes ((struct ipa_opt_pass *) pass);
1353 1354 1355
	    }
	  summaries_generated = true;
	}
1356
      if (execute_one_pass (pass) && pass->sub)
1357 1358 1359 1360
	{
	  if (pass->sub->type == GIMPLE_PASS)
	    do_per_function_toporder ((void (*)(void *))execute_pass_list,
				      pass->sub);
1361 1362
	  else if (pass->sub->type == SIMPLE_IPA_PASS
		   || pass->sub->type == IPA_PASS)
1363 1364 1365 1366
	    execute_ipa_pass_list (pass->sub);
	  else
	    gcc_unreachable ();
	}
1367 1368
      if (!current_function_decl)
	cgraph_process_new_functions ();
1369
      pass = pass->next;
Richard Henderson committed
1370
    }
1371
  while (pass);
1372
}
1373

1374
#include "gt-passes.h"