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]

Patch for PR target/20632


David Mosberger wrote:

Yesterday I posted this GCC bug report:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20632

I wouldn't normally mention this here, but I thought it might be of
some interest because it describes a stall condition that occurs on
all McKinley-derived cores.  Specifically, if you issue an F-unit
instruction within 6 cycles of reading ar.bsp, ar.bspstore, ar.unat,
ar.rnat, or cr.ifs, the processor will stall for the remainder of that
6 cycle window.  I found this the hard way while tuning the ia64 linux
syscall path, but it's easy to demonstrate with the attached program
and I confirmed with the chip folks that this is indeed the expect (if
not desired/ideal) behavior.

The moral of the story is that it's generally a good idea to avoid
F-unit instructions and, in particular, F-unit NOPs.

Now, as for GCC: does anybody on this list understand how the new
scheduler/bundler works?  I suspect it's easy to fix current GCC to
avoid F (and B) unit NOPs for someone who's already somewhat familiar
with that code.



 The following patch changes ia64 gcc behaviour in choosing nops.
With the patch F nops will be used only if usage of the other nops is
not possible.

The patch improves SPECFP2000 by 0.7% (from 442 to 445 on 1.4Ghz
itanium2) mainly because of big improvement (about 11%) on art
benchmark.  SPECINT2000 rate is not changed.

The patch has been sucessfully tested by bootstrap.

Jim, is the changes in ia64.c ok for you.  After your formal approval
the changes I'll commit the patch.

2005-03-31 Vladimir Makarov <vmakarov@redhat.com>

	* genautomata.c (first_cycle_unit_presence): Check all alternative
	states for unit presence.

	* doc/md.texi: Remove remark about impossibility to query unit
	presence in non nondeterministic automaton state.
	
	* config/ia64/ia64.c (get_template): Change order of unit querying.

Index: genautomata.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genautomata.c,v
retrieving revision 1.61
diff -c -d -p -r1.61 genautomata.c
*** genautomata.c	21 Feb 2005 14:39:49 -0000	1.61
--- genautomata.c	31 Mar 2005 16:53:56 -0000
*************** copy_equiv_class (vla_ptr_t *to, const v
*** 6120,6134 ****
  static int
  first_cycle_unit_presence (state_t state, int unit_num)
  {
!   int presence_p;
  
    if (state->component_states == NULL)
!     presence_p = test_unit_reserv (state->reservs, 0, unit_num);
    else
!     presence_p
!       = test_unit_reserv (state->component_states->state->reservs,
! 			  0, unit_num);
!   return presence_p;
  }
  
  /* The function returns nonzero value if STATE is not equivalent to
--- 6120,6138 ----
  static int
  first_cycle_unit_presence (state_t state, int unit_num)
  {
!   alt_state_t alt_state;
  
    if (state->component_states == NULL)
!     return test_unit_reserv (state->reservs, 0, unit_num);
    else
!     {
!       for (alt_state = state->component_states;
! 	   alt_state != NULL;
! 	   alt_state = alt_state->next_sorted_alt_state)
! 	if (test_unit_reserv (alt_state->state->reservs, 0, unit_num))
! 	  return true;
!     }
!   return false;
  }
  
  /* The function returns nonzero value if STATE is not equivalent to
Index: doc/md.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/md.texi,v
retrieving revision 1.126
diff -c -d -p -r1.126 md.texi
*** doc/md.texi	5 Mar 2005 19:56:29 -0000	1.126
--- doc/md.texi	31 Mar 2005 16:53:56 -0000
*************** the treatment of operator @samp{|} in th
*** 6232,6240 ****
  usual treatment of the operator is to try the first alternative and,
  if the reservation is not possible, the second alternative.  The
  nondeterministic treatment means trying all alternatives, some of them
! may be rejected by reservations in the subsequent insns.  You can not
! query functional unit reservations in nondeterministic automaton
! states.
  
  @item
  @dfn{progress} means output of a progress bar showing how many states
--- 6232,6238 ----
  usual treatment of the operator is to try the first alternative and,
  if the reservation is not possible, the second alternative.  The
  nondeterministic treatment means trying all alternatives, some of them
! may be rejected by reservations in the subsequent insns.
  
  @item
  @dfn{progress} means output of a progress bar showing how many states
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.350
diff -c -d -p -r1.350 ia64.c
*** config/ia64/ia64.c	17 Mar 2005 17:35:16 -0000	1.350
--- config/ia64/ia64.c	31 Mar 2005 16:53:56 -0000
*************** get_template (state_t state, int pos)
*** 6489,6510 ****
    switch (pos)
      {
      case 3:
!       if (cpu_unit_reservation_p (state, _0mii_))
! 	return 0;
!       else if (cpu_unit_reservation_p (state, _0mmi_))
  	return 1;
!       else if (cpu_unit_reservation_p (state, _0mfi_))
! 	return 2;
!       else if (cpu_unit_reservation_p (state, _0mmf_))
! 	return 3;
!       else if (cpu_unit_reservation_p (state, _0bbb_))
! 	return 4;
!       else if (cpu_unit_reservation_p (state, _0mbb_))
! 	return 5;
!       else if (cpu_unit_reservation_p (state, _0mib_))
! 	return 6;
        else if (cpu_unit_reservation_p (state, _0mmb_))
  	return 7;
        else if (cpu_unit_reservation_p (state, _0mfb_))
  	return 8;
        else if (cpu_unit_reservation_p (state, _0mlx_))
--- 6489,6510 ----
    switch (pos)
      {
      case 3:
!       if (cpu_unit_reservation_p (state, _0mmi_))
  	return 1;
!       else if (cpu_unit_reservation_p (state, _0mii_))
! 	return 0;
        else if (cpu_unit_reservation_p (state, _0mmb_))
  	return 7;
+       else if (cpu_unit_reservation_p (state, _0mib_))
+ 	return 6;
+       else if (cpu_unit_reservation_p (state, _0mbb_))
+ 	return 5;
+       else if (cpu_unit_reservation_p (state, _0bbb_))
+ 	return 4;
+       else if (cpu_unit_reservation_p (state, _0mmf_))
+ 	return 3;
+       else if (cpu_unit_reservation_p (state, _0mfi_))
+ 	return 2;
        else if (cpu_unit_reservation_p (state, _0mfb_))
  	return 8;
        else if (cpu_unit_reservation_p (state, _0mlx_))
*************** get_template (state_t state, int pos)
*** 6512,6533 ****
        else
  	abort ();
      case 6:
!       if (cpu_unit_reservation_p (state, _1mii_))
! 	return 0;
!       else if (cpu_unit_reservation_p (state, _1mmi_))
  	return 1;
!       else if (cpu_unit_reservation_p (state, _1mfi_))
! 	return 2;
!       else if (_1mmf_ >= 0 && cpu_unit_reservation_p (state, _1mmf_))
! 	return 3;
!       else if (cpu_unit_reservation_p (state, _1bbb_))
! 	return 4;
!       else if (cpu_unit_reservation_p (state, _1mbb_))
! 	return 5;
!       else if (cpu_unit_reservation_p (state, _1mib_))
! 	return 6;
        else if (cpu_unit_reservation_p (state, _1mmb_))
  	return 7;
        else if (cpu_unit_reservation_p (state, _1mfb_))
  	return 8;
        else if (cpu_unit_reservation_p (state, _1mlx_))
--- 6512,6533 ----
        else
  	abort ();
      case 6:
!       if (cpu_unit_reservation_p (state, _1mmi_))
  	return 1;
!       else if (cpu_unit_reservation_p (state, _1mii_))
! 	return 0;
        else if (cpu_unit_reservation_p (state, _1mmb_))
  	return 7;
+       else if (cpu_unit_reservation_p (state, _1mib_))
+ 	return 6;
+       else if (cpu_unit_reservation_p (state, _1mbb_))
+ 	return 5;
+       else if (cpu_unit_reservation_p (state, _1bbb_))
+ 	return 4;
+       else if (_1mmf_ >= 0 && cpu_unit_reservation_p (state, _1mmf_))
+ 	return 3;
+       else if (cpu_unit_reservation_p (state, _1mfi_))
+ 	return 2;
        else if (cpu_unit_reservation_p (state, _1mfb_))
  	return 8;
        else if (cpu_unit_reservation_p (state, _1mlx_))

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