PHULVER%OCVAXC@VB.CC.CMU.EDU (Barron Hulver x8290) (04/05/88)
Is FORTRAN faster than C? probably.
Which one do I use? C.
oh well...
In order of peep-hole optimizing efficiency, here is
how I would rate various compilers:
FORTRAN
C
PASCAL
BASIC
BASIC
COBOL
I list basic twice because it depends on whether you use
the /LINES qualifier (the default) when compiling.
Also, whether your longwords are on longword boundaries is
a significant performance factor on most cpus. VAX C does
seem to align longwords on longword boundaries.
I would assume FORTRAN does as well but I have not checked
this.
Finally, for production C programs be sure to link to make
it shareable:
$ LINK program, sys$input/options
sys$library:vaxcrtl/share
and not:
$ LINK program, sys$library:vaxcrtl
...Barron Hulver
Oberlin College
phulver @ oberlin (bitnet)
phulver % ocvaxa @ vb.cc.cmu.edu (arpanet)
ocvaxa::phulver (ccnet)
Here are the programs that I used to reach the above
conclusions.
------------------ TABLE OF CONTENTS -------------------
PEEPB.BAS;7
PEEPC.C;7
PEEPCOMPILE.COM;3
PEEPF.FOR;9
PEEPL.COB;14
PEEPP.PAS;4
PEEPPRINT.COM;1
ALIGN.COM;2
ALIGN.RUN;2
ALIGN.C;12
------------- PEEPB.BAS;7 ------------------
10 rem /* peephole optimization */
20 declare integer long n,m
30 rem /* redundant load/store test */
40 n = 1%
50 m = 1%
60 rem /* test for unreachable code */
70 if (n > 0%) then goto 100
80 goto 200
90 print "label_start";
100 print "label_1";
110 goto 200
199 rem /* test for flow of control optimization */
200 if (n > 0%) goto 1100
210 goto 1500
1100 print "label_11"
1110 goto 9000
1500 print "label_15"
1510 goto 9000
9000 print "label_end"
9100 rem /* algebraic simplification */
9110 n = n + 0%
9120 n = n * 1%
9200 rem /* reduction in strength (add/subtract from itselt or bit shift 1 */
9210 n = n * 2%
9220 n = n / 2%
9300 rem /* reduction in strength (bit shift 3)
9310 m = n * 8%
9320 m = n / 8%
9400 rem /* machine idiom. (replace add with increment instruction */
9410 n = n + 1%
9500 rem /* no use. detect a variable assignment that is not used */
9510 m = n + 17%
9520 m = n + 14%
9600 rem /* test for constant folding */
9610 n = 3% + 4% + 7%
9620 n = 10% + 20% + 30%
9700 rem /* force a usage of the variables */
9710 print n,m
9999 end
------------- PEEPC.C;7 ------------------
/* peephole optimization */
main()
{
long int n,m;
/* redundant load/store test */
n = 1;
m = 1;
/* test for unreachable code */
if (n > 0) goto label_1;
goto label_2;
printf("label_start\n");
label_1:
printf("label_1\n");
goto label_2;
/* test for flow of control optimization */
label_2:
if (n > 0) goto label_11;
goto label_15;
label_11:
printf("label_11\n");
goto label_end;
label_15:
printf("label_15\n");
goto label_end;
label_end:
printf("label_end\n");
/* algebraic simplification */
n = n + 0;
n = n * 1;
/* reduction in strength (add/subtract from itself or bit shift 1) */
n = n * 2;
n = n / 2;
/* reduction in strength (bit shift 3) */
m = n * 8;
m = n / 8;
/* machine idiom. (replace add with increment instruction */
n = n + 1;
/* no use. detect a variable assignment that is not used */
m = n + 17;
m = n + 14;
/* test for constant folding */
n = 3 + 4 + 7;
n = 10 + 20 + 30;
/* force a usage of the variables */
printf("n: %d, m: %d\n", n, m);
}
------------- PEEPCOMPILE.COM;3 ------------------
$! BASIC
$ basic/list/machine peepb
$ basic/list=peepbn/machine/noopt peepb
$ basic/list=peepbo/machine/check=(nooverflow,nobounds)/nolines peepb
$!
$! C
$ cc/list/machine peepc
$ cc/list=peepcn/machine/noopt peepc
$!
$! COBOL
$ cobol/list/machine peepl
$ cobol/list=peepln/machine/noopt peepl
$!
$! FORTRAN
$ fortran/list/machine peepf
$ fortran/list=peepfn/machine/noopt peepf
$!
$! PASCAL
$ pascal/list/machine peepp
$ pascal/list=peeppn/machine/noopt peepp
------------- PEEPF.FOR;9 ------------------
c
c peephole optimization
c
implicit integer(a-z)
c /* redundant load/store test */
n = 1
m = 1
c /* test for unreachable code */
if (n .gt. 0) goto 1
goto 2
print *,'label_start'
1 print *,'label_1'
goto 2
c /* test for flow of control optimization */
2 if (n .gt. 0) goto 11
goto 15
11 print *,'label_11'
goto 99
15 print *,'label_15'
goto 99
99 print *,'label_end'
c /* algebraic simplification */
n = n + 0
n = n * 1
c /* reduction in strength (add/subtract from itself or bit shift 1 */
n = n * 2
n = n / 2
c /* reduction in strength (bit shift 3) */
m = n * 8
m = n / 8
c /* machine idiom. replace add with increment instruction */
n = n + 1
c /* no use. detect a variable assignment that is not used */
m = n + 17
m = n + 14
c /* force a usage of the variables */
write(8,1000) n,m
1000 format(x,i,5x,i)
stop
end
------------- PEEPL.COB;14 ------------------
IDENTIFICATION DIVISION.
PROGRAM-ID. PEEPL.
AUTHOR. BARRON L. HULVER.
*
* peephole optimization
*
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. X.
OBJECT-COMPUTER. X.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OUTFILE ASSIGN TO OUTFILE_LOG.
DATA DIVISION.
FILE SECTION.
FD OUTFILE
LABEL RECORDS ARE OMITTED,
DATA RECORD IS OUTFILE-RECORD.
01 OUTFILE-RECORD PIC X(133).
WORKING-STORAGE SECTION.
01 MY-VARIABLES.
03 N PIC S9(9) COMP.
03 M PIC S9(9) COMP.
PROCEDURE DIVISION.
00-START.
* /* Redundant load/store test */
MOVE 1 TO N.
MOVE 1 TO M.
* /* Test for unreachable code */
IF N GREATER THAN ZERO GO TO LABEL-1.
GO TO LABEL-2.
DISPLAY "Label_start".
LABEL-1.
DISPLAY "Label_1".
GO TO LABEL-2.
* /* Test for flow of control optimization */
LABEL-2.
IF N GREATER THAN 0 GO TO LABEL-11.
GO TO LABEL-15.
LABEL-11.
DISPLAY "Label_11".
GO TO LABEL-END.
LABEL-15.
DISPLAY "Label_15".
GO TO LABEL-END.
LABEL-END.
DISPLAY "Label_end".
* /* algebraic simplification */
ADD 0 TO N.
MULTIPLY N BY 1 GIVING N.
* /* reduction in strength (add/subtract from itself or bit shift 1 */
MULTIPLY N BY 2 GIVING N.
DIVIDE N BY 2 GIVING N.
* /* reduction in strength (bit shift 3)
COMPUTE M = N * 8.
COMPUTE M = N / 8.
* /* machine idiom. (replace add with increment instruction) */
COMPUTE N = N + 1.
* /* no use. detect a variable assignment that is not used */
COMPUTE M = N + 17.
COMPUTE M = N + 14.
* /* test for constant folding */
COMPUTE N = 3 + 4 + 7.
COMPUTE N = 10 + 20 + 30.
* /* force a usage of the variables */
DISPLAY N,M.
STOP RUN.
------------- PEEPP.PAS;4 ------------------
program peep (input, output);
var
n, m : integer;
label
label_1, label_2, label_11, label_15, label_end;
begin
{Redundant load/store test}
n := 1;
m := 1;
{Test for unreachable code}
if n > 0 then goto label_1;
goto label_2;
writeln('label_start');
label_1:
writeln('label_1');
goto label_2;
{Test for flow of control optimization}
label_2:
if n > 0 then goto label_11;
goto label_15;
label_11:
writeln('label_11');
goto label_end;
label_15:
writeln('label_15');
goto label_end;
label_end:
writeln('label_end');
{Algebraic simplification}
n := n + 0;
n := n * 1;
{Reduction in strength (add/subtract from itself or bit-shift 1)}
n := n * 2;
n := n div 2;
{Reduction in strength (bit-shift 3)}
m := n * 8;
m := n div 8;
{machine idiom. (replace add with increment instruction}
n := n + 1;
{no use. detect a variable assignment that is not used}
m := n + 17;
m := n + 14;
{test for constant folding}
n := 3 + 4 + 7;
n := 10 + 20 + 30;
{Force a usage of the variables}
writeln('n = ', n, 'm = ', m);
end.
------------- PEEPPRINT.COM;1 ------------------
$ print/head/name="src optim" -
peepb.bas, peepc.c, peepf.for, peepl.cob, peepp.pas
$ print/head/name="std optim" peep*.lis
$ print/head/name="no optim" peep%n.lis
------------- ALIGN.COM;2 ------------------
$ cc/list/machine align
$ link/map/full align, sys$input/options
sys$library:vaxcrtl/share
$ run align
------------- ALIGN.RUN;2 ------------------
@align
$ cc/list/machine align
$ link/map/full align, sys$input/options
sys$library:vaxcrtl/share
$ run align
..aligned? 0, 0, 0
..addr = J 254, B 278, J2 27C, M 280
..offset = 0, 0, 0
------------- ALIGN.C;12 ------------------
main()
{
static char junk;
static long int var_1;
static long int var_2;
static long int var_3;
static long int var_4;
static long int var_5;
static long int var_6;
static long int var_7;
static long int var_8;
static long int bigstuff;
static char junk2;
static long int morestuff;
static unsigned long junk_a;
static unsigned long big_a;
static unsigned long more_a;
static unsigned long junk_m;
static unsigned long big_m;
static unsigned long more_m;
junk_a = &junk;
junk_m = junk_a % 4;
big_a = &bigstuff;
big_m = big_a % 4;
more_a = &morestuff;
more_m = more_a % 4;
printf("..aligned? %d, %d, %d\n", junk, bigstuff, morestuff);
printf("..addr = J %8X, B %8X, J2 %8X, M %8X\n", junk_a, big_a, &junk2, more_a);
printf("..offset = %d, %d, %d\n", junk_m, big_m, more_m);
}
---------------------------------------------------------