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: [itanium-sched-branch] Removing schedule groups for more accurate insn scheduling [patch]


  The following patch removes schedule groups by adding new
dependencies.  It permits to take insn resources into account more
accurately.  Early all groups are considered as the group leader insn
only.  The patch also switches on usage of latency times from DFA
descriptions.

  The patch increases SPECint2000 rate from 190 to 192.  The
branchpoint has SPECint2000 equal to 191.

  So the goal of the project has been achieved.  We have no regression
on
quality of insn scheduler (I use SPECInt2000 as the major test) and
the compiler is about 40% faster (see my previous emails).

  But I'll try to improve insn scheduling more before to get
an approval to merge the branch into main line.

Vlad

2002-09-30  Vladimir Makarov  <vmakarov@redhat.com>

        * sched-deps.c (remove_dependence, group_leader): Remove it.
        (add_dependence): Add dependence to group leader to.
        (set_sched_group_p): Add dependence to the first insn of the
        schedule group too.
        (sched_analyze_insn): Make dependence to jump as
anti-dependence.
        Change true dependence by anti-dependence when
        `reg_pending_barrier'.

        * sched-rgn.c (init_ready_list, can_schedule_ready_p,
        add_branch_dependences): Ignore schedule groups.

        * sched-ebb.c (init_ready_list): Ditto.

        * (move_insn, set_priorities): Ditto.

        * config/ia64/ia64.c (ia64_sched_init): Check that schedule
group
        flag is clear after reload.
        (adjust_cost): Change cost only for output dependencies.
        
        * config/ia64/ia64.md: Add more insns into bypass for MM-insns.
Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.47
diff -c -p -r1.47 sched-deps.c
*** sched-deps.c	8 Sep 2002 03:42:46 -0000	1.47
--- sched-deps.c	30 Sep 2002 15:33:53 -0000
*************** static sbitmap *forward_dependency_cache
*** 81,94 ****
  static int deps_may_trap_p PARAMS ((rtx));
  static void add_dependence_list PARAMS ((rtx, rtx, enum reg_note));
  static void add_dependence_list_and_free PARAMS ((rtx, rtx *, enum reg_note));
- static void remove_dependence PARAMS ((rtx, rtx));
  static void set_sched_group_p PARAMS ((rtx));
  
  static void flush_pending_lists PARAMS ((struct deps *, rtx, int, int));
  static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx));
  static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx));
  static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx));
- static rtx group_leader PARAMS ((rtx));
  
  static rtx get_condition PARAMS ((rtx));
  static int conditions_mutex_p PARAMS ((rtx, rtx));
--- 81,92 ----
*************** add_dependence (insn, elem, dep_type)
*** 235,252 ****
        rtx nnext;
        while ((nnext = next_nonnote_insn (next)) != NULL
  	     && INSN_P (nnext)
  	     && SCHED_GROUP_P (nnext))
  	next = nnext;
  
!       /* Again, don't depend an insn on itself.  */
!       if (insn == next)
! 	return;
  
-       /* Make the dependence to NEXT, the last insn of the group, instead
-          of the original ELEM.  */
-       elem = next;
      }
  
    present_p = 1;
  #ifdef INSN_SCHEDULING
    /* ??? No good way to tell from here whether we're doing interblock
--- 233,248 ----
        rtx nnext;
        while ((nnext = next_nonnote_insn (next)) != NULL
  	     && INSN_P (nnext)
+ 	     && next != insn
  	     && SCHED_GROUP_P (nnext))
  	next = nnext;
  
!       if (insn != next)
! 	add_dependence (insn, next, REG_DEP_ANTI);
  
      }
  
+ 
    present_p = 1;
  #ifdef INSN_SCHEDULING
    /* ??? No good way to tell from here whether we're doing interblock
*************** add_dependence_list_and_free (insn, list
*** 382,457 ****
      }
  }
  
- /* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
-    of INSN.  Abort if not found.  */
- 
- static void
- remove_dependence (insn, elem)
-      rtx insn;
-      rtx elem;
- {
-   rtx prev, link, next;
-   int found = 0;
- 
-   for (prev = 0, link = LOG_LINKS (insn); link; link = next)
-     {
-       next = XEXP (link, 1);
-       if (XEXP (link, 0) == elem)
- 	{
- 	  if (prev)
- 	    XEXP (prev, 1) = next;
- 	  else
- 	    LOG_LINKS (insn) = next;
- 
- #ifdef INSN_SCHEDULING
- 	  /* If we are removing a dependency from the LOG_LINKS list,
- 	     make sure to remove it from the cache too.  */
- 	  if (true_dependency_cache != NULL)
- 	    {
- 	      if (REG_NOTE_KIND (link) == 0)
- 		RESET_BIT (true_dependency_cache[INSN_LUID (insn)],
- 			   INSN_LUID (elem));
- 	      else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
- 		RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
- 			   INSN_LUID (elem));
- 	      else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- 		RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
- 			   INSN_LUID (elem));
- 	    }
- #endif
- 
- 	  free_INSN_LIST_node (link);
- 
- 	  found = 1;
- 	}
-       else
- 	prev = link;
-     }
- 
-   if (!found)
-     abort ();
-   return;
- }
- 
- /* Return an insn which represents a SCHED_GROUP, which is
-    the last insn in the group.  */
- 
- static rtx
- group_leader (insn)
-      rtx insn;
- {
-   rtx prev;
- 
-   do
-     {
-       prev = insn;
-       insn = next_nonnote_insn (insn);
-     }
-   while (insn && INSN_P (insn) && SCHED_GROUP_P (insn));
- 
-   return prev;
- }
- 
  /* Set SCHED_GROUP_P and care for the rest of the bookkeeping that
     goes along with that.  */
  
--- 378,383 ----
*************** set_sched_group_p (insn)
*** 463,483 ****
  
    SCHED_GROUP_P (insn) = 1;
  
!   /* There may be a note before this insn now, but all notes will
!      be removed before we actually try to schedule the insns, so
!      it won't cause a problem later.  We must avoid it here though.  */
    prev = prev_nonnote_insn (insn);
! 
!   /* Make a copy of all dependencies on the immediately previous insn,
!      and add to this insn.  This is so that all the dependencies will
!      apply to the group.  Remove an explicit dependence on this insn
!      as SCHED_GROUP_P now represents it.  */
! 
!   if (find_insn_list (prev, LOG_LINKS (insn)))
!     remove_dependence (insn, prev);
! 
!   for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
!     add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link));
  }
  
  /* Process an insn's memory dependencies.  There are four kinds of
--- 389,409 ----
  
    SCHED_GROUP_P (insn) = 1;
  
!   for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
!     {
!       prev = insn;
!       do
! 	{
! 	  prev = prev_nonnote_insn (prev);
! 	  if (XEXP (link, 0) == prev)
! 	    break;
! 	}
!       while (SCHED_GROUP_P (prev));
!       if (XEXP (link, 0) != prev)
! 	add_dependence (prev, XEXP (link, 0), REG_DEP_ANTI);
!     }
    prev = prev_nonnote_insn (insn);
!   add_dependence (insn, prev, REG_DEP_ANTI);
  }
  
  /* Process an insn's memory dependencies.  There are four kinds of
*************** sched_analyze_insn (deps, x, insn, loop_
*** 973,979 ****
  	  INIT_REG_SET (&tmp);
  
  	  (*current_sched_info->compute_jump_reg_dependencies) (insn, &tmp);
! 	  IOR_REG_SET (reg_pending_uses, &tmp);
  	  CLEAR_REG_SET (&tmp);
  
  	  /* All memory writes and volatile reads must happen before the
--- 899,913 ----
  	  INIT_REG_SET (&tmp);
  
  	  (*current_sched_info->compute_jump_reg_dependencies) (insn, &tmp);
! 	  /* Make latency of jump equal to 0 by using anti-dependence.  */
! 	  EXECUTE_IF_SET_IN_REG_SET (&tmp, 0, i,
! 	    {
! 	      struct deps_reg *reg_last = &deps->reg_last[i];
! 	      add_dependence_list (insn, reg_last->sets, REG_DEP_ANTI);
! 	      add_dependence_list (insn, reg_last->clobbers, REG_DEP_ANTI);
! 	      reg_last->uses_length++;
! 	      reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
! 	    });
  	  CLEAR_REG_SET (&tmp);
  
  	  /* All memory writes and volatile reads must happen before the
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1039,1052 ****
    /* Add dependencies if a scheduling barrier was found.  */
    if (reg_pending_barrier)
      {
        if (GET_CODE (PATTERN (insn)) == COND_EXEC)
  	{
  	  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
  	    {
  	      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, 0);
! 	      add_dependence_list (insn, reg_last->clobbers, 0);
  	    });
  	}
        else
--- 973,988 ----
    /* Add dependencies if a scheduling barrier was found.  */
    if (reg_pending_barrier)
      {
+       /* In the case of barrier the most added dependencies are not
+          real, so we use anti-dependence here.  */
        if (GET_CODE (PATTERN (insn)) == COND_EXEC)
  	{
  	  EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
  	    {
  	      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
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1056,1063 ****
  	      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, 0);
! 	      add_dependence_list_and_free (insn, &reg_last->clobbers, 0);
  	      reg_last->uses_length = 0;
  	      reg_last->clobbers_length = 0;
  	    });
--- 992,1001 ----
  	      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;
  	    });
*************** compute_forward_dependences (head, tail)
*** 1418,1428 ****
        if (! INSN_P (insn))
  	continue;
  
-       insn = group_leader (insn);
- 
        for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
  	{
! 	  rtx x = group_leader (XEXP (link, 0));
  	  rtx new_link;
  
  	  if (x != XEXP (link, 0))
--- 1356,1364 ----
        if (! INSN_P (insn))
  	continue;
  
        for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
  	{
! 	  rtx x = XEXP (link, 0);
  	  rtx new_link;
  
  	  if (x != XEXP (link, 0))
Index: sched-rgn.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-rgn.c,v
retrieving revision 1.48.10.1
diff -c -p -r1.48.10.1 sched-rgn.c
*** sched-rgn.c	26 Sep 2002 15:35:49 -0000	1.48.10.1
--- sched-rgn.c	30 Sep 2002 15:33:54 -0000
*************** init_ready_list (ready)
*** 2023,2039 ****
       Count number of insns in the target block being scheduled.  */
    for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
      {
!       rtx next;
! 
!       if (! INSN_P (insn))
! 	continue;
!       next = NEXT_INSN (insn);
! 
!       if (INSN_DEP_COUNT (insn) == 0
! 	  && (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
  	ready_add (ready, insn);
!       if (!(SCHED_GROUP_P (insn)))
! 	target_n_insns++;
      }
  
    /* Add to ready list all 'ready' insns in valid source blocks.
--- 2023,2031 ----
       Count number of insns in the target block being scheduled.  */
    for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
      {
!       if (INSN_DEP_COUNT (insn) == 0)
  	ready_add (ready, insn);
!       target_n_insns++;
      }
  
    /* Add to ready list all 'ready' insns in valid source blocks.
*************** init_ready_list (ready)
*** 2067,2085 ****
  							     insn, insn) <= 3)))
  			&& check_live (insn, bb_src)
  			&& is_exception_free (insn, bb_src, target_bb))))
! 	      {
! 		rtx next;
! 
! 		/* Note that we haven't squirreled away the notes for
! 		   blocks other than the current.  So if this is a
! 		   speculative insn, NEXT might otherwise be a note.  */
! 		next = next_nonnote_insn (insn);
! 		if (INSN_DEP_COUNT (insn) == 0
! 		    && (! next
! 			|| ! INSN_P (next)
! 			|| SCHED_GROUP_P (next) == 0))
! 		  ready_add (ready, insn);
! 	      }
  	  }
        }
  }
--- 2059,2066 ----
  							     insn, insn) <= 3)))
  			&& check_live (insn, bb_src)
  			&& is_exception_free (insn, bb_src, target_bb))))
! 	      if (INSN_DEP_COUNT (insn) == 0)
! 		ready_add (ready, insn);
  	  }
        }
  }
*************** can_schedule_ready_p (insn)
*** 2097,2103 ****
    /* An interblock motion?  */
    if (INSN_BB (insn) != target_bb)
      {
-       rtx temp;
        basic_block b1;
  
        if (IS_SPECULATIVE_INSN (insn))
--- 2078,2083 ----
*************** can_schedule_ready_p (insn)
*** 2114,2131 ****
  	}
        nr_inter++;
  
-       /* Find the beginning of the scheduling group.  */
-       /* ??? Ought to update basic block here, but later bits of
- 	 schedule_block assumes the original insn block is
- 	 still intact.  */
- 
-       temp = insn;
-       while (SCHED_GROUP_P (temp))
- 	temp = PREV_INSN (temp);
- 
        /* Update source block boundaries.  */
!       b1 = BLOCK_FOR_INSN (temp);
!       if (temp == b1->head && insn == b1->end)
  	{
  	  /* We moved all the insns in the basic block.
  	     Emit a note after the last insn and update the
--- 2094,2102 ----
  	}
        nr_inter++;
  
        /* Update source block boundaries.  */
!       b1 = BLOCK_FOR_INSN (insn);
!       if (insn == b1->head && insn == b1->end)
  	{
  	  /* We moved all the insns in the basic block.
  	     Emit a note after the last insn and update the
*************** can_schedule_ready_p (insn)
*** 2139,2147 ****
  	  /* We took insns from the end of the basic block,
  	     so update the end of block boundary so that it
  	     points to the first insn we did not move.  */
! 	  b1->end = PREV_INSN (temp);
  	}
!       else if (temp == b1->head)
  	{
  	  /* We took insns from the start of the basic block,
  	     so update the start of block boundary so that
--- 2110,2118 ----
  	  /* We took insns from the end of the basic block,
  	     so update the end of block boundary so that it
  	     points to the first insn we did not move.  */
! 	  b1->end = PREV_INSN (insn);
  	}
!       else if (insn == b1->head)
  	{
  	  /* We took insns from the start of the basic block,
  	     so update the start of block boundary so that
*************** add_branch_dependences (head, tail)
*** 2361,2377 ****
  	  CANT_MOVE (insn) = 1;
  
  	  last = insn;
- 	  /* Skip over insns that are part of a group.
- 	     Make each insn explicitly depend on the previous insn.
- 	     This ensures that only the group header will ever enter
- 	     the ready queue (and, when scheduled, will automatically
- 	     schedule the SCHED_GROUP_P block).  */
- 	  while (SCHED_GROUP_P (insn))
- 	    {
- 	      rtx temp = prev_nonnote_insn (insn);
- 	      add_dependence (insn, temp, REG_DEP_ANTI);
- 	      insn = temp;
- 	    }
  	}
  
        /* Don't overrun the bounds of the basic block.  */
--- 2332,2337 ----
*************** add_branch_dependences (head, tail)
*** 2393,2402 ****
  
  	add_dependence (last, insn, REG_DEP_ANTI);
  	INSN_REF_COUNT (insn) = 1;
- 
- 	/* Skip over insns that are part of a group.  */
- 	while (SCHED_GROUP_P (insn))
- 	  insn = prev_nonnote_insn (insn);
        }
  }
  
--- 2353,2358 ----
Index: sched-ebb.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-ebb.c,v
retrieving revision 1.17.16.1
diff -c -p -r1.17.16.1 sched-ebb.c
*** sched-ebb.c	26 Sep 2002 15:35:48 -0000	1.17.16.1
--- sched-ebb.c	30 Sep 2002 15:33:54 -0000
*************** init_ready_list (ready)
*** 88,101 ****
       Count number of insns in the target block being scheduled.  */
    for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
      {
!       rtx next;
! 
!       if (! INSN_P (insn))
! 	continue;
!       next = NEXT_INSN (insn);
! 
!       if (INSN_DEP_COUNT (insn) == 0
! 	  && (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
  	ready_add (ready, insn);
        if (!(SCHED_GROUP_P (insn)))
  	target_n_insns++;
--- 88,94 ----
       Count number of insns in the target block being scheduled.  */
    for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
      {
!       if (INSN_DEP_COUNT (insn) == 0)
  	ready_add (ready, insn);
        if (!(SCHED_GROUP_P (insn)))
  	target_n_insns++;
Index: haifa-sched.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/haifa-sched.c,v
retrieving revision 1.211.10.1
diff -c -p -r1.211.10.1 haifa-sched.c
*** haifa-sched.c	25 Sep 2002 19:11:07 -0000	1.211.10.1
--- haifa-sched.c	30 Sep 2002 15:33:54 -0000
*************** move_insn (insn, last)
*** 1742,1766 ****
  {
    rtx retval = NULL;
  
-   /* If INSN has SCHED_GROUP_P set, then issue it and any other
-      insns with SCHED_GROUP_P set first.  */
-   while (SCHED_GROUP_P (insn))
-     {
-       rtx prev = PREV_INSN (insn);
- 
-       /* Move a SCHED_GROUP_P insn.  */
-       move_insn1 (insn, last);
-       /* If this is the first call to reemit_notes, then record
- 	 its return value.  */
-       if (retval == NULL_RTX)
- 	retval = reemit_notes (insn, insn);
-       else
- 	reemit_notes (insn, insn);
-       /* Consume SCHED_GROUP_P flag.  */
-       SCHED_GROUP_P (insn) = 0;
-       insn = prev;
-     }
- 
    /* Now move the first non SCHED_GROUP_P insn.  */
    move_insn1 (insn, last);
  
--- 1742,1747 ----
*************** move_insn (insn, last)
*** 1771,1776 ****
--- 1752,1759 ----
    else
      reemit_notes (insn, insn);
  
+   SCHED_GROUP_P (insn) = 0;
+ 
    return retval;
  }
  
*************** set_priorities (head, tail)
*** 2307,2314 ****
        if (GET_CODE (insn) == NOTE)
  	continue;
  
!       if (!(SCHED_GROUP_P (insn)))
! 	n_insn++;
        (void) priority (insn);
      }
  
--- 2290,2296 ----
        if (GET_CODE (insn) == NOTE)
  	continue;
  
!       n_insn++;
        (void) priority (insn);
      }
  
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.184.4.3
diff -c -p -r1.184.4.3 ia64.c
*** config/ia64/ia64.c	26 Sep 2002 15:35:49 -0000	1.184.4.3
--- config/ia64/ia64.c	30 Sep 2002 15:33:55 -0000
*************** ia64_adjust_cost (insn, link, dep_insn, 
*** 5474,5597 ****
       rtx insn, link, dep_insn;
       int cost;
  {
-   enum attr_type dep_type;
    enum attr_itanium_class dep_class;
    enum attr_itanium_class insn_class;
-   rtx dep_set, set, src, addr;
  
!   if (GET_CODE (PATTERN (insn)) == CLOBBER
!       || GET_CODE (PATTERN (insn)) == USE
!       || GET_CODE (PATTERN (dep_insn)) == CLOBBER
!       || GET_CODE (PATTERN (dep_insn)) == USE
!       /* @@@ Not accurate for indirect calls.  */
!       || GET_CODE (insn) == CALL_INSN
!       || ia64_safe_type (insn) == TYPE_S)
!     return 0;
! 
!   if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT
!       || REG_NOTE_KIND (link) == REG_DEP_ANTI)
!     return 0;
  
-   dep_type = ia64_safe_type (dep_insn);
-   dep_class = ia64_safe_itanium_class (dep_insn);
    insn_class = ia64_safe_itanium_class (insn);
! 
!   /* Compares that feed a conditional branch can execute in the same
!      cycle.  */
!   dep_set = ia64_single_set (dep_insn);
!   set = ia64_single_set (insn);
! 
!   if (dep_type != TYPE_F
!       && dep_set
!       && GET_CODE (SET_DEST (dep_set)) == REG
!       && PR_REG (REGNO (SET_DEST (dep_set)))
!       && GET_CODE (insn) == JUMP_INSN)
      return 0;
  
-   if (dep_set && GET_CODE (SET_DEST (dep_set)) == MEM)
-     {
-       /* ??? Can't find any information in the documenation about whether
- 	 a sequence
- 	   st [rx] = ra
- 	   ld rb = [ry]
- 	 splits issue.  Assume it doesn't.  */
-       return 0;
-     }
- 
-   src = set ? SET_SRC (set) : 0;
-   addr = 0;
-   if (set)
-     {
-       if (GET_CODE (SET_DEST (set)) == MEM)
- 	addr = XEXP (SET_DEST (set), 0);
-       else if (GET_CODE (SET_DEST (set)) == SUBREG
- 	       && GET_CODE (SUBREG_REG (SET_DEST (set))) == MEM)
- 	addr = XEXP (SUBREG_REG (SET_DEST (set)), 0);
-       else
- 	{
- 	  addr = src;
- 	  if (GET_CODE (addr) == UNSPEC && XVECLEN (addr, 0) > 0)
- 	    addr = XVECEXP (addr, 0, 0);
- 	  while (GET_CODE (addr) == SUBREG || GET_CODE (addr) == ZERO_EXTEND)
- 	    addr = XEXP (addr, 0);
- 	  if (GET_CODE (addr) == MEM)
- 	    addr = XEXP (addr, 0);
- 	  else
- 	    addr = 0;
- 	}
-     }
- 
-   if (addr && GET_CODE (addr) == POST_MODIFY)
-     addr = XEXP (addr, 0);
- 
-   set = ia64_single_set (dep_insn);
- 
-   if ((dep_class == ITANIUM_CLASS_IALU
-        || dep_class == ITANIUM_CLASS_ILOG
-        || dep_class == ITANIUM_CLASS_LD)
-       && (insn_class == ITANIUM_CLASS_LD
- 	  || insn_class == ITANIUM_CLASS_ST))
-     {
-       if (! addr || ! set)
- 	abort ();
-       /* This isn't completely correct - an IALU that feeds an address has
- 	 a latency of 1 cycle if it's issued in an M slot, but 2 cycles
- 	 otherwise.  Unfortunately there's no good way to describe this.  */
-       if (reg_overlap_mentioned_p (SET_DEST (set), addr))
- 	return cost + 1;
-     }
- 
-   if ((dep_class == ITANIUM_CLASS_IALU
-        || dep_class == ITANIUM_CLASS_ILOG
-        || dep_class == ITANIUM_CLASS_LD)
-       && (insn_class == ITANIUM_CLASS_MMMUL
- 	  || insn_class == ITANIUM_CLASS_MMSHF
- 	  || insn_class == ITANIUM_CLASS_MMSHFI))
-     return 3;
- 
-   if (dep_class == ITANIUM_CLASS_FMAC
-       && (insn_class == ITANIUM_CLASS_FMISC
- 	  || insn_class == ITANIUM_CLASS_FCVTFX
- 	  || insn_class == ITANIUM_CLASS_XMPY))
-     return 7;
- 
-   if ((dep_class == ITANIUM_CLASS_FMAC
-        || dep_class == ITANIUM_CLASS_FMISC
-        || dep_class == ITANIUM_CLASS_FCVTFX
-        || dep_class == ITANIUM_CLASS_XMPY)
-       && insn_class == ITANIUM_CLASS_STF)
-     return 8;
- 
-   /* Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
-      but HP engineers say any non-MM operation.  */
-   if ((dep_class == ITANIUM_CLASS_MMMUL
-        || dep_class == ITANIUM_CLASS_MMSHF
-        || dep_class == ITANIUM_CLASS_MMSHFI)
-       && insn_class != ITANIUM_CLASS_MMMUL
-       && insn_class != ITANIUM_CLASS_MMSHF
-       && insn_class != ITANIUM_CLASS_MMSHFI)
-     return 4;
- 
    return cost;
  }
  
--- 5474,5491 ----
       rtx insn, link, dep_insn;
       int cost;
  {
    enum attr_itanium_class dep_class;
    enum attr_itanium_class insn_class;
  
!   if (REG_NOTE_KIND (link) != REG_DEP_OUTPUT)
!     return cost;
  
    insn_class = ia64_safe_itanium_class (insn);
!   dep_class = ia64_safe_itanium_class (dep_insn);
!   if (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF
!       || insn_class == ITANIUM_CLASS_ST || insn_class == ITANIUM_CLASS_STF)
      return 0;
  
    return cost;
  }
  
*************** ia64_sched_init (dump, sched_verbose, ma
*** 5649,5654 ****
--- 5543,5558 ----
       int sched_verbose ATTRIBUTE_UNUSED;
       int max_ready ATTRIBUTE_UNUSED;
  {
+ #ifdef ENABLE_CHECKING
+   rtx insn;
+   
+   if (reload_completed)
+     for (insn = NEXT_INSN (current_sched_info->prev_head);
+ 	 insn != current_sched_info->next_tail;
+ 	 insn = NEXT_INSN (insn))
+       if (SCHED_GROUP_P (insn))
+ 	abort ();
+ #endif
    last_scheduled_insn = NULL_RTX;
    init_insn_group_barriers ();
  }
Index: config/ia64/ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.90.10.2
diff -c -p -r1.90.10.2 ia64.md
*** config/ia64/ia64.md	25 Sep 2002 19:11:09 -0000	1.90.10.2
--- config/ia64/ia64.md	30 Sep 2002 15:33:55 -0000
***************
*** 1097,1103 ****
  (define_bypass  3 "1_ld" "1_ld"  "ia64_ld_address_bypass_p")
  (define_bypass  3 "1_ld" "1_st"  "ia64_st_address_bypass_p")
  
! (define_bypass  4 "1_mmmul,1_mmshf" "1_ialu,1_ilog,1_ishf,1_st,1_ld")
  ;; ??? how to describe that if scheduled < 4 cycle then latency is 10 cycles.
  ;; (define_bypass  10 "1_mmmul,1_mmshf" "1_ialu,1_ilog,1_ishf,1_st,1_ld")
  
--- 1097,1110 ----
  (define_bypass  3 "1_ld" "1_ld"  "ia64_ld_address_bypass_p")
  (define_bypass  3 "1_ld" "1_st"  "ia64_st_address_bypass_p")
  
! ;; Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
! ;;      but HP engineers say any non-MM operation.
! (define_bypass  4 "1_mmmul,1_mmshf"
!      "1_br,1_fcmp,1_fcvtfx,1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,\
!       1_frbr,1_frfr,1_frpr,1_ialu,1_icmp,1_ilog,1_ishf,1_ld,1_chk_s,\
!       1_long_i,1_rse_m,1_sem,1_stf,1_st,1_syst_m0,1_syst_m,\
!       1_tbit,1_toar_i,1_toar_m,1_tobr,1_tofr,1_topr,1_xmpy,1_xtd")
! 
  ;; ??? how to describe that if scheduled < 4 cycle then latency is 10 cycles.
  ;; (define_bypass  10 "1_mmmul,1_mmshf" "1_ialu,1_ilog,1_ishf,1_st,1_ld")
  


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