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: patch committed to dataflow branch


Kenneth Zadeck wrote:
> This patch converts the threading of the prologue and epilogue to use df.
>
> This code has been bootstrapped and regression tested on
>
> x86_64-unknown-linux-gnu
> powerpc64-unknown-linux-gnu
> i686-pc-linux-gnu
>
> Kenny
>
>
>   
forgot again to attach the patch.
>
> 2006-04-15  Kenneth Zadeck <zadeck@naturalbridge.com>
>     * tree-pass.h (pass_flow2): Renamed to
>     pass_thread_prologue_and_epilogue.
>     * passes.c (pass_flow2): Ditto.
>     * final.c (rest_of_clean_state): Removed flow2_completed.
>     * config/i386/i386.md: Ditto.
>     * config/sh/sh.md: Ditto.
>     * config/mips/mips.md: Ditto.
>     * config/h8300/h8300.md: Ditto.
>     * flow.c: Ditto.
>     (rest_of_handle_flow2): Moved to function.c as
>     rest_of_handle_thread_prologue_and_epilogue.
>     * timevar.def (TV_FLOW2): Renamed to
>     TV_THREAD_PROLOGUE_AND_EPILOGUE.
>     * function.c (keep_stack_depressed): Added df parameter.
>     (thread_prologue_and_epilogue_insns): Made local function and
>     removed unused parameter.  Added local instance of df.
>     (rest_of_handle_thread_prologue_and_epilogue): New function
>     renamed from flow.c.
>     (pass_thread_prologue_and_epilogue): New pass.  
>     * rtl.h    (flow2_completed, thread_prologue_and_epilogue_insns):
>     Removed.
>     * df-problems.c (df_ru_get_bb_info, df_rd_get_bb_info,
>     df_lr_get_bb_info, df_ur_get_bb_info, df_urec_get_bb_info): Added
>     check.
>     * Makefile.in (function.o): Added timevar.h.
>    
>   

Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 112921)
+++ tree-pass.h	(working copy)
@@ -377,7 +377,7 @@ extern struct tree_opt_pass pass_postrel
 extern struct tree_opt_pass pass_gcse2;
 extern struct tree_opt_pass pass_split_after_reload;
 extern struct tree_opt_pass pass_branch_target_load_optimize1;
-extern struct tree_opt_pass pass_flow2;
+extern struct tree_opt_pass pass_thread_prologue_and_epilogue;
 extern struct tree_opt_pass pass_stack_adjustments;
 extern struct tree_opt_pass pass_peephole2;
 extern struct tree_opt_pass pass_if_after_reload;
Index: final.c
===================================================================
--- final.c	(revision 112855)
+++ final.c	(working copy)
@@ -4021,7 +4021,6 @@ rest_of_clean_state (void)
 
   reload_completed = 0;
   epilogue_completed = 0;
-  flow2_completed = 0;
   no_new_pseudos = 0;
 #ifdef STACK_REGS
   regstack_completed = 0;
Index: flow.c
===================================================================
--- flow.c	(revision 112855)
+++ flow.c	(working copy)
@@ -174,9 +174,6 @@ Software Foundation, 51 Franklin Street,
 #endif
 #endif
 
-/* Nonzero if the second flow pass has completed.  */
-int flow2_completed;
-
 /* Maximum register number used in this function, plus one.  */
 
 int max_regno;
@@ -4165,44 +4162,3 @@ struct tree_opt_pass pass_life =
   'f'                                   /* letter */
 };
 
-static unsigned int
-rest_of_handle_flow2 (void)
-{
-#if 0
-  int i;
-#endif
-  if (optimize)
-    cleanup_cfg (CLEANUP_EXPENSIVE);
-#if 0
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    fprintf (stderr, "regs_ever_live[%d]=%d before prologue\n", i,
-	     regs_ever_live[i]);
-#endif
-  /* On some machines, the prologue and epilogue code, or parts thereof,
-     can be represented as RTL.  Doing so lets us schedule insns between
-     it and the rest of the code and also allows delayed branch
-     scheduling to operate in the epilogue.  */
-  thread_prologue_and_epilogue_insns (get_insns ());
-  epilogue_completed = 1;
-  flow2_completed = 1;
-  return 0;
-}
-
-struct tree_opt_pass pass_flow2 =
-{
-  "flow2",                              /* name */
-  NULL,                                 /* gate */
-  rest_of_handle_flow2,                 /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_FLOW2,                             /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  TODO_verify_flow,                     /* todo_flags_start */
-  TODO_dump_func |
-  TODO_ggc_collect,                     /* todo_flags_finish */
-  'w'                                   /* letter */
-};
-
Index: timevar.def
===================================================================
--- timevar.def	(revision 112855)
+++ timevar.def	(working copy)
@@ -156,7 +156,7 @@ DEFTIMEVAR (TV_GLOBAL_ALLOC          , "
 DEFTIMEVAR (TV_RELOAD_CSE_REGS       , "reload CSE regs")
 DEFTIMEVAR (TV_SEQABSTR              , "sequence abstraction")
 DEFTIMEVAR (TV_GCSE_AFTER_RELOAD      , "load CSE after reload")
-DEFTIMEVAR (TV_FLOW2                 , "flow 2")
+DEFTIMEVAR (TV_THREAD_PROLOGUE_AND_EPILOGUE, "thread prologue and epilogue")
 DEFTIMEVAR (TV_IFCVT2		     , "if-conversion 2")
 DEFTIMEVAR (TV_PEEPHOLE2             , "peephole 2")
 DEFTIMEVAR (TV_RENAME_REGISTERS      , "rename registers")
Index: function.c
===================================================================
--- function.c	(revision 112855)
+++ function.c	(working copy)
@@ -64,6 +64,7 @@ Software Foundation, 51 Franklin Street,
 #include "tree-pass.h"
 #include "predict.h"
 #include "df.h"
+#include "timevar.h"
 
 #ifndef LOCAL_ALIGNMENT
 #define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
@@ -210,7 +212,7 @@ static int contains (rtx, VEC(int,heap) 
 static void emit_return_into_block (basic_block, rtx);
 #endif
 #if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
-static rtx keep_stack_depressed (rtx);
+static rtx keep_stack_depressed (struct df *, rtx);
 #endif
 static void prepare_function_start (tree);
 static void do_clobber_return_reg (rtx, void *);
@@ -4763,7 +4765,7 @@ static void emit_equiv_load (struct epi_
    no modifications to the stack pointer.  Return the new list of insns.  */
 
 static rtx
-keep_stack_depressed (rtx insns)
+keep_stack_depressed (struct df *df, rtx insns)
 {
   int j;
   struct epi_info info;
@@ -4880,7 +4882,7 @@ keep_stack_depressed (rtx insns)
 		    && !fixed_regs[regno]
 		    && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)
 		    && !REGNO_REG_SET_P
-		    (DF_LIVE_IN (rtl_df, EXIT_BLOCK_PTR), regno)
+		    (DF_UPWARD_LIVE_IN (df, EXIT_BLOCK_PTR), regno)
 		    && !refers_to_regno_p (regno,
 					   regno + hard_regno_nregs[regno]
 								   [Pmode],
@@ -5092,8 +5094,8 @@ emit_equiv_load (struct epi_info *p)
    this into place with notes indicating where the prologue ends and where
    the epilogue begins.  Update the basic block information when possible.  */
 
-void
-thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
+static void
+thread_prologue_and_epilogue_insns (void)
 {
   int inserted = 0;
   edge e;
@@ -5107,6 +5109,20 @@ thread_prologue_and_epilogue_insns (rtx 
   rtx epilogue_end = NULL_RTX;
 #endif
   edge_iterator ei;
+  struct df * df = df_init (DF_HARD_REGS);
+
+  /* Do not even think about running dce here!!!!  All life, as we
+     know it will cease!!!  There is dead code created by the previous
+     call to split_all_insns that is resurrected by the prologue and
+     epilogue.  This does not appear to be a bug in dce.  On the
+     x86-64 this shows up as failues in g++ excepion handling and is
+     extremely difficult to debug because the problem is with the way
+     that that the g++ library is compiled and this library was not
+     designed for modular testing.  All of the test cases that when
+     dce is added here fail in the gcc library, not in the test
+     case.  */
+  df_lr_add_problem (df, 0);
+  df_analyze (df);
 
 #ifdef HAVE_prologue
   if (HAVE_prologue)
@@ -5275,7 +5291,7 @@ thread_prologue_and_epilogue_insns (rtx 
 	 it, massage the epilogue to actually do that.  */
       if (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
 	  && TYPE_RETURNS_STACK_DEPRESSED (TREE_TYPE (current_function_decl)))
-	seq = keep_stack_depressed (seq);
+	seq = keep_stack_depressed (df, seq);
 #endif
 
       emit_jump_insn (seq);
@@ -5422,6 +5438,7 @@ epilogue_done:
 	}
     }
 #endif
+  df_finish (df);
 }
 
 /* Reposition the prologue-end and epilogue-begin notes after instruction
@@ -5607,5 +5624,38 @@ struct tree_opt_pass pass_leaf_regs =
   0                                     /* letter */
 };
 
+static unsigned int
+rest_of_handle_thread_prologue_and_epilogue (void)
+{
+  if (optimize)
+    cleanup_cfg (CLEANUP_EXPENSIVE);
+  /* On some machines, the prologue and epilogue code, or parts thereof,
+     can be represented as RTL.  Doing so lets us schedule insns between
+     it and the rest of the code and also allows delayed branch
+     scheduling to operate in the epilogue.  */
+
+  thread_prologue_and_epilogue_insns ();
+  epilogue_completed = 1;
+  return 0;
+}
+
+struct tree_opt_pass pass_thread_prologue_and_epilogue =
+{
+  "pro_and_epilogue",                   /* name */
+  NULL,                                 /* gate */
+  rest_of_handle_thread_prologue_and_epilogue, /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_THREAD_PROLOGUE_AND_EPILOGUE,      /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  TODO_verify_flow,                     /* todo_flags_start */
+  TODO_dump_func |
+  TODO_ggc_collect,                     /* todo_flags_finish */
+  'w'                                   /* letter */
+};
+
 
 #include "gt-function.h"
Index: rtl.h
===================================================================
--- rtl.h	(revision 112855)
+++ rtl.h	(working copy)
@@ -1962,10 +1962,6 @@ extern rtx gen_rtx_MEM (enum machine_mod
 extern rtx output_constant_def (tree, int);
 extern rtx lookup_constant_def (tree);
 
-/* Nonzero after the second flow pass has completed.
-   Set to 1 or 0 by toplev.c  */
-extern int flow2_completed;
-
 /* Nonzero after end of reload pass.
    Set to 1 or 0 by reload1.c.  */
 
@@ -1979,7 +1975,6 @@ extern int epilogue_completed;
 
 extern int reload_in_progress;
 
-
 #ifdef STACK_REGS
 /* Nonzero after end of regstack pass.
    Set to 1 or 0 by reg-stack.c.  */
@@ -2124,7 +2119,6 @@ extern void init_loop (void);
 
 /* In function.c */
 extern void reposition_prologue_and_epilogue_notes (void);
-extern void thread_prologue_and_epilogue_insns (rtx);
 extern int prologue_epilogue_contains (rtx);
 extern int sibcall_epilogue_contains (rtx);
 extern void mark_temp_addr_taken (rtx);
Index: df-problems.c
===================================================================
--- df-problems.c	(revision 112855)
+++ df-problems.c	(working copy)
@@ -301,6 +301,7 @@ struct df_ru_problem_data
 struct df_ru_bb_info *
 df_ru_get_bb_info (struct dataflow *dflow, unsigned int index)
 {
+  gcc_assert (dflow);
   return (struct df_ru_bb_info *) dflow->block_info[index];
 }
 
@@ -833,6 +834,7 @@ struct df_rd_problem_data
 struct df_rd_bb_info *
 df_rd_get_bb_info (struct dataflow *dflow, unsigned int index)
 {
+  gcc_assert (dflow);
   return (struct df_rd_bb_info *) dflow->block_info[index];
 }
 
@@ -1334,6 +1336,7 @@ df_rd_add_problem (struct df *df, int fl
 struct df_lr_bb_info *
 df_lr_get_bb_info (struct dataflow *dflow, unsigned int index)
 {
+  gcc_assert (dflow);
   return (struct df_lr_bb_info *) dflow->block_info[index];
 }
 
@@ -1855,6 +1858,7 @@ df_lr_add_problem (struct df *df, int fl
 struct df_ur_bb_info *
 df_ur_get_bb_info (struct dataflow *dflow, unsigned int index)
 {
+  gcc_assert (dflow);
   return (struct df_ur_bb_info *) dflow->block_info[index];
 }
 
@@ -2221,6 +2225,7 @@ struct df_urec_problem_data
 struct df_urec_bb_info *
 df_urec_get_bb_info (struct dataflow *dflow, unsigned int index)
 {
+  gcc_assert (dflow);
   return (struct df_urec_bb_info *) dflow->block_info[index];
 }
 
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 112855)
+++ Makefile.in	(working copy)
@@ -2166,7 +2166,7 @@ function.o : function.c $(CONFIG_H) $(SY
    $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
    output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) $(TM_P_H) langhooks.h \
    gt-function.h $(TARGET_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) $(PREDICT_H) \
-   tree-pass.h $(DF_H)
+   tree-pass.h $(DF_H) timevar.h
 stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \
    libfuncs.h except.h $(RECOG_H) toplev.h output.h $(GGC_H) $(TM_P_H) \
Index: passes.c
===================================================================
--- passes.c	(revision 112921)
+++ passes.c	(working copy)
@@ -675,7 +675,7 @@ init_optimization_passes (void)
   NEXT_PASS (pass_rtl_dse);
   NEXT_PASS (pass_split_after_reload);
   NEXT_PASS (pass_branch_target_load_optimize1);
-  NEXT_PASS (pass_flow2);
+  NEXT_PASS (pass_thread_prologue_and_epilogue);
   NEXT_PASS (pass_clear_df);
   NEXT_PASS (pass_rtl_seqabstr);
   NEXT_PASS (pass_stack_adjustments);
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 112855)
+++ config/i386/i386.md	(working copy)
@@ -1867,7 +1867,7 @@ (define_split
   [(set (match_operand:DI 0 "push_operand" "")
         (match_operand:DI 1 "immediate_operand" ""))]
   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
-		    ? flow2_completed : reload_completed)
+		    ? epilogue_completed : reload_completed)
    && !symbolic_operand (operands[1], DImode)
    && !x86_64_immediate_operand (operands[1], DImode)"
   [(set (match_dup 0) (match_dup 1))
@@ -2097,7 +2097,7 @@ (define_split
   [(set (match_operand:DI 0 "memory_operand" "")
         (match_operand:DI 1 "immediate_operand" ""))]
   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
-		    ? flow2_completed : reload_completed)
+		    ? epilogue_completed : reload_completed)
    && !symbolic_operand (operands[1], DImode)
    && !x86_64_immediate_operand (operands[1], DImode)"
   [(set (match_dup 2) (match_dup 3))
@@ -10453,7 +10453,7 @@ (define_split
 		   (match_operand:QI 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
-		     ? flow2_completed : reload_completed)"
+		     ? epilogue_completed : reload_completed)"
   [(const_int 0)]
   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
 
@@ -11208,7 +11208,7 @@ (define_split
 		     (match_operand:QI 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
-		     ? flow2_completed : reload_completed)"
+		     ? epilogue_completed : reload_completed)"
   [(const_int 0)]
   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
 
@@ -11743,7 +11743,7 @@ (define_split 
 		     (match_operand:QI 2 "nonmemory_operand" "")))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
-		     ? flow2_completed : reload_completed)"
+		     ? epilogue_completed : reload_completed)"
   [(const_int 0)]
   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
 
Index: config/sh/sh.md
===================================================================
--- config/sh/sh.md	(revision 112855)
+++ config/sh/sh.md	(working copy)
@@ -9897,7 +9897,7 @@ (define_split
   [(set (reg:PSI FPSCR_REG)
 	(mem:PSI (match_operand:SI 0 "register_operand" "")))]
   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
-   && (flag_peephole2 ? flow2_completed : reload_completed)"
+   && (flag_peephole2 ? epilogue_completed : reload_completed)"
   [(const_int 0)]
 {
   rtx fpscr, mem, new_insn;
Index: config/mips/mips.md
===================================================================
--- config/mips/mips.md	(revision 112855)
+++ config/mips/mips.md	(working copy)
@@ -3026,7 +3026,7 @@ (define_insn_and_split "*lea_high64"
 	(high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
   "#"
-  "&& flow2_completed"
+  "&& epilogue_completed"
   [(set (match_dup 0) (high:DI (match_dup 2)))
    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
Index: config/h8300/h8300.md
===================================================================
--- config/h8300/h8300.md	(revision 112855)
+++ config/h8300/h8300.md	(working copy)
@@ -1210,7 +1210,7 @@ (define_split
   [(set (match_operand:HI 0 "stack_pointer_operand" "")
 	(plus:HI (match_dup 0)
 		 (match_operand 1 "const_int_gt_2_operand" "")))]
-  "TARGET_H8300 && flow2_completed"
+  "TARGET_H8300 && epilogue_completed"
   [(const_int 0)]
   "split_adds_subs (HImode, operands); DONE;")
 
@@ -3017,7 +3017,7 @@ (define_split
 			[(match_dup 0)
 			 (match_operand:QI 1 "register_operand" "")]))
    (clobber (match_operand:QI 3 "register_operand" ""))]
-  "flow2_completed
+  "epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
   [(set (cc0)
 	(match_dup 1))
@@ -3048,7 +3048,7 @@ (define_split
 			[(match_dup 0)
 			 (match_operand:QI 1 "register_operand" "")]))
    (clobber (match_operand:QI 3 "register_operand" ""))]
-  "flow2_completed
+  "epilogue_completed
    && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
   [(set (match_dup 3)
 	(match_dup 1))
@@ -4183,7 +4183,7 @@ (define_split
 		(match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
    && REGNO (operands[0]) != REGNO (operands[1])"
   [(parallel [(set (match_dup 3)
@@ -4203,7 +4203,7 @@ (define_split
 		(match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
         && REGNO (operands[0]) != REGNO (operands[1]))"
   [(set (match_dup 2)
@@ -4286,7 +4286,7 @@ (define_split
 		 (match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
    && REGNO (operands[0]) != REGNO (operands[1])"
   [(parallel [(set (match_dup 3)
@@ -4306,7 +4306,7 @@ (define_split
 		 (match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
         && REGNO (operands[0]) != REGNO (operands[1]))"
   [(set (match_dup 2)

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