🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #1270

Performance feature

#1270
From: James Cownie
Date: Thu, 05 Nov 1992 14:14
80 lines
2792 bytes
Using the cygnus-2.0.2 release of GCC running on Solaris 2.0 on a
SPARC I have observed the following non-fatal "feature".

Code in "do_jump (exp, if_false_label, if_true_label)" in the file
expr.c has the effect of narrowing bitwise and operations to smaller
modes than those written in the code. This occurs even if the machine
description macros set SLOW_BYTE_ACCESS to be 1.

The effect of this can be that code like this --

int Poll_Event (event)
unsigned  int *event;
{
   unsigned  int *a = &event[1];

   return (a[0] & 1) ? 1:0;
}
 
when compiled thus :-
gcc -S foo.c -O2 

generates code like this
	.file	"foo.c"
	.section	".text"
	.align 4
	.global Poll_Event
	.type	 Poll_Event,#function
Poll_Event:
	!#PROLOGUE# 0
	!#PROLOGUE# 1
	ldub [%o0+7],%o0
	retl
	and %o0,1,%o0
.LLfe1:
	.size	 Poll_Event,.LLfe1-Poll_Event
	.ident	"GCC: (GNU) cygnus-2.0.2"

which accesses store as a byte, rather than as an int (which was what
the user said, and which should be faster than the byte access).

The relevant compiler code is (as above) in "do_jump" in expr.c, and
looks like this

    case BIT_AND_EXPR:
      /* If we are AND'ing with a small constant, do this comparison in the
	 smallest type that fits.  If the machine doesn't have comparisons
	 that small, it will be converted back to the wider comparison.
	 This helps if we are testing the sign bit of a narrower object.
	 combine can't do this for us because it can't know whether a
	 ZERO_EXTRACT or a compare in a smaller mode exists, but we do.  */
      if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
	  && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_INT
	  && (i = floor_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))) >= 0
	  && (type = type_for_size (i + 1, 1)) != 0
	  && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp)))
	{
	  do_jump (convert (type, exp), if_false_label, if_true_label);
	  break;
	}
      goto normal;

I'd suggest that maybe this should be surrounded with
#if (!SLOW_BYTE_ACCESS)
...
#endif

but maybe there's a better solution ?

Thanks in advance. Keep up the good work.

-- Jim
James Cownie 
Meiko Limited
650 Aztec West
Bristol BS12 4SD
England

Phone : +44 454 616171
FAX   : +44 454 618188
E-Mail: jim@meiko.co.uk or jim@meiko.com
Technical Details
Message-ID: <9211051414.AA00474@hub.meiko.co.uk>
Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!sun-barr!ames!saimiri.primate.wisc.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!meiko.co.UK!jim

Show Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!sun-barr!ames!saimiri.primate.wisc.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!meiko.co.UK!jim
From: jim@meiko.co.UK (James Cownie)
Subject: Performance feature
Message-ID: <9211051414.AA00474@hub.meiko.co.uk>
Sender: gnulists@ai.mit.edu
Organization: GNUs Not Usenet
Distribution: gnu
Date: Thu, 5 Nov 1992 14:14:14 GMT
Approved: bug-gcc@prep.ai.mit.edu
Lines: 82