This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: New options to disable/enable any pass for any functions (issue4550056)


Will fix the Changelog, and add documentation.

Thanks,

David



On Wed, May 18, 2011 at 1:26 PM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Wed, May 18, 2011 at 8:37 PM, David Li <davidxl@google.com> wrote:
>>
>> In gcc, not all passes have user level control to turn it on/off, and
>> there is no way to flip on/off the pass for a subset of functions. I
>> implemented a generic option handling scheme in gcc to allow
>> disabling/enabling any gcc pass for any specified function(s). ?The
>> new options will be very useful for things like performance
>> experiments and bug triaging (gcc has dbgcnt mechanism, but not all
>> passes have the counter).
>>
>> The option syntax is very similar to -fdump- options. The following
>> are some examples:
>>
>> -fdisable-tree-ccp1 ? ?<--- disable ccp1 for all functions
>> -fenable-tree-cunroll=1 ? <--- enable complete unroll for the function
>> ? ? ? ? ? ? ? ? ? ? ? ? ? whose cgraphnode uid is 1
>> -fdisable-rtl-gcse2=1:100,300,400:1000 ? <-- disable gcse2 for
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? functions at the following
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ranges [1,1], [300,400], and [400,1000]
>> -fdisable-tree-einline --> disable early inlining for all callers
>> -fdisable-ipa-inline --> disable ipa inlininig
>>
>> In the gcc dumps, the uid numbers are displayed in the function header.
>>
>> The options are intended to be used internally by gcc developers.
>>
>> Ok for trunk ? (There is a little LIPO specific change that can be removed).
>>
>> David
>>
>> 2011-05-18 ?David Li ?<davidxl@google.com>
>>
>> ? ? ? ?* final.c (rest_of_clean_state): Call function header dumper.
>> ? ? ? ?* opts-global.c (handle_common_deferred_options): Handle new options.
>> ? ? ? ?* tree-cfg.c (gimple_dump_cfg): Call function header dumper.
>> ? ? ? ?* passes.c (register_one_dump_file): Call register_pass_name.
>> ? ? ? ?(pass_init_dump_file): Call function header dumper.
>> ? ? ? ?(execute_one_pass): Check explicit enable/disable flag.
>> ? ? ? ?(passr_hash): New function.
>> ? ? ? ?(passr_eq):
>> ? ? ? ?(register_pass_name):
>> ? ? ? ?(get_pass_by_name):
>> ? ? ? ?(pass_hash):
>> ? ? ? ?(pass_eq):
>> ? ? ? ?(enable_disable_pass):
>> ? ? ? ?(is_pass_explicitly_enabled_or_disabled):
>> ? ? ? ?(is_pass_explicitly_enabled):
>> ? ? ? ?(is_pass_explicitly_disabled):
>
> Bogus changelog entry.
>
> New options need documenting in doc/invoke.texi.
>
> Richard.
>
>>
>> Index: tree-pass.h
>> ===================================================================
>> --- tree-pass.h (revision 173635)
>> +++ tree-pass.h (working copy)
>> @@ -644,4 +644,12 @@ extern bool first_pass_instance;
>> ?/* Declare for plugins. ?*/
>> ?extern void do_per_function_toporder (void (*) (void *), void *);
>>
>> +extern void enable_disable_pass (const char *, bool);
>> +extern bool is_pass_explicitly_disabled (struct opt_pass *, tree);
>> +extern bool is_pass_explicitly_enabled (struct opt_pass *, tree);
>> +extern void register_pass_name (struct opt_pass *, const char *);
>> +extern struct opt_pass *get_pass_by_name (const char *);
>> +struct function;
>> +extern void pass_dump_function_header (FILE *, tree, struct function *);
>> +
>> ?#endif /* GCC_TREE_PASS_H */
>> Index: final.c
>> ===================================================================
>> --- final.c ? ? (revision 173635)
>> +++ final.c ? ? (working copy)
>> @@ -4456,19 +4456,7 @@ rest_of_clean_state (void)
>> ? ? ? ?}
>> ? ? ? else
>> ? ? ? ?{
>> - ? ? ? ? const char *aname;
>> - ? ? ? ? struct cgraph_node *node = cgraph_node (current_function_decl);
>> -
>> - ? ? ? ? aname = (IDENTIFIER_POINTER
>> - ? ? ? ? ? ? ? ? ?(DECL_ASSEMBLER_NAME (current_function_decl)));
>> - ? ? ? ? fprintf (final_output, "\n;; Function (%s) %s\n\n", aname,
>> - ? ? ? ? ? ?node->frequency == NODE_FREQUENCY_HOT
>> - ? ? ? ? ? ?? " (hot)"
>> - ? ? ? ? ? ?: node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
>> - ? ? ? ? ? ?? " (unlikely executed)"
>> - ? ? ? ? ? ?: node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
>> - ? ? ? ? ? ?? " (executed once)"
>> - ? ? ? ? ? ?: "");
>> + ? ? ? ? pass_dump_function_header (final_output, current_function_decl, cfun);
>>
>> ? ? ? ? ?flag_dump_noaddr = flag_dump_unnumbered = 1;
>> ? ? ? ? ?if (flag_compare_debug_opt || flag_compare_debug)
>> Index: common.opt
>> ===================================================================
>> --- common.opt ?(revision 173635)
>> +++ common.opt ?(working copy)
>> @@ -1018,6 +1018,14 @@ fdiagnostics-show-option
>> ?Common Var(flag_diagnostics_show_option) Init(1)
>> ?Amend appropriate diagnostic messages with the command line option that controls them
>>
>> +fdisable-
>> +Common Joined RejectNegative Var(common_deferred_options) Defer
>> +-fdisable-[tree|rtl|ipa]-<pass>=range1+range2 disables an optimization pass
>> +
>> +fenable-
>> +Common Joined RejectNegative Var(common_deferred_options) Defer
>> +-fenable-[tree|rtl|ipa]-<pass>=range1+range2 enables an optimization pass
>> +
>> ?fdump-
>> ?Common Joined RejectNegative Var(common_deferred_options) Defer
>> ?-fdump-<type> ?Dump various compiler internals to a file
>> Index: opts-global.c
>> ===================================================================
>> --- opts-global.c ? ? ? (revision 173635)
>> +++ opts-global.c ? ? ? (working copy)
>> @@ -411,6 +411,12 @@ handle_common_deferred_options (void)
>> ? ? ? ? ? ?error ("unrecognized command line option %<-fdump-%s%>", opt->arg);
>> ? ? ? ? ?break;
>>
>> + ? ? ? case OPT_fenable_:
>> + ? ? ? case OPT_fdisable_:
>> + ? ? ? ? enable_disable_pass (opt->arg, (opt->opt_index == OPT_fenable_?
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?true : false));
>> + ? ? ? ? ?break;
>> +
>> ? ? ? ?case OPT_ffixed_:
>> ? ? ? ? ?/* Deferred. ?*/
>> ? ? ? ? ?fix_register (opt->arg, 1, 1);
>> Index: tree-cfg.c
>> ===================================================================
>> --- tree-cfg.c ?(revision 173636)
>> +++ tree-cfg.c ?(working copy)
>> @@ -2090,11 +2090,7 @@ gimple_dump_cfg (FILE *file, int flags)
>> ?{
>> ? if (flags & TDF_DETAILS)
>> ? ? {
>> - ? ? ?const char *funcname
>> - ? ? ? = lang_hooks.decl_printable_name (current_function_decl, 2);
>> -
>> - ? ? ?fputc ('\n', file);
>> - ? ? ?fprintf (file, ";; Function %s\n\n", funcname);
>> + ? ? ?pass_dump_function_header (file, current_function_decl, cfun);
>> ? ? ? fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n",
>> ? ? ? ? ? ? ? n_basic_blocks, n_edges, last_basic_block);
>>
>> Index: passes.c
>> ===================================================================
>> --- passes.c ? ?(revision 173635)
>> +++ passes.c ? ?(working copy)
>> @@ -382,7 +382,7 @@ void
>> ?register_one_dump_file (struct opt_pass *pass)
>> ?{
>> ? char *dot_name, *flag_name, *glob_name;
>> - ?const char *name, *prefix;
>> + ?const char *name, *full_name, *prefix;
>> ? char num[10];
>> ? int flags, id;
>>
>> @@ -411,6 +411,8 @@ register_one_dump_file (struct opt_pass
>> ? glob_name = concat (prefix, name, NULL);
>> ? id = dump_register (dot_name, flag_name, glob_name, flags);
>> ? set_pass_for_id (id, pass);
>> + ?full_name = concat (prefix, pass->name, num, NULL);
>> + ?register_pass_name (pass, full_name);
>> ?}
>>
>> ?/* Recursive worker function for register_dump_files. ?*/
>> @@ -454,6 +456,298 @@ register_dump_files (struct opt_pass *pa
>> ? register_dump_files_1 (pass, properties);
>> ?}
>>
>> +struct pass_registry
>> +{
>> + ?const char* unique_name;
>> + ?struct opt_pass *pass;
>> +};
>> +
>> +/* Pass registry hash function. ?*/
>> +
>> +static hashval_t
>> +passr_hash (const void *p)
>> +{
>> + ?const struct pass_registry *const s = (const struct pass_registry *const) p;
>> + ?return htab_hash_string (s->unique_name);
>> +}
>> +
>> +/* Hash equal function ?*/
>> +
>> +static int
>> +passr_eq (const void *p1, const void *p2)
>> +{
>> + ?const struct pass_registry *const s1 = (const struct pass_registry *const) p1;
>> + ?const struct pass_registry *const s2 = (const struct pass_registry *const) p2;
>> +
>> + ?return !strcmp (s1->unique_name, s2->unique_name);
>> +}
>> +
>> +static htab_t pass_name_tab = NULL;
>> +
>> +/* Register PASS with NAME. ?*/
>> +
>> +void
>> +register_pass_name (struct opt_pass *pass, const char *name)
>> +{
>> + ?struct pass_registry **slot;
>> + ?struct pass_registry pr;
>> +
>> + ?if (!pass_name_tab)
>> + ? ?pass_name_tab = htab_create (10, passr_hash, passr_eq, NULL);
>> +
>> + ?pr.unique_name = name;
>> + ?slot = (struct pass_registry **) htab_find_slot (pass_name_tab, &pr, INSERT);
>> + ?if (!*slot)
>> + ? ?{
>> + ? ? ?struct pass_registry *new_pr;
>> +
>> + ? ? ?new_pr = XCNEW (struct pass_registry);
>> + ? ? ?new_pr->unique_name = xstrdup (name);
>> + ? ? ?new_pr->pass = pass;
>> + ? ? ?*slot = new_pr;
>> + ? ?}
>> + ?else
>> + ? ?gcc_assert ((*slot)->pass == pass);
>> +}
>> +
>> +/* Returns the pass with NAME. ?*/
>> +
>> +struct opt_pass *
>> +get_pass_by_name (const char *name)
>> +{
>> + ?struct pass_registry **slot, pr;
>> +
>> + ?gcc_assert (pass_name_tab);
>> + ?pr.unique_name = name;
>> + ?slot = (struct pass_registry **) htab_find_slot (pass_name_tab, &pr, NO_INSERT);
>> +
>> + ?if (!slot || !*slot)
>> + ? ?return NULL;
>> +
>> + ?return (*slot)->pass;
>> +}
>> +
>> +
>> +/* Range [start, last]. ?*/
>> +
>> +struct uid_range
>> +{
>> + ?struct opt_pass *pass;
>> + ?unsigned int start;
>> + ?unsigned int last;
>> + ?struct uid_range *next;
>> +};
>> +
>> +/* Hash function for pass structure. ?*/
>> +
>> +static hashval_t
>> +pass_hash (const void *s)
>> +{
>> + ?const struct uid_range *const p = (const struct uid_range *const) s;
>> + ?return p->pass->static_pass_number;
>> +}
>> +
>> +/* Pass equal function ?*/
>> +
>> +static int
>> +pass_eq (const void *s1, const void *s2)
>> +{
>> + ?const struct uid_range *const p1 = (const struct uid_range *const) s1;
>> + ?const struct uid_range *const p2 = (const struct uid_range *const) s2;
>> + ?return p1->pass->static_pass_number == p2->pass->static_pass_number;
>> +}
>> +
>> +htab_t enabled_pass_uid_range_tab = NULL;
>> +htab_t disabled_pass_uid_range_tab = NULL;
>> +
>> +/* Parse option string for -fdisable- and -fenabler-
>> + ? The syntax of the options:
>> +
>> + ? -fenable-<pass_name>
>> + ? -fdisable-<pass_name>
>> +
>> + ? -fenable-<pass_name>=s1:e1,s2:e2,...
>> + ? -fdisable-<pass_name>=s1:e1,s2:e2,...
>> +*/
>> +
>> +void
>> +enable_disable_pass (const char *arg, bool is_enable)
>> +{
>> + ?struct opt_pass *pass;
>> + ?htab_t the_tab;
>> + ?char *range_str, *phase_name;
>> + ?char *argstr = xstrdup (arg);
>> +
>> + ?range_str = strchr (argstr,'=');
>> + ?if (range_str)
>> + ? ?{
>> + ? ? ?*range_str = '\0';
>> + ? ? ?range_str++;
>> + ? ?}
>> +
>> + ?phase_name = argstr;
>> + ?if (!*phase_name)
>> + ? ?{
>> + ? ? ?error ("Unrecognized option %s", is_enable ? "-fenable" : "-fdisable");
>> + ? ? ?free (argstr);
>> + ? ? ?return;
>> + ? ?}
>> + ?pass = get_pass_by_name (phase_name);
>> + ?if (!pass)
>> + ? ?{
>> + ? ? ?error ("Unknown pass %s specified in %s",
>> + ? ? ? ? ? ?phase_name,
>> + ? ? ? ? ? ?is_enable ? "-fenable" : "-fdisable");
>> + ? ? ?free (argstr);
>> + ? ? ?return;
>> + ? ?}
>> + ?if (is_enable)
>> + ? ?{
>> + ? ? ?if (!enabled_pass_uid_range_tab)
>> + ? ? ? enabled_pass_uid_range_tab = htab_create (10, pass_hash, pass_eq, NULL);
>> + ? ? ?the_tab = enabled_pass_uid_range_tab;
>> + ? ?}
>> + ?else
>> + ? ?{
>> + ? ? ?if (!disabled_pass_uid_range_tab)
>> + ? ? ? disabled_pass_uid_range_tab = htab_create (10, pass_hash, pass_eq, NULL);
>> + ? ? ?the_tab = disabled_pass_uid_range_tab;
>> + ? ?}
>> +
>> + ?if (!range_str)
>> + ? ?{
>> + ? ? ?struct uid_range **slot;
>> + ? ? ?struct uid_range *new_range = XCNEW (struct uid_range);
>> +
>> + ? ? ?new_range->pass = pass;
>> + ? ? ?new_range->start = 0;
>> + ? ? ?new_range->last = (unsigned)-1;
>> +
>> + ? ? ?slot = (struct uid_range **) htab_find_slot (the_tab, new_range, INSERT);
>> + ? ? ?new_range->next = *slot;
>> + ? ? ?*slot = new_range;
>> + ? ? ?inform (UNKNOWN_LOCATION, "%s pass %s for functions in the range of [%u, %u]\n",
>> + ? ? ? ? ? ? ?is_enable? "Enable":"Disable", phase_name, new_range->start, new_range->last);
>> + ? ?}
>> + ?else
>> + ? ?{
>> + ? ? ?char *next_range = NULL;
>> + ? ? ?char *one_range = range_str;
>> + ? ? ?char *end_val = NULL;
>> +
>> + ? ? ?do
>> + ? ? ? {
>> + ? ? ? ? struct uid_range **slot;
>> + ? ? ? ? struct uid_range *new_range;
>> + ? ? ? ? char *invalid = NULL;
>> + ? ? ? ? long start;
>> +
>> + ? ? ? ? next_range = strchr (one_range, ',');
>> + ? ? ? ? if (next_range)
>> + ? ? ? ? ? {
>> + ? ? ? ? ? ? *next_range = '\0';
>> + ? ? ? ? ? ? next_range++;
>> + ? ? ? ? ? }
>> +
>> + ? ? ? ? end_val = strchr (one_range, ':');
>> + ? ? ? ? if (end_val)
>> + ? ? ? ? ? {
>> + ? ? ? ? ? ? *end_val = '\0';
>> + ? ? ? ? ? ? end_val++;
>> + ? ? ? ? ? }
>> + ? ? ? ? start = strtol (one_range, &invalid, 10);
>> + ? ? ? ? if (*invalid || start < 0)
>> + ? ? ? ? ? {
>> + ? ? ? ? ? ? error ("Invalid range %s in option %s",
>> + ? ? ? ? ? ? ? ? ? ?one_range,
>> + ? ? ? ? ? ? ? ? ? ?is_enable ? "-fenable" : "-fdisable");
>> + ? ? ? ? ? ? free (argstr);
>> + ? ? ? ? ? ? return;
>> + ? ? ? ? ? }
>> + ? ? ? ? if (!end_val)
>> + ? ? ? ? ? {
>> + ? ? ? ? ? ? new_range = XCNEW (struct uid_range);
>> + ? ? ? ? ? ? ?new_range->pass = pass;
>> + ? ? ? ? ? ? new_range->start = (unsigned) start;
>> + ? ? ? ? ? ? new_range->last = (unsigned) start;
>> + ? ? ? ? ? }
>> + ? ? ? ? else
>> + ? ? ? ? ? {
>> + ? ? ? ? ? ? long last = strtol (end_val, &invalid, 10);
>> + ? ? ? ? ? ? if (*invalid || last < start)
>> + ? ? ? ? ? ? ? {
>> + ? ? ? ? ? ? ? ? error ("Invalid range %s in option %s",
>> + ? ? ? ? ? ? ? ? ? ? ? ?end_val,
>> + ? ? ? ? ? ? ? ? ? ? ? ?is_enable ? "-fenable" : "-fdisable");
>> + ? ? ? ? ? ? ? ? free (argstr);
>> + ? ? ? ? ? ? ? ? return;
>> + ? ? ? ? ? ? ? }
>> + ? ? ? ? ? ? new_range = XCNEW (struct uid_range);
>> + ? ? ? ? ? ? ?new_range->pass = pass;
>> + ? ? ? ? ? ? new_range->start = (unsigned) start;
>> + ? ? ? ? ? ? new_range->last = (unsigned) last;
>> + ? ? ? ? ? }
>> + ? ? ? ? slot = (struct uid_range **) htab_find_slot (the_tab, new_range, INSERT);
>> + ? ? ? ? new_range->next = *slot;
>> + ? ? ? ? *slot = new_range;
>> + ? ? ? ? ?inform (UNKNOWN_LOCATION, "%s pass %s for functions in the range of [%u, %u]\n",
>> + ? ? ? ? ? ? ? ? ?is_enable? "Enable":"Disable", phase_name, new_range->start, new_range->last);
>> +
>> + ? ? ? ? one_range = next_range;
>> + ? ? ? } while (next_range);
>> + ? ?}
>> +
>> + ?free (argstr);
>> +}
>> +
>> +/* Returns true if PASS is explicitly enabled/disabled for FUNC. ?*/
>> +
>> +static bool
>> +is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tree func, htab_t tab)
>> +{
>> + ?struct uid_range **slot, *range, key;
>> + ?int cgraph_uid;
>> +
>> + ?if (!tab)
>> + ? ?return false;
>> +
>> + ?key.pass = pass;
>> + ?slot = (struct uid_range **) htab_find_slot (tab, &key, NO_INSERT);
>> + ?if (!slot || !*slot)
>> + ? ?return false;
>> +
>> + ?cgraph_uid = func ? cgraph_node (func)->uid : 0;
>> +
>> + ?range = *slot;
>> + ?while (range)
>> + ? ?{
>> + ? ? ?if ((unsigned) cgraph_uid >= range->start
>> + ? ? ? ? && (unsigned) cgraph_uid <= range->last)
>> + ? ? ? return true;
>> + ? ? ?range = range->next;
>> + ? ?}
>> +
>> + ?return false;
>> +}
>> +
>> +/* Returns true if PASS is explicitly enabled for FUNC. ?*/
>> +
>> +bool
>> +is_pass_explicitly_enabled (struct opt_pass *pass, tree func)
>> +{
>> + ?return is_pass_explicitly_enabled_or_disabled (pass, func, enabled_pass_uid_range_tab);
>> +}
>> +
>> +/* Returns true if PASS is explicitly disabled for FUNC. ?*/
>> +
>> +bool
>> +is_pass_explicitly_disabled (struct opt_pass *pass, tree func)
>> +{
>> + ?return is_pass_explicitly_enabled_or_disabled (pass, func, disabled_pass_uid_range_tab);
>> +}
>> +
>> +
>> ?/* Look at the static_pass_number and duplicate the pass
>> ? ?if it is already added to a list. */
>>
>> @@ -1349,6 +1643,29 @@ verify_curr_properties (void *data)
>> ?}
>> ?#endif
>>
>> +void
>> +pass_dump_function_header (FILE *dump_file, tree fdecl, struct function *fun)
>> +{
>> + ?const char *dname, *aname;
>> + ?struct cgraph_node *node = cgraph_node (fdecl);
>> + ?dname = lang_hooks.decl_printable_name (fdecl, 2);
>> + ?aname = (IDENTIFIER_POINTER
>> + ? ? ? ? ?(DECL_ASSEMBLER_NAME (fdecl)));
>> + ?if (L_IPO_COMP_MODE)
>> + ? ?fprintf (dump_file, "\n;; Function %s (%s)[%d:%d][uid=%d]", dname, aname,
>> + ? ? ? ? ? ?FUNC_DECL_MODULE_ID (fun), FUNC_DECL_FUNC_ID (fun), node->uid);
>> + ?else
>> + ? ?fprintf (dump_file, "\n;; Function %s (%s)[uid=%d]", dname, aname, node->uid);
>> + ?fprintf (dump_file, "%s\n\n",
>> + ? ? ? ? ? node->frequency == NODE_FREQUENCY_HOT
>> + ? ? ? ? ? ? " (hot)"
>> + ? ? ? ? ? : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
>> + ? ? ? ? ? ? " (unlikely executed)"
>> + ? ? ? ? ? : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
>> + ? ? ? ? ? ? " (executed once)"
>> + ? ? ? ? ? : "");
>> +}
>> +
>> ?/* Initialize pass dump file. ?*/
>> ?/* This is non-static so that the plugins can use it. ?*/
>>
>> @@ -1362,26 +1679,7 @@ pass_init_dump_file (struct opt_pass *pa
>> ? ? ? dump_file_name = get_dump_file_name (pass->static_pass_number);
>> ? ? ? dump_file = dump_begin (pass->static_pass_number, &dump_flags);
>> ? ? ? if (dump_file && current_function_decl)
>> - ? ? ? {
>> - ? ? ? ? const char *dname, *aname;
>> - ? ? ? ? struct cgraph_node *node = cgraph_node (current_function_decl);
>> - ? ? ? ? dname = lang_hooks.decl_printable_name (current_function_decl, 2);
>> - ? ? ? ? aname = (IDENTIFIER_POINTER
>> - ? ? ? ? ? ? ? ? ?(DECL_ASSEMBLER_NAME (current_function_decl)));
>> - ? ? ? ? if (L_IPO_COMP_MODE)
>> - ? ? ? ? ? fprintf (dump_file, "\n;; Function %s (%s)[%d:%d]", dname, aname,
>> - ? ? ? ? ? ? ? ? ? ?FUNC_DECL_MODULE_ID (cfun), FUNC_DECL_FUNC_ID (cfun));
>> - ? ? ? ? else
>> - ? ? ? ? ? fprintf (dump_file, "\n;; Function %s (%s)", dname, aname);
>> - ? ? ? ? fprintf (dump_file, "%s\n\n",
>> - ? ? ? ? ? ?node->frequency == NODE_FREQUENCY_HOT
>> - ? ? ? ? ? ?? " (hot)"
>> - ? ? ? ? ? ?: node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
>> - ? ? ? ? ? ?? " (unlikely executed)"
>> - ? ? ? ? ? ?: node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
>> - ? ? ? ? ? ?? " (executed once)"
>> - ? ? ? ? ? ?: "");
>> - ? ? ? }
>> + ? ? ? ?pass_dump_function_header (dump_file, current_function_decl, cfun);
>> ? ? ? return initializing_dump;
>> ? ? }
>> ? else
>> @@ -1525,6 +1823,8 @@ execute_one_pass (struct opt_pass *pass)
>> ?{
>> ? bool initializing_dump;
>> ? unsigned int todo_after = 0;
>> + ?bool explicitly_enabled = false;
>> + ?bool explicitly_disabled = false;
>>
>> ? bool gate_status;
>>
>> @@ -1535,11 +1835,15 @@ execute_one_pass (struct opt_pass *pass)
>> ? else
>> ? ? gcc_assert (cfun && current_function_decl);
>>
>> + ?explicitly_enabled = is_pass_explicitly_enabled (pass, current_function_decl);
>> + ?explicitly_disabled = is_pass_explicitly_disabled (pass, current_function_decl);
>> +
>> ? current_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 == NULL) ? true : pass->gate();
>> + ?gate_status = !explicitly_disabled && (gate_status || explicitly_enabled);
>>
>> ? /* Override gate with plugin. ?*/
>> ? invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
>>
>> --
>> This patch is available for review at http://codereview.appspot.com/4550056
>>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]