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]

haifa and clobbers


Clobbers should not interfere with each other wrt scheduling;
removing this restriction allows for a bit more freedom in 
slotting instructions.

Of course dependancies wrt uses or sets are still required.

This was reviewed by Jeff.


r~


        * haifa-sched.c (reg_last_clobbers): New.
        (reg_pending_clobbers, bb_reg_last_clobbers): New.
        (compute_block_backward_dependences): Allocate memory for them.
        (schedule_region): Likewise.
        (sched_analyze_1): Clobbers don't interfere with one another.
        They do interfere with sets ...
        (sched_analyze_2): ... and uses.
        (sched_analyze): Likewise.
        (sched_analyze_insn): Update reg_last_clobbers appropriately.

Index: haifa-sched.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/haifa-sched.c,v
retrieving revision 1.81
diff -c -p -d -r1.81 haifa-sched.c
*** haifa-sched.c	1999/02/25 23:45:21	1.81
--- haifa-sched.c	1999/03/07 19:15:14
*************** static int current_block_num;
*** 251,257 ****
--- 251,259 ----
     by splitting insns.  */
  static rtx *reg_last_uses;
  static rtx *reg_last_sets;
+ static rtx *reg_last_clobbers;
  static regset reg_pending_sets;
+ static regset reg_pending_clobbers;
  static int reg_pending_sets_all;
  
  /* Vector indexed by INSN_UID giving the original ordering of the insns.  */
*************** static rtx last_scheduled_insn;
*** 1054,1059 ****
--- 1056,1062 ----
  
  static rtx **bb_reg_last_uses;
  static rtx **bb_reg_last_sets;
+ static rtx **bb_reg_last_clobbers;
  
  static rtx *bb_pending_read_insns;
  static rtx *bb_pending_read_mems;
*************** sched_analyze_1 (x, insn)
*** 3309,3314 ****
--- 3312,3318 ----
  {
    register int regno;
    register rtx dest = SET_DEST (x);
+   enum rtx_code code = GET_CODE (x);
  
    if (dest == 0)
      return;
*************** sched_analyze_1 (x, insn)
*** 3358,3367 ****
  	      for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
  		add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
  
! 	      SET_REGNO_REG_SET (reg_pending_sets, regno + i);
  
! 	      if ((call_used_regs[regno + i] || global_regs[regno + i]))
! 		/* Function calls clobber all call_used regs.  */
  		for (u = last_function_call; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  	    }
--- 3362,3381 ----
  	      for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
  		add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
  
! 	      /* Clobbers need not be ordered with respect to one another,
! 		 but sets must be ordered with respect to a pending clobber. */
! 	      if (code == SET)
! 		{
! 	          for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
! 		    add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
! 	          SET_REGNO_REG_SET (reg_pending_sets, regno + i);
! 		}
! 	      else
! 		SET_REGNO_REG_SET (reg_pending_clobbers, regno + i);
  
! 	      /* Function calls clobber all call_used regs.  */
! 	      if (global_regs[regno + i]
! 		  || (code == SET && call_used_regs[regno + i]))
  		for (u = last_function_call; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  	    }
*************** sched_analyze_1 (x, insn)
*** 3377,3383 ****
  	  for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
  	    add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
  
! 	  SET_REGNO_REG_SET (reg_pending_sets, regno);
  
  	  /* Pseudos that are REG_EQUIV to something may be replaced
  	     by that during reloading.  We need only add dependencies for
--- 3391,3400 ----
  	  for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
  	    add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
  
! 	  if (code == SET)
! 	    SET_REGNO_REG_SET (reg_pending_sets, regno);
! 	  else
! 	    SET_REGNO_REG_SET (reg_pending_clobbers, regno);
  
  	  /* Pseudos that are REG_EQUIV to something may be replaced
  	     by that during reloading.  We need only add dependencies for
*************** sched_analyze_2 (x, insn)
*** 3528,3533 ****
--- 3545,3554 ----
  		for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), 0);
  
+ 		/* ??? This should never happen.  */
+ 		for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
+ 		  add_dependence (insn, XEXP (u, 0), 0);
+ 
  		if ((call_used_regs[regno + i] || global_regs[regno + i]))
  		  /* Function calls clobber all call_used regs.  */
  		  for (u = last_function_call; u; u = XEXP (u, 1))
*************** sched_analyze_2 (x, insn)
*** 3541,3546 ****
--- 3562,3571 ----
  	    for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
  	      add_dependence (insn, XEXP (u, 0), 0);
  
+ 	    /* ??? This should never happen.  */
+ 	    for (u = reg_last_clobbers[regno]; u; u = XEXP (u, 1))
+ 	      add_dependence (insn, XEXP (u, 0), 0);
+ 
  	    /* Pseudos that are REG_EQUIV to something may be replaced
  	       by that during reloading.  We need only add dependencies for
  	       the address in the REG_EQUIV note.  */
*************** sched_analyze_2 (x, insn)
*** 3631,3639 ****
  		  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  		reg_last_uses[i] = 0;
  
- 		/* reg_last_sets[r] is now a list of insns */
  		for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), 0);
  	      }
  	    reg_pending_sets_all = 1;
  
--- 3656,3666 ----
  		  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  		reg_last_uses[i] = 0;
  
  		for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), 0);
+ 
+ 		for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ 		  add_dependence (insn, XEXP (u, 0), 0);
  	      }
  	    reg_pending_sets_all = 1;
  
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3762,3770 ****
  		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  	      reg_last_uses[i] = 0;
  
- 	      /* reg_last_sets[r] is now a list of insns */
  	      for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		add_dependence (insn, XEXP (u, 0), 0);
  	    }
  	  reg_pending_sets_all = 1;
  
--- 3789,3799 ----
  		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  	      reg_last_uses[i] = 0;
  
  	      for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		add_dependence (insn, XEXP (u, 0), 0);
+ 
+ 	      for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ 		add_dependence (insn, XEXP (u, 0), 0);
  	    }
  	  reg_pending_sets_all = 1;
  
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3773,3792 ****
  
      }
  
    EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
  			     {
- 			       /* reg_last_sets[r] is now a list of insns */
  			       free_list (&reg_last_sets[i], &unused_insn_list);
  			       reg_last_sets[i]
  				 = alloc_INSN_LIST (insn, NULL_RTX);
  			     });
    CLEAR_REG_SET (reg_pending_sets);
  
    if (reg_pending_sets_all)
      {
        for (i = 0; i < maxreg; i++)
  	{
- 	  /* reg_last_sets[r] is now a list of insns */
  	  free_list (&reg_last_sets[i], &unused_insn_list);
  	  reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
  	}
--- 3802,3830 ----
  
      }
  
+   /* Accumulate clobbers until the next set so that it will be output dependant
+      on all of them.  At the next set we can clear the clobber list, since
+      subsequent sets will be output dependant on it.  */
    EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
  			     {
  			       free_list (&reg_last_sets[i], &unused_insn_list);
+ 			       free_list (&reg_last_clobbers[i],
+ 					  &unused_insn_list);
  			       reg_last_sets[i]
  				 = alloc_INSN_LIST (insn, NULL_RTX);
  			     });
+   EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i,
+ 			     {
+ 			       reg_last_clobbers[i]
+ 				 = alloc_INSN_LIST (insn, reg_last_clobbers[i]);
+ 			     });
    CLEAR_REG_SET (reg_pending_sets);
+   CLEAR_REG_SET (reg_pending_clobbers);
  
    if (reg_pending_sets_all)
      {
        for (i = 0; i < maxreg; i++)
  	{
  	  free_list (&reg_last_sets[i], &unused_insn_list);
  	  reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
  	}
*************** sched_analyze (head, tail)
*** 3884,3892 ****
  
  		  reg_last_uses[i] = 0;
  
- 		  /* reg_last_sets[r] is now a list of insns */
  		  for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		    add_dependence (insn, XEXP (u, 0), 0);
  		}
  	      reg_pending_sets_all = 1;
  
--- 3922,3932 ----
  
  		  reg_last_uses[i] = 0;
  
  		  for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		    add_dependence (insn, XEXP (u, 0), 0);
+ 
+ 		  for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ 		    add_dependence (insn, XEXP (u, 0), 0);
  		}
  	      reg_pending_sets_all = 1;
  
*************** sched_analyze (head, tail)
*** 3909,3918 ****
  		      add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  		    reg_last_uses[i] = 0;
  
- 		    /* reg_last_sets[r] is now a list of insns */
  		    for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		      add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  
  		    SET_REGNO_REG_SET (reg_pending_sets, i);
  		  }
  	    }
--- 3949,3961 ----
  		      add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  		    reg_last_uses[i] = 0;
  
  		    for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		      add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  
+ 		    if (global_regs[i])
+ 		      for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ 		        add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+ 
  		    SET_REGNO_REG_SET (reg_pending_sets, i);
  		  }
  	    }
*************** compute_block_backward_dependences (bb)
*** 7232,7240 ****
--- 7275,7285 ----
      {
        reg_last_uses = (rtx *) alloca (max_reg * sizeof (rtx));
        reg_last_sets = (rtx *) alloca (max_reg * sizeof (rtx));
+       reg_last_clobbers = (rtx *) alloca (max_reg * sizeof (rtx));
  
        bzero ((char *) reg_last_uses, max_reg * sizeof (rtx));
        bzero ((char *) reg_last_sets, max_reg * sizeof (rtx));
+       bzero ((char *) reg_last_clobbers, max_reg * sizeof (rtx));
  
        pending_read_insns = 0;
        pending_read_mems = 0;
*************** compute_block_backward_dependences (bb)
*** 7252,7257 ****
--- 7297,7303 ----
      {
        reg_last_uses = bb_reg_last_uses[bb];
        reg_last_sets = bb_reg_last_sets[bb];
+       reg_last_clobbers = bb_reg_last_clobbers[bb];
  
        pending_read_insns = bb_pending_read_insns[bb];
        pending_read_mems = bb_pending_read_mems[bb];
*************** compute_block_backward_dependences (bb)
*** 7323,7328 ****
--- 7369,7384 ----
  		      = alloc_INSN_LIST (XEXP (u, 0),
  					 (bb_reg_last_sets[bb_succ])[reg]);
  		  }
+ 
+ 		for (u = reg_last_clobbers[reg]; u; u = XEXP (u, 1))
+ 		  {
+ 		    if (find_insn_list (XEXP (u, 0), (bb_reg_last_clobbers[bb_succ])[reg]))
+ 		      continue;
+ 
+ 		    (bb_reg_last_clobbers[bb_succ])[reg]
+ 		      = alloc_INSN_LIST (XEXP (u, 0),
+ 					 (bb_reg_last_clobbers[bb_succ])[reg]);
+ 		  }
  	      }
  
  	    /* mem read/write lists are inherited by bb_succ */
*************** compute_block_backward_dependences (bb)
*** 7397,7402 ****
--- 7453,7460 ----
       3-5% on average.  */
    for (b = 0; b < max_reg; ++b)
      {
+       if (reg_last_clobbers[b])
+ 	free_list (&reg_last_clobbers[b], &unused_insn_list);
        if (reg_last_sets[b])
  	free_list (&reg_last_sets[b], &unused_insn_list);
        if (reg_last_uses[b])
*************** compute_block_backward_dependences (bb)
*** 7408,7413 ****
--- 7466,7472 ----
      {
        bb_reg_last_uses[bb] = (rtx *) NULL_RTX;
        bb_reg_last_sets[bb] = (rtx *) NULL_RTX;
+       bb_reg_last_clobbers[bb] = (rtx *) NULL_RTX;
      }
  }
  
*************** schedule_region (rgn)
*** 7560,7565 ****
--- 7619,7625 ----
    current_blocks = RGN_BLOCKS (rgn);
  
    reg_pending_sets = ALLOCA_REG_SET ();
+   reg_pending_clobbers = ALLOCA_REG_SET ();
    reg_pending_sets_all = 0;
  
    /* initializations for region data dependence analyisis */
*************** schedule_region (rgn)
*** 7571,7591 ****
        bb_reg_last_uses = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
        space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
        bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
!       init_rtx_vector (bb_reg_last_uses, space, current_nr_blocks, maxreg * sizeof (rtx *));
  
        bb_reg_last_sets = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
        space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
        bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
!       init_rtx_vector (bb_reg_last_sets, space, current_nr_blocks, maxreg * sizeof (rtx *));
  
        bb_pending_read_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
        bb_pending_read_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
!       bb_pending_write_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
        bb_pending_write_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
!       bb_pending_lists_length = (int *) alloca (current_nr_blocks * sizeof (int));
!       bb_last_pending_memory_flush = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
        bb_last_function_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
!       bb_sched_before_next_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
  
        init_rgn_data_dependences (current_nr_blocks);
      }
--- 7631,7664 ----
        bb_reg_last_uses = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
        space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
        bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
!       init_rtx_vector (bb_reg_last_uses, space, current_nr_blocks,
! 		       maxreg * sizeof (rtx *));
  
        bb_reg_last_sets = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
        space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
        bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
!       init_rtx_vector (bb_reg_last_sets, space, current_nr_blocks,
! 		       maxreg * sizeof (rtx *));
! 
!       bb_reg_last_clobbers =
! 	(rtx **) alloca (current_nr_blocks * sizeof (rtx *));
!       space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
!       bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
!       init_rtx_vector (bb_reg_last_clobbers, space, current_nr_blocks,
! 		       maxreg * sizeof (rtx *));
  
        bb_pending_read_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
        bb_pending_read_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
!       bb_pending_write_insns =
! 	(rtx *) alloca (current_nr_blocks * sizeof (rtx));
        bb_pending_write_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
!       bb_pending_lists_length =
! 	(int *) alloca (current_nr_blocks * sizeof (int));
!       bb_last_pending_memory_flush =
! 	(rtx *) alloca (current_nr_blocks * sizeof (rtx));
        bb_last_function_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
!       bb_sched_before_next_call =
! 	(rtx *) alloca (current_nr_blocks * sizeof (rtx));
  
        init_rgn_data_dependences (current_nr_blocks);
      }
*************** schedule_region (rgn)
*** 7703,7708 ****
--- 7776,7782 ----
    free_pending_lists ();
  
    FREE_REG_SET (reg_pending_sets);
+   FREE_REG_SET (reg_pending_clobbers);
  }
  
  /* Subroutine of update_flow_info.  Determines whether any new REG_NOTEs are


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