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]

avoid cfg rebuild after combine


Bootstrapped/regtested i686 together with other today patches

Ne čec 15 21:45:03 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* basic-block.h (purge_all_dead_edges, purge_dead_edges): New functions.
	* toplev.c (rest_of_compilation): Conditionally call purge_all_dead_edges
	after combine.
	* gcse.c (cprop_cc0_jump, cprop_insn): New argument "basic_block".
	(cprop_jump): Likewise; call purge_dead_edges if substitution suceeded.

*** /p1/jumpr2/jumpr/egcs/gcc/basic-block.h	Sat Jul 14 14:57:44 2001
--- basic-block.h	Sun Jul 15 21:30:26 2001
*************** extern void dump_regset			PARAMS ((regse
*** 597,602 ****
--- 599,606 ----
  extern void debug_regset		PARAMS ((regset));
  extern void allocate_reg_life_data      PARAMS ((void));
  extern void find_unreachable_blocks	PARAMS ((void));
+ extern void purge_all_dead_edges	PARAMS ((void));
+ extern void purge_dead_edges		PARAMS ((basic_block));
  
  /* This function is always defined so it can be called from the
     debugger, and it is declared extern so we don't get warnings about
*** /p1/jumpr2/jumpr/egcs/gcc/flow.c	Sat Jul 14 22:05:38 2001
--- flow.c	Sun Jul 15 21:05:09 2001
*************** init_flow ()
*** 9832,9835 ****
--- 9857,9919 ----
        obstack_free (&flow_obstack, flow_firstobj);
        flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
      }
+ }
+ 
+ /* Assume that the preceeding pass has possibly eliminated jump instructions
+    or converted the unconditional jumps.  Eliminate the edges from CFG.  */
+ 
+ void
+ purge_dead_edges (bb)
+      basic_block bb;
+ {
+   edge e, next;
+   rtx insn = bb->end;
+   if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn))
+     return;
+   if (GET_CODE (insn) == JUMP_INSN)
+     {
+       for (e = bb->succ; e; e = next)
+ 	{
+ 	  next = e->succ_next;
+ 	  if (e->dest == EXIT_BLOCK_PTR || e->dest->head != JUMP_LABEL (insn))
+ 	    remove_edge (e);
+ 	}
+       if (bb->succ->succ_next)
+ 	abort ();
+       bb->succ->probability = REG_BR_PROB_BASE;
+       bb->succ->count = bb->count;
+ 
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
+       return;
+     }
+   /* In case we see other insn, we are not sure if the edges are not just
+      edges created by the insn we see.  See whether we do have normal edges
+      created by jump insn.  */
+   for (e = bb->succ; e && (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU));
+        e = e->succ_next);
+   if (!e)
+     return;
+   for (e = bb->succ; e; e = next)
+     if (!(e->flags & EDGE_FALLTHRU))
+       remove_edge (e);
+   if (!bb->succ || bb->succ->succ_next)
+     abort ();
+   bb->succ->probability = REG_BR_PROB_BASE;
+   bb->succ->count = bb->count;
+ 
+   if (rtl_dump_file)
+     fprintf (rtl_dump_file, "Purged non-fallthru edges from bb %i\n",
+ 	     bb->index);
+   return;
+ }
+ 
+ /* Search all basic blocks for potentionally dead edges and purge them.  */
+ 
+ void
+ purge_all_dead_edges ()
+ {
+   int i;
+   for (i = 0; i < n_basic_blocks; i++)
+     purge_dead_edges (BASIC_BLOCK (i));
  }
*** /p1/jumpr2/jumpr/egcs/gcc/gcse.c	Thu Jul 12 18:03:39 2001
--- gcse.c	Sun Jul 15 20:56:41 2001
*************** static void compute_cprop_data	PARAMS ((
*** 616,629 ****
  static void find_used_regs	PARAMS ((rtx *, void *));
  static int try_replace_reg	PARAMS ((rtx, rtx, rtx));
  static struct expr *find_avail_set PARAMS ((int, rtx));
! static int cprop_jump		PARAMS ((rtx, rtx, rtx));
  #ifdef HAVE_cc0
! static int cprop_cc0_jump	PARAMS ((rtx, struct reg_use *, rtx));
  #endif
  static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
  static int load_killed_in_block_p    PARAMS ((basic_block, int, rtx, int));
  static void canon_list_insert        PARAMS ((rtx, rtx, void *));
! static int cprop_insn		PARAMS ((rtx, int));
  static int cprop		PARAMS ((int));
  static int one_cprop_pass	PARAMS ((int, int));
  static void alloc_pre_mem	PARAMS ((int, int));
--- 616,629 ----
  static void find_used_regs	PARAMS ((rtx *, void *));
  static int try_replace_reg	PARAMS ((rtx, rtx, rtx));
  static struct expr *find_avail_set PARAMS ((int, rtx));
! static int cprop_jump		PARAMS ((basic_block, rtx, rtx, rtx));
  #ifdef HAVE_cc0
! static int cprop_cc0_jump	PARAMS ((basic_block, rtx, struct reg_use *, rtx));
  #endif
  static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
  static int load_killed_in_block_p    PARAMS ((basic_block, int, rtx, int));
  static void canon_list_insert        PARAMS ((rtx, rtx, void *));
! static int cprop_insn		PARAMS ((basic_block, rtx, int));
  static int cprop		PARAMS ((int));
  static int one_cprop_pass	PARAMS ((int, int));
  static void alloc_pre_mem	PARAMS ((int, int));
*************** hash_scan_set (pat, insn, set_p)
*** 2205,2211 ****
  	  /* Is SET_SRC something we want to gcse?  */
  	  && want_to_gcse_p (src)
  	  /* Don't CSE a nop.  */
! 	  && ! set_noop_p (pat)
  	  /* Don't GCSE if it has attached REG_EQUIV note.
  	     At this point this only function parameters should have
  	     REG_EQUIV notes and if the argument slot is used somewhere
--- 2205,2211 ----
  	  /* Is SET_SRC something we want to gcse?  */
  	  && want_to_gcse_p (src)
  	  /* Don't CSE a nop.  */
! 	  && ! set_noop_p (pat, insn)
  	  /* Don't GCSE if it has attached REG_EQUIV note.
  	     At this point this only function parameters should have
  	     REG_EQUIV notes and if the argument slot is used somewhere
*************** find_avail_set (regno, insn)
*** 4107,4116 ****
     nonzero if a change was made.  We know INSN has just a SET.  */
  
  static int
! cprop_jump (insn, from, src)
       rtx insn;
       rtx from;
       rtx src;
  {
    rtx set = PATTERN (insn);
    rtx new = simplify_replace_rtx (SET_SRC (set), from, src);
--- 4107,4117 ----
     nonzero if a change was made.  We know INSN has just a SET.  */
  
  static int
! cprop_jump (bb, insn, from, src)
       rtx insn;
       rtx from;
       rtx src;
+      basic_block bb;
  {
    rtx set = PATTERN (insn);
    rtx new = simplify_replace_rtx (SET_SRC (set), from, src);
*************** cprop_jump (insn, from, src)
*** 4151,4156 ****
--- 4152,4158 ----
        print_rtl (gcse_file, src);
        fprintf (gcse_file, "\n");
      }
+   purge_dead_edges (bb);
  
    return 1;
  }
*************** cprop_jump (insn, from, src)
*** 4164,4170 ****
     Returns nonzero if a change was made.  */
  
  static int
! cprop_cc0_jump (insn, reg_used, src)
       rtx insn;
       struct reg_use *reg_used;
       rtx src;
--- 4166,4173 ----
     Returns nonzero if a change was made.  */
  
  static int
! cprop_cc0_jump (bb, insn, reg_used, src)
!      basic_block bb;
       rtx insn;
       struct reg_use *reg_used;
       rtx src;
*************** cprop_cc0_jump (insn, reg_used, src)
*** 4175,4181 ****
    rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)),
  				      reg_used->reg_rtx, src);
  
!   if (! cprop_jump (jump, cc0_rtx, new_src))
      return 0;
  
    /* If we succeeded, delete the cc0 setter.  */
--- 4178,4184 ----
    rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)),
  				      reg_used->reg_rtx, src);
  
!   if (! cprop_jump (bb, jump, cc0_rtx, new_src))
      return 0;
  
    /* If we succeeded, delete the cc0 setter.  */
*************** cprop_cc0_jump (insn, reg_used, src)
*** 4191,4197 ****
     The result is non-zero if a change was made.  */
  
  static int
! cprop_insn (insn, alter_jumps)
       rtx insn;
       int alter_jumps;
  {
--- 4194,4201 ----
     The result is non-zero if a change was made.  */
  
  static int
! cprop_insn (bb, insn, alter_jumps)
!      basic_block bb;
       rtx insn;
       int alter_jumps;
  {
*************** cprop_insn (insn, alter_jumps)
*** 4275,4281 ****
  		   && GET_CODE (insn) == JUMP_INSN
  		   && condjump_p (insn)
  		   && ! simplejump_p (insn))
! 	    changed |= cprop_jump (insn, reg_used->reg_rtx, src);
  
  #ifdef HAVE_cc0
  	  /* Similar code for machines that use a pair of CC0 setter and
--- 4279,4285 ----
  		   && GET_CODE (insn) == JUMP_INSN
  		   && condjump_p (insn)
  		   && ! simplejump_p (insn))
! 	    changed |= cprop_jump (bb, insn, reg_used->reg_rtx, src);
  
  #ifdef HAVE_cc0
  	  /* Similar code for machines that use a pair of CC0 setter and
*************** cprop (alter_jumps)
*** 4344,4350 ****
  	   insn = NEXT_INSN (insn))
  	if (INSN_P (insn))
  	  {
! 	    changed |= cprop_insn (insn, alter_jumps);
  
  	    /* Keep track of everything modified by this insn.  */
  	    /* ??? Need to be careful w.r.t. mods done to INSN.  Don't
--- 4348,4354 ----
  	   insn = NEXT_INSN (insn))
  	if (INSN_P (insn))
  	  {
! 	    changed |= cprop_insn (bb, insn, alter_jumps);
  
  	    /* Keep track of everything modified by this insn.  */
  	    /* ??? Need to be careful w.r.t. mods done to INSN.  Don't
*** /p1/jumpr2/jumpr/egcs/gcc/toplev.c	Sat Jul 14 14:57:44 2001
--- toplev.c	Sun Jul 15 21:29:05 2001
*************** rest_of_compilation (decl)
*** 3349,3355 ****
  	  timevar_pop (TV_JUMP);
  
  	  timevar_push (TV_FLOW);
! 	  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
  	  cleanup_cfg (CLEANUP_EXPENSIVE);
  
  	  /* Blimey.  We've got to have the CFG up to date for the call to
--- 3358,3364 ----
  	  timevar_pop (TV_JUMP);
  
  	  timevar_push (TV_FLOW);
! 	  purge_all_dead_edges ();
  	  cleanup_cfg (CLEANUP_EXPENSIVE);
  
  	  /* Blimey.  We've got to have the CFG up to date for the call to


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