diff mbox

[RFC] Disable FWPROP on pathological cases

Message ID 201201242226.29027.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou Jan. 24, 2012, 9:26 p.m. UTC
Starting with the 4.5.x series, we have pathological cases (Ada code generated 
by a code generator from a model) where FWPROP takes 80% of the compilation 
time at -O1 (for essentially no benefits).  There are very few basic blocks 
(typically 1) and tens of thousands of uses registered with DF, so processing 
them takes a while (top function in the profile: local_ref_killed_between_p).

The attached patch is an attempt (modelled on gcse.c) at disabling the pass for 
these pathological cases.  Thoughts?


	* Makefile.in (fwprop.o): Add intl.h.
	* fwprop.c: Include intl.h.
	(is_too_expensive): New function.
	(fwprop): Call it and return early if it returns true.
	(fwprop_addr): Likewise.

Comments

Jakub Jelinek Jan. 24, 2012, 9:40 p.m. UTC | #1
On Tue, Jan 24, 2012 at 10:26:28PM +0100, Eric Botcazou wrote:
> +static bool
> +is_too_expensive (const char *pass)
> +{
> +  int ratio = DF_USES_TABLE_SIZE () / (n_basic_blocks - NUM_FIXED_BLOCKS);
> +
> +  /* Trying to propagate into uses in functions with gigantic basic blocks
> +     will take a long time and is unlikely to be particularly useful.  */
> +  if (ratio > 20000)

Use a param for this instead of constant?

	Jakub
Steven Bosscher Jan. 24, 2012, 11:19 p.m. UTC | #2
On Tue, Jan 24, 2012 at 10:26 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Starting with the 4.5.x series, we have pathological cases (Ada code generated
> by a code generator from a model) where FWPROP takes 80% of the compilation
> time at -O1 (for essentially no benefits).  There are very few basic blocks
> (typically 1) and tens of thousands of uses registered with DF, so processing
> them takes a while (top function in the profile: local_ref_killed_between_p).

Would it work to punt in local_ref_killed_between_p if
(DF_INSN_LUID(to) - DF_INSN_LUID(from)) is greater than some value?

Ciao!
Steven
diff mbox

Patch

Index: Makefile.in
===================================================================
--- Makefile.in	(revision 183423)
+++ Makefile.in	(working copy)
@@ -3023,9 +3023,10 @@  dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) co
    $(TREE_PASS_H) alloc-pool.h $(ALIAS_H) dse.h $(OPTABS_H) $(TARGET_H) \
    $(BITMAP_H) $(PARAMS_H)
 fwprop.o : fwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
-   $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) $(BASIC_BLOCK_H) \
-   output.h $(DF_H) alloc-pool.h $(TIMEVAR_H) $(TREE_PASS_H) $(TARGET_H) \
-   $(TM_P_H) $(CFGLOOP_H) $(EMIT_RTL_H) domwalk.h sparseset.h
+   $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) \
+   intl.h $(BASIC_BLOCK_H) output.h $(DF_H) alloc-pool.h $(TIMEVAR_H) \
+   $(TREE_PASS_H) $(TARGET_H) $(TM_P_H) $(CFGLOOP_H) $(EMIT_RTL_H) \
+   domwalk.h sparseset.h
 web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(DIAGNOSTIC_CORE_H) \
    insn-config.h $(RECOG_H) $(DF_H) $(OBSTACK_H) $(TIMEVAR_H) $(TREE_PASS_H)
Index: fwprop.c
===================================================================
--- fwprop.c	(revision 183423)
+++ fwprop.c	(working copy)
@@ -32,6 +32,7 @@  along with GCC; see the file COPYING3.
 #include "insn-config.h"
 #include "recog.h"
 #include "flags.h"
+#include "intl.h"
 #include "obstack.h"
 #include "basic-block.h"
 #include "output.h"
@@ -1435,6 +1436,28 @@  fwprop_done (void)
 }
 
 
+/* Return true if the function is too expensive to optimize.  PASS is the
+   optimization about to be performed.  */
+
+static bool
+is_too_expensive (const char *pass)
+{
+  int ratio = DF_USES_TABLE_SIZE () / (n_basic_blocks - NUM_FIXED_BLOCKS);
+
+  /* Trying to propagate into uses in functions with gigantic basic blocks
+     will take a long time and is unlikely to be particularly useful.  */
+  if (ratio > 20000)
+    {
+      warning (OPT_Wdisabled_optimization,
+	       "%s: %d basic blocks and %d uses/basic block",
+	       pass, n_basic_blocks - NUM_FIXED_BLOCKS, ratio);
+
+      return true;
+    }
+
+  return false;
+}
+
 /* Main entry point.  */
 
 static bool
@@ -1451,6 +1474,12 @@  fwprop (void)
 
   fwprop_init ();
 
+  if (is_too_expensive (_("FWPROP1 disabled")))
+    {
+      fwprop_done ();
+      return 0;
+    }
+
   /* Go through all the uses.  df_uses_create will create new ones at the
      end, and we'll go through them as well.
 
@@ -1469,8 +1498,10 @@  fwprop (void)
     }
 
   fwprop_done ();
+
   if (need_cleanup)
     cleanup_cfg (0);
+
   return 0;
 }
 
@@ -1503,6 +1534,12 @@  fwprop_addr (void)
 
   fwprop_init ();
 
+  if (is_too_expensive (_("FWPROP2 disabled")))
+    {
+      fwprop_done ();
+      return 0;
+    }
+
   /* Go through all the uses.  df_uses_create will create new ones at the
      end, and we'll go through them as well.  */
   for (i = 0; i < DF_USES_TABLE_SIZE (); i++)
@@ -1520,6 +1557,7 @@  fwprop_addr (void)
 
   if (need_cleanup)
     cleanup_cfg (0);
+
   return 0;
 }