RFA: register pending barrier patch

Vladimir N. Makarov vmakarov@redhat.com
Mon Apr 7 00:18:00 GMT 2003


  The following patch solves the problem mentioned in

http://gcc.gnu.org/ml/gcc/2003-03/msg01537.html

Actually this problem could occur only for processors without pipeline
locks (like VLIW).  So the patch is safe for the most processors.  It
should be safe for VLIW processors too because it changes some
anti-dependencies onto true-dependencies.

The patch has been tested on regression tests and bootstrap for x86
and ia64.  I did not find a degradation.

Vlad

2003-04-06  Vladimir Makarov  <vmakarov@redhat.com>

        * sched-deps.c (reg_pending_barrier_mode): New enumeration.
        (reg_pending_barrier): Make it of the enumeration type.
        (sched_analyze_2): Define the barrier as MOVE_BARRIER or
        TRUE_BARRIER.
        (sched_analyze): Ditto.
        (sched_analyze_insn): Ditto.  Use anti-dependencies for
        MOVE_BARRIER and true-dependencies as TRUE_BARRIER.
        (init_deps_global): Initialize the barrier as NO_BARRIER.


-------------- next part --------------
Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.56
diff -c -p -r1.56 sched-deps.c
*** sched-deps.c	11 Mar 2003 09:17:38 -0000	1.56
--- sched-deps.c	7 Apr 2003 00:12:10 -0000
*************** static regset_head reg_pending_uses_head
*** 54,60 ****
  static regset reg_pending_sets;
  static regset reg_pending_clobbers;
  static regset reg_pending_uses;
! static bool reg_pending_barrier;
  
  /* To speed up the test for duplicate dependency links we keep a
     record of dependencies created by add_dependence when the average
--- 54,71 ----
  static regset reg_pending_sets;
  static regset reg_pending_clobbers;
  static regset reg_pending_uses;
! 
! /* The following enumeration values tell us what dependencies we
!    should use to implement the barrier.  We use true-dependencies for
!    TRUE_BARRIER and anti-dependencies for MOVE_BARRIER.  */
! enum reg_pending_barrier_mode
! {
!   NOT_A_BARRIER = 0,
!   MOVE_BARRIER,
!   TRUE_BARRIER
! };
! 
! static enum reg_pending_barrier_mode reg_pending_barrier;
  
  /* To speed up the test for duplicate dependency links we keep a
     record of dependencies created by add_dependence when the average
*************** sched_analyze_2 (deps, x, insn)
*** 748,754 ****
  	   mode.  An insn should not be moved across this even if it only uses
  	   pseudo-regs because it might give an incorrectly rounded result.  */
  	if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
! 	  reg_pending_barrier = true;
  
  	/* For all ASM_OPERANDS, we must traverse the vector of input operands.
  	   We can not just fall through here since then we would be confused
--- 759,765 ----
  	   mode.  An insn should not be moved across this even if it only uses
  	   pseudo-regs because it might give an incorrectly rounded result.  */
  	if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
! 	  reg_pending_barrier = TRUE_BARRIER;
  
  	/* For all ASM_OPERANDS, we must traverse the vector of input operands.
  	   We can not just fall through here since then we would be confused
*************** sched_analyze_insn (deps, x, insn, loop_
*** 867,873 ****
  	    sched_analyze_2 (deps, XEXP (link, 0), insn);
  	}
        if (find_reg_note (insn, REG_SETJMP, NULL))
! 	reg_pending_barrier = true;
      }
  
    if (GET_CODE (insn) == JUMP_INSN)
--- 878,884 ----
  	    sched_analyze_2 (deps, XEXP (link, 0), insn);
  	}
        if (find_reg_note (insn, REG_SETJMP, NULL))
! 	reg_pending_barrier = MOVE_BARRIER;
      }
  
    if (GET_CODE (insn) == JUMP_INSN)
*************** sched_analyze_insn (deps, x, insn, loop_
*** 875,881 ****
        rtx next;
        next = next_nonnote_insn (insn);
        if (next && GET_CODE (next) == BARRIER)
! 	reg_pending_barrier = true;
        else
  	{
  	  rtx pending, pending_mem;
--- 886,892 ----
        rtx next;
        next = next_nonnote_insn (insn);
        if (next && GET_CODE (next) == BARRIER)
! 	reg_pending_barrier = TRUE_BARRIER;
        else
  	{
  	  rtx pending, pending_mem;
*************** sched_analyze_insn (deps, x, insn, loop_
*** 940,946 ****
  	      || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END
  	      || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_BEG
  	      || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_END)
! 	    reg_pending_barrier = true;
  
  	  link = XEXP (link, 1);
  	}
--- 951,957 ----
  	      || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END
  	      || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_BEG
  	      || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_END)
! 	    reg_pending_barrier = MOVE_BARRIER;
  
  	  link = XEXP (link, 1);
  	}
*************** sched_analyze_insn (deps, x, insn, loop_
*** 952,958 ****
       where block boundaries fall.  This is mighty confusing elsewhere.
       Therefore, prevent such an instruction from being moved.  */
    if (can_throw_internal (insn))
!     reg_pending_barrier = true;
  
    /* Add dependencies if a scheduling barrier was found.  */
    if (reg_pending_barrier)
--- 963,969 ----
       where block boundaries fall.  This is mighty confusing elsewhere.
       Therefore, prevent such an instruction from being moved.  */
    if (can_throw_internal (insn))
!     reg_pending_barrier = MOVE_BARRIER;
  
    /* Add dependencies if a scheduling barrier was found.  */
    if (reg_pending_barrier)
*************** sched_analyze_insn (deps, x, insn, loop_
*** 965,972 ****
  	    {
  	      struct deps_reg *reg_last = &deps->reg_last[i];
  	      add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
! 	      add_dependence_list (insn, reg_last->sets, REG_DEP_ANTI);
! 	      add_dependence_list (insn, reg_last->clobbers, REG_DEP_ANTI);
  	    });
  	}
        else
--- 976,987 ----
  	    {
  	      struct deps_reg *reg_last = &deps->reg_last[i];
  	      add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
! 	      add_dependence_list
! 		(insn, reg_last->sets,
! 		 reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
! 	      add_dependence_list
! 		(insn, reg_last->clobbers,
! 		 reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
  	    });
  	}
        else
*************** sched_analyze_insn (deps, x, insn, loop_
*** 976,985 ****
  	      struct deps_reg *reg_last = &deps->reg_last[i];
  	      add_dependence_list_and_free (insn, &reg_last->uses,
  					    REG_DEP_ANTI);
! 	      add_dependence_list_and_free (insn, &reg_last->sets,
! 					    REG_DEP_ANTI);
! 	      add_dependence_list_and_free (insn, &reg_last->clobbers,
! 					    REG_DEP_ANTI);
  	      reg_last->uses_length = 0;
  	      reg_last->clobbers_length = 0;
  	    });
--- 991,1002 ----
  	      struct deps_reg *reg_last = &deps->reg_last[i];
  	      add_dependence_list_and_free (insn, &reg_last->uses,
  					    REG_DEP_ANTI);
! 	      add_dependence_list_and_free
! 		(insn, &reg_last->sets,
! 		 reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
! 	      add_dependence_list_and_free
! 		(insn, &reg_last->clobbers,
! 		 reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
  	      reg_last->uses_length = 0;
  	      reg_last->clobbers_length = 0;
  	    });
*************** sched_analyze_insn (deps, x, insn, loop_
*** 993,999 ****
  	}
  
        flush_pending_lists (deps, insn, true, true);
!       reg_pending_barrier = false;
      }
    else
      {
--- 1010,1016 ----
  	}
  
        flush_pending_lists (deps, insn, true, true);
!       reg_pending_barrier = NOT_A_BARRIER;
      }
    else
      {
*************** sched_analyze (deps, head, tail)
*** 1190,1196 ****
  	    {
  	      /* This is setjmp.  Assume that all registers, not just
  		 hard registers, may be clobbered by this call.  */
! 	      reg_pending_barrier = true;
  	    }
  	  else
  	    {
--- 1207,1213 ----
  	    {
  	      /* This is setjmp.  Assume that all registers, not just
  		 hard registers, may be clobbered by this call.  */
! 	      reg_pending_barrier = MOVE_BARRIER;
  	    }
  	  else
  	    {
*************** init_deps_global ()
*** 1505,1511 ****
    reg_pending_sets = INITIALIZE_REG_SET (reg_pending_sets_head);
    reg_pending_clobbers = INITIALIZE_REG_SET (reg_pending_clobbers_head);
    reg_pending_uses = INITIALIZE_REG_SET (reg_pending_uses_head);
!   reg_pending_barrier = false;
  }
  
  /* Free everything used by the dependency analysis code.  */
--- 1522,1528 ----
    reg_pending_sets = INITIALIZE_REG_SET (reg_pending_sets_head);
    reg_pending_clobbers = INITIALIZE_REG_SET (reg_pending_clobbers_head);
    reg_pending_uses = INITIALIZE_REG_SET (reg_pending_uses_head);
!   reg_pending_barrier = NOT_A_BARRIER;
  }
  
  /* Free everything used by the dependency analysis code.  */


More information about the Gcc-patches mailing list