[PATCH 5/6] pass current function to opt_pass::gate ()

Richard Biener richard.guenther@gmail.com
Thu Apr 17 09:00:00 GMT 2014


On Thu, Apr 17, 2014 at 10:37 AM,  <tsaunders@mozilla.com> wrote:
> From: Trevor Saunders <tsaunders@mozilla.com>
>
> Hi,
>
>  This gets rid of usage of cfun, and a bunch of useless functions.
>
> bootstrap + regtest passed on x86_64-unknown-linux-gnu, ok?

Ok.

Thanks,
Richard.

> Trev
>
> 2014-03-19  Trevor Saunders  <tsaunders@mozilla.com>
>
> gcc/
>         * passes.c (opt_pass::gate): Take function * argument.
>         (gate_all_early_local_passes): Merge into
>         (early_local_passes::gate): this.
>         (gate_all_early_optimizations): Merge into
>         (all_early_optimizations::gate): this.
>         (gate_all_optimizations): Mege into
>         (all_optimizations::gate): this.
>         (gate_all_optimizations_g): Merge into
>         (all_optimizations_g::gate): this.
>         (gate_rest_of_compilation): Mege into
>         (rest_of_compilation::gate): this.
>         (gate_postreload): Merge into
>         (postreload::gate): this.
>         (dump_one_pass): Pass cfun to the pass's gate method.
>         (execute_ipa_summary_passes): Likewise.
>         (execute_one_pass): Likewise.
>         (ipa_write_summaries_2): Likewise.
>         (ipa_write_optimization_summaries_1): Likewise.
>         (ipa_read_summaries_1): Likewise.
>         (ipa_read_optimization_summaries_1): Likewise.
>         (execute_ipa_stmt_fixups): Likewise.
>         * tree-pass.h (opt_pass::gate): Add function * argument.
>         * asan.c, auto-inc-dec.c, bb-reorder.c, bt-load.c,
>         combine-stack-adj.c, combine.c, compare-elim.c,
>         config/epiphany/resolve-sw-modes.c, config/i386/i386.c,
>         config/rl78/rl78.c, config/sh/sh_optimize_sett_clrt.cc,
>         config/sh/sh_treg_combine.cc, config/sparc/sparc.c, cprop.c, cse.c,
>         dce.c, df-core.c, dse.c, dwarf2cfi.c, except.c,  fwprop.c, gcse.c,
>         gimple-ssa-isolate-paths.c, gimple-ssa-strength-reduction.c,
>         graphite.c, ifcvt.c, init-regs.c, ipa-cp.c, ipa-devirt.c,
>         ipa-profile.c, ipa-pure-const.c, ipa-reference.c, ipa-split.c, ipa.c,
>         loop-init.c, lower-subreg.c, mode-switching.c, modulo-sched.c,
>         omp-low.c, postreload-gcse.c, postreload.c, predict.c, recog.c, ree.c,
>         reg-stack.c, regcprop.c, regrename.c, reorg.c, sched-rgn.c,
>         store-motion.c, tracer.c, trans-mem.c, tree-call-cdce.c, tree-cfg.c,
>         tree-cfgcleanup.c, tree-complex.c, tree-eh.c, tree-emutls.c,
>         tree-if-conv.c, tree-into-ssa.c, tree-loop-distribution.c,
>         tree-nrv.c, tree-parloops.c, tree-predcom.c, tree-profile.c,
>         tree-sra.c, tree-ssa-ccp.c, tree-ssa-copy.c, tree-ssa-copyrename.c,
>         tree-ssa-dce.c, tree-ssa-dom.c, tree-ssa-dse.c, tree-ssa-forwprop.c,
>         tree-ssa-ifcombine.c, tree-ssa-loop-ch.c, tree-ssa-loop-im.c,
>         tree-ssa-loop-ivcanon.c, tree-ssa-loop-prefetch.c,
>         tree-ssa-loop-unswitch.c, tree-ssa-loop.c, tree-ssa-math-opts.c,
>         tree-ssa-phiopt.c, tree-ssa-phiprop.c, tree-ssa-pre.c,
>         tree-ssa-reassoc.c, tree-ssa-sink.c, tree-ssa-strlen.c,
>         tree-ssa-structalias.c, tree-ssa-uncprop.c, tree-ssa-uninit.c,
>         tree-ssa.c, tree-stdarg.c, tree-switch-conversion.c, tree-tailcall.c,
>         tree-vect-generic.c, tree-vectorizer.c, tree-vrp.c, tsan.c, ubsan.c,
>         var-tracking.c, vtable-verify.c, web.c: Adjust.
>
> gcc/testsuite/
>         * g++.dg/plugin/dumb_plugin.c, g++.dg/plugin/selfasign.c,
>         gcc.dg/plugin/one_time_plugin.c, gcc.dg/plugin/selfasign.c: Adjust.
>
>
>
> diff --git a/gcc/asan.c b/gcc/asan.c
> index e26ce41..3fe50ef 100644
> --- a/gcc/asan.c
> +++ b/gcc/asan.c
> @@ -2504,7 +2504,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_asan (m_ctxt); }
> -  bool gate () { return gate_asan (); }
> +  virtual bool gate (function *) { return gate_asan (); }
>    unsigned int execute () { return asan_instrument (); }
>
>  }; // class pass_asan
> @@ -2517,12 +2517,6 @@ make_pass_asan (gcc::context *ctxt)
>    return new pass_asan (ctxt);
>  }
>
> -static bool
> -gate_asan_O0 (void)
> -{
> -  return !optimize && gate_asan ();
> -}
> -
>  namespace {
>
>  const pass_data pass_data_asan_O0 =
> @@ -2548,7 +2542,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_asan_O0 (); }
> +  virtual bool gate (function *) { return !optimize && gate_asan (); }
>    unsigned int execute () { return asan_instrument (); }
>
>  }; // class pass_asan_O0
> @@ -2599,12 +2593,6 @@ execute_sanopt (void)
>    return 0;
>  }
>
> -static bool
> -gate_sanopt (void)
> -{
> -  return flag_sanitize;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_sanopt =
> @@ -2630,7 +2618,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_sanopt (); }
> +  virtual bool gate (function *) { return flag_sanitize; }
>    unsigned int execute () { return execute_sanopt (); }
>
>  }; // class pass_sanopt
> diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
> index 4346e85..e1485a3 100644
> --- a/gcc/auto-inc-dec.c
> +++ b/gcc/auto-inc-dec.c
> @@ -1495,17 +1495,6 @@ rest_of_handle_auto_inc_dec (void)
>
>  /* Discover auto-inc auto-dec instructions.  */
>
> -static bool
> -gate_auto_inc_dec (void)
> -{
> -#ifdef AUTO_INC_DEC
> -  return (optimize > 0 && flag_auto_inc_dec);
> -#else
> -  return false;
> -#endif
> -}
> -
> -
>  namespace {
>
>  const pass_data pass_data_inc_dec =
> @@ -1530,7 +1519,16 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_auto_inc_dec (); }
> +  virtual bool gate (function *)
> +    {
> +#ifdef AUTO_INC_DEC
> +      return (optimize > 0 && flag_auto_inc_dec);
> +#else
> +      return false;
> +#endif
> +    }
> +
> +
>    unsigned int execute () { return rest_of_handle_auto_inc_dec (); }
>
>  }; // class pass_inc_dec
> diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
> index 6ac0242..57103bd 100644
> --- a/gcc/bb-reorder.c
> +++ b/gcc/bb-reorder.c
> @@ -2302,15 +2302,6 @@ insert_section_boundary_note (void)
>      }
>  }
>
> -static bool
> -gate_handle_reorder_blocks (void)
> -{
> -  if (targetm.cannot_modify_jumps_p ())
> -    return false;
> -  return (optimize > 0
> -         && (flag_reorder_blocks || flag_reorder_blocks_and_partition));
> -}
> -
>  static unsigned int
>  rest_of_handle_reorder_blocks (void)
>  {
> @@ -2355,7 +2346,14 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_reorder_blocks (); }
> +  virtual bool gate (function *)
> +    {
> +      if (targetm.cannot_modify_jumps_p ())
> +       return false;
> +      return (optimize > 0
> +             && (flag_reorder_blocks || flag_reorder_blocks_and_partition));
> +    }
> +
>    unsigned int execute () { return rest_of_handle_reorder_blocks (); }
>
>  }; // class pass_reorder_blocks
> @@ -2374,16 +2372,6 @@ make_pass_reorder_blocks (gcc::context *ctxt)
>     which can seriously pessimize code with many computed jumps in the source
>     code, such as interpreters.  See e.g. PR15242.  */
>
> -static bool
> -gate_duplicate_computed_gotos (void)
> -{
> -  if (targetm.cannot_modify_jumps_p ())
> -    return false;
> -  return (optimize > 0
> -         && flag_expensive_optimizations
> -         && ! optimize_function_for_size_p (cfun));
> -}
> -
>
>  static unsigned int
>  duplicate_computed_gotos (void)
> @@ -2527,11 +2515,21 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_duplicate_computed_gotos (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return duplicate_computed_gotos (); }
>
>  }; // class pass_duplicate_computed_gotos
>
> +bool
> +pass_duplicate_computed_gotos::gate (function *fun)
> +{
> +  if (targetm.cannot_modify_jumps_p ())
> +    return false;
> +  return (optimize > 0
> +         && flag_expensive_optimizations
> +         && ! optimize_function_for_size_p (fun));
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> @@ -2540,22 +2538,6 @@ make_pass_duplicate_computed_gotos (gcc::context *ctxt)
>    return new pass_duplicate_computed_gotos (ctxt);
>  }
>
> -static bool
> -gate_handle_partition_blocks (void)
> -{
> -  /* The optimization to partition hot/cold basic blocks into separate
> -     sections of the .o file does not work well with linkonce or with
> -     user defined section attributes.  Don't call it if either case
> -     arises.  */
> -  return (flag_reorder_blocks_and_partition
> -          && optimize
> -         /* See gate_handle_reorder_blocks.  We should not partition if
> -            we are going to omit the reordering.  */
> -         && optimize_function_for_speed_p (cfun)
> -         && !DECL_ONE_ONLY (current_function_decl)
> -         && !user_defined_section_attribute);
> -}
> -
>  /* This function is the main 'entrance' for the optimization that
>     partitions hot and cold basic blocks into separate sections of the
>     .o file (to improve performance and cache locality).  Ideally it
> @@ -2750,11 +2732,27 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_partition_blocks (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return partition_hot_cold_basic_blocks (); }
>
>  }; // class pass_partition_blocks
>
> +bool
> +pass_partition_blocks::gate (function *fun)
> +{
> +  /* The optimization to partition hot/cold basic blocks into separate
> +     sections of the .o file does not work well with linkonce or with
> +     user defined section attributes.  Don't call it if either case
> +     arises.  */
> +  return (flag_reorder_blocks_and_partition
> +         && optimize
> +         /* See gate_handle_reorder_blocks.  We should not partition if
> +            we are going to omit the reordering.  */
> +         && optimize_function_for_speed_p (fun)
> +         && !DECL_ONE_ONLY (current_function_decl)
> +         && !user_defined_section_attribute);
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/bt-load.c b/gcc/bt-load.c
> index d44917f..fc2aea7 100644
> --- a/gcc/bt-load.c
> +++ b/gcc/bt-load.c
> @@ -1494,12 +1494,6 @@ branch_target_load_optimize (bool after_prologue_epilogue_gen)
>      }
>  }
>
> -static bool
> -gate_handle_branch_target_load_optimize1 (void)
> -{
> -  return flag_branch_target_load_optimize;
> -}
> -
>
>  static unsigned int
>  rest_of_handle_branch_target_load_optimize1 (void)
> @@ -1532,7 +1526,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_branch_target_load_optimize1 (); }
> +  virtual bool gate (function *) { return flag_branch_target_load_optimize; }
>    unsigned int execute () {
>      return rest_of_handle_branch_target_load_optimize1 ();
>    }
> @@ -1547,12 +1541,6 @@ make_pass_branch_target_load_optimize1 (gcc::context *ctxt)
>    return new pass_branch_target_load_optimize1 (ctxt);
>  }
>
> -static bool
> -gate_handle_branch_target_load_optimize2 (void)
> -{
> -  return (optimize > 0 && flag_branch_target_load_optimize2);
> -}
> -
>
>  static unsigned int
>  rest_of_handle_branch_target_load_optimize2 (void)
> @@ -1600,7 +1588,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_branch_target_load_optimize2 (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize > 0 && flag_branch_target_load_optimize2);
> +    }
> +
>    unsigned int execute () {
>      return rest_of_handle_branch_target_load_optimize2 ();
>    }
> diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
> index ec22ab3..37fc7a5 100644
> --- a/gcc/combine-stack-adj.c
> +++ b/gcc/combine-stack-adj.c
> @@ -619,21 +619,6 @@ combine_stack_adjustments_for_block (basic_block bb)
>      free_csa_reflist (reflist);
>  }
>
> -
> -static bool
> -gate_handle_stack_adjustments (void)
> -{
> -  /* This is kind of a heuristic.  We need to run combine_stack_adjustments
> -     even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
> -     and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
> -     push instructions will have popping returns.  */
> -#ifndef PUSH_ROUNDING
> -  if (ACCUMULATE_OUTGOING_ARGS)
> -    return false;
> -#endif
> -  return flag_combine_stack_adjustments;
> -}
> -
>  static unsigned int
>  rest_of_handle_stack_adjustments (void)
>  {
> @@ -667,11 +652,25 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_stack_adjustments (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return rest_of_handle_stack_adjustments (); }
>
>  }; // class pass_stack_adjustments
>
> +bool
> +pass_stack_adjustments::gate (function *)
> +{
> +  /* This is kind of a heuristic.  We need to run combine_stack_adjustments
> +     even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
> +     and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
> +     push instructions will have popping returns.  */
> +#ifndef PUSH_ROUNDING
> +  if (ACCUMULATE_OUTGOING_ARGS)
> +    return false;
> +#endif
> +  return flag_combine_stack_adjustments;
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/combine.c b/gcc/combine.c
> index 63933c0..1b1e33c 100644
> --- a/gcc/combine.c
> +++ b/gcc/combine.c
> @@ -13854,12 +13854,6 @@ dump_combine_total_stats (FILE *file)
>       total_attempts, total_merges, total_extras, total_successes);
>  }
>
> -static bool
> -gate_handle_combine (void)
> -{
> -  return (optimize > 0);
> -}
> -
>  /* Try combining insns through substitution.  */
>  static unsigned int
>  rest_of_handle_combine (void)
> @@ -13914,7 +13908,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_combine (); }
> +  virtual bool gate (function *) { return (optimize > 0); }
>    unsigned int execute () { return rest_of_handle_combine (); }
>
>  }; // class pass_combine
> diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c
> index e66b1c6..9cddb7a 100644
> --- a/gcc/compare-elim.c
> +++ b/gcc/compare-elim.c
> @@ -643,15 +643,6 @@ execute_compare_elim_after_reload (void)
>    return 0;
>  }
>
> -static bool
> -gate_compare_elim_after_reload (void)
> -{
> -  /* Setting this target hook value is how a backend indicates the need.  */
> -  if (targetm.flags_regnum == INVALID_REGNUM)
> -    return false;
> -  return flag_compare_elim_after_reload;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_compare_elim_after_reload =
> @@ -677,7 +668,14 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_compare_elim_after_reload (); }
> +  virtual bool gate (function *)
> +    {
> +      /* Setting this target hook value is how a backend indicates the need.  */
> +      if (targetm.flags_regnum == INVALID_REGNUM)
> +       return false;
> +      return flag_compare_elim_after_reload;
> +    }
> +
>    unsigned int execute () { return execute_compare_elim_after_reload (); }
>
>  }; // class pass_compare_elim_after_reload
> diff --git a/gcc/config/epiphany/resolve-sw-modes.c b/gcc/config/epiphany/resolve-sw-modes.c
> index 486330c..31928fd 100644
> --- a/gcc/config/epiphany/resolve-sw-modes.c
> +++ b/gcc/config/epiphany/resolve-sw-modes.c
> @@ -45,12 +45,6 @@ along with GCC; see the file COPYING3.  If not see
>     insert new mode setting insns on the edges where the other mode
>     becomes unambigous.  */
>
> -static bool
> -gate_resolve_sw_modes (void)
> -{
> -  return optimize;
> -}
> -
>  static unsigned
>  resolve_sw_modes (void)
>  {
> @@ -185,7 +179,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_resolve_sw_modes (); }
> +  virtual bool gate (function *) { return optimize; }
>    unsigned int execute () { return resolve_sw_modes (); }
>
>  }; // class pass_resolve_sw_modes
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 6dd1bbe..8cfdaf6 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -2493,12 +2493,6 @@ static const struct ptt processor_target_table[PROCESSOR_max] =
>    {"btver2", &btver2_cost, 16, 10, 16, 7, 11}
>  };
>
> -static bool
> -gate_insert_vzeroupper (void)
> -{
> -  return TARGET_AVX && !TARGET_AVX512F && TARGET_VZEROUPPER;
> -}
> -
>  static unsigned int
>  rest_of_handle_insert_vzeroupper (void)
>  {
> @@ -2542,7 +2536,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_insert_vzeroupper (); }
> +  virtual bool gate (function *)
> +    {
> +      return TARGET_AVX && !TARGET_AVX512F && TARGET_VZEROUPPER;
> +    }
> +
>    unsigned int execute () { return rest_of_handle_insert_vzeroupper (); }
>
>  }; // class pass_insert_vzeroupper
> diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
> index 88b030f..988e1cd 100644
> --- a/gcc/config/rl78/rl78.c
> +++ b/gcc/config/rl78/rl78.c
> @@ -117,13 +117,6 @@ rl78_init_machine_status (void)
>    return m;
>  }
>
> -/* Returns whether to run the devirtualization pass.  */
> -static bool
> -devirt_gate (void)
> -{
> -  return true;
> -}
> -
>  /* Runs the devirtualization pass.  */
>  static unsigned int
>  devirt_pass (void)
> @@ -160,7 +153,6 @@ public:
>    }
>
>    /* opt_pass methods: */
> -  bool gate () { return devirt_gate (); }
>    unsigned int execute () { return devirt_pass (); }
>  };
>
> @@ -243,7 +235,6 @@ public:
>    }
>
>    /* opt_pass methods: */
> -  bool gate () { return devirt_gate (); }
>    unsigned int execute () { return move_elim_pass (); }
>  };
>
> diff --git a/gcc/config/sh/sh_optimize_sett_clrt.cc b/gcc/config/sh/sh_optimize_sett_clrt.cc
> index 85cb6a1..5b1afcd 100644
> --- a/gcc/config/sh/sh_optimize_sett_clrt.cc
> +++ b/gcc/config/sh/sh_optimize_sett_clrt.cc
> @@ -79,7 +79,7 @@ class sh_optimize_sett_clrt : public rtl_opt_pass
>  public:
>    sh_optimize_sett_clrt (gcc::context* ctx, const char* name);
>    virtual ~sh_optimize_sett_clrt (void);
> -  virtual bool gate (void);
> +  virtual bool gate (function *);
>    virtual unsigned int execute (void);
>
>  private:
> @@ -161,7 +161,7 @@ sh_optimize_sett_clrt::~sh_optimize_sett_clrt (void)
>  }
>
>  bool
> -sh_optimize_sett_clrt::gate (void)
> +sh_optimize_sett_clrt::gate (function *)
>  {
>    return optimize > 0;
>  }
> diff --git a/gcc/config/sh/sh_treg_combine.cc b/gcc/config/sh/sh_treg_combine.cc
> index 1285ba2..57eddd2 100644
> --- a/gcc/config/sh/sh_treg_combine.cc
> +++ b/gcc/config/sh/sh_treg_combine.cc
> @@ -424,7 +424,7 @@ class sh_treg_combine : public rtl_opt_pass
>  public:
>    sh_treg_combine (gcc::context* ctx, bool split_insns, const char* name);
>    virtual ~sh_treg_combine (void);
> -  virtual bool gate (void);
> +  virtual bool gate (function *);
>    virtual unsigned int execute (void);
>
>  private:
> @@ -1435,7 +1435,7 @@ sh_treg_combine::try_optimize_cbranch (rtx insn)
>  }
>
>  bool
> -sh_treg_combine::gate (void)
> +sh_treg_combine::gate (function *)
>  {
>    return optimize > 0;
>  }
> diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
> index a63e813..5578cb8 100644
> --- a/gcc/config/sparc/sparc.c
> +++ b/gcc/config/sparc/sparc.c
> @@ -871,13 +871,6 @@ mem_ref (rtx x)
>     pass runs as late as possible.  The pass is inserted in the pass pipeline
>     at the end of sparc_option_override.  */
>
> -static bool
> -sparc_gate_work_around_errata (void)
> -{
> -  /* The only errata we handle are those of the AT697F and UT699.  */
> -  return sparc_fix_at697f != 0 || sparc_fix_ut699 != 0;
> -}
> -
>  static unsigned int
>  sparc_do_work_around_errata (void)
>  {
> @@ -1146,7 +1139,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return sparc_gate_work_around_errata (); }
> +  virtual bool gate (function *)
> +    {
> +      /* The only errata we handle are those of the AT697F and UT699.  */
> +      return sparc_fix_at697f != 0 || sparc_fix_ut699 != 0;
> +    }
> +
>    unsigned int execute () { return sparc_do_work_around_errata (); }
>
>  }; // class pass_work_around_errata
> diff --git a/gcc/cprop.c b/gcc/cprop.c
> index f22cde7..9802b8a 100644
> --- a/gcc/cprop.c
> +++ b/gcc/cprop.c
> @@ -1896,14 +1896,6 @@ one_cprop_pass (void)
>     setjmp.
>     FIXME: Should just handle setjmp via REG_SETJMP notes.  */
>
> -static bool
> -gate_rtl_cprop (void)
> -{
> -  return optimize > 0 && flag_gcse
> -    && !cfun->calls_setjmp
> -    && dbg_cnt (cprop);
> -}
> -
>  static unsigned int
>  execute_rtl_cprop (void)
>  {
> @@ -1944,7 +1936,13 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_rtl_cprop (m_ctxt); }
> -  bool gate () { return gate_rtl_cprop (); }
> +  virtual bool gate (function *fun)
> +    {
> +      return optimize > 0 && flag_gcse
> +       && !fun->calls_setjmp
> +       && dbg_cnt (cprop);
> +    }
> +
>    unsigned int execute () { return execute_rtl_cprop (); }
>
>  }; // class pass_rtl_cprop
> diff --git a/gcc/cse.c b/gcc/cse.c
> index 6edea01..60ec9a9 100644
> --- a/gcc/cse.c
> +++ b/gcc/cse.c
> @@ -7457,12 +7457,6 @@ cse_condition_code_reg (void)
>  /* Perform common subexpression elimination.  Nonzero value from
>     `cse_main' means that jumps were simplified and some code may now
>     be unreachable, so do jump optimization again.  */
> -static bool
> -gate_handle_cse (void)
> -{
> -  return optimize > 0;
> -}
> -
>  static unsigned int
>  rest_of_handle_cse (void)
>  {
> @@ -7515,7 +7509,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_cse (); }
> +  virtual bool gate (function *) { return optimize > 0; }
>    unsigned int execute () { return rest_of_handle_cse (); }
>
>  }; // class pass_cse
> @@ -7529,12 +7523,6 @@ make_pass_cse (gcc::context *ctxt)
>  }
>
>
> -static bool
> -gate_handle_cse2 (void)
> -{
> -  return optimize > 0 && flag_rerun_cse_after_loop;
> -}
> -
>  /* Run second CSE pass after loop optimizations.  */
>  static unsigned int
>  rest_of_handle_cse2 (void)
> @@ -7594,7 +7582,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_cse2 (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_rerun_cse_after_loop;
> +    }
> +
>    unsigned int execute () { return rest_of_handle_cse2 (); }
>
>  }; // class pass_cse2
> @@ -7607,12 +7599,6 @@ make_pass_cse2 (gcc::context *ctxt)
>    return new pass_cse2 (ctxt);
>  }
>
> -static bool
> -gate_handle_cse_after_global_opts (void)
> -{
> -  return optimize > 0 && flag_rerun_cse_after_global_opts;
> -}
> -
>  /* Run second CSE pass after loop optimizations.  */
>  static unsigned int
>  rest_of_handle_cse_after_global_opts (void)
> @@ -7671,7 +7657,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_cse_after_global_opts (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_rerun_cse_after_global_opts;
> +    }
> +
>    unsigned int execute () {
>      return rest_of_handle_cse_after_global_opts ();
>    }
> diff --git a/gcc/dce.c b/gcc/dce.c
> index 33cdefd..1d290e3 100644
> --- a/gcc/dce.c
> +++ b/gcc/dce.c
> @@ -779,13 +779,6 @@ rest_of_handle_ud_dce (void)
>  }
>
>
> -static bool
> -gate_ud_dce (void)
> -{
> -  return optimize > 1 && flag_dce
> -    && dbg_cnt (dce_ud);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ud_rtl_dce =
> @@ -810,7 +803,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ud_dce (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 1 && flag_dce && dbg_cnt (dce_ud);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_ud_dce (); }
>
>  }; // class pass_ud_rtl_dce
> @@ -1211,13 +1208,6 @@ run_fast_dce (void)
>  }
>
>
> -static bool
> -gate_fast_dce (void)
> -{
> -  return optimize > 0 && flag_dce
> -    && dbg_cnt (dce_fast);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_fast_rtl_dce =
> @@ -1242,7 +1232,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_fast_dce (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_dce && dbg_cnt (dce_fast);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_fast_dce (); }
>
>  }; // class pass_fast_rtl_dce
> diff --git a/gcc/df-core.c b/gcc/df-core.c
> index 9909ac3..bd3cb31 100644
> --- a/gcc/df-core.c
> +++ b/gcc/df-core.c
> @@ -740,13 +740,6 @@ rest_of_handle_df_initialize (void)
>  }
>
>
> -static bool
> -gate_opt (void)
> -{
> -  return optimize > 0;
> -}
> -
> -
>  namespace {
>
>  const pass_data pass_data_df_initialize_opt =
> @@ -771,7 +764,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_opt (); }
> +  virtual bool gate (function *) { return optimize > 0; }
>    unsigned int execute () { return rest_of_handle_df_initialize (); }
>
>  }; // class pass_df_initialize_opt
> @@ -785,13 +778,6 @@ make_pass_df_initialize_opt (gcc::context *ctxt)
>  }
>
>
> -static bool
> -gate_no_opt (void)
> -{
> -  return optimize == 0;
> -}
> -
> -
>  namespace {
>
>  const pass_data pass_data_df_initialize_no_opt =
> @@ -816,7 +802,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_no_opt (); }
> +  virtual bool gate (function *) { return optimize == 0; }
>    unsigned int execute () { return rest_of_handle_df_initialize (); }
>
>  }; // class pass_df_initialize_no_opt
> diff --git a/gcc/dse.c b/gcc/dse.c
> index a3a66b1..a80c025 100644
> --- a/gcc/dse.c
> +++ b/gcc/dse.c
> @@ -608,11 +608,6 @@ static bitmap kill_on_calls;
>
>  /* The number of bits used in the global bitmaps.  */
>  static unsigned int current_position;
> -
> -
> -static bool gate_dse1 (void);
> -static bool gate_dse2 (void);
> -
>
>  /*----------------------------------------------------------------------------
>     Zeroth step.
> @@ -3712,20 +3707,6 @@ rest_of_handle_dse (void)
>    return 0;
>  }
>
> -static bool
> -gate_dse1 (void)
> -{
> -  return optimize > 0 && flag_dse
> -    && dbg_cnt (dse1);
> -}
> -
> -static bool
> -gate_dse2 (void)
> -{
> -  return optimize > 0 && flag_dse
> -    && dbg_cnt (dse2);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_rtl_dse1 =
> @@ -3750,7 +3731,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_dse1 (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_dse && dbg_cnt (dse1);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_dse (); }
>
>  }; // class pass_rtl_dse1
> @@ -3787,7 +3772,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_dse2 (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_dse && dbg_cnt (dse2);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_dse (); }
>
>  }; // class pass_rtl_dse2
> diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
> index d278a27..3749277 100644
> --- a/gcc/dwarf2cfi.c
> +++ b/gcc/dwarf2cfi.c
> @@ -3377,21 +3377,6 @@ dwarf2out_do_cfi_asm (void)
>    return true;
>  }
>
> -static bool
> -gate_dwarf2_frame (void)
> -{
> -#ifndef HAVE_prologue
> -  /* Targets which still implement the prologue in assembler text
> -     cannot use the generic dwarf2 unwinding.  */
> -  return false;
> -#endif
> -
> -  /* ??? What to do for UI_TARGET unwinding?  They might be able to benefit
> -     from the optimized shrink-wrapping annotations that we will compute.
> -     For now, only produce the CFI notes for dwarf2.  */
> -  return dwarf2out_do_frame ();
> -}
> -
>  namespace {
>
>  const pass_data pass_data_dwarf2_frame =
> @@ -3416,11 +3401,26 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_dwarf2_frame (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return execute_dwarf2_frame (); }
>
>  }; // class pass_dwarf2_frame
>
> +bool
> +pass_dwarf2_frame::gate (function *)
> +{
> +#ifndef HAVE_prologue
> +  /* Targets which still implement the prologue in assembler text
> +     cannot use the generic dwarf2 unwinding.  */
> +  return false;
> +#endif
> +
> +  /* ??? What to do for UI_TARGET unwinding?  They might be able to benefit
> +     from the optimized shrink-wrapping annotations that we will compute.
> +     For now, only produce the CFI notes for dwarf2.  */
> +  return dwarf2out_do_frame ();
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/except.c b/gcc/except.c
> index cf3cd5f..2015809 100644
> --- a/gcc/except.c
> +++ b/gcc/except.c
> @@ -2620,17 +2620,6 @@ convert_to_eh_region_ranges (void)
>    return 0;
>  }
>
> -static bool
> -gate_convert_to_eh_region_ranges (void)
> -{
> -  /* Nothing to do for SJLJ exceptions or if no regions created.  */
> -  if (cfun->eh->region_tree == NULL)
> -    return false;
> -  if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
> -    return false;
> -  return true;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_convert_to_eh_region_ranges =
> @@ -2655,11 +2644,22 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_convert_to_eh_region_ranges (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return convert_to_eh_region_ranges (); }
>
>  }; // class pass_convert_to_eh_region_ranges
>
> +bool
> +pass_convert_to_eh_region_ranges::gate (function *)
> +{
> +  /* Nothing to do for SJLJ exceptions or if no regions created.  */
> +  if (cfun->eh->region_tree == NULL)
> +    return false;
> +  if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
> +    return false;
> +  return true;
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/fwprop.c b/gcc/fwprop.c
> index 061d533..c6fa4ee 100644
> --- a/gcc/fwprop.c
> +++ b/gcc/fwprop.c
> @@ -1508,7 +1508,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_fwprop (); }
> +  virtual bool gate (function *) { return gate_fwprop (); }
>    unsigned int execute () { return fwprop (); }
>
>  }; // class pass_rtl_fwprop
> @@ -1573,7 +1573,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_fwprop (); }
> +  virtual bool gate (function *) { return gate_fwprop (); }
>    unsigned int execute () { return fwprop_addr (); }
>
>  }; // class pass_rtl_fwprop_addr
> diff --git a/gcc/gcse.c b/gcc/gcse.c
> index 6797b08..942ea64 100644
> --- a/gcc/gcse.c
> +++ b/gcc/gcse.c
> @@ -4157,24 +4157,6 @@ is_too_expensive (const char *pass)
>    return false;
>  }
>
> -/* All the passes implemented in this file.  Each pass has its
> -   own gate and execute function, and at the end of the file a
> -   pass definition for passes.c.
> -
> -   We do not construct an accurate cfg in functions which call
> -   setjmp, so none of these passes runs if the function calls
> -   setjmp.
> -   FIXME: Should just handle setjmp via REG_SETJMP notes.  */
> -
> -static bool
> -gate_rtl_pre (void)
> -{
> -  return optimize > 0 && flag_gcse
> -    && !cfun->calls_setjmp
> -    && optimize_function_for_speed_p (cfun)
> -    && dbg_cnt (pre);
> -}
> -
>  static unsigned int
>  execute_rtl_pre (void)
>  {
> @@ -4188,18 +4170,6 @@ execute_rtl_pre (void)
>    return 0;
>  }
>
> -static bool
> -gate_rtl_hoist (void)
> -{
> -  return optimize > 0 && flag_gcse
> -    && !cfun->calls_setjmp
> -    /* It does not make sense to run code hoisting unless we are optimizing
> -       for code size -- it rarely makes programs faster, and can make then
> -       bigger if we did PRE (when optimizing for space, we don't run PRE).  */
> -    && optimize_function_for_size_p (cfun)
> -    && dbg_cnt (hoist);
> -}
> -
>  static unsigned int
>  execute_rtl_hoist (void)
>  {
> @@ -4238,11 +4208,25 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_pre (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return execute_rtl_pre (); }
>
>  }; // class pass_rtl_pre
>
> +/* We do not construct an accurate cfg in functions which call
> +   setjmp, so none of these passes runs if the function calls
> +   setjmp.
> +   FIXME: Should just handle setjmp via REG_SETJMP notes.  */
> +
> +bool
> +pass_rtl_pre::gate (function *fun)
> +{
> +  return optimize > 0 && flag_gcse
> +    && !fun->calls_setjmp
> +    && optimize_function_for_speed_p (fun)
> +    && dbg_cnt (pre);
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> @@ -4276,11 +4260,23 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_hoist (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return execute_rtl_hoist (); }
>
>  }; // class pass_rtl_hoist
>
> +bool
> +pass_rtl_hoist::gate (function *)
> +{
> +  return optimize > 0 && flag_gcse
> +    && !cfun->calls_setjmp
> +    /* It does not make sense to run code hoisting unless we are optimizing
> +       for code size -- it rarely makes programs faster, and can make then
> +       bigger if we did PRE (when optimizing for space, we don't run PRE).  */
> +    && optimize_function_for_size_p (cfun)
> +    && dbg_cnt (hoist);
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
> index e0ce2ec..ab6185c 100644
> --- a/gcc/gimple-ssa-isolate-paths.c
> +++ b/gcc/gimple-ssa-isolate-paths.c
> @@ -414,15 +414,6 @@ gimple_ssa_isolate_erroneous_paths (void)
>    return 0;
>  }
>
> -static bool
> -gate_isolate_erroneous_paths (void)
> -{
> -  /* If we do not have a suitable builtin function for the trap statement,
> -     then do not perform the optimization.  */
> -  return (flag_isolate_erroneous_paths_dereference != 0
> -         || flag_isolate_erroneous_paths_attribute != 0);
> -}
> -
>  namespace {
>  const pass_data pass_data_isolate_erroneous_paths =
>  {
> @@ -447,7 +438,14 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_isolate_erroneous_paths (m_ctxt); }
> -  bool gate () { return gate_isolate_erroneous_paths (); }
> +  virtual bool gate (function *)
> +    {
> +      /* If we do not have a suitable builtin function for the trap statement,
> +        then do not perform the optimization.  */
> +      return (flag_isolate_erroneous_paths_dereference != 0
> +             || flag_isolate_erroneous_paths_attribute != 0);
> +    }
> +
>    unsigned int execute () { return gimple_ssa_isolate_erroneous_paths (); }
>
>  }; // class pass_isolate_erroneous_paths
> diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
> index 8d19031..a8596e0 100644
> --- a/gcc/gimple-ssa-strength-reduction.c
> +++ b/gcc/gimple-ssa-strength-reduction.c
> @@ -3646,12 +3646,6 @@ execute_strength_reduction (void)
>    return 0;
>  }
>
> -static bool
> -gate_strength_reduction (void)
> -{
> -  return flag_tree_slsr;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_strength_reduction =
> @@ -3676,7 +3670,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_strength_reduction (); }
> +  virtual bool gate (function *) { return flag_tree_slsr; }
>    unsigned int execute () { return execute_strength_reduction (); }
>
>  }; // class pass_strength_reduction
> diff --git a/gcc/graphite.c b/gcc/graphite.c
> index 03a7161..68c9390 100644
> --- a/gcc/graphite.c
> +++ b/gcc/graphite.c
> @@ -374,7 +374,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_graphite_transforms (); }
> +  virtual bool gate (function *) { return gate_graphite_transforms (); }
>
>  }; // class pass_graphite
>
> @@ -410,7 +410,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_graphite_transforms (); }
> +  virtual bool gate (function *) { return gate_graphite_transforms (); }
>    unsigned int execute () { return graphite_transforms (); }
>
>  }; // class pass_graphite_transforms
> diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
> index 5c0843d..657b585 100644
> --- a/gcc/ifcvt.c
> +++ b/gcc/ifcvt.c
> @@ -4512,13 +4512,6 @@ if_convert (bool after_combine)
>  #endif
>  }
>
> -static bool
> -gate_handle_if_conversion (void)
> -{
> -  return (optimize > 0)
> -    && dbg_cnt (if_conversion);
> -}
> -
>  /* If-conversion and CFG cleanup.  */
>  static unsigned int
>  rest_of_handle_if_conversion (void)
> @@ -4562,7 +4555,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_if_conversion (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize > 0) && dbg_cnt (if_conversion);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_if_conversion (); }
>
>  }; // class pass_rtl_ifcvt
> @@ -4575,13 +4572,6 @@ make_pass_rtl_ifcvt (gcc::context *ctxt)
>    return new pass_rtl_ifcvt (ctxt);
>  }
>
> -static bool
> -gate_handle_if_after_combine (void)
> -{
> -  return optimize > 0 && flag_if_conversion
> -    && dbg_cnt (if_after_combine);
> -}
> -
>
>  /* Rerun if-conversion, as combine may have simplified things enough
>     to now meet sequence length restrictions.  */
> @@ -4616,7 +4606,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_if_after_combine (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_if_conversion
> +       && dbg_cnt (if_after_combine);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_if_after_combine (); }
>
>  }; // class pass_if_after_combine
> @@ -4630,13 +4625,6 @@ make_pass_if_after_combine (gcc::context *ctxt)
>  }
>
>
> -static bool
> -gate_handle_if_after_reload (void)
> -{
> -  return optimize > 0 && flag_if_conversion2
> -    && dbg_cnt (if_after_reload);
> -}
> -
>  static unsigned int
>  rest_of_handle_if_after_reload (void)
>  {
> @@ -4669,7 +4657,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_if_after_reload (); }
> +  virtual bool gate (function *)
> +    {
> +      return optimize > 0 && flag_if_conversion2
> +       && dbg_cnt (if_after_reload);
> +    }
> +
>    unsigned int execute () { return rest_of_handle_if_after_reload (); }
>
>  }; // class pass_if_after_reload
> diff --git a/gcc/init-regs.c b/gcc/init-regs.c
> index 265fed7..2025b77 100644
> --- a/gcc/init-regs.c
> +++ b/gcc/init-regs.c
> @@ -125,12 +125,6 @@ initialize_uninitialized_regs (void)
>    BITMAP_FREE (already_genned);
>  }
>
> -static bool
> -gate_initialize_regs (void)
> -{
> -  return optimize > 0;
> -}
> -
>  static unsigned int
>  rest_of_handle_initialize_regs (void)
>  {
> @@ -162,7 +156,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_initialize_regs (); }
> +  virtual bool gate (function *) { return optimize > 0; }
>    unsigned int execute () { return rest_of_handle_initialize_regs (); }
>
>  }; // class pass_initialize_regs
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index 1f28b69..ee48fc0 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -3762,16 +3762,6 @@ ipcp_read_summary (void)
>    ipa_prop_read_jump_functions ();
>  }
>
> -/* Gate for IPCP optimization.  */
> -
> -static bool
> -cgraph_gate_cp (void)
> -{
> -  /* FIXME: We should remove the optimize check after we ensure we never run
> -     IPA passes when not optimizing.  */
> -  return flag_ipa_cp && optimize;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_cp =
> @@ -3807,7 +3797,13 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return cgraph_gate_cp (); }
> +  virtual bool gate (function *)
> +    {
> +      /* FIXME: We should remove the optimize check after we ensure we never run
> +        IPA passes when not optimizing.  */
> +      return flag_ipa_cp && optimize;
> +    }
> +
>    unsigned int execute () { return ipcp_driver (); }
>
>  }; // class pass_ipa_cp
> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
> index 19369c6..3bc6815 100644
> --- a/gcc/ipa-devirt.c
> +++ b/gcc/ipa-devirt.c
> @@ -1911,16 +1911,6 @@ ipa_devirt (void)
>    return ndevirtualized ? TODO_remove_functions : 0;
>  }
>
> -/* Gate for speculative IPA devirtualization optimization.  */
> -
> -static bool
> -gate_ipa_devirt (void)
> -{
> -  return (flag_devirtualize
> -         && flag_devirtualize_speculatively
> -         && optimize);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_devirt =
> @@ -1954,7 +1944,13 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ipa_devirt (); }
> +  virtual bool gate (function *)
> +    {
> +      return (flag_devirtualize
> +             && flag_devirtualize_speculatively
> +             && optimize);
> +    }
> +
>    unsigned int execute () { return ipa_devirt (); }
>
>  }; // class pass_ipa_devirt
> diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
> index f2a72de..7b58716 100644
> --- a/gcc/ipa-profile.c
> +++ b/gcc/ipa-profile.c
> @@ -711,12 +711,6 @@ ipa_profile (void)
>    return 0;
>  }
>
> -static bool
> -gate_ipa_profile (void)
> -{
> -  return flag_ipa_profile;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_profile =
> @@ -750,7 +744,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ipa_profile (); }
> +  virtual bool gate (function *) { return flag_ipa_profile; }
>    unsigned int execute () { return ipa_profile (); }
>
>  }; // class pass_ipa_profile
> diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
> index eac3636..eab7633 100644
> --- a/gcc/ipa-pure-const.c
> +++ b/gcc/ipa-pure-const.c
> @@ -1541,7 +1541,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_pure_const (); }
> +  virtual bool gate (function *) { return gate_pure_const (); }
>    unsigned int execute () { return propagate (); }
>
>  }; // class pass_ipa_pure_const
> @@ -1716,7 +1716,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_local_pure_const (m_ctxt); }
> -  bool gate () { return gate_pure_const (); }
> +  virtual bool gate (function *) { return gate_pure_const (); }
>    unsigned int execute () { return local_pure_const (); }
>
>  }; // class pass_local_pure_const
> @@ -1740,12 +1740,6 @@ execute_warn_function_noreturn (void)
>    return 0;
>  }
>
> -static bool
> -gate_warn_function_noreturn (void)
> -{
> -  return warn_suggest_attribute_noreturn;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_warn_function_noreturn =
> @@ -1770,7 +1764,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_warn_function_noreturn (); }
> +  virtual bool gate (function *) { return warn_suggest_attribute_noreturn; }
>    unsigned int execute () { return execute_warn_function_noreturn (); }
>
>  }; // class pass_warn_function_noreturn
> diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
> index 126948e..51a57ac 100644
> --- a/gcc/ipa-reference.c
> +++ b/gcc/ipa-reference.c
> @@ -1148,14 +1148,6 @@ ipa_reference_read_optimization_summary (void)
>      }
>  }
>
> -static bool
> -gate_reference (void)
> -{
> -  return (flag_ipa_reference
> -         /* Don't bother doing anything if the program has errors.  */
> -         && !seen_error ());
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_reference =
> @@ -1191,7 +1183,13 @@ public:
>      {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_reference (); }
> +  virtual bool gate (function *)
> +    {
> +      return (flag_ipa_reference
> +             /* Don't bother doing anything if the program has errors.  */
> +             && !seen_error ());
> +    }
> +
>    unsigned int execute () { return propagate (); }
>
>  }; // class pass_ipa_reference
> diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
> index ebb9197..187dc98 100644
> --- a/gcc/ipa-split.c
> +++ b/gcc/ipa-split.c
> @@ -1646,17 +1646,6 @@ execute_split_functions (void)
>    return todo;
>  }
>
> -/* Gate function splitting pass.  When doing profile feedback, we want
> -   to execute the pass after profiling is read.  So disable one in
> -   early optimization.  */
> -
> -static bool
> -gate_split_functions (void)
> -{
> -  return (flag_partial_inlining
> -         && !profile_arc_flag && !flag_branch_probabilities);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_split_functions =
> @@ -1681,11 +1670,20 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_split_functions (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return execute_split_functions (); }
>
>  }; // class pass_split_functions
>
> +bool
> +pass_split_functions::gate (function *)
> +{
> +  /* When doing profile feedback, we want to execute the pass after profiling
> +     is read.  So disable one in early optimization.  */
> +  return (flag_partial_inlining
> +         && !profile_arc_flag && !flag_branch_probabilities);
> +}
> +
>  } // anon namespace
>
>  gimple_opt_pass *
> @@ -1694,17 +1692,6 @@ make_pass_split_functions (gcc::context *ctxt)
>    return new pass_split_functions (ctxt);
>  }
>
> -/* Gate feedback driven function splitting pass.
> -   We don't need to split when profiling at all, we are producing
> -   lousy code anyway.  */
> -
> -static bool
> -gate_feedback_split_functions (void)
> -{
> -  return (flag_partial_inlining
> -         && flag_branch_probabilities);
> -}
> -
>  /* Execute function splitting pass.  */
>
>  static unsigned int
> @@ -1740,11 +1727,20 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_feedback_split_functions (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return execute_feedback_split_functions (); }
>
>  }; // class pass_feedback_split_functions
>
> +bool
> +pass_feedback_split_functions::gate (function *)
> +{
> +  /* We don't need to split when profiling at all, we are producing
> +     lousy code anyway.  */
> +  return (flag_partial_inlining
> +         && flag_branch_probabilities);
> +}
> +
>  } // anon namespace
>
>  gimple_opt_pass *
> diff --git a/gcc/ipa.c b/gcc/ipa.c
> index 5e06509..7af2584 100644
> --- a/gcc/ipa.c
> +++ b/gcc/ipa.c
> @@ -1272,14 +1272,6 @@ make_pass_ipa_free_inline_summary (gcc::context *ctxt)
>    return new pass_ipa_free_inline_summary (ctxt);
>  }
>
> -/* Do not re-run on ltrans stage.  */
> -
> -static bool
> -gate_whole_program_function_and_variable_visibility (void)
> -{
> -  return !flag_ltrans;
> -}
> -
>  /* Bring functionss local at LTO time with -fwhole-program.  */
>
>  static unsigned int
> @@ -1324,9 +1316,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () {
> -    return gate_whole_program_function_and_variable_visibility ();
> -  }
> +
> +  virtual bool gate (function *)
> +    {
> +      /* Do not re-run on ltrans stage.  */
> +      return !flag_ltrans;
> +    }
>    unsigned int execute () {
>      return whole_program_function_and_variable_visibility ();
>    }
> @@ -1613,16 +1608,6 @@ ipa_cdtor_merge (void)
>    return 0;
>  }
>
> -/* Perform the pass when we have no ctors/dtors support
> -   or at LTO time to merge multiple constructors into single
> -   function.  */
> -
> -static bool
> -gate_ipa_cdtor_merge (void)
> -{
> -  return !targetm.have_ctors_dtors || (optimize && in_lto_p);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_cdtor_merge =
> @@ -1656,11 +1641,20 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ipa_cdtor_merge (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return ipa_cdtor_merge (); }
>
>  }; // class pass_ipa_cdtor_merge
>
> +bool
> +pass_ipa_cdtor_merge::gate (function *)
> +{
> +  /* Perform the pass when we have no ctors/dtors support
> +     or at LTO time to merge multiple constructors into single
> +     function.  */
> +  return !targetm.have_ctors_dtors || (optimize && in_lto_p);
> +}
> +
>  } // anon namespace
>
>  ipa_opt_pass_d *
> diff --git a/gcc/loop-init.c b/gcc/loop-init.c
> index d0bd4ec..6da29d3 100644
> --- a/gcc/loop-init.c
> +++ b/gcc/loop-init.c
> @@ -287,31 +287,8 @@ fix_loop_structure (bitmap changed_bbs)
>    return number_of_loops (cfun) - old_nloops;
>  }
>
> -/* Gate for the RTL loop superpass.  The actual passes are subpasses.
> -   See passes.c for more on that.  */
> -
> -static bool
> -gate_handle_loop2 (void)
> -{
> -  if (optimize > 0
> -      && (flag_move_loop_invariants
> -         || flag_unswitch_loops
> -         || flag_peel_loops
> -         || flag_unroll_loops
> -#ifdef HAVE_doloop_end
> -         || (flag_branch_on_count_reg && HAVE_doloop_end)
> -#endif
> -        ))
> -    return true;
> -  else
> -    {
> -      /* No longer preserve loops, remove them now.  */
> -      cfun->curr_properties &= ~PROP_loops;
> -      if (current_loops)
> -       loop_optimizer_finalize ();
> -      return false;
> -    }
> -}
> +/* The RTL loop superpass.  The actual passes are subpasses.  See passes.c for
> +   more on that.  */
>
>  namespace {
>
> @@ -337,10 +314,33 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_loop2 (); }
> +  virtual bool gate (function *);
>
>  }; // class pass_loop2
>
> +bool
> +pass_loop2::gate (function *fun)
> +{
> +  if (optimize > 0
> +      && (flag_move_loop_invariants
> +         || flag_unswitch_loops
> +         || flag_peel_loops
> +         || flag_unroll_loops
> +#ifdef HAVE_doloop_end
> +         || (flag_branch_on_count_reg && HAVE_doloop_end)
> +#endif
> +      ))
> +    return true;
> +  else
> +    {
> +      /* No longer preserve loops, remove them now.  */
> +      fun->curr_properties &= ~PROP_loops;
> +      if (current_loops)
> +       loop_optimizer_finalize ();
> +      return false;
> +    }
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> @@ -461,12 +461,6 @@ make_pass_rtl_loop_done (gcc::context *ctxt)
>
>
>  /* Loop invariant code motion.  */
> -static bool
> -gate_rtl_move_loop_invariants (void)
> -{
> -  return flag_move_loop_invariants;
> -}
> -
>  static unsigned int
>  rtl_move_loop_invariants (void)
>  {
> @@ -500,7 +494,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_move_loop_invariants (); }
> +  virtual bool gate (function *) { return flag_move_loop_invariants; }
>    unsigned int execute () { return rtl_move_loop_invariants (); }
>
>  }; // class pass_rtl_move_loop_invariants
> @@ -514,13 +508,6 @@ make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
>  }
>
>
> -/* Loop unswitching for RTL.  */
> -static bool
> -gate_rtl_unswitch (void)
> -{
> -  return flag_unswitch_loops;
> -}
> -
>  static unsigned int
>  rtl_unswitch (void)
>  {
> @@ -553,7 +540,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_unswitch (); }
> +  virtual bool gate (function *) { return flag_unswitch_loops; }
>    unsigned int execute () { return rtl_unswitch (); }
>
>  }; // class pass_rtl_unswitch
> @@ -567,13 +554,6 @@ make_pass_rtl_unswitch (gcc::context *ctxt)
>  }
>
>
> -/* Loop unswitching for RTL.  */
> -static bool
> -gate_rtl_unroll_and_peel_loops (void)
> -{
> -  return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
> -}
> -
>  static unsigned int
>  rtl_unroll_and_peel_loops (void)
>  {
> @@ -619,7 +599,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_unroll_and_peel_loops (); }
> +  virtual bool gate (function *)
> +    {
> +      return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
> +    }
> +
>    unsigned int execute () { return rtl_unroll_and_peel_loops (); }
>
>  }; // class pass_rtl_unroll_and_peel_loops
> @@ -633,17 +617,6 @@ make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt)
>  }
>
>
> -/* The doloop optimization.  */
> -static bool
> -gate_rtl_doloop (void)
> -{
> -#ifdef HAVE_doloop_end
> -  return (flag_branch_on_count_reg && HAVE_doloop_end);
> -#else
> -  return 0;
> -#endif
> -}
> -
>  static unsigned int
>  rtl_doloop (void)
>  {
> @@ -678,11 +651,21 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_doloop (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return rtl_doloop (); }
>
>  }; // class pass_rtl_doloop
>
> +bool
> +pass_rtl_doloop::gate (function *)
> +{
> +#ifdef HAVE_doloop_end
> +  return (flag_branch_on_count_reg && HAVE_doloop_end);
> +#else
> +  return false;
> +#endif
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
> index 53ef1d9..89d9763 100644
> --- a/gcc/lower-subreg.c
> +++ b/gcc/lower-subreg.c
> @@ -1687,14 +1687,6 @@ decompose_multiword_subregs (bool decompose_copies)
>    BITMAP_FREE (subreg_context);
>  }
>
> -/* Gate function for lower subreg pass.  */
> -
> -static bool
> -gate_handle_lower_subreg (void)
> -{
> -  return flag_split_wide_types != 0;
> -}
> -
>  /* Implement first lower subreg pass.  */
>
>  static unsigned int
> @@ -1737,7 +1729,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_lower_subreg (); }
> +  virtual bool gate (function *) { return flag_split_wide_types != 0; }
>    unsigned int execute () { return rest_of_handle_lower_subreg (); }
>
>  }; // class pass_lower_subreg
> @@ -1775,7 +1767,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_lower_subreg (); }
> +  virtual bool gate (function *) { return flag_split_wide_types != 0; }
>    unsigned int execute () { return rest_of_handle_lower_subreg2 (); }
>
>  }; // class pass_lower_subreg2
> diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
> index d73135a..e73d6ee 100644
> --- a/gcc/mode-switching.c
> +++ b/gcc/mode-switching.c
> @@ -789,16 +789,6 @@ optimize_mode_switching (void)
>
>  #endif /* OPTIMIZE_MODE_SWITCHING */
>
> -static bool
> -gate_mode_switching (void)
> -{
> -#ifdef OPTIMIZE_MODE_SWITCHING
> -  return true;
> -#else
> -  return false;
> -#endif
> -}
> -
>  static unsigned int
>  rest_of_handle_mode_switching (void)
>  {
> @@ -836,7 +826,15 @@ public:
>    /* The epiphany backend creates a second instance of this pass, so we need
>       a clone method.  */
>    opt_pass * clone () { return new pass_mode_switching (m_ctxt); }
> -  bool gate () { return gate_mode_switching (); }
> +  virtual bool gate (function *)
> +    {
> +#ifdef OPTIMIZE_MODE_SWITCHING
> +      return true;
> +#else
> +      return false;
> +#endif
> +    }
> +
>    unsigned int execute () { return rest_of_handle_mode_switching (); }
>
>  }; // class pass_mode_switching
> diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
> index a097df3..20e2e62 100644
> --- a/gcc/modulo-sched.c
> +++ b/gcc/modulo-sched.c
> @@ -3323,13 +3323,6 @@ rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle)
>
>  #endif /* INSN_SCHEDULING */
>
> -static bool
> -gate_handle_sms (void)
> -{
> -  return (optimize > 0 && flag_modulo_sched);
> -}
> -
> -
>  /* Run instruction scheduler.  */
>  /* Perform SMS module scheduling.  */
>  static unsigned int
> @@ -3380,7 +3373,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_sms (); }
> +  virtual bool gate (function *)
> +{
> +  return (optimize > 0 && flag_modulo_sched);
> +}
> +
>    unsigned int execute () { return rest_of_handle_sms (); }
>
>  }; // class pass_sms
> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
> index cadec81..0e96b88 100644
> --- a/gcc/omp-low.c
> +++ b/gcc/omp-low.c
> @@ -8326,13 +8326,6 @@ execute_expand_omp (void)
>
>  /* OMP expansion -- the default pass, run before creation of SSA form.  */
>
> -static bool
> -gate_expand_omp (void)
> -{
> -  return ((flag_openmp != 0 || flag_openmp_simd != 0
> -          || flag_cilkplus != 0) && !seen_error ());
> -}
> -
>  namespace {
>
>  const pass_data pass_data_expand_omp =
> @@ -8357,7 +8350,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_expand_omp (); }
> +  virtual bool gate (function *)
> +    {
> +      return ((flag_openmp != 0 || flag_openmp_simd != 0
> +              || flag_cilkplus != 0) && !seen_error ());
> +    }
> +
>    unsigned int execute () { return execute_expand_omp (); }
>
>  }; // class pass_expand_omp
> @@ -10617,12 +10615,6 @@ diagnose_omp_structured_block_errors (void)
>    return 0;
>  }
>
> -static bool
> -gate_diagnose_omp_blocks (void)
> -{
> -  return flag_openmp || flag_cilkplus;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_diagnose_omp_blocks =
> @@ -10647,7 +10639,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_diagnose_omp_blocks (); }
> +  virtual bool gate (function *) { return flag_openmp || flag_cilkplus; }
>    unsigned int execute () {
>      return diagnose_omp_structured_block_errors ();
>    }
> @@ -11811,13 +11803,19 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return ((flag_openmp || flag_openmp_simd
> -                         || flag_cilkplus || (in_lto_p && !flag_wpa))
> -                        && (targetm.simd_clone.compute_vecsize_and_simdlen
> -                            != NULL)); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return ipa_omp_simd_clone (); }
>  };
>
> +bool
> +pass_omp_simd_clone::gate (function *)
> +{
> +  return ((flag_openmp || flag_openmp_simd
> +          || flag_cilkplus
> +          || (in_lto_p && !flag_wpa))
> +         && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL));
> +}
> +
>  } // anon namespace
>
>  simple_ipa_opt_pass *
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 5d5a94c..b71c11e 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -108,7 +108,7 @@ opt_pass::clone ()
>  }
>
>  bool
> -opt_pass::gate ()
> +opt_pass::gate (function *)
>  {
>    return true;
>  }
> @@ -337,15 +337,6 @@ execute_all_early_local_passes (void)
>    return 0;
>  }
>
> -/* Gate: execute, or not, all of the non-trivial optimizations.  */
> -
> -static bool
> -gate_all_early_local_passes (void)
> -{
> -         /* Don't bother doing anything if the program has errors.  */
> -  return (!seen_error () && !in_lto_p);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_early_local_passes =
> @@ -370,7 +361,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_all_early_local_passes (); }
> +  virtual bool gate (function *)
> +    {
> +      /* Don't bother doing anything if the program has errors.  */
> +      return (!seen_error () && !in_lto_p);
> +    }
> +
>    unsigned int execute () { return execute_all_early_local_passes (); }
>
>  }; // class pass_early_local_passes
> @@ -383,16 +379,6 @@ make_pass_early_local_passes (gcc::context *ctxt)
>    return new pass_early_local_passes (ctxt);
>  }
>
> -/* Gate: execute, or not, all of the non-trivial optimizations.  */
> -
> -static bool
> -gate_all_early_optimizations (void)
> -{
> -  return (optimize >= 1
> -         /* Don't bother doing anything if the program has errors.  */
> -         && !seen_error ());
> -}
> -
>  namespace {
>
>  const pass_data pass_data_all_early_optimizations =
> @@ -417,7 +403,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_all_early_optimizations (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize >= 1
> +             /* Don't bother doing anything if the program has errors.  */
> +             && !seen_error ());
> +    }
>
>  }; // class pass_all_early_optimizations
>
> @@ -429,14 +420,6 @@ make_pass_all_early_optimizations (gcc::context *ctxt)
>    return new pass_all_early_optimizations (ctxt);
>  }
>
> -/* Gate: execute, or not, all of the non-trivial optimizations.  */
> -
> -static bool
> -gate_all_optimizations (void)
> -{
> -  return optimize >= 1 && !optimize_debug;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_all_optimizations =
> @@ -461,7 +444,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_all_optimizations (); }
> +  virtual bool gate (function *) { return optimize >= 1 && !optimize_debug; }
>
>  }; // class pass_all_optimizations
>
> @@ -473,14 +456,6 @@ make_pass_all_optimizations (gcc::context *ctxt)
>    return new pass_all_optimizations (ctxt);
>  }
>
> -/* Gate: execute, or not, all of the non-trivial optimizations.  */
> -
> -static bool
> -gate_all_optimizations_g (void)
> -{
> -  return optimize >= 1 && optimize_debug;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_all_optimizations_g =
> @@ -505,7 +480,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_all_optimizations_g (); }
> +  virtual bool gate (function *) { return optimize >= 1 && optimize_debug; }
>
>  }; // class pass_all_optimizations_g
>
> @@ -517,14 +492,6 @@ make_pass_all_optimizations_g (gcc::context *ctxt)
>    return new pass_all_optimizations_g (ctxt);
>  }
>
> -static bool
> -gate_rest_of_compilation (void)
> -{
> -  /* 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 || seen_error ());
> -}
> -
>  namespace {
>
>  const pass_data pass_data_rest_of_compilation =
> @@ -549,7 +516,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rest_of_compilation (); }
> +  virtual bool gate (function *)
> +    {
> +      /* 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 || seen_error ());
> +    }
>
>  }; // class pass_rest_of_compilation
>
> @@ -561,12 +533,6 @@ make_pass_rest_of_compilation (gcc::context *ctxt)
>    return new pass_rest_of_compilation (ctxt);
>  }
>
> -static bool
> -gate_postreload (void)
> -{
> -  return reload_completed;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_postreload =
> @@ -591,7 +557,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_postreload (); }
> +  virtual bool gate (function *) { return reload_completed; }
>
>  }; // class pass_postreload
>
> @@ -823,7 +789,7 @@ dump_one_pass (opt_pass *pass, int pass_indent)
>    const char *pn;
>    bool is_on, is_really_on;
>
> -  is_on = pass->gate ();
> +  is_on = pass->gate (cfun);
>    is_really_on = override_gate_status (pass, current_function_decl, is_on);
>
>    if (pass->static_pass_number <= 0)
> @@ -1976,7 +1942,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
>
>        /* Execute all of the IPA_PASSes in the list.  */
>        if (ipa_pass->type == IPA_PASS
> -         && pass->gate ()
> +         && pass->gate (cfun)
>           && ipa_pass->generate_summary)
>         {
>           pass_init_dump_file (pass);
> @@ -2128,7 +2094,7 @@ execute_one_pass (opt_pass *pass)
>
>    /* Check whether gate check should be avoided.
>       User controls the value of the gate through the parameter "gate_status". */
> -  gate_status = pass->gate ();
> +  gate_status = pass->gate (cfun);
>    gate_status = override_gate_status (pass, current_function_decl, gate_status);
>
>    /* Override gate with plugin.  */
> @@ -2274,7 +2240,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
>        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>        if (pass->type == IPA_PASS
>           && ipa_pass->write_summary
> -         && pass->gate ())
> +         && pass->gate (cfun))
>         {
>           /* If a timevar is present, start it.  */
>           if (pass->tv_id)
> @@ -2392,7 +2358,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass,
>        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>        if (pass->type == IPA_PASS
>           && ipa_pass->write_optimization_summary
> -         && pass->gate ())
> +         && pass->gate (cfun))
>         {
>           /* If a timevar is present, start it.  */
>           if (pass->tv_id)
> @@ -2470,7 +2436,7 @@ ipa_read_summaries_1 (opt_pass *pass)
>        gcc_assert (!cfun);
>        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>
> -      if (pass->gate ())
> +      if (pass->gate (cfun))
>         {
>           if (pass->type == IPA_PASS && ipa_pass->read_summary)
>             {
> @@ -2520,7 +2486,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass)
>        gcc_assert (!cfun);
>        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>
> -      if (pass->gate ())
> +      if (pass->gate (cfun))
>         {
>           if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
>             {
> @@ -2597,7 +2563,7 @@ execute_ipa_stmt_fixups (opt_pass *pass,
>      {
>        /* Execute all of the IPA_PASSes in the list.  */
>        if (pass->type == IPA_PASS
> -         && pass->gate ())
> +         && pass->gate (cfun))
>         {
>           ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
>
> diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
> index 264bd9a..8a804fb 100644
> --- a/gcc/postreload-gcse.c
> +++ b/gcc/postreload-gcse.c
> @@ -1308,13 +1308,6 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
>  }
>
>
> -static bool
> -gate_handle_gcse2 (void)
> -{
> -  return (optimize > 0 && flag_gcse_after_reload
> -         && optimize_function_for_speed_p (cfun));
> -}
> -
>
>  static unsigned int
>  rest_of_handle_gcse2 (void)
> @@ -1348,7 +1341,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_gcse2 (); }
> +  virtual bool gate (function *fun)
> +    {
> +      return (optimize > 0 && flag_gcse_after_reload
> +             && optimize_function_for_speed_p (fun));
> +    }
> +
>    unsigned int execute () { return rest_of_handle_gcse2 (); }
>
>  }; // class pass_gcse2
> diff --git a/gcc/postreload.c b/gcc/postreload.c
> index 0870183..0568c53 100644
> --- a/gcc/postreload.c
> +++ b/gcc/postreload.c
> @@ -2315,13 +2315,6 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
>      }
>  }
>
> -static bool
> -gate_handle_postreload (void)
> -{
> -  return (optimize > 0 && reload_completed);
> -}
> -
> -
>  static unsigned int
>  rest_of_handle_postreload (void)
>  {
> @@ -2363,7 +2356,8 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_postreload (); }
> +  virtual bool gate (function *) { return (optimize > 0 && reload_completed); }
> +
>    unsigned int execute () { return rest_of_handle_postreload (); }
>
>  }; // class pass_postreload_cse
> diff --git a/gcc/predict.c b/gcc/predict.c
> index dccde72..068c187 100644
> --- a/gcc/predict.c
> +++ b/gcc/predict.c
> @@ -3131,12 +3131,6 @@ compute_function_frequency (void)
>      }
>  }
>
> -static bool
> -gate_estimate_probability (void)
> -{
> -  return flag_guess_branch_prob;
> -}
> -
>  /* Build PREDICT_EXPR.  */
>  tree
>  build_predict_expr (enum br_predictor predictor, enum prediction taken)
> @@ -3177,7 +3171,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_estimate_probability (); }
> +  virtual bool gate (function *) { return flag_guess_branch_prob; }
>    unsigned int execute () { return tree_estimate_probability_driver (); }
>
>  }; // class pass_profile
> diff --git a/gcc/recog.c b/gcc/recog.c
> index b7113aa..8afea7e 100644
> --- a/gcc/recog.c
> +++ b/gcc/recog.c
> @@ -3810,12 +3810,6 @@ if_test_bypass_p (rtx out_insn, rtx in_insn)
>    return true;
>  }
>
> -static bool
> -gate_handle_peephole2 (void)
> -{
> -  return (optimize > 0 && flag_peephole2);
> -}
> -
>  static unsigned int
>  rest_of_handle_peephole2 (void)
>  {
> @@ -3852,7 +3846,7 @@ public:
>    /* The epiphany backend creates a second instance of this pass, so we need
>       a clone method.  */
>    opt_pass * clone () { return new pass_peephole2 (m_ctxt); }
> -  bool gate () { return gate_handle_peephole2 (); }
> +  virtual bool gate (function *) { return (optimize > 0 && flag_peephole2); }
>    unsigned int execute () { return rest_of_handle_peephole2 (); }
>
>  }; // class pass_peephole2
> @@ -3958,24 +3952,6 @@ make_pass_split_after_reload (gcc::context *ctxt)
>    return new pass_split_after_reload (ctxt);
>  }
>
> -static bool
> -gate_handle_split_before_regstack (void)
> -{
> -#if HAVE_ATTR_length && defined (STACK_REGS)
> -  /* If flow2 creates new instructions which need splitting
> -     and scheduling after reload is not done, they might not be
> -     split until final which doesn't allow splitting
> -     if HAVE_ATTR_length.  */
> -# ifdef INSN_SCHEDULING
> -  return (optimize && !flag_schedule_insns_after_reload);
> -# else
> -  return (optimize);
> -# endif
> -#else
> -  return 0;
> -#endif
> -}
> -
>  static unsigned int
>  rest_of_handle_split_before_regstack (void)
>  {
> @@ -4007,13 +3983,31 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_split_before_regstack (); }
> +  virtual bool gate (function *);
>    unsigned int execute () {
>      return rest_of_handle_split_before_regstack ();
>    }
>
>  }; // class pass_split_before_regstack
>
> +bool
> +pass_split_before_regstack::gate (function *)
> +{
> +#if HAVE_ATTR_length && defined (STACK_REGS)
> +  /* If flow2 creates new instructions which need splitting
> +     and scheduling after reload is not done, they might not be
> +     split until final which doesn't allow splitting
> +     if HAVE_ATTR_length.  */
> +# ifdef INSN_SCHEDULING
> +  return (optimize && !flag_schedule_insns_after_reload);
> +# else
> +  return (optimize);
> +# endif
> +#else
> +  return 0;
> +#endif
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> @@ -4022,16 +4016,6 @@ make_pass_split_before_regstack (gcc::context *ctxt)
>    return new pass_split_before_regstack (ctxt);
>  }
>
> -static bool
> -gate_handle_split_before_sched2 (void)
> -{
> -#ifdef INSN_SCHEDULING
> -  return optimize > 0 && flag_schedule_insns_after_reload;
> -#else
> -  return 0;
> -#endif
> -}
> -
>  static unsigned int
>  rest_of_handle_split_before_sched2 (void)
>  {
> @@ -4065,7 +4049,15 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_split_before_sched2 (); }
> +  virtual bool gate (function *)
> +    {
> +#ifdef INSN_SCHEDULING
> +      return optimize > 0 && flag_schedule_insns_after_reload;
> +#else
> +      return false;
> +#endif
> +    }
> +
>    unsigned int execute () { return rest_of_handle_split_before_sched2 (); }
>
>  }; // class pass_split_before_sched2
> @@ -4078,18 +4070,6 @@ make_pass_split_before_sched2 (gcc::context *ctxt)
>    return new pass_split_before_sched2 (ctxt);
>  }
>
> -/* The placement of the splitting that we do for shorten_branches
> -   depends on whether regstack is used by the target or not.  */
> -static bool
> -gate_do_final_split (void)
> -{
> -#if HAVE_ATTR_length && !defined (STACK_REGS)
> -  return 1;
> -#else
> -  return 0;
> -#endif
> -}
> -
>  namespace {
>
>  const pass_data pass_data_split_for_shorten_branches =
> @@ -4114,7 +4094,17 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_do_final_split (); }
> +  virtual bool gate (function *)
> +    {
> +      /* The placement of the splitting that we do for shorten_branches
> +        depends on whether regstack is used by the target or not.  */
> +#if HAVE_ATTR_length && !defined (STACK_REGS)
> +      return true;
> +#else
> +      return false;
> +#endif
> +    }
> +
>    unsigned int execute () { return split_all_insns_noflow (); }
>
>  }; // class pass_split_for_shorten_branches
> diff --git a/gcc/ree.c b/gcc/ree.c
> index 09dfa61..435bb88 100644
> --- a/gcc/ree.c
> +++ b/gcc/ree.c
> @@ -1093,14 +1093,6 @@ rest_of_handle_ree (void)
>    return 0;
>  }
>
> -/* Run REE pass when flag_ree is set at optimization level > 0.  */
> -
> -static bool
> -gate_handle_ree (void)
> -{
> -  return (optimize > 0 && flag_ree);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ree =
> @@ -1125,7 +1117,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_ree (); }
> +  virtual bool gate (function *) { return (optimize > 0 && flag_ree); }
>    unsigned int execute () { return rest_of_handle_ree (); }
>
>  }; // class pass_ree
> diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
> index 02e3e09..f8f8658 100644
> --- a/gcc/reg-stack.c
> +++ b/gcc/reg-stack.c
> @@ -3285,16 +3285,6 @@ reg_to_stack (void)
>  }
>  #endif /* STACK_REGS */
>
> -static bool
> -gate_handle_stack_regs (void)
> -{
> -#ifdef STACK_REGS
> -  return 1;
> -#else
> -  return 0;
> -#endif
> -}
> -
>  namespace {
>
>  const pass_data pass_data_stack_regs =
> @@ -3319,7 +3309,14 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_stack_regs (); }
> +  virtual bool gate (function *)
> +    {
> +#ifdef STACK_REGS
> +      return true;
> +#else
> +      return false;
> +#endif
> +    }
>
>  }; // class pass_stack_regs
>
> diff --git a/gcc/regcprop.c b/gcc/regcprop.c
> index a7dbbc3..24992e4 100644
> --- a/gcc/regcprop.c
> +++ b/gcc/regcprop.c
> @@ -1247,13 +1247,6 @@ validate_value_data (struct value_data *vd)
>  }
>  #endif
>
> -static bool
> -gate_handle_cprop (void)
> -{
> -  return (optimize > 0 && (flag_cprop_registers));
> -}
> -
> -
>  namespace {
>
>  const pass_data pass_data_cprop_hardreg =
> @@ -1278,7 +1271,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_cprop (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize > 0 && (flag_cprop_registers));
> +    }
> +
>    unsigned int execute () { return copyprop_hardreg_forward (); }
>
>  }; // class pass_cprop_hardreg
> diff --git a/gcc/regrename.c b/gcc/regrename.c
> index 30f7abc..321d5bf 100644
> --- a/gcc/regrename.c
> +++ b/gcc/regrename.c
> @@ -1836,12 +1836,6 @@ regrename_optimize (void)
>    return 0;
>  }
>
> -static bool
> -gate_handle_regrename (void)
> -{
> -  return (optimize > 0 && (flag_rename_registers));
> -}
> -
>  namespace {
>
>  const pass_data pass_data_regrename =
> @@ -1866,7 +1860,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_regrename (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize > 0 && (flag_rename_registers));
> +    }
> +
>    unsigned int execute () { return regrename_optimize (); }
>
>  }; // class pass_regrename
> diff --git a/gcc/reorg.c b/gcc/reorg.c
> index fff342f..22f0b5a 100644
> --- a/gcc/reorg.c
> +++ b/gcc/reorg.c
> @@ -3863,17 +3863,6 @@ dbr_schedule (rtx first)
>  }
>  #endif /* DELAY_SLOTS */
>
> -static bool
> -gate_handle_delay_slots (void)
> -{
> -#ifdef DELAY_SLOTS
> -  /* At -O0 dataflow info isn't updated after RA.  */
> -  return optimize > 0 && flag_delayed_branch && !crtl->dbr_scheduled_p;
> -#else
> -  return 0;
> -#endif
> -}
> -
>  /* Run delay slot optimization.  */
>  static unsigned int
>  rest_of_handle_delay_slots (void)
> @@ -3908,11 +3897,22 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_delay_slots (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return rest_of_handle_delay_slots (); }
>
>  }; // class pass_delay_slots
>
> +bool
> +pass_delay_slots::gate (function *)
> +{
> +#ifdef DELAY_SLOTS
> +  /* At -O0 dataflow info isn't updated after RA.  */
> +  return optimize > 0 && flag_delayed_branch && !crtl->dbr_scheduled_p;
> +#else
> +  return 0;
> +#endif
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> @@ -3922,12 +3922,6 @@ make_pass_delay_slots (gcc::context *ctxt)
>  }
>
>  /* Machine dependent reorg pass.  */
> -static bool
> -gate_handle_machine_reorg (void)
> -{
> -  return targetm.machine_dependent_reorg != 0;
> -}
> -
>
>  static unsigned int
>  rest_of_handle_machine_reorg (void)
> @@ -3960,7 +3954,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_machine_reorg (); }
> +  virtual bool gate (function *)
> +    {
> +      return targetm.machine_dependent_reorg != 0;
> +    }
> +
>    unsigned int execute () { return rest_of_handle_machine_reorg (); }
>
>  }; // class pass_machine_reorg
> diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
> index 18b50a4..e0a80c2 100644
> --- a/gcc/sched-rgn.c
> +++ b/gcc/sched-rgn.c
> @@ -3591,16 +3591,6 @@ advance_target_bb (basic_block bb, rtx insn)
>
>  #endif
>
> -static bool
> -gate_handle_live_range_shrinkage (void)
> -{
> -#ifdef INSN_SCHEDULING
> -  return flag_live_range_shrinkage;
> -#else
> -  return 0;
> -#endif
> -}
> -
>  /* Run instruction scheduler.  */
>  static unsigned int
>  rest_of_handle_live_range_shrinkage (void)
> @@ -3618,16 +3608,6 @@ rest_of_handle_live_range_shrinkage (void)
>    return 0;
>  }
>
> -static bool
> -gate_handle_sched (void)
> -{
> -#ifdef INSN_SCHEDULING
> -  return optimize > 0 && flag_schedule_insns && dbg_cnt (sched_func);
> -#else
> -  return 0;
> -#endif
> -}
> -
>  /* Run instruction scheduler.  */
>  static unsigned int
>  rest_of_handle_sched (void)
> @@ -3642,17 +3622,6 @@ rest_of_handle_sched (void)
>    return 0;
>  }
>
> -static bool
> -gate_handle_sched2 (void)
> -{
> -#ifdef INSN_SCHEDULING
> -  return optimize > 0 && flag_schedule_insns_after_reload
> -    && !targetm.delay_sched2 && dbg_cnt (sched2_func);
> -#else
> -  return 0;
> -#endif
> -}
> -
>  /* Run second scheduling pass after reload.  */
>  static unsigned int
>  rest_of_handle_sched2 (void)
> @@ -3699,7 +3668,15 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_live_range_shrinkage (); }
> +  virtual bool gate (function *)
> +    {
> +#ifdef INSN_SCHEDULING
> +      return flag_live_range_shrinkage;
> +#else
> +      return 0;
> +#endif
> +    }
> +
>    unsigned int execute () { return rest_of_handle_live_range_shrinkage (); }
>
>  }; // class pass_live_range_shrinkage
> @@ -3737,11 +3714,21 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_sched (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return rest_of_handle_sched (); }
>
>  }; // class pass_sched
>
> +bool
> +pass_sched::gate (function *)
> +{
> +#ifdef INSN_SCHEDULING
> +  return optimize > 0 && flag_schedule_insns && dbg_cnt (sched_func);
> +#else
> +  return 0;
> +#endif
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> @@ -3775,11 +3762,22 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_sched2 (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return rest_of_handle_sched2 (); }
>
>  }; // class pass_sched2
>
> +bool
> +pass_sched2::gate (function *)
> +{
> +#ifdef INSN_SCHEDULING
> +  return optimize > 0 && flag_schedule_insns_after_reload
> +    && !targetm.delay_sched2 && dbg_cnt (sched2_func);
> +#else
> +  return 0;
> +#endif
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/store-motion.c b/gcc/store-motion.c
> index 5aacaad..7c57754 100644
> --- a/gcc/store-motion.c
> +++ b/gcc/store-motion.c
> @@ -1223,15 +1223,6 @@ one_store_motion_pass (void)
>  }
>
>
> -static bool
> -gate_rtl_store_motion (void)
> -{
> -  return optimize > 0 && flag_gcse_sm
> -    && !cfun->calls_setjmp
> -    && optimize_function_for_speed_p (cfun)
> -    && dbg_cnt (store_motion);
> -}
> -
>  static unsigned int
>  execute_rtl_store_motion (void)
>  {
> @@ -1266,11 +1257,20 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_rtl_store_motion (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return execute_rtl_store_motion (); }
>
>  }; // class pass_rtl_store_motion
>
> +bool
> +pass_rtl_store_motion::gate (function *fun)
> +{
> +  return optimize > 0 && flag_gcse_sm
> +    && !fun->calls_setjmp
> +    && optimize_function_for_speed_p (fun)
> +    && dbg_cnt (store_motion);
> +}
> +
>  } // anon namespace
>
>  rtl_opt_pass *
> diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
> index d73bea8..a3b04a2 100644
> --- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
> +++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
> @@ -52,12 +52,6 @@ execute_dumb_plugin_example (void)
>    return 0;
>  }
>
> -static bool
> -gate_dumb_plugin_example (void)
> -{
> -  return true;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_dumb_plugin_example =
> @@ -82,7 +76,6 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_dumb_plugin_example (); }
>    unsigned int execute () { return execute_dumb_plugin_example (); }
>
>  }; // class pass_dumb_plugin_example
> diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c
> index 8df8579..033047b 100644
> --- a/gcc/testsuite/g++.dg/plugin/selfassign.c
> +++ b/gcc/testsuite/g++.dg/plugin/selfassign.c
> @@ -270,14 +270,6 @@ execute_warn_self_assign (void)
>    return 0;
>  }
>
> -/* Pass gate function. Currently always returns true.  */
> -
> -static bool
> -gate_warn_self_assign (void)
> -{
> -  return true;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_warn_self_assign =
> @@ -302,7 +294,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_warn_self_assign (); }
> +  bool gate (function *) { return true; }
>    unsigned int execute () { return execute_warn_self_assign (); }
>
>  }; // class pass_warn_self_assign
> diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
> index 33106ad..18e8b07 100644
> --- a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
> +++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
> @@ -49,7 +49,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate ();
> +  virtual bool gate (function *);
>    unsigned int execute ();
>
>  private:
> @@ -58,7 +58,7 @@ private:
>
>  } // anon namespace
>
> -bool one_pass::gate (void)
> +bool one_pass::gate (function *)
>  {
>    return true;
>  }
> diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c
> index 8df8579..098df06 100644
> --- a/gcc/testsuite/gcc.dg/plugin/selfassign.c
> +++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c
> @@ -270,14 +270,6 @@ execute_warn_self_assign (void)
>    return 0;
>  }
>
> -/* Pass gate function. Currently always returns true.  */
> -
> -static bool
> -gate_warn_self_assign (void)
> -{
> -  return true;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_warn_self_assign =
> @@ -302,7 +294,6 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_warn_self_assign (); }
>    unsigned int execute () { return execute_warn_self_assign (); }
>
>  }; // class pass_warn_self_assign
> diff --git a/gcc/tracer.c b/gcc/tracer.c
> index 73e3209..794d385 100644
> --- a/gcc/tracer.c
> +++ b/gcc/tracer.c
> @@ -398,12 +398,6 @@ tracer (void)
>    return changed ? TODO_cleanup_cfg : 0;
>  }
>
> -static bool
> -gate_tracer (void)
> -{
> -  return (optimize > 0 && flag_tracer && flag_reorder_blocks);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_tracer =
> @@ -428,7 +422,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tracer (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize > 0 && flag_tracer && flag_reorder_blocks);
> +    }
> +
>    unsigned int execute () { return tracer (); }
>
>  }; // class pass_tracer
> diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
> index a259b77..be876f5 100644
> --- a/gcc/trans-mem.c
> +++ b/gcc/trans-mem.c
> @@ -456,14 +456,6 @@ build_tm_abort_call (location_t loc, bool is_outer)
>                                              AR_USERABORT
>                                              | (is_outer ? AR_OUTERABORT : 0)));
>  }
> -
> -/* Common gateing function for several of the TM passes.  */
> -
> -static bool
> -gate_tm (void)
> -{
> -  return flag_tm;
> -}
>
>  /* Map for aribtrary function replacement under TM, as created
>     by the tm_wrap attribute.  */
> @@ -863,7 +855,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tm (); }
> +  virtual bool gate (function *) { return flag_tm; }
>    unsigned int execute () { return diagnose_tm_blocks (); }
>
>  }; // class pass_diagnose_tm_blocks
> @@ -1785,7 +1777,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tm (); }
> +  virtual bool gate (function *) { return flag_tm; }
>    unsigned int execute () { return execute_lower_tm (); }
>
>  }; // class pass_lower_tm
> @@ -2062,7 +2054,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tm_init (); }
> +  virtual bool gate (function *) { return gate_tm_init (); }
>
>  }; // class pass_tm_init
>
> @@ -3929,12 +3921,6 @@ execute_tm_memopt (void)
>    return 0;
>  }
>
> -static bool
> -gate_tm_memopt (void)
> -{
> -  return flag_tm && optimize > 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_tm_memopt =
> @@ -3959,7 +3945,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tm_memopt (); }
> +  virtual bool gate (function *) { return flag_tm && optimize > 0; }
>    unsigned int execute () { return execute_tm_memopt (); }
>
>  }; // class pass_tm_memopt
> @@ -5594,7 +5580,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tm (); }
> +  virtual bool gate (function *) { return flag_tm; }
>    unsigned int execute () { return ipa_tm_execute (); }
>
>  }; // class pass_ipa_tm
> diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
> index 3293493..c271493 100644
> --- a/gcc/tree-call-cdce.c
> +++ b/gcc/tree-call-cdce.c
> @@ -917,15 +917,6 @@ tree_call_cdce (void)
>    return 0;
>  }
>
> -static bool
> -gate_call_cdce (void)
> -{
> -  /* The limit constants used in the implementation
> -     assume IEEE floating point format.  Other formats
> -     can be supported in the future if needed.  */
> -  return flag_tree_builtin_call_dce != 0 && optimize_function_for_speed_p (cfun);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_call_cdce =
> @@ -950,7 +941,15 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_call_cdce (); }
> +  virtual bool gate (function *fun)
> +    {
> +      /* The limit constants used in the implementation
> +        assume IEEE floating point format.  Other formats
> +        can be supported in the future if needed.  */
> +      return flag_tree_builtin_call_dce != 0
> +               && optimize_function_for_speed_p (fun);
> +    }
> +
>    unsigned int execute () { return tree_call_cdce (); }
>
>  }; // class pass_call_cdce
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index 739ca54..08e0280 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -8355,12 +8355,6 @@ run_warn_unused_result (void)
>    return 0;
>  }
>
> -static bool
> -gate_warn_unused_result (void)
> -{
> -  return flag_warn_unused_result;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_warn_unused_result =
> @@ -8385,7 +8379,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_warn_unused_result (); }
> +  virtual bool gate (function *) { return flag_warn_unused_result; }
>    unsigned int execute () { return run_warn_unused_result (); }
>
>  }; // class pass_warn_unused_result
> diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
> index 914523d..19433f9 100644
> --- a/gcc/tree-cfgcleanup.c
> +++ b/gcc/tree-cfgcleanup.c
> @@ -1035,12 +1035,6 @@ merge_phi_nodes (void)
>    return 0;
>  }
>
> -static bool
> -gate_merge_phi (void)
> -{
> -  return 1;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_merge_phi =
> @@ -1066,7 +1060,6 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_merge_phi (m_ctxt); }
> -  bool gate () { return gate_merge_phi (); }
>    unsigned int execute () { return merge_phi_nodes (); }
>
>  }; // class pass_merge_phi
> diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
> index 283c827..9ec83d9 100644
> --- a/gcc/tree-complex.c
> +++ b/gcc/tree-complex.c
> @@ -1693,14 +1693,6 @@ make_pass_lower_complex (gcc::context *ctxt)
>  }
>
>
> -static bool
> -gate_no_optimization (void)
> -{
> -  /* With errors, normal optimization passes are not run.  If we don't
> -     lower complex operations at all, rtl expansion will abort.  */
> -  return !(cfun->curr_properties & PROP_gimple_lcx);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_lower_complex_O0 =
> @@ -1725,7 +1717,13 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_no_optimization (); }
> +  virtual bool gate (function *fun)
> +    {
> +      /* With errors, normal optimization passes are not run.  If we don't
> +        lower complex operations at all, rtl expansion will abort.  */
> +      return !(fun->curr_properties & PROP_gimple_lcx);
> +    }
> +
>    unsigned int execute () { return tree_lower_complex (); }
>
>  }; // class pass_lower_complex_O0
> diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
> index f51f18c..41f96c4 100644
> --- a/gcc/tree-eh.c
> +++ b/gcc/tree-eh.c
> @@ -3115,12 +3115,6 @@ refactor_eh (void)
>    return 0;
>  }
>
> -static bool
> -gate_refactor_eh (void)
> -{
> -  return flag_exceptions != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_refactor_eh =
> @@ -3145,7 +3139,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_refactor_eh (); }
> +  virtual bool gate (function *) { return flag_exceptions != 0; }
>    unsigned int execute () { return refactor_eh (); }
>
>  }; // class pass_refactor_eh
> @@ -3341,12 +3335,6 @@ execute_lower_resx (void)
>    return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
>  }
>
> -static bool
> -gate_lower_resx (void)
> -{
> -  return flag_exceptions != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_lower_resx =
> @@ -3371,7 +3359,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_lower_resx (); }
> +  virtual bool gate (function *) { return flag_exceptions != 0; }
>    unsigned int execute () { return execute_lower_resx (); }
>
>  }; // class pass_lower_resx
> @@ -3749,12 +3737,6 @@ execute_lower_eh_dispatch (void)
>    return flags;
>  }
>
> -static bool
> -gate_lower_eh_dispatch (void)
> -{
> -  return cfun->eh->region_tree != NULL;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_lower_eh_dispatch =
> @@ -3779,7 +3761,8 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_lower_eh_dispatch (); }
> +  virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; }
> +
>    unsigned int execute () { return execute_lower_eh_dispatch (); }
>
>  }; // class pass_lower_eh_dispatch
> @@ -4596,12 +4579,6 @@ execute_cleanup_eh (void)
>    return ret;
>  }
>
> -static bool
> -gate_cleanup_eh (void)
> -{
> -  return cfun->eh != NULL && cfun->eh->region_tree != NULL;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_cleanup_eh =
> @@ -4627,7 +4604,11 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_cleanup_eh (m_ctxt); }
> -  bool gate () { return gate_cleanup_eh (); }
> +  virtual bool gate (function *fun)
> +    {
> +      return fun->eh != NULL && fun->eh->region_tree != NULL;
> +    }
> +
>    unsigned int execute () { return execute_cleanup_eh (); }
>
>  }; // class pass_cleanup_eh
> diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
> index 84aa008..280a606 100644
> --- a/gcc/tree-emutls.c
> +++ b/gcc/tree-emutls.c
> @@ -816,14 +816,6 @@ ipa_lower_emutls (void)
>    return TODO_verify_all;
>  }
>
> -/* If the target supports TLS natively, we need do nothing here.  */
> -
> -static bool
> -gate_emutls (void)
> -{
> -  return !targetm.have_tls;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_lower_emutls =
> @@ -848,7 +840,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_emutls (); }
> +  virtual bool gate (function *)
> +    {
> +      /* If the target supports TLS natively, we need do nothing here.  */
> +      return !targetm.have_tls;
> +    }
> +
>    unsigned int execute () { return ipa_lower_emutls (); }
>
>  }; // class pass_ipa_lower_emutls
> diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
> index b87c476..90b62a8 100644
> --- a/gcc/tree-if-conv.c
> +++ b/gcc/tree-if-conv.c
> @@ -2013,17 +2013,6 @@ main_tree_if_conversion (void)
>    return todo;
>  }
>
> -/* Returns true when the if-conversion pass is enabled.  */
> -
> -static bool
> -gate_tree_if_conversion (void)
> -{
> -  return (((flag_tree_loop_vectorize || cfun->has_force_vectorize_loops)
> -          && flag_tree_loop_if_convert != 0)
> -         || flag_tree_loop_if_convert == 1
> -         || flag_tree_loop_if_convert_stores == 1);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_if_conversion =
> @@ -2049,11 +2038,20 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_if_conversion (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return main_tree_if_conversion (); }
>
>  }; // class pass_if_conversion
>
> +bool
> +pass_if_conversion::gate (function *fun)
> +{
> +  return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
> +          && flag_tree_loop_if_convert != 0)
> +         || flag_tree_loop_if_convert == 1
> +         || flag_tree_loop_if_convert_stores == 1);
> +}
> +
>  } // anon namespace
>
>  gimple_opt_pass *
> diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
> index dec5a5b..332901d 100644
> --- a/gcc/tree-into-ssa.c
> +++ b/gcc/tree-into-ssa.c
> @@ -2365,15 +2365,6 @@ rewrite_into_ssa (void)
>    return 0;
>  }
>
> -/* Gate for IPCP optimization.  */
> -
> -static bool
> -gate_into_ssa (void)
> -{
> -  /* Do nothing for funcions that was produced already in SSA form.  */
> -  return !(cfun->curr_properties & PROP_ssa);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_build_ssa =
> @@ -2398,7 +2389,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_into_ssa (); }
> +  virtual bool gate (function *fun)
> +    {
> +      /* Do nothing for funcions that was produced already in SSA form.  */
> +      return !(fun->curr_properties & PROP_ssa);
> +    }
> +
>    unsigned int execute () { return rewrite_into_ssa (); }
>
>  }; // class pass_build_ssa
> diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
> index dcc61c7..0a15412 100644
> --- a/gcc/tree-loop-distribution.c
> +++ b/gcc/tree-loop-distribution.c
> @@ -1790,13 +1790,6 @@ out:
>    return 0;
>  }
>
> -static bool
> -gate_tree_loop_distribution (void)
> -{
> -  return flag_tree_loop_distribution
> -    || flag_tree_loop_distribute_patterns;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_loop_distribution =
> @@ -1821,7 +1814,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_loop_distribution (); }
> +  virtual bool gate (function *)
> +    {
> +      return flag_tree_loop_distribution
> +       || flag_tree_loop_distribute_patterns;
> +    }
> +
>    unsigned int execute () { return tree_loop_distribution (); }
>
>  }; // class pass_loop_distribution
> diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
> index a39bc5e..71f8d68 100644
> --- a/gcc/tree-nrv.c
> +++ b/gcc/tree-nrv.c
> @@ -272,12 +272,6 @@ tree_nrv (void)
>    return 0;
>  }
>
> -static bool
> -gate_pass_return_slot (void)
> -{
> -  return optimize > 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_nrv =
> @@ -302,7 +296,8 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_pass_return_slot (); }
> +  virtual bool gate (function *) { return optimize > 0; }
> +
>    unsigned int execute () { return tree_nrv (); }
>
>  }; // class pass_nrv
> diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
> index e346074..a46fa51 100644
> --- a/gcc/tree-parloops.c
> +++ b/gcc/tree-parloops.c
> @@ -2253,12 +2253,6 @@ parallelize_loops (void)
>
>  /* Parallelization.  */
>
> -static bool
> -gate_tree_parallelize_loops (void)
> -{
> -  return flag_tree_parallelize_loops > 1;
> -}
> -
>  static unsigned
>  tree_parallelize_loops (void)
>  {
> @@ -2294,7 +2288,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_parallelize_loops (); }
> +  virtual bool gate (function *) { return flag_tree_parallelize_loops > 1; }
>    unsigned int execute () { return tree_parallelize_loops (); }
>
>  }; // class pass_parallelize_loops
> diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> index 9bb6455..9de2822 100644
> --- a/gcc/tree-pass.h
> +++ b/gcc/tree-pass.h
> @@ -25,6 +25,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "timevar.h"
>  #include "dumpfile.h"
>
> +struct function;
> +
>  /* Optimization pass type.  */
>  enum opt_pass_type
>  {
> @@ -88,7 +90,7 @@ public:
>
>    /* This pass and all sub-passes are executed only if the function returns
>       true.  The default implementation returns true.  */
> -  virtual bool gate ();
> +  virtual bool gate (function *fun);
>
>    /* This is the code to run.  If has_execute is false, then there should
>       be sub-passes otherwise this pass does nothing.
> diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
> index 859a112..7dd86e1 100644
> --- a/gcc/tree-predcom.c
> +++ b/gcc/tree-predcom.c
> @@ -2573,12 +2573,6 @@ run_tree_predictive_commoning (void)
>    return tree_predictive_commoning ();
>  }
>
> -static bool
> -gate_tree_predictive_commoning (void)
> -{
> -  return flag_predictive_commoning != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_predcom =
> @@ -2603,7 +2597,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_predictive_commoning (); }
> +  virtual bool gate (function *) { return flag_predictive_commoning != 0; }
>    unsigned int execute () { return run_tree_predictive_commoning (); }
>
>  }; // class pass_predcom
> diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
> index 0372c92..b7d0466 100644
> --- a/gcc/tree-profile.c
> +++ b/gcc/tree-profile.c
> @@ -663,16 +663,6 @@ tree_profiling (void)
>    return 0;
>  }
>
> -/* When profile instrumentation, use or test coverage shall be performed.  */
> -
> -static bool
> -gate_tree_profile_ipa (void)
> -{
> -  return (!in_lto_p
> -         && (flag_branch_probabilities || flag_test_coverage
> -             || profile_arc_flag));
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ipa_tree_profile =
> @@ -697,11 +687,20 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_profile_ipa (); }
> +  virtual bool gate (function *);
>    unsigned int execute () { return tree_profiling (); }
>
>  }; // class pass_ipa_tree_profile
>
> +bool
> +pass_ipa_tree_profile::gate (function *)
> +{
> +  /* When profile instrumentation, use or test coverage shall be performed.  */
> +  return (!in_lto_p
> +         && (flag_branch_probabilities || flag_test_coverage
> +             || profile_arc_flag));
> +}
> +
>  } // anon namespace
>
>  simple_ipa_opt_pass *
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index acca2a7..27f71a3 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -3524,7 +3524,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_intra_sra (); }
> +  virtual bool gate (function *) { return gate_intra_sra (); }
>    unsigned int execute () { return early_intra_sra (); }
>
>  }; // class pass_sra_early
> @@ -3561,7 +3561,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_intra_sra (); }
> +  virtual bool gate (function *) { return gate_intra_sra (); }
>    unsigned int execute () { return late_intra_sra (); }
>
>  }; // class pass_sra
> @@ -5051,13 +5051,6 @@ ipa_early_sra (void)
>    return ret;
>  }
>
> -/* Return if early ipa sra shall be performed.  */
> -static bool
> -ipa_early_sra_gate (void)
> -{
> -  return flag_ipa_sra && dbg_cnt (eipa_sra);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_early_ipa_sra =
> @@ -5082,7 +5075,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return ipa_early_sra_gate (); }
> +  virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); }
>    unsigned int execute () { return ipa_early_sra (); }
>
>  }; // class pass_early_ipa_sra
> diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
> index c7a7e89..c4a5c71 100644
> --- a/gcc/tree-ssa-ccp.c
> +++ b/gcc/tree-ssa-ccp.c
> @@ -2287,13 +2287,6 @@ do_ssa_ccp (void)
>  }
>
>
> -static bool
> -gate_ccp (void)
> -{
> -  return flag_tree_ccp != 0;
> -}
> -
> -
>  namespace {
>
>  const pass_data pass_data_ccp =
> @@ -2320,7 +2313,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_ccp (m_ctxt); }
> -  bool gate () { return gate_ccp (); }
> +  virtual bool gate (function *) { return flag_tree_ccp != 0; }
>    unsigned int execute () { return do_ssa_ccp (); }
>
>  }; // class pass_ccp
> diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
> index fc26d03..bd6ac04 100644
> --- a/gcc/tree-ssa-copy.c
> +++ b/gcc/tree-ssa-copy.c
> @@ -644,12 +644,6 @@ execute_copy_prop (void)
>    return 0;
>  }
>
> -static bool
> -gate_copy_prop (void)
> -{
> -  return flag_tree_copy_prop != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_copy_prop =
> @@ -676,7 +670,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_copy_prop (m_ctxt); }
> -  bool gate () { return gate_copy_prop (); }
> +  virtual bool gate (function *) { return flag_tree_copy_prop != 0; }
>    unsigned int execute () { return execute_copy_prop (); }
>
>  }; // class pass_copy_prop
> diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
> index 0da3d82..65d8044 100644
> --- a/gcc/tree-ssa-copyrename.c
> +++ b/gcc/tree-ssa-copyrename.c
> @@ -435,14 +435,6 @@ rename_ssa_copies (void)
>    return 0;
>  }
>
> -/* Return true if copy rename is to be performed.  */
> -
> -static bool
> -gate_copyrename (void)
> -{
> -  return flag_tree_copyrename != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_rename_ssa_copies =
> @@ -468,7 +460,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_rename_ssa_copies (m_ctxt); }
> -  bool gate () { return gate_copyrename (); }
> +  virtual bool gate (function *) { return flag_tree_copyrename != 0; }
>    unsigned int execute () { return rename_ssa_copies (); }
>
>  }; // class pass_rename_ssa_copies
> diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
> index 8db149e..e5799b9 100644
> --- a/gcc/tree-ssa-dce.c
> +++ b/gcc/tree-ssa-dce.c
> @@ -1504,12 +1504,6 @@ tree_ssa_cd_dce (void)
>    return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
>  }
>
> -static bool
> -gate_dce (void)
> -{
> -  return flag_tree_dce != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_dce =
> @@ -1535,7 +1529,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_dce (m_ctxt); }
> -  bool gate () { return gate_dce (); }
> +  virtual bool gate (function *) { return flag_tree_dce != 0; }
>    unsigned int execute () { return tree_ssa_dce (); }
>
>  }; // class pass_dce
> @@ -1573,7 +1567,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_dce_loop (m_ctxt); }
> -  bool gate () { return gate_dce (); }
> +  virtual bool gate (function *) { return flag_tree_dce != 0; }
>    unsigned int execute () { return tree_ssa_dce_loop (); }
>
>  }; // class pass_dce_loop
> @@ -1611,7 +1605,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_cd_dce (m_ctxt); }
> -  bool gate () { return gate_dce (); }
> +  virtual bool gate (function *) { return flag_tree_dce != 0; }
>    unsigned int execute () { return tree_ssa_cd_dce (); }
>
>  }; // class pass_cd_dce
> diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
> index 8101a54..b9cc5cc 100644
> --- a/gcc/tree-ssa-dom.c
> +++ b/gcc/tree-ssa-dom.c
> @@ -952,12 +952,6 @@ tree_ssa_dominator_optimize (void)
>    return 0;
>  }
>
> -static bool
> -gate_dominator (void)
> -{
> -  return flag_tree_dom != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_dominator =
> @@ -985,7 +979,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_dominator (m_ctxt); }
> -  bool gate () { return gate_dominator (); }
> +  virtual bool gate (function *) { return flag_tree_dom != 0; }
>    unsigned int execute () { return tree_ssa_dominator_optimize (); }
>
>  }; // class pass_dominator
> @@ -3142,7 +3136,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_phi_only_cprop (m_ctxt); }
> -  bool gate () { return gate_dominator (); }
> +  virtual bool gate (function *) { return flag_tree_dom != 0; }
>    unsigned int execute () { return eliminate_degenerate_phis (); }
>
>  }; // class pass_phi_only_cprop
> diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
> index 0096b4c..b6fbdaf 100644
> --- a/gcc/tree-ssa-dse.c
> +++ b/gcc/tree-ssa-dse.c
> @@ -80,7 +80,6 @@ along with GCC; see the file COPYING3.  If not see
>     remove their dead edges eventually.  */
>  static bitmap need_eh_cleanup;
>
> -static bool gate_dse (void);
>  static unsigned int tree_ssa_dse (void);
>
>
> @@ -363,12 +362,6 @@ tree_ssa_dse (void)
>    return 0;
>  }
>
> -static bool
> -gate_dse (void)
> -{
> -  return flag_tree_dse != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_dse =
> @@ -394,7 +387,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_dse (m_ctxt); }
> -  bool gate () { return gate_dse (); }
> +  virtual bool gate (function *) { return flag_tree_dse != 0; }
>    unsigned int execute () { return tree_ssa_dse (); }
>
>  }; // class pass_dse
> diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
> index 66ae113..8d5ca5f 100644
> --- a/gcc/tree-ssa-forwprop.c
> +++ b/gcc/tree-ssa-forwprop.c
> @@ -3831,13 +3831,6 @@ ssa_forward_propagate_and_combine (void)
>    return todoflags;
>  }
>
> -
> -static bool
> -gate_forwprop (void)
> -{
> -  return flag_tree_forwprop;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_forwprop =
> @@ -3863,7 +3856,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_forwprop (m_ctxt); }
> -  bool gate () { return gate_forwprop (); }
> +  virtual bool gate (function *) { return flag_tree_forwprop; }
>    unsigned int execute () { return ssa_forward_propagate_and_combine (); }
>
>  }; // class pass_forwprop
> diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
> index ef0c0c4..b901f37 100644
> --- a/gcc/tree-ssa-ifcombine.c
> +++ b/gcc/tree-ssa-ifcombine.c
> @@ -756,12 +756,6 @@ tree_ssa_ifcombine (void)
>    return cfg_changed ? TODO_cleanup_cfg : 0;
>  }
>
> -static bool
> -gate_ifcombine (void)
> -{
> -  return 1;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_tree_ifcombine =
> @@ -786,7 +780,6 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ifcombine (); }
>    unsigned int execute () { return tree_ssa_ifcombine (); }
>
>  }; // class pass_tree_ifcombine
> diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
> index 99cc39c..34d1f70 100644
> --- a/gcc/tree-ssa-loop-ch.c
> +++ b/gcc/tree-ssa-loop-ch.c
> @@ -257,12 +257,6 @@ copy_loop_headers (void)
>    return 0;
>  }
>
> -static bool
> -gate_ch (void)
> -{
> -  return flag_tree_ch != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ch =
> @@ -288,7 +282,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ch (); }
> +  virtual bool gate (function *) { return flag_tree_ch != 0; }
>    unsigned int execute () { return copy_loop_headers (); }
>
>  }; // class pass_ch
> diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
> index aab521e..f38ee95 100644
> --- a/gcc/tree-ssa-loop-im.c
> +++ b/gcc/tree-ssa-loop-im.c
> @@ -2538,12 +2538,6 @@ tree_ssa_loop_im (void)
>    return tree_ssa_lim ();
>  }
>
> -static bool
> -gate_tree_ssa_loop_im (void)
> -{
> -  return flag_tree_loop_im != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_lim =
> @@ -2569,7 +2563,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_lim (m_ctxt); }
> -  bool gate () { return gate_tree_ssa_loop_im (); }
> +  virtual bool gate (function *) { return flag_tree_loop_im != 0; }
>    unsigned int execute () { return tree_ssa_loop_im (); }
>
>  }; // class pass_lim
> diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
> index 177666d..df82816 100644
> --- a/gcc/tree-ssa-loop-ivcanon.c
> +++ b/gcc/tree-ssa-loop-ivcanon.c
> @@ -1265,12 +1265,6 @@ tree_ssa_loop_ivcanon (void)
>    return canonicalize_induction_variables ();
>  }
>
> -static bool
> -gate_tree_ssa_loop_ivcanon (void)
> -{
> -  return flag_tree_loop_ivcanon != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_iv_canon =
> @@ -1295,7 +1289,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_ssa_loop_ivcanon (); }
> +  virtual bool gate (function *) { return flag_tree_loop_ivcanon != 0; }
>    unsigned int execute () { return tree_ssa_loop_ivcanon (); }
>
>  }; // class pass_iv_canon
> @@ -1321,12 +1315,6 @@ tree_complete_unroll (void)
>                                        || optimize >= 3, true);
>  }
>
> -static bool
> -gate_tree_complete_unroll (void)
> -{
> -  return true;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_complete_unroll =
> @@ -1351,7 +1339,6 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_complete_unroll (); }
>    unsigned int execute () { return tree_complete_unroll (); }
>
>  }; // class pass_complete_unroll
> @@ -1385,12 +1372,6 @@ tree_complete_unroll_inner (void)
>    return ret;
>  }
>
> -static bool
> -gate_tree_complete_unroll_inner (void)
> -{
> -  return optimize >= 2;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_complete_unrolli =
> @@ -1415,7 +1396,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_complete_unroll_inner (); }
> +  virtual bool gate (function *) { return optimize >= 2; }
>    unsigned int execute () { return tree_complete_unroll_inner (); }
>
>  }; // class pass_complete_unrolli
> diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
> index dd52703..17b13d1 100644
> --- a/gcc/tree-ssa-loop-prefetch.c
> +++ b/gcc/tree-ssa-loop-prefetch.c
> @@ -2013,12 +2013,6 @@ tree_ssa_loop_prefetch (void)
>    return tree_ssa_prefetch_arrays ();
>  }
>
> -static bool
> -gate_tree_ssa_loop_prefetch (void)
> -{
> -  return flag_prefetch_loop_arrays > 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_loop_prefetch =
> @@ -2043,7 +2037,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_ssa_loop_prefetch (); }
> +  virtual bool gate (function *) { return flag_prefetch_loop_arrays > 0; }
>    unsigned int execute () { return tree_ssa_loop_prefetch (); }
>
>  }; // class pass_loop_prefetch
> diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
> index e755b62..90bb205 100644
> --- a/gcc/tree-ssa-loop-unswitch.c
> +++ b/gcc/tree-ssa-loop-unswitch.c
> @@ -411,12 +411,6 @@ tree_ssa_loop_unswitch (void)
>    return tree_ssa_unswitch_loops ();
>  }
>
> -static bool
> -gate_tree_ssa_loop_unswitch (void)
> -{
> -  return flag_unswitch_loops != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_tree_unswitch =
> @@ -441,7 +435,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_ssa_loop_unswitch (); }
> +  virtual bool gate (function *) { return flag_unswitch_loops != 0; }
>    unsigned int execute () { return tree_ssa_loop_unswitch (); }
>
>  }; // class pass_tree_unswitch
> diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
> index 84e24a1..38e7b13 100644
> --- a/gcc/tree-ssa-loop.c
> +++ b/gcc/tree-ssa-loop.c
> @@ -44,12 +44,6 @@ along with GCC; see the file COPYING3.  If not see
>
>  /* The loop superpass.  */
>
> -static bool
> -gate_tree_loop (void)
> -{
> -  return flag_tree_loop_optimize != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_tree_loop =
> @@ -74,7 +68,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_loop (); }
> +  virtual bool gate (function *) { return flag_tree_loop_optimize != 0; }
>
>  }; // class pass_tree_loop
>
> @@ -152,12 +146,6 @@ tree_loop_vectorize (void)
>    return vectorize_loops ();
>  }
>
> -static bool
> -gate_tree_loop_vectorize (void)
> -{
> -  return flag_tree_loop_vectorize || cfun->has_force_vectorize_loops;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_vectorize =
> @@ -182,7 +170,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_loop_vectorize (); }
> +  virtual bool gate (function *fun)
> +    {
> +      return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
> +    }
> +
>    unsigned int execute () { return tree_loop_vectorize (); }
>
>  }; // class pass_vectorize
> @@ -207,12 +199,6 @@ check_data_deps (void)
>    return 0;
>  }
>
> -static bool
> -gate_check_data_deps (void)
> -{
> -  return flag_check_data_deps != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_check_data_deps =
> @@ -237,7 +223,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_check_data_deps (); }
> +  virtual bool gate (function *) { return flag_check_data_deps != 0; }
>    unsigned int execute () { return check_data_deps (); }
>
>  }; // class pass_check_data_deps
> @@ -252,12 +238,6 @@ make_pass_check_data_deps (gcc::context *ctxt)
>
>  /* Propagation of constants using scev.  */
>
> -static bool
> -gate_scev_const_prop (void)
> -{
> -  return flag_tree_scev_cprop;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_scev_cprop =
> @@ -283,7 +263,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_scev_const_prop (); }
> +  virtual bool gate (function *) { return flag_tree_scev_cprop; }
>    unsigned int execute () { return scev_const_prop (); }
>
>  }; // class pass_scev_cprop
> @@ -357,12 +337,6 @@ tree_ssa_loop_ivopts (void)
>    return 0;
>  }
>
> -static bool
> -gate_tree_ssa_loop_ivopts (void)
> -{
> -  return flag_ivopts != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_iv_optimize =
> @@ -387,7 +361,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_ssa_loop_ivopts (); }
> +  virtual bool gate (function *) { return flag_ivopts != 0; }
>    unsigned int execute () { return tree_ssa_loop_ivopts (); }
>
>  }; // class pass_iv_optimize
> diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
> index f63c75d..fef1b1e 100644
> --- a/gcc/tree-ssa-math-opts.c
> +++ b/gcc/tree-ssa-math-opts.c
> @@ -504,12 +504,6 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
>    occ_head = NULL;
>  }
>
> -static bool
> -gate_cse_reciprocals (void)
> -{
> -  return optimize && flag_reciprocal_math;
> -}
> -
>  /* Go through all the floating-point SSA_NAMEs, and call
>     execute_cse_reciprocals_1 on each of them.  */
>  static unsigned int
> @@ -678,7 +672,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_cse_reciprocals (); }
> +  virtual bool gate (function *) { return optimize && flag_reciprocal_math; }
>    unsigned int execute () { return execute_cse_reciprocals (); }
>
>  }; // class pass_cse_reciprocals
> @@ -1562,14 +1556,6 @@ execute_cse_sincos (void)
>    return cfg_changed ? TODO_cleanup_cfg : 0;
>  }
>
> -static bool
> -gate_cse_sincos (void)
> -{
> -  /* We no longer require either sincos or cexp, since powi expansion
> -     piggybacks on this pass.  */
> -  return optimize;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_cse_sincos =
> @@ -1595,7 +1581,13 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_cse_sincos (); }
> +  virtual bool gate (function *)
> +    {
> +      /* We no longer require either sincos or cexp, since powi expansion
> +        piggybacks on this pass.  */
> +      return optimize;
> +    }
> +
>    unsigned int execute () { return execute_cse_sincos (); }
>
>  }; // class pass_cse_sincos
> @@ -2065,12 +2057,6 @@ execute_optimize_bswap (void)
>           | TODO_verify_stmts : 0);
>  }
>
> -static bool
> -gate_optimize_bswap (void)
> -{
> -  return flag_expensive_optimizations && optimize;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_optimize_bswap =
> @@ -2095,7 +2081,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_optimize_bswap (); }
> +  virtual bool gate (function *)
> +    {
> +      return flag_expensive_optimizations && optimize;
> +    }
> +
>    unsigned int execute () { return execute_optimize_bswap (); }
>
>  }; // class pass_optimize_bswap
> @@ -2874,12 +2864,6 @@ execute_optimize_widening_mul (void)
>    return cfg_changed ? TODO_cleanup_cfg : 0;
>  }
>
> -static bool
> -gate_optimize_widening_mul (void)
> -{
> -  return flag_expensive_optimizations && optimize;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_optimize_widening_mul =
> @@ -2905,7 +2889,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_optimize_widening_mul (); }
> +  virtual bool gate (function *)
> +    {
> +      return flag_expensive_optimizations && optimize;
> +    }
> +
>    unsigned int execute () { return execute_optimize_widening_mul (); }
>
>  }; // class pass_optimize_widening_mul
> diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
> index 3892317..1ee39a5 100644
> --- a/gcc/tree-ssa-phiopt.c
> +++ b/gcc/tree-ssa-phiopt.c
> @@ -2202,11 +2202,6 @@ gate_hoist_loads (void)
>
>  /* Always do these optimizations if we have SSA
>     trees to work on.  */
> -static bool
> -gate_phiopt (void)
> -{
> -  return 1;
> -}
>
>  namespace {
>
> @@ -2234,7 +2229,6 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_phiopt (m_ctxt); }
> -  bool gate () { return gate_phiopt (); }
>    unsigned int execute () { return tree_ssa_phiopt (); }
>
>  }; // class pass_phiopt
> @@ -2247,12 +2241,6 @@ make_pass_phiopt (gcc::context *ctxt)
>    return new pass_phiopt (ctxt);
>  }
>
> -static bool
> -gate_cselim (void)
> -{
> -  return flag_tree_cselim;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_cselim =
> @@ -2278,7 +2266,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_cselim (); }
> +  virtual bool gate (function *) { return flag_tree_cselim; }
>    unsigned int execute () { return tree_ssa_cs_elim (); }
>
>  }; // class pass_cselim
> diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
> index d67f488..cbdbc6e 100644
> --- a/gcc/tree-ssa-phiprop.c
> +++ b/gcc/tree-ssa-phiprop.c
> @@ -409,12 +409,6 @@ tree_ssa_phiprop (void)
>    return 0;
>  }
>
> -static bool
> -gate_phiprop (void)
> -{
> -  return flag_tree_phiprop;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_phiprop =
> @@ -439,7 +433,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_phiprop (); }
> +  virtual bool gate (function *) { return flag_tree_phiprop; }
>    unsigned int execute () { return tree_ssa_phiprop (); }
>
>  }; // class pass_phiprop
> diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
> index 1329fe2..cda315a 100644
> --- a/gcc/tree-ssa-pre.c
> +++ b/gcc/tree-ssa-pre.c
> @@ -4771,12 +4771,6 @@ do_pre (void)
>    return todo;
>  }
>
> -static bool
> -gate_pre (void)
> -{
> -  return flag_tree_pre != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_pre =
> @@ -4803,7 +4797,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_pre (); }
> +  virtual bool gate (function *) { return flag_tree_pre != 0; }
>    unsigned int execute () { return do_pre (); }
>
>  }; // class pass_pre
> @@ -4842,12 +4836,6 @@ execute_fre (void)
>    return todo;
>  }
>
> -static bool
> -gate_fre (void)
> -{
> -  return flag_tree_fre != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_fre =
> @@ -4873,7 +4861,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_fre (m_ctxt); }
> -  bool gate () { return gate_fre (); }
> +  virtual bool gate (function *) { return flag_tree_fre != 0; }
>    unsigned int execute () { return execute_fre (); }
>
>  }; // class pass_fre
> diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
> index 0b37b7b..92a215a 100644
> --- a/gcc/tree-ssa-reassoc.c
> +++ b/gcc/tree-ssa-reassoc.c
> @@ -4665,12 +4665,6 @@ execute_reassoc (void)
>    return 0;
>  }
>
> -static bool
> -gate_tree_ssa_reassoc (void)
> -{
> -  return flag_tree_reassoc != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_reassoc =
> @@ -4698,7 +4692,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_reassoc (m_ctxt); }
> -  bool gate () { return gate_tree_ssa_reassoc (); }
> +  virtual bool gate (function *) { return flag_tree_reassoc != 0; }
>    unsigned int execute () { return execute_reassoc (); }
>
>  }; // class pass_reassoc
> diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
> index 4a7410d..6803160 100644
> --- a/gcc/tree-ssa-sink.c
> +++ b/gcc/tree-ssa-sink.c
> @@ -588,12 +588,6 @@ do_sink (void)
>    return 0;
>  }
>
> -static bool
> -gate_sink (void)
> -{
> -  return flag_tree_sink != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_sink_code =
> @@ -621,7 +615,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_sink (); }
> +  virtual bool gate (function *) { return flag_tree_sink != 0; }
>    unsigned int execute () { return do_sink (); }
>
>  }; // class pass_sink_code
> diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
> index aa6b6b9..fb83093 100644
> --- a/gcc/tree-ssa-strlen.c
> +++ b/gcc/tree-ssa-strlen.c
> @@ -2089,12 +2089,6 @@ tree_ssa_strlen (void)
>    return 0;
>  }
>
> -static bool
> -gate_strlen (void)
> -{
> -  return flag_optimize_strlen != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_strlen =
> @@ -2119,7 +2113,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_strlen (); }
> +  virtual bool gate (function *) { return flag_optimize_strlen != 0; }
>    unsigned int execute () { return tree_ssa_strlen (); }
>
>  }; // class pass_strlen
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index 9e1cdbc..3548ac5 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -6989,12 +6989,6 @@ compute_may_aliases (void)
>    return 0;
>  }
>
> -static bool
> -gate_tree_pta (void)
> -{
> -  return flag_tree_pta;
> -}
> -
>  /* A dummy pass to cause points-to information to be computed via
>     TODO_rebuild_alias.  */
>
> @@ -7022,7 +7016,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_pta (); }
> +  virtual bool gate (function *) { return flag_tree_pta; }
>
>  }; // class pass_build_alias
>
> @@ -7061,7 +7055,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_pta (); }
> +  virtual bool gate (function *) { return flag_tree_pta; }
>
>  }; // class pass_build_ealias
>
> @@ -7074,16 +7068,6 @@ make_pass_build_ealias (gcc::context *ctxt)
>  }
>
>
> -/* Return true if we should execute IPA PTA.  */
> -static bool
> -gate_ipa_pta (void)
> -{
> -  return (optimize
> -         && flag_ipa_pta
> -         /* Don't bother doing anything if the program has errors.  */
> -         && !seen_error ());
> -}
> -
>  /* IPA PTA solutions for ESCAPED.  */
>  struct pt_solution ipa_escaped_pt
>    = { true, false, false, false, false, false, false, false, NULL };
> @@ -7452,7 +7436,14 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ipa_pta (); }
> +  virtual bool gate (function *)
> +    {
> +      return (optimize
> +             && flag_ipa_pta
> +             /* Don't bother doing anything if the program has errors.  */
> +             && !seen_error ());
> +    }
> +
>    unsigned int execute () { return ipa_pta_execute (); }
>
>  }; // class pass_ipa_pta
> diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
> index 41f4bd8..e39ce88 100644
> --- a/gcc/tree-ssa-uncprop.c
> +++ b/gcc/tree-ssa-uncprop.c
> @@ -581,12 +581,6 @@ uncprop_dom_walker::before_dom_children (basic_block bb)
>    uncprop_into_successor_phis (bb);
>  }
>
> -static bool
> -gate_uncprop (void)
> -{
> -  return flag_tree_dom != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_uncprop =
> @@ -612,7 +606,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_uncprop (m_ctxt); }
> -  bool gate () { return gate_uncprop (); }
> +  virtual bool gate (function *) { return flag_tree_dom != 0; }
>    unsigned int execute () { return tree_ssa_uncprop (); }
>
>  }; // class pass_uncprop
> diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
> index 86d84a1..03ff3b8 100644
> --- a/gcc/tree-ssa-uninit.c
> +++ b/gcc/tree-ssa-uninit.c
> @@ -2383,7 +2383,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_late_warn_uninitialized (m_ctxt); }
> -  bool gate () { return gate_warn_uninitialized (); }
> +  virtual bool gate (function *) { return gate_warn_uninitialized (); }
>    unsigned int execute () { return execute_late_warn_uninitialized (); }
>
>  }; // class pass_late_warn_uninitialized
> @@ -2441,7 +2441,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_warn_uninitialized (); }
> +  virtual bool gate (function *) { return gate_warn_uninitialized (); }
>    unsigned int execute () { return execute_early_warn_uninitialized (); }
>
>  }; // class pass_early_warn_uninitialized
> diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
> index ecc8da3..52126ca 100644
> --- a/gcc/tree-ssa.c
> +++ b/gcc/tree-ssa.c
> @@ -1139,15 +1139,6 @@ execute_init_datastructures (void)
>    return 0;
>  }
>
> -/* Gate for IPCP optimization.  */
> -
> -static bool
> -gate_init_datastructures (void)
> -{
> -  /* Do nothing for funcions that was produced already in SSA form.  */
> -  return !(cfun->curr_properties & PROP_ssa);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_init_datastructures =
> @@ -1172,7 +1163,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_init_datastructures (); }
> +  virtual bool gate (function *fun)
> +    {
> +      /* Do nothing for funcions that was produced already in SSA form.  */
> +      return !(fun->curr_properties & PROP_ssa);
> +    }
> +
>    unsigned int execute () { return execute_init_datastructures (); }
>
>  }; // class pass_init_datastructures
> diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
> index 7da36c4..710711b 100644
> --- a/gcc/tree-stdarg.c
> +++ b/gcc/tree-stdarg.c
> @@ -663,18 +663,6 @@ check_all_va_list_escapes (struct stdarg_info *si)
>    return false;
>  }
>
> -
> -/* Return true if this optimization pass should be done.
> -   It makes only sense for stdarg functions.  */
> -
> -static bool
> -gate_optimize_stdarg (void)
> -{
> -  /* This optimization is only for stdarg functions.  */
> -  return cfun->stdarg != 0;
> -}
> -
> -
>  /* Entry point to the stdarg optimization pass.  */
>
>  static unsigned int
> @@ -1023,7 +1011,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_optimize_stdarg (); }
> +  virtual bool gate (function *fun)
> +    {
> +      /* This optimization is only for stdarg functions.  */
> +      return fun->stdarg != 0;
> +    }
> +
>    unsigned int execute () { return execute_optimize_stdarg (); }
>
>  }; // class pass_stdarg
> diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
> index cf2e763..a0f9d19 100644
> --- a/gcc/tree-switch-conversion.c
> +++ b/gcc/tree-switch-conversion.c
> @@ -1465,14 +1465,6 @@ do_switchconv (void)
>    return 0;
>  }
>
> -/* The pass gate. */
> -
> -static bool
> -switchconv_gate (void)
> -{
> -  return flag_tree_switch_conversion != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_convert_switch =
> @@ -1499,7 +1491,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return switchconv_gate (); }
> +  virtual bool gate (function *) { return flag_tree_switch_conversion != 0; }
>    unsigned int execute () { return do_switchconv (); }
>
>  }; // class pass_convert_switch
> diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
> index b3a6256..84cdbde 100644
> --- a/gcc/tree-tailcall.c
> +++ b/gcc/tree-tailcall.c
> @@ -1108,7 +1108,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_tail_recursion (m_ctxt); }
> -  bool gate () { return gate_tail_calls (); }
> +  virtual bool gate (function *) { return gate_tail_calls (); }
>    unsigned int execute () { return execute_tail_recursion (); }
>
>  }; // class pass_tail_recursion
> @@ -1145,7 +1145,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tail_calls (); }
> +  virtual bool gate (function *) { return gate_tail_calls (); }
>    unsigned int execute () { return execute_tail_calls (); }
>
>  }; // class pass_tail_calls
> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
> index 035c143..4274417 100644
> --- a/gcc/tree-vect-generic.c
> +++ b/gcc/tree-vect-generic.c
> @@ -1528,12 +1528,6 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
>  /* Use this to lower vector operations introduced by the vectorizer,
>     if it may need the bit-twiddling tricks implemented in this file.  */
>
> -static bool
> -gate_expand_vector_operations_ssa (void)
> -{
> -  return !(cfun->curr_properties & PROP_gimple_lvec);
> -}
> -
>  static unsigned int
>  expand_vector_operations (void)
>  {
> @@ -1586,7 +1580,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_expand_vector_operations_ssa (); }
> +  virtual bool gate (function *fun)
> +    {
> +      return !(fun->curr_properties & PROP_gimple_lvec);
> +    }
> +
>    unsigned int execute () { return expand_vector_operations (); }
>
>  }; // class pass_lower_vector
> diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
> index 17be3aa..7b5691a 100644
> --- a/gcc/tree-vectorizer.c
> +++ b/gcc/tree-vectorizer.c
> @@ -613,12 +613,6 @@ execute_vect_slp (void)
>    return 0;
>  }
>
> -static bool
> -gate_vect_slp (void)
> -{
> -  return flag_tree_slp_vectorize != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_slp_vectorize =
> @@ -644,7 +638,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_vect_slp (); }
> +  virtual bool gate (function *) { return flag_tree_slp_vectorize != 0; }
>    unsigned int execute () { return execute_vect_slp (); }
>
>  }; // class pass_slp_vectorize
> @@ -702,13 +696,6 @@ increase_alignment (void)
>  }
>
>
> -static bool
> -gate_increase_alignment (void)
> -{
> -  return flag_section_anchors && flag_tree_loop_vectorize;
> -}
> -
> -
>  namespace {
>
>  const pass_data pass_data_ipa_increase_alignment =
> @@ -733,7 +720,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_increase_alignment (); }
> +  virtual bool gate (function *)
> +    {
> +      return flag_section_anchors && flag_tree_loop_vectorize;
> +    }
> +
>    unsigned int execute () { return increase_alignment (); }
>
>  }; // class pass_ipa_increase_alignment
> diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
> index 4ccb90b..80f3888 100644
> --- a/gcc/tree-vrp.c
> +++ b/gcc/tree-vrp.c
> @@ -9894,12 +9894,6 @@ execute_vrp (void)
>    return 0;
>  }
>
> -static bool
> -gate_vrp (void)
> -{
> -  return flag_tree_vrp != 0;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_vrp =
> @@ -9927,7 +9921,7 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_vrp (m_ctxt); }
> -  bool gate () { return gate_vrp (); }
> +  virtual bool gate (function *) { return flag_tree_vrp != 0; }
>    unsigned int execute () { return execute_vrp (); }
>
>  }; // class pass_vrp
> diff --git a/gcc/tsan.c b/gcc/tsan.c
> index f30cf57..b413bb5 100644
> --- a/gcc/tsan.c
> +++ b/gcc/tsan.c
> @@ -715,14 +715,6 @@ tsan_pass (void)
>    return 0;
>  }
>
> -/* The pass's gate.  */
> -
> -static bool
> -tsan_gate (void)
> -{
> -  return (flag_sanitize & SANITIZE_THREAD) != 0;
> -}
> -
>  /* Inserts __tsan_init () into the list of CTORs.  */
>
>  void
> @@ -765,7 +757,11 @@ public:
>
>    /* opt_pass methods: */
>    opt_pass * clone () { return new pass_tsan (m_ctxt); }
> -  bool gate () { return tsan_gate (); }
> +  virtual bool gate (function *)
> +{
> +  return (flag_sanitize & SANITIZE_THREAD) != 0;
> +}
> +
>    unsigned int execute () { return tsan_pass (); }
>
>  }; // class pass_tsan
> @@ -778,12 +774,6 @@ make_pass_tsan (gcc::context *ctxt)
>    return new pass_tsan (ctxt);
>  }
>
> -static bool
> -tsan_gate_O0 (void)
> -{
> -  return (flag_sanitize & SANITIZE_THREAD) != 0 && !optimize;
> -}
> -
>  namespace {
>
>  const pass_data pass_data_tsan_O0 =
> @@ -808,7 +798,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return tsan_gate_O0 (); }
> +  virtual bool gate (function *)
> +    {
> +      return (flag_sanitize & SANITIZE_THREAD) != 0 && !optimize;
> +    }
> +
>    unsigned int execute () { return tsan_pass (); }
>
>  }; // class pass_tsan_O0
> diff --git a/gcc/ubsan.c b/gcc/ubsan.c
> index c205e6b..8e7dda5 100644
> --- a/gcc/ubsan.c
> +++ b/gcc/ubsan.c
> @@ -902,13 +902,6 @@ ubsan_pass (void)
>    return 0;
>  }
>
> -static bool
> -gate_ubsan (void)
> -{
> -  return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
> -                         | SANITIZE_BOOL | SANITIZE_ENUM);
> -}
> -
>  namespace {
>
>  const pass_data pass_data_ubsan =
> @@ -933,7 +926,12 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_ubsan (); }
> +  virtual bool gate (function *)
> +    {
> +      return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW
> +                             | SANITIZE_BOOL | SANITIZE_ENUM);
> +    }
> +
>    unsigned int execute () { return ubsan_pass (); }
>
>  }; // class pass_ubsan
> diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
> index e6ca3af..4586afc 100644
> --- a/gcc/var-tracking.c
> +++ b/gcc/var-tracking.c
> @@ -10344,14 +10344,6 @@ variable_tracking_main (void)
>    return ret;
>  }
>
> -static bool
> -gate_handle_var_tracking (void)
> -{
> -  return (flag_var_tracking && !targetm.delay_vartrack);
> -}
> -
> -
> -
>  namespace {
>
>  const pass_data pass_data_variable_tracking =
> @@ -10376,7 +10368,11 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_var_tracking (); }
> +  virtual bool gate (function *)
> +    {
> +      return (flag_var_tracking && !targetm.delay_vartrack);
> +    }
> +
>    unsigned int execute () { return variable_tracking_main (); }
>
>  }; // class pass_variable_tracking
> diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
> index 99caa88..601b2ce 100644
> --- a/gcc/vtable-verify.c
> +++ b/gcc/vtable-verify.c
> @@ -740,14 +740,6 @@ vtable_verify_main (void)
>    return ret;
>  }
>
> -/* Gate function for the pass.  */
> -
> -static bool
> -gate_tree_vtable_verify (void)
> -{
> -  return (flag_vtable_verify);
> -}
> -
>  /* Definition of this optimization pass.  */
>
>  namespace {
> @@ -774,7 +766,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_tree_vtable_verify (); }
> +  virtual bool gate (function *) { return (flag_vtable_verify); }
>    unsigned int execute () { return vtable_verify_main (); }
>
>  }; // class pass_vtable_verify
> diff --git a/gcc/web.c b/gcc/web.c
> index ba4172e..50fc9e6 100644
> --- a/gcc/web.c
> +++ b/gcc/web.c
> @@ -325,12 +325,6 @@ replace_ref (df_ref ref, rtx reg)
>  }
>
>
> -static bool
> -gate_handle_web (void)
> -{
> -  return (optimize > 0 && flag_web);
> -}
> -
>  /* Main entry point.  */
>
>  static unsigned int
> @@ -473,7 +467,7 @@ public:
>    {}
>
>    /* opt_pass methods: */
> -  bool gate () { return gate_handle_web (); }
> +  virtual bool gate (function *) { return (optimize > 0 && flag_web); }
>    unsigned int execute () { return web_main (); }
>
>  }; // class pass_web
> --
> 1.9.2
>



More information about the Gcc-patches mailing list