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)


The latest version that only exports 2 functions from passes.c.

David

On Thu, May 26, 2011 at 2:04 PM, Xinliang David Li <davidxl@google.com> wrote:
> On Thu, May 26, 2011 at 2:04 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Wed, May 25, 2011 at 6:53 PM, Joseph S. Myers
>> <joseph@codesourcery.com> wrote:
>>> On Wed, 25 May 2011, Xinliang David Li wrote:
>>>
>>>> Ping. The link to the message:
>>>>
>>>> http://gcc.gnu.org/ml/gcc-patches/2011-05/msg01303.html
>>>
>>> I don't consider this an option handling patch. ?Patches adding whole new
>>> features involving new options should be reviewed by maintainers for the
>>> part of the compiler relevant to those features (since there isn't a pass
>>> manager maintainer, I guess that means middle-end).
>>
>> Hmm, I suppose then you reviewed the option handling parts and they
>> are ok? ?Those globbing options always cause headache to me.
>>
>> +-fenable-ipa-@var{pass} @gol
>> +-fenable-rtl-@var{pass} @gol
>> +-fenable-rtl-@var{pass}=@var{range-list} @gol
>> +-fenable-tree-@var{pass} @gol
>>
>> so, no -fenable-tree-@var{pass}=@var{range-list}?
>>
>
> Missed. Will add.
>
>
>> Does the pass name match 1:1 with the dump file name? ?In which
>> case
>
> Yes.
>
>>
>> +Disable ipa pass @var{pass}. @var{pass} is the pass name. If the same
>> pass is statically invoked in the compiler multiple times, the pass
>> name should be appended with a sequential number starting from 1.
>>
>> isn't true as passes that are invoked only a single time lack the number
>> suffix (yes, I'd really like that to be changed ...)
>
> Yes, pass with single static instance does not need number suffix.
>
>>
>> Please break likes also in .texi files and stick to 80 columns.
>
> Done.
>
>> ?Please
>> document that these options are debugging options and regular
>> options for enabling/disabling passes should be used. ?I would suggest
>> to group documentation differently and document -fenable-* and
>> -fdisable-*, thus,
>>
>> + -fdisable-@var{kind}-@var{pass}
>> + -fenable-@var{kind}-@var{pass}
>>
>> Even in .texi files please two spaces after a full-stop.
>
> Done
>
>>
>> +extern void enable_disable_pass (const char *, bool);
>>
>> I'd rather have both enable_pass and disable_pass ;)
>
> Ok.
>
>>
>> +struct function;
>> +extern void pass_dump_function_header (FILE *, tree, struct function *);
>>
>> that's odd and probably should be split out, the function should
>> maybe reside in tree-pretty-print.c.
>
> Ok.
>
>>
>> Index: tree-ssa-loop-ivopts.c
>> ===================================================================
>> --- tree-ssa-loop-ivopts.c ? ? ?(revision 173837)
>> +++ tree-ssa-loop-ivopts.c ? ? ?(working copy)
>> @@ -3968,7 +3968,7 @@ get_computation_cost_at (struct ivopts_d
>>
>> well - doesn't belong here ;)
>
> Sorry -- many things in the same client -- not needed with your latest
> change anyway.
>
>>
>> +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);
>> +}
>>
>> you can use htab_hash_string and strcmp directly, no need for these
>> wrappers.
>
> The hashtable entry is not string in this case. It is pass_registry,
> thus the wrapper.
>
>>
>> +void
>> +register_pass_name (struct opt_pass *pass, const char *name)
>>
>> doesn't seem to need exporting, so don't and make it static.
>
> Done.
>
>>
>> + ?if (!pass_name_tab)
>> + ? ?pass_name_tab = htab_create (10, passr_hash, passr_eq, NULL);
>>
>> see above, the initial size should be larger - we have 223 passes at the
>> moment, so use 256.
>
> Done.
>
>>
>> + ?else
>> + ? ?return; /* Ignore plugin passes. ?*/
>>
>> ? ?You mean they might clash?
>
> Yes, name clash.
>
>>
>> +struct opt_pass *
>> +get_pass_by_name (const char *name)
>>
>> doesn't need exporting either.
>
> Done.
>
>>
>> + ? ? ?if (is_enable)
>> + ? ? ? ?error ("unrecognized option -fenable");
>> + ? ? ?else
>> + ? ? ? ?error ("unrecognized option -fdisable");
>>
>> I think that should be fatal_error - Joseph?
>>
>> + ? ? ?if (is_enable)
>> + ? ? ? ?error ("unknown pass %s specified in -fenable", phase_name);
>> + ? ? ?else
>> + ? ? ? ?error ("unknown pass %s specified in -fdisble", phase_name);
>>
>> likewise.
>>
>> + ? ? ?if (!enabled_pass_uid_range_tab)
>> + ? ? ? enabled_pass_uid_range_tab = htab_create (10, pass_hash, pass_eq, NULL);
>>
>> instead of using a hashtable here please use a VEC indexed by
>> the static_pass_number which shoud speed up
>
> Ok. ?The reason I did not use it is because in most of the cases, the
> htab will be very small -- it is determined by the number of passes
> specified in the command line, while the VEC requires allocating const
> size array. Not an issue as long as by default the array is not
> allocated.
>
>>
>> +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;
>>
>> and simplify the code quite a bit.
>>
>> + ?cgraph_uid = func ? cgraph_get_node (func)->uid : 0;
>>
>> note that cgraph uids are recycled, so it might not be the best idea
>> to use them as discriminator (though I don't have a good idea how
>> to represent ranges without them).
>
> Yes. It is not a big problem as the blind search does not need to know
> the id->name mapping. Once the id s found, it can be easily discovered
> via dump.
>
>>
>> + ?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);
>>
>> so explicitly disabling wins over explicit enabling ;) ?I think this
>> implementation detail and the fact that you always query both
>> hints at that the interface should be like
>>
>> gate_status = override_gate_status (pass, current_function_decl, gate_status);
>
> Done.
>
>>
>> instead.
>>
>> Thus, please split out the function header dumping changes and rework
>> the rest of the patch as suggested.
>
> Split out. The new patch is attached.
>
> Ok after testing is done?
>
> Thanks,
>
> David
>
>>
>> Thanks,
>> Richard.
>>
>>> --
>>> Joseph S. Myers
>>> joseph@codesourcery.com
>>>
>>
>
Index: passes.c
===================================================================
--- passes.c	(revision 174076)
+++ passes.c	(working copy)
@@ -97,6 +97,8 @@ along with GCC; see the file COPYING3.  
    The variable current_pass is also used for statistics and plugins.  */
 struct opt_pass *current_pass;
 
+static void register_pass_name (struct opt_pass *, const char *);
+
 /* Call from anywhere to find out what pass this is.  Useful for
    printing out debugging information deep inside an service
    routine.  */
@@ -375,7 +377,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;
 
@@ -404,6 +406,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.  */
@@ -447,6 +451,322 @@ 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.  */
+
+static 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 (256, 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
+    return; /* Ignore plugin passes.  */
+}
+
+/* Returns the pass with NAME.  */
+
+static 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
+{
+  unsigned int start;
+  unsigned int last;
+  struct uid_range *next;
+};
+
+typedef struct uid_range *uid_range_p;
+
+#define MAX_PASS_ID 512
+
+DEF_VEC_P(uid_range_p);
+DEF_VEC_ALLOC_P(uid_range_p, heap);
+
+static VEC(uid_range_p, heap) *enabled_pass_uid_range_tab = NULL;
+static VEC(uid_range_p, heap) *disabled_pass_uid_range_tab = NULL;
+
+/* Parse option string for -fdisable- and -fenable-
+   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,...
+*/
+
+static void
+enable_disable_pass (const char *arg, bool is_enable)
+{
+  struct opt_pass *pass;
+  VEC(uid_range_p, heap) *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)
+    {
+      if (is_enable)
+        error ("unrecognized option -fenable");
+      else
+        error ("unrecognized option -fdisable");
+      free (argstr);
+      return;
+    }
+  pass = get_pass_by_name (phase_name);
+  if (!pass || pass->static_pass_number >= MAX_PASS_ID)
+    {
+      if (is_enable)
+        error ("unknown pass %s specified in -fenable", phase_name);
+      else
+        error ("unknown pass %s specified in -fdisble", phase_name);
+      free (argstr);
+      return;
+    }
+  if (is_enable)
+    {
+      if (!enabled_pass_uid_range_tab)
+        VEC_safe_grow_cleared (uid_range_p, heap,
+                               enabled_pass_uid_range_tab, MAX_PASS_ID);
+      the_tab = enabled_pass_uid_range_tab;
+    }
+  else
+    {
+      if (!disabled_pass_uid_range_tab)
+        VEC_safe_grow_cleared (uid_range_p, heap,
+                               disabled_pass_uid_range_tab, MAX_PASS_ID);
+      the_tab = disabled_pass_uid_range_tab;
+    }
+
+  if (!range_str)
+    {
+      uid_range_p slot;
+      uid_range_p new_range = XCNEW (struct uid_range);
+
+      new_range->start = 0;
+      new_range->last = (unsigned)-1;
+
+      slot = VEC_index (uid_range_p, the_tab, pass->static_pass_number);
+      new_range->next = slot;
+      VEC_replace (uid_range_p, the_tab, pass->static_pass_number,
+                   new_range);
+      if (is_enable)
+        inform (UNKNOWN_LOCATION, "enable pass %s for functions in the range "
+                "of [%u, %u]", phase_name, new_range->start, new_range->last);
+      else
+        inform (UNKNOWN_LOCATION, "disable pass %s for functions in the range "
+                "of [%u, %u]", phase_name, new_range->start, new_range->last);
+    }
+  else
+    {
+      char *next_range = NULL;
+      char *one_range = range_str;
+      char *end_val = NULL;
+
+      do
+	{
+	  uid_range_p slot;
+	  uid_range_p 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->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->start = (unsigned) start;
+	      new_range->last = (unsigned) last;
+	    }
+
+          slot = VEC_index (uid_range_p, the_tab, pass->static_pass_number);
+          new_range->next = slot;
+          VEC_replace (uid_range_p, the_tab, pass->static_pass_number,
+                       new_range);
+
+          if (is_enable)
+            inform (UNKNOWN_LOCATION,
+                    "enable pass %s for functions in the range of [%u, %u]",
+                    phase_name, new_range->start, new_range->last);
+          else
+            inform (UNKNOWN_LOCATION,
+                    "disable pass %s for functions in the range of [%u, %u]",
+                    phase_name, new_range->start, new_range->last);
+
+	  one_range = next_range;
+	} while (next_range);
+    }
+
+  free (argstr);
+}
+
+/* Enable pass specified by ARG.  */
+
+void
+enable_pass (const char *arg)
+{
+  enable_disable_pass (arg, true);
+}
+
+/* Disable pass specified by ARG.  */
+
+void
+disable_pass (const char *arg)
+{
+  enable_disable_pass (arg, false);
+}
+
+/* Returns true if PASS is explicitly enabled/disabled for FUNC.  */
+
+static bool
+is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass,
+					tree func,
+					VEC(uid_range_p, heap) *tab)
+{
+  uid_range_p slot, range;
+  int cgraph_uid;
+
+  if (!tab
+      || pass->static_pass_number >= MAX_PASS_ID
+      || pass->static_pass_number == -1)
+    return false;
+
+  slot = VEC_index (uid_range_p, tab, pass->static_pass_number);
+  if (!slot)
+    return false;
+
+  cgraph_uid = func ? cgraph_get_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.  */
+
+static 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.  */
+
+static 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. */
 
@@ -1493,6 +1813,26 @@ execute_all_ipa_transforms (void)
     }
 }
 
+/* Check if PASS is explicitly disabled or enabled and return
+   the gate status.  FUNC is the function to be processed, and
+   GATE_STATUS is the gate status determined by pass manager by
+   default.  */
+
+static bool
+override_gate_status (struct opt_pass *pass, tree func, bool gate_status)
+{
+  bool explicitly_enabled = false;
+  bool explicitly_disabled = false;
+
+  explicitly_enabled = is_pass_explicitly_enabled (pass, func);
+  explicitly_disabled = is_pass_explicitly_disabled (pass, func);
+
+  gate_status = !explicitly_disabled && (gate_status || explicitly_enabled);
+
+  return gate_status;
+}
+
+
 /* Execute PASS. */
 
 bool
@@ -1515,6 +1855,7 @@ execute_one_pass (struct 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 == NULL) ? true : pass->gate();
+  gate_status = override_gate_status (pass, current_function_decl, gate_status);
 
   /* Override gate with plugin.  */
   invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 174076)
+++ tree-pass.h	(working copy)
@@ -637,4 +637,8 @@ extern bool first_pass_instance;
 /* Declare for plugins.  */
 extern void do_per_function_toporder (void (*) (void *), void *);
 
+extern void disable_pass (const char *);
+extern void enable_pass (const char *);
+struct function;
+
 #endif /* GCC_TREE_PASS_H */
Index: opts-global.c
===================================================================
--- opts-global.c	(revision 174076)
+++ opts-global.c	(working copy)
@@ -370,6 +370,14 @@ handle_common_deferred_options (void)
 	    error ("unrecognized command line option %<-fdump-%s%>", opt->arg);
 	  break;
 
+	case OPT_fenable_:
+	case OPT_fdisable_:
+	  if (opt->opt_index == OPT_fenable_)
+	    enable_pass (opt->arg);
+          else
+	    disable_pass (opt->arg);
+          break;
+
 	case OPT_ffixed_:
 	  /* Deferred.  */
 	  fix_register (opt->arg, 1, 1);
Index: common.opt
===================================================================
--- common.opt	(revision 174076)
+++ common.opt	(working copy)
@@ -977,6 +977,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: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 174076)
+++ doc/invoke.texi	(working copy)
@@ -282,6 +282,11 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
+-fdisable-ipa-@var{pass_name} @gol
+-fdisable-rtl-@var{pass_name} @gol
+-fdisable-rtl-@var{pass-name}=@var{range-list} @gol
+-fdisable-tree-@var{pass_name} @gol
+-fdisable-tree-@var{pass-name}=@var{range-list} @gol
 -fdump-noaddr -fdump-unnumbered -fdump-unnumbered-links @gol
 -fdump-translation-unit@r{[}-@var{n}@r{]} @gol
 -fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol
@@ -313,6 +318,11 @@ Objective-C and Objective-C++ Dialects}.
 -fcompare-debug@r{[}=@var{opts}@r{]}  -fcompare-debug-second @gol
 -feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
 -feliminate-unused-debug-symbols -femit-class-debug-always @gol
+-fenable-ipa-@var{pass} @gol
+-fenable-rtl-@var{pass} @gol
+-fenable-rtl-@var{pass}=@var{range-list} @gol
+-fenable-tree-@var{pass} @gol
+-fenable-tree-@var{pass}=@var{range-list} @gol
 -fdebug-types-section @gol
 -fmem-report -fpre-ipa-mem-report -fpost-ipa-mem-report -fprofile-arcs @gol
 -frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
@@ -4986,6 +4996,7 @@ more closely, if you do not optimize.
 @opindex fdbg-cnt-list
 Print the name and the counter upper bound for all debug counters.
 
+
 @item -fdbg-cnt=@var{counter-value-list}
 @opindex fdbg-cnt
 Set the internal debug counter upper bound.  @var{counter-value-list}
@@ -4995,7 +5006,75 @@ All debug counters have the initial uppe
 thus dbg_cnt() returns true always unless the upper bound is set by this option.
 e.g. With -fdbg-cnt=dce:10,tail_call:0
 dbg_cnt(dce) will return true only for first 10 invocations
-and dbg_cnt(tail_call) will return false always.
+
+@item -fdisable-@var{ipa|tree|rtl}-@var{pass}
+@itemx -fenable-@var{ipa|tree|rtl}-@var{pass}
+@itemx -fdisable-@var{tree|rtl}-@var{pass}=@var{range-list}
+@itemx -fenable-@var{tree|rtl}-@var{pass}=@var{range-list}
+@opindex fdisable-
+@opindex fenable-
+
+This is a set of debugging options that are used to explicitly disable/enable
+optimization passes. For compiler users, regular options for enabling/disabling
+passes should be used instead.
+
+@itemize
+
+@item -fdisable-ipa-@var{pass}
+Disable ipa pass @var{pass}. @var{pass} is the pass name.  If the same pass is
+statically invoked in the compiler multiple times, the pass name should be
+appended with a sequential number starting from 1.
+
+@item -fdisable-rtl-@var{pass}
+@item -fdisable-rtl-@var{pass}=@var{range-list}
+Disable rtl pass @var{pass}.  @var{pass} is the pass name.  If the same pass is
+statically invoked in the compiler multiple times, the pass name should be
+appended with a sequential number starting from 1.  @var{range-list} is a comma
+seperated list of function ranges.  Each range is a number pair seperated by a colon.
+The range is inclusive in both ends.  If the range is trivial, the number pair can be
+simplified a a single number.  If the function's cgraph node's @var{uid} is falling
+within one of the specified ranges, the @var{pass} is disabled for that function.
+The @var{uid} is shown in the function header of a dump file.
+
+@item -fdisable-tree-@var{pass}
+@item -fdisable-tree-@var{pass}=@var{range-list}
+Disable tree pass @var{pass}.  See @option{-fdisable-rtl} for the description of
+option arguments.
+
+@item -fenable-ipa-@var{pass}
+Enable ipa pass @var{pass}.  @var{pass} is the pass name.  If the same pass is
+statically invoked in the compiler multiple times, the pass name should be
+appended with a sequential number starting from 1.
+
+@item -fenable-rtl-@var{pass}
+@item -fenable-rtl-@var{pass}=@var{range-list}
+Enable rtl pass @var{pass}.  See @option{-fdisable-rtl} for option argument
+description and examples.
+
+@item -fenable-tree-@var{pass}
+@item -fenable-tree-@var{pass}=@var{range-list}
+Enable tree pass @var{pass}.  See @option{-fdisable-rtl} for the description
+of option arguments.
+
+@smallexample
+
+# disable ccp1 for all functions
+   -fdisable-tree-ccp1
+# disable complete unroll for function whose cgraph node uid is 1
+   -fenable-tree-cunroll=1
+# disable gcse2 for functions at the following ranges [1,1],
+# [300,400], and [400,1000]
+   -fdisable-rtl-gcse2=1:100,300,400:1000
+# disable early inlining
+   -fdisable-tree-einline
+# disable ipa inlining
+   -fdisable-ipa-inline
+# enable tree full unroll
+   -fenable-tree-unroll
+
+@end smallexample
+
+@end itemize
 
 @item -d@var{letters}
 @itemx -fdump-rtl-@var{pass}

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