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