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]

ia64 eh, part 14


If non-call instructions that throw exceptions that are caught within
the function are modeled properly, that is, actually force the basic
block to end, then we cannot move them without moving the basic block
boundary.  Letting that happen confuses the scheduler immensely.


r~


        * sched-deps.c (sched_analyze_insn): Consolidate scheduling
        barrier code.  Add a scheduling barrier if a non-call insn
        can throw internally.

Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.9
diff -c -p -d -r1.9 sched-deps.c
*** sched-deps.c	2001/01/19 18:28:58	1.9
--- sched-deps.c	2001/03/28 07:38:03
*************** sched_analyze_insn (deps, x, insn, loop_
*** 972,977 ****
--- 972,978 ----
       rtx loop_notes;
  {
    register RTX_CODE code = GET_CODE (x);
+   int schedule_barrier_found = 0;
    rtx link;
    int i;
  
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1021,1042 ****
  
    if (GET_CODE (insn) == JUMP_INSN)
      {
!       rtx next, u, pending, pending_mem;
        next = next_nonnote_insn (insn);
        if (next && GET_CODE (next) == BARRIER)
! 	{
! 	  for (i = 0; i < deps->max_reg; i++)
! 	    {
! 	      struct deps_reg *reg_last = &deps->reg_last[i];
! 
! 	      for (u = reg_last->uses; u; u = XEXP (u, 1))
! 		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 	      for (u = reg_last->sets; u; u = XEXP (u, 1))
! 		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 	      for (u = reg_last->clobbers; u; u = XEXP (u, 1))
! 		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 	    }
! 	}
        else
  	{
  	  regset_head tmp;
--- 1022,1031 ----
  
    if (GET_CODE (insn) == JUMP_INSN)
      {
!       rtx next, u;
        next = next_nonnote_insn (insn);
        if (next && GET_CODE (next) == BARRIER)
! 	schedule_barrier_found = 1;
        else
  	{
  	  regset_head tmp;
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1054,1086 ****
  
  	  CLEAR_REG_SET (&tmp);
  	}
-       pending = deps->pending_write_insns;
-       pending_mem = deps->pending_write_mems;
-       while (pending)
- 	{
- 	  add_dependence (insn, XEXP (pending, 0), 0);
- 
- 	  pending = XEXP (pending, 1);
- 	  pending_mem = XEXP (pending_mem, 1);
- 	}
- 
-       for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
- 	add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
      }
  
    /* If there is a {LOOP,EHREGION}_{BEG,END} note in the middle of a basic
       block, then we must be sure that no instructions are scheduled across it.
       Otherwise, the reg_n_refs info (which depends on loop_depth) would
       become incorrect.  */
- 
    if (loop_notes)
      {
-       int schedule_barrier_found = 0;
        rtx link;
  
        /* Update loop_notes with any notes from this insn.  Also determine
  	 if any of the notes on the list correspond to instruction scheduling
! 	 barriers (loop, eh & setjmp notes, but not range notes.  */
        link = loop_notes;
        while (XEXP (link, 1))
  	{
--- 1043,1061 ----
  
  	  CLEAR_REG_SET (&tmp);
  	}
      }
  
    /* If there is a {LOOP,EHREGION}_{BEG,END} note in the middle of a basic
       block, then we must be sure that no instructions are scheduled across it.
       Otherwise, the reg_n_refs info (which depends on loop_depth) would
       become incorrect.  */
    if (loop_notes)
      {
        rtx link;
  
        /* Update loop_notes with any notes from this insn.  Also determine
  	 if any of the notes on the list correspond to instruction scheduling
! 	 barriers (loop, eh & setjmp notes, but not range notes).  */
        link = loop_notes;
        while (XEXP (link, 1))
  	{
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1095,1124 ****
  	}
        XEXP (link, 1) = REG_NOTES (insn);
        REG_NOTES (insn) = loop_notes;
  
!       /* Add dependencies if a scheduling barrier was found.  */
!       if (schedule_barrier_found)
  	{
! 	  for (i = 0; i < deps->max_reg; i++)
! 	    {
! 	      struct deps_reg *reg_last = &deps->reg_last[i];
! 	      rtx u;
  
! 	      for (u = reg_last->uses; u; u = XEXP (u, 1))
! 		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 	      for (u = reg_last->sets; u; u = XEXP (u, 1))
! 		add_dependence (insn, XEXP (u, 0), 0);
! 	      for (u = reg_last->clobbers; u; u = XEXP (u, 1))
! 		add_dependence (insn, XEXP (u, 0), 0);
  
! 	      if (GET_CODE (PATTERN (insn)) != COND_EXEC)
! 		free_INSN_LIST_list (&reg_last->uses);
! 	    }
! 	  reg_pending_sets_all = 1;
  
! 	  flush_pending_lists (deps, insn, 0);
  	}
  
      }
  
    /* Accumulate clobbers until the next set so that it will be output
--- 1070,1117 ----
  	}
        XEXP (link, 1) = REG_NOTES (insn);
        REG_NOTES (insn) = loop_notes;
+     }
  
!   /* If this instruction can throw an exception, then moving it changes
!      where block boundaries fall.  This is mighty confusing elsewhere. 
!      Therefore, prevent such an instruction from being moved.  */
!   if (flag_non_call_exceptions && can_throw_internal (insn))
!     schedule_barrier_found = 1;
! 
!   /* Add dependencies if a scheduling barrier was found.  */
!   if (schedule_barrier_found)
!     {
!       rtx u, pending, pending_mem;
! 
!       for (i = 0; i < deps->max_reg; i++)
  	{
! 	  struct deps_reg *reg_last = &deps->reg_last[i];
  
! 	  for (u = reg_last->uses; u; u = XEXP (u, 1))
! 	    add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 	  for (u = reg_last->sets; u; u = XEXP (u, 1))
! 	    add_dependence (insn, XEXP (u, 0), 0);
! 	  for (u = reg_last->clobbers; u; u = XEXP (u, 1))
! 	    add_dependence (insn, XEXP (u, 0), 0);
  
! 	  if (GET_CODE (PATTERN (insn)) != COND_EXEC)
! 	    free_INSN_LIST_list (&reg_last->uses);
! 	}
!       flush_pending_lists (deps, insn, 0);
  
!       pending = deps->pending_write_insns;
!       pending_mem = deps->pending_write_mems;
!       while (pending)
! 	{
! 	  add_dependence (insn, XEXP (pending, 0), 0);
! 	  pending = XEXP (pending, 1);
! 	  pending_mem = XEXP (pending_mem, 1);
  	}
  
+       for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
+ 	add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+ 
+       reg_pending_sets_all = 1;
      }
  
    /* Accumulate clobbers until the next set so that it will be output


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