jthomas@NMSU.EDU (04/10/89)
First, my compliments on the code gcc produces -O !!
(What do I know? Well, I've been observing compiled code for ~20 years. I
was the DEC F40 and Fortran-10 maintainer for a while, ...)
I would like to point to one slight deoptimization that happens in the 68k
code generation. The following program is a chopped version of a larger
file that was my first (but definitely not last!) experiment (well, maybe
it was my only "experiment" - now I just use gcc -O always).
------------------------------ code ------------------------------
union PointCalculateFormat
{
struct
{
short int IntegerPart;
unsigned short int FractionPart;
} DividedValue;
struct
{
int CombinedParts;
} CombinedValue;
};
#define PointFormatOneHalf 0x8000 /* value for 1/2 in above format */
struct XPointArray {
short x,y;
};
extern void foo(struct XPointArray *x); /* dummy to cause code generation */
void DrawALine(FromX, /* starting X coordinate */
FromY, /* starting Y coordinate */
ToX, /* ending X coordinate */
ToY) /* ending Y coordinate */
int FromX, FromY, ToX, ToY;
{
union PointCalculateFormat CurrentX, CurrentY; /* moving X & Y positions */
int XIncrement, YIncrement; /* delta values between adjacent points */
/* (actually in PointCalculateFormat, but */
/* only referenced in int format for speed */
int ConversionFactor; /* from ToX-FromX to above delta values */
struct XPointArray XPA; /* values for X plot points argument */
int StepIndex, NumberOfSteps; /* loop control */
NumberOfSteps = 10; /* dummy */
/* figure out the deltas between from and to coordinate values */
XIncrement = ToX - FromX;
YIncrement = ToY - FromY;
/* set up initial values of current X and Y values
* The integer parts are copies of FromX and FromY.
* The fraction parts are 1/2 to automagically provide roundoff for the
* coordinate which is not going in unit steps.
*/
CurrentX.DividedValue.IntegerPart = (short) FromX;
CurrentX.DividedValue.FractionPart = PointFormatOneHalf;
CurrentY.DividedValue.IntegerPart = (short) FromY;
CurrentY.DividedValue.FractionPart = PointFormatOneHalf;
/* now actually calculate and plot the points */
for (StepIndex = 0; StepIndex < NumberOfSteps; StepIndex++)
{
CurrentX.CombinedValue.CombinedParts += XIncrement;
CurrentY.CombinedValue.CombinedParts += YIncrement;
XPA.x = CurrentX.DividedValue.IntegerPart;
XPA.y = CurrentY.DividedValue.IntegerPart;
foo(&XPA);
}
}
------------------------------end of code------------------------------
When the above program is compiled gcc -S, the lines for XPA.x = and
XPA.y = produce:
movew a6@(-4),a6@(-24)
movew a6@(-8),a6@(-22)
, whereas when compiled gcc -O -S they produce:
bfexts d4{#0:#16},d0
movew d0,a6@(-4)
bfexts d3{#0:#16},d0
movew d0,a6@(-2)
. (In the larger program, or possibly it was with 1.33, the code used
movew, extl, movew . I will assume {yeah, I know that's the wrong thing to
do, but I expect that to change if you change this} that is because of the
same things that are happening here.)
The optimized version "probably" should use:
movew d4,a6@(-4)
movew d3,a6@(-2)
?
The compiler is:
gcc version 1.34
, compiled with:
tm-sun3-nfp.h
m68k.md
, under:
SunOS v3.5
, on a:
Sun 3