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]

[tree-ssa] Forward replacement of single use vars in conditionals


This pass turns stuff like:


  bb0:
    x = a COND b;
    if (x) goto ... else goto ...
 
Into (when x's only use is inside the condition in the COND_EXPR):
 
   bb0:
     if (a COND b) goto ... else goto ...
  

Similarly for (x == 0), (x != 0), (x == 1) and (x != 1).


This transformations eliminates "x" and the statement which assigns a
value to "x".  More importantly, it allows us to do more jump threading.


Consider something like this:

<bb 0>:
  goto <bb 3> (<L2>);

<L0>:;
  insn_10 = insn_1->fld[1].rtx;
  T.0_11 = insn_10->code;
  T.1_12 = rtx_class[T.0_11];
  if (T.1_12 == 105) goto <L1>; else goto <L2>;

<L1>:;
  n_insns_13 = n_insns_2 - 1;

  # n_insns_2 = PHI <blah_5(0), n_insns_2(1), n_insns_13(2)>;
  # insn_1 = PHI <insn_3(0), insn_10(1), insn_10(2)>;
<L2>:;
<L3>:;
  if (n_insns_2 > 0) goto <L0>; else goto <L4>;

<L4>:;
  <D1079>_7 = n_insns_2 <= 0;
  if (<D1079>_7 == 0) goto <L6>; else goto <L7>;

<L6>:;
  foo ();

<L7>:;
  return;


The block starting at <L4> is impossible to thread through as it starts
with a statement that is rather difficult to prove is a NOP (without
immediate use information in the dominator optimizer).  That's terribly
unfortunate as if we could thread through that block this little mess
collapses down to "return" :-)

[ This was taken from a much larger testcase in bt-load.c. ]

I'll also note that this change allows us to completely optimize the
testcase in 13869.  The testcase collapses down to a "return 0" as the
forward substitution exposes a jump threading opportunity.


The implementation is marginally complicated by the desire to avoid 
computing the full immediate uses information and to avoid lazily 
computing immediate uses.

Instead we do a scan for interesting COND_EXPRs and their associated
variables.  We record the interesting COND_EXPRs (so we do not have to
rescan) and the interesting variables (so we can compute immediate uses
for all of them at once).

Once the initial scan is complete, we compute immediate uses and in cases
where the interesting variables are used only by the COND_EXPR we do the
substitution.

The net result is we're quite efficient.



I'll be checking in a testcase for this optimization and the resulting
jump threading opportunities it can expose shortly as well.


	* Makefile.in (OBJS-common): Add tree-ssa-forwprop.o
	(tree-ssa-forwprop.o): Add dependencies.
	* timevar.def (TV_TREE_FORWPROP): New timevar.
	* tree-optimize.c (init_tree_optimization_passes): Link in
	the forward propagation pass.
	* tree-pass.h (pass_forwprop): Declare.
	* tree-ssa-forwprop.c: New file with forward propagation pass.
	* doc/invoke.texi: Document dump for forward propagation pass.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.176
diff -c -3 -p -r1.903.2.176 Makefile.in
*** Makefile.in	10 Feb 2004 23:23:15 -0000	1.903.2.176
--- Makefile.in	11 Feb 2004 21:24:05 -0000
*************** OBJS-common = \
*** 870,876 ****
   tree-alias-type.o gimplify.o tree-pretty-print.o                          \
   tree-alias-common.o tree-ssa-ccp.o tree-browser.o @ANDER@ tree-ssa-dce.o  \
   tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o       \
!  tree-ssa-phiopt.o							   \
   tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o	   \
   tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
   alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o	  	   \
--- 870,876 ----
   tree-alias-type.o gimplify.o tree-pretty-print.o                          \
   tree-alias-common.o tree-ssa-ccp.o tree-browser.o @ANDER@ tree-ssa-dce.o  \
   tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o       \
!  tree-ssa-phiopt.o tree-ssa-forwprop.o					   \
   tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o	   \
   tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
   alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o	  	   \
*************** tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $
*** 1537,1542 ****
--- 1537,1545 ----
     errors.h toplev.h function.h $(TIMEVAR_H) tree-alias-common.h \
     $(TM_H) coretypes.h $(TREE_DUMP_H) tree-ssa-live.h langhooks.h \
     cfgloop.h domwalk.h tree-pass.h
+ tree-ssa-forwprop.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+    $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+    $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H)
  tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
     $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H)
Index: timevar.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/timevar.def,v
retrieving revision 1.14.2.33
diff -c -3 -p -r1.14.2.33 timevar.def
*** timevar.def	10 Feb 2004 23:23:15 -0000	1.14.2.33
--- timevar.def	11 Feb 2004 21:24:06 -0000
*************** DEFTIMEVAR (TV_TREE_CCP		     , "tree CC
*** 75,80 ****
--- 75,81 ----
  DEFTIMEVAR (TV_TREE_SPLIT_EDGES      , "tree split crit edges")
  DEFTIMEVAR (TV_TREE_PRE		     , "tree PRE")
  DEFTIMEVAR (TV_TREE_PHIOPT	     , "tree optimize phi nodes ")
+ DEFTIMEVAR (TV_TREE_FORWPROP	     , "tree forward propagate")
  DEFTIMEVAR (TV_TREE_DCE		     , "tree conservative DCE")
  DEFTIMEVAR (TV_TREE_CD_DCE	     , "tree aggressive DCE")
  DEFTIMEVAR (TV_TREE_LOOP	     , "tree loop optimization")
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.118
diff -c -3 -p -r1.1.4.118 tree-optimize.c
*** tree-optimize.c	10 Feb 2004 23:23:15 -0000	1.1.4.118
--- tree-optimize.c	11 Feb 2004 21:24:08 -0000
*************** init_tree_optimization_passes (void)
*** 283,288 ****
--- 283,289 ----
    NEXT_PASS (pass_dce);
    NEXT_PASS (pass_dominator);
    NEXT_PASS (DUP_PASS (pass_dce));
+   NEXT_PASS (pass_forwprop);
    NEXT_PASS (pass_phiopt);
    NEXT_PASS (pass_may_alias);
    NEXT_PASS (pass_del_pta);
*************** init_tree_optimization_passes (void)
*** 291,296 ****
--- 292,298 ----
    NEXT_PASS (pass_sra);
    NEXT_PASS (DUP_PASS (pass_dominator));
    NEXT_PASS (DUP_PASS (pass_dce));
+   NEXT_PASS (DUP_PASS (pass_forwprop));
    NEXT_PASS (DUP_PASS (pass_phiopt));
    NEXT_PASS (pass_tail_recursion);
    NEXT_PASS (pass_loop);
*************** init_tree_optimization_passes (void)
*** 300,305 ****
--- 302,308 ----
    NEXT_PASS (pass_pre);
    NEXT_PASS (DUP_PASS (pass_dominator));
    NEXT_PASS (pass_cd_dce);
+   NEXT_PASS (DUP_PASS (pass_forwprop));
    NEXT_PASS (DUP_PASS (pass_phiopt));
    NEXT_PASS (pass_tail_calls);
    NEXT_PASS (pass_late_warn_uninitialized);
Index: tree-pass.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-pass.h,v
retrieving revision 1.1.2.9
diff -c -3 -p -r1.1.2.9 tree-pass.h
*** tree-pass.h	10 Feb 2004 23:23:15 -0000	1.1.2.9
--- tree-pass.h	11 Feb 2004 21:24:08 -0000
*************** extern struct tree_opt_pass pass_early_w
*** 118,123 ****
--- 118,124 ----
  extern struct tree_opt_pass pass_late_warn_uninitialized;
  extern struct tree_opt_pass pass_warn_function_return;
  extern struct tree_opt_pass pass_phiopt;
+ extern struct tree_opt_pass pass_forwprop;
  
  
  #endif /* GCC_TREE_PASS_H */
Index: tree-ssa-forwprop.c
===================================================================
RCS file: tree-ssa-forwprop.c
diff -N tree-ssa-forwprop.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- tree-ssa-forwprop.c	11 Feb 2004 21:24:08 -0000
***************
*** 0 ****
--- 1,336 ----
+ /* Forward propagation of single use variables.
+    Copyright (C) 2004 Free Software Foundation, Inc.
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+ 
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "errors.h"
+ #include "ggc.h"
+ #include "tree.h"
+ #include "rtl.h"
+ #include "tm_p.h"
+ #include "basic-block.h"
+ #include "timevar.h"
+ #include "diagnostic.h"
+ #include "tree-flow.h"
+ #include "tree-pass.h"
+ #include "tree-dump.h"
+ 
+ /* This pass performs simple forward propagation of single use variables
+    from their definition site into their single use site.
+ 
+    Right now we only bother forward propagating into COND_EXPRs since those
+    are relatively common cases where forward propagation creates valid
+    gimple code without the expression needing to fold.  ie
+ 
+      bb0:
+        x = a COND b;
+        if (x) goto ... else goto ...
+ 
+    Will be transformed into:
+ 
+      bb0:
+        if (a COND b) goto ... else goto ...
+  
+ 
+    Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
+ 
+    In addition to eliminating the variable and the statement which assigns
+    a value to the variable, we may be able to later thread the jump without
+    adding insane complexity in the dominator optimizer. 
+ 
+    This will (of course) be extended as other needs arise.  */
+ 
+ /* Bitmap of variables for which we want immediate uses.  This is set
+    by record_single_argument_cond_exprs and tested in need_imm_uses_for.  */
+ static bitmap vars;
+ 
+ static bool need_imm_uses_for (tree);
+ static void tree_ssa_forward_propagate_single_use_vars (void);
+ static varray_type record_single_argument_cond_exprs (void);
+ static void substitute_single_use_vars (varray_type);
+ 
+ /* Function indicating whether we ought to include information for 'var'
+    when calculating immediate uses.  */
+ 
+ static bool
+ need_imm_uses_for (tree var)
+ {
+   return bitmap_bit_p (vars, SSA_NAME_VERSION (var));
+ }
+ 
+ /* Find all COND_EXPRs with a condition that is a naked SSA_NAME or
+    an equality comparison against zero or one.
+ 
+    Record the identified COND_EXPRs and the SSA_NAME used in the COND_EXPR
+    into a virtual array, which is returned to the caller.  Also record
+    into VARS that we will need immediate uses for the identified SSA_NAME.
+ 
+    The more uninteresting COND_EXPRs and associated SSA_NAMEs we can
+    filter out here, the faster this pass will run since its runtime is
+    dominated by the time to build immediate uses.  */
+ 
+ static varray_type
+ record_single_argument_cond_exprs (void)
+ {
+   basic_block bb;
+   varray_type retval;
+ 
+   vars = BITMAP_XMALLOC ();
+ 
+   VARRAY_TREE_INIT (retval, 10, "forward propagation objects");
+ 
+   /* The first pass over the blocks gathers the set of variables we need
+      immediate uses for as well as the set of interesting COND_EXPRs.
+ 
+      A simpler implementation may be appropriate if/when we have a lower
+      overhead means of getting immediate use information.  */
+   FOR_EACH_BB (bb)
+     {
+       tree last = last_stmt (bb);
+ 
+       /* See if this block ends in a COND_EXPR.  */
+       if (last && TREE_CODE (last) == COND_EXPR)
+ 	{
+ 	  tree cond = COND_EXPR_COND (last);
+ 	  enum tree_code cond_code = TREE_CODE (cond);
+ 
+ 	  /* If the condition is a lone variable or an equality test of an
+ 	     SSA_NAME against zero, then we may have an optimizable case. 
+ 
+ 	     Note these conditions also ensure the COND_EXPR has no
+ 	     virtual operands or other side effects.  */
+ 	  if (cond_code == SSA_NAME
+ 	      || ((cond_code == EQ_EXPR || cond_code == NE_EXPR)
+ 		  && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
+ 		  && (integer_zerop (TREE_OPERAND (cond, 1))
+ 		      || integer_onep (TREE_OPERAND (cond, 1)))))
+ 	    {
+ 	      tree def;
+ 	      tree test_var;
+ 
+ 	      if (cond_code == SSA_NAME)
+ 		test_var = cond;
+ 	      else
+ 		test_var = TREE_OPERAND (cond, 0);
+ 
+ 	      /* Now get the defining statement for TEST_VAR and verify that
+ 	         it's an assignment from a relational expression or a
+ 	         TRUTH_NOT_EXPR and that the source operands are either
+ 		 SSA_NAMES or some gimple invariant.  */
+ 	      def = SSA_NAME_DEF_STMT (test_var);
+ 	      if (TREE_CODE (def) == MODIFY_EXPR)
+ 		{
+ 		  tree def_rhs = TREE_OPERAND (def, 1);
+ 
+ 		  if (TREE_CODE_CLASS (TREE_CODE (def_rhs)) == '<')
+ 		    {
+ 		      tree op0 = TREE_OPERAND (def_rhs, 0);
+ 		      tree op1 = TREE_OPERAND (def_rhs, 1);
+ 
+ 		      /* Both operands of DEF_RHS must be SSA_NAMEs or
+ 			 constants.  */
+ 		      if ((TREE_CODE (op0) != SSA_NAME
+ 			   && !is_gimple_min_invariant (op0))
+ 			  || (TREE_CODE (op1) != SSA_NAME
+ 			      && !is_gimple_min_invariant (op1)))
+ 			continue;
+ 		    }
+ 		  else if (TREE_CODE (def_rhs) == TRUTH_NOT_EXPR)
+ 		    {
+ 		      def_rhs = TREE_OPERAND (def_rhs, 0);
+ 
+ 		      /* DEF_RHS must be an SSA_NAME or constant.  */
+ 		      if (TREE_CODE (def_rhs) != SSA_NAME
+ 			  && !is_gimple_min_invariant (def_rhs))
+ 			continue;
+ 		    }
+ 		  else
+ 		    continue;
+ 
+ 		  /* All the tests passed, record COND_EXPR and TEST_VAR
+ 		     as interesting.  */
+ 		  VARRAY_PUSH_TREE (retval, last);
+ 		  VARRAY_PUSH_TREE (retval, test_var);
+ 		  bitmap_set_bit (vars, SSA_NAME_VERSION (test_var));
+ 		}
+ 	    }
+ 	}
+     }
+   return retval;
+ }
+ 
+ /* Given FORWPROP_DATA containing pairs of potentially optimizable COND_EXPRs
+    and the SSA_NAME used in the COND_EXPR, attempt to rewrite the condition
+    in each COND_EXPR to use the RHS of the statement which defines the
+    SSA_NAME used in the COND_EXPR.  */
+   
+ static void
+ substitute_single_use_vars (varray_type forwprop_data)
+ {
+   unsigned int i;
+ 
+   for (i = 0; i < VARRAY_ACTIVE_SIZE (forwprop_data); i += 2)
+     {
+       tree test_var = VARRAY_TREE (forwprop_data, i + 1);
+       tree def = SSA_NAME_DEF_STMT (test_var);
+       dataflow_t df;
+       int num_uses;
+ 
+       /* Now compute the immediate uses of TEST_VAR.  */
+       df = get_immediate_uses (def);
+       num_uses = num_immediate_uses (df);
+ 
+       /* If TEST_VAR is used precisely one time, then we may have
+          an optimizable case.  */
+       if (num_uses == 1)
+ 	{
+ 	  tree cond_stmt = VARRAY_TREE (forwprop_data, i);
+ 	  tree cond = COND_EXPR_COND (cond_stmt);
+ 	  enum tree_code cond_code = TREE_CODE (cond);
+ 	  tree def_rhs = TREE_OPERAND (def, 1);
+ 	  enum tree_code def_rhs_code = TREE_CODE (def_rhs);
+ 	  block_stmt_iterator bsi;
+ 	  tree new_cond;
+ 
+ 	  /* We have to handle DEF being defined by a conditional vs
+ 	     a TRUTH_NOT_EXPR differently...  */
+ 	  if (TREE_CODE_CLASS (def_rhs_code) == '<')
+ 	    {
+ 	      /* TEST_VAR was set from a relational operator.  */
+ 	      tree op0 = TREE_OPERAND (def_rhs, 0);
+ 	      tree op1 = TREE_OPERAND (def_rhs, 1);
+ 
+ 	      new_cond = build (def_rhs_code, boolean_type_node, op0, op1);
+ 
+ 	      /* Invert the conditional if necessary.  */
+ 	      if ((cond_code == EQ_EXPR
+ 		   && integer_zerop (TREE_OPERAND (cond, 1)))
+ 		  || (cond_code == NE_EXPR
+ 		      && integer_onep (TREE_OPERAND (cond, 1))))
+ 		{
+ 		  new_cond = invert_truthvalue (new_cond);
+ 
+ 		  /* If we did not get a simple relational expression or
+ 		     bare SSA_NAME, then we can not optimize this case.  */
+ 		  if (TREE_CODE_CLASS (TREE_CODE (new_cond)) != '<'
+ 		      && TREE_CODE (new_cond) != SSA_NAME)
+ 		    continue;
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      /* TEST_VAR was set from a TRUTH_NOT_EXPR.  */
+ 	      if (cond_code == SSA_NAME
+ 		  || (cond_code == NE_EXPR
+ 		      && integer_zerop (TREE_OPERAND (cond, 1)))
+ 		  || (cond_code == EQ_EXPR
+ 		      && integer_onep (TREE_OPERAND (cond, 1))))
+ 		new_cond = build (EQ_EXPR, boolean_type_node,
+ 				  TREE_OPERAND (def_rhs, 0),
+ 				  convert (TREE_TYPE (def_rhs),
+ 					   integer_zero_node));
+ 	      else
+ 		new_cond = build (NE_EXPR, boolean_type_node,
+ 				  TREE_OPERAND (def_rhs, 0),
+ 				  convert (TREE_TYPE (def_rhs),
+ 					   integer_zero_node));
+ 	    }
+ 
+ 	  /* Dump details.  */
+ 	  if (tree_dump_file && (tree_dump_flags & TDF_DETAILS))
+ 	    {
+ 	      fprintf (tree_dump_file, "  Replaced '");
+ 	      print_generic_expr (tree_dump_file, cond, 0);
+ 	      fprintf (tree_dump_file, "' with '");
+ 	      print_generic_expr (tree_dump_file, new_cond, 0);
+ 	      fprintf (tree_dump_file, "'\n");
+ 	    }
+ 
+ 	  /* Replace the condition.  */
+ 	  COND_EXPR_COND (cond_stmt) = new_cond;
+ 	  modify_stmt (cond_stmt);
+ 
+ 	  /* Now delete the defining statement, unfortunately
+ 	     we have to find the defining statement in whatever
+ 	     block it might be in.  */
+ 	  for (bsi = bsi_start (bb_for_stmt (def));
+ 	       !bsi_end_p (bsi);
+ 	       bsi_next (&bsi))
+ 	    {
+ 	      if (def == bsi_stmt (bsi))
+ 		{
+ 		  bsi_remove (&bsi);
+ 		  break;
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ /* Main entry point for the forward propagation optimizer.  */
+ 
+ static void
+ tree_ssa_forward_propagate_single_use_vars (void)
+ {
+   varray_type forwprop_data;
+ 
+   /* First get a list of all the interesting COND_EXPRs and potential single
+      use variables which feed those COND_EXPRs.  */
+   forwprop_data = record_single_argument_cond_exprs ();
+ 
+   /* Now compute immediate uses for all the variables we care about.  */
+   compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
+ 
+   /* We are done with the VARS bitmap and other dataflow information.  */
+   BITMAP_XFREE (vars);
+   vars = NULL;
+ 
+   /* And optimize.  */
+   substitute_single_use_vars (forwprop_data);
+ 
+   /* All done.  Clean up.  */
+   free_df ();
+   VARRAY_CLEAR (forwprop_data);
+ }
+ 
+ 
+ static bool
+ gate_forwprop (void)
+ {
+   return 1;
+ }
+ 
+ struct tree_opt_pass pass_forwprop = {
+   "forwprop",			/* name */
+   gate_forwprop,		/* gate */
+   tree_ssa_forward_propagate_single_use_vars,	/* execute */
+   NULL,				/* sub */
+   NULL,				/* next */
+   0,				/* static_pass_number */
+   TV_TREE_FORWPROP,		/* tv_id */
+   PROP_cfg | PROP_ssa,		/* properties_required */
+   0,				/* properties_provided */
+   0,				/* properties_destroyed */
+   0,				/* todo_flags_start */
+   TODO_dump_func | TODO_ggc_collect	/* todo_flags_finish */
+   | TODO_verify_ssa
+ };
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.152.2.70
diff -c -3 -p -r1.152.2.70 invoke.texi
*** doc/invoke.texi	10 Feb 2004 23:23:16 -0000	1.152.2.70
--- doc/invoke.texi	11 Feb 2004 21:24:50 -0000
*************** in the following sections.
*** 255,260 ****
--- 255,261 ----
  -fdump-tree-gimple@r{[}-raw@r{]} -fdump-tree-mudflap@r{[}-@var{n}@r{]} @gol
  -fdump-tree-dom@r{[}-@var{n}@r{]} @gol
  -fdump-tree-phiopt@r{[}-@var{n}@r{]} @gol
+ -fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
  -fdump-tree-loop@r{[}-@var{n}@r{]} -fdump-tree-sra@r{[}-@var{n}@r{]} @gol
  -feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
  -feliminate-unused-debug-symbols -fmem-report -fprofile-arcs @gol
*************** name is made by appending @file{.dom} to
*** 3526,3531 ****
--- 3527,3537 ----
  @opindex fdump-tree-phiopt
  Dump each function after optimizing PHI nodes into straightline code.  The 
file
  name is made by appending @file{.phiopt} to the source file name.
+ 
+ @item forwprop
+ @opindex fdump-tree-forwprop
+ Dump each function after forward propagating single use variables.  The file
+ name is made by appending @file{.forwprop} to the source file name.
  
  @item loop
  @opindex fdump-tree-loop











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