Related articles |
---|
C->C compiler? pinkus@comm.mot.com (1996-05-13) |
Re: C->C compiler? torbenm@diku.dk (1996-05-14) |
Re: C->C compiler? ashish@usl.edu (Ashish Ashtekar) (1996-05-14) |
Re: C->C compiler? sethml@ugcs.caltech.edu (1996-05-18) |
Re: C->C compiler? stefan.monnier@lia.di.epfl.ch (Stefan Monnier) (1996-05-21) |
From: | sethml@ugcs.caltech.edu (Seth M. LaForge) |
Newsgroups: | comp.compilers |
Date: | 18 May 1996 23:09:24 -0400 |
Organization: | California Institute of Technology |
References: | 96-05-085 |
Keywords: | C, optimize |
>Is there a C->C compiler which optimizes C code?
Actually, SGI has a C source-to-source optimizer, called copt,
available on IRIX 5.3 systems with their development package. It's
invoked during compilation if you include the -sopt flag on the
command line. I'm not sure quite what the point is, since it doesn't
seem to do anything that the standard global optimizer (uopt) doesn't
do. In any case, here's a little excerpt from the man page:
NAME
copt - C Scalar Optimizer
SYNOPSIS
/usr/lib/copt [ options ] ...
DESCRIPTION
Copt is a source-to-source optimizing C preprocessor that implements
several scalar optimizations, such as loop unrolling and inlining. Copt
optimizes C by restructuring certain portions of code. The amount of
code that is optimized varies depending on the value of certain copt
command line options, directives, and assertions.
Copt is normally invoked by using the -sopt option to cc(1), although it
can be run separately. When copt is used as part of a cc compilation,
the copt options below must appear in a comma-separated list following
the -sopt option without any intervening blanks.
Here's an example of some test code:
static int abs(int c) {
if (c < 0)
return -c;
else
return c;
}
int mult(int a, int b) {
int ctr;
int r = 0;
for (ctr = 0; ctr < abs(b); ++ctr)
if (b > 0)
r += a;
else
r -= a;
return r;
}
When run through copt with the command line
'/usr/lib/copt test.c -inl=abs -cmp=test.m', the output is:
static int abs( int c )
{
if (c < 0) {
return -c;
} else {
return c;
}
}
int mult( int a, int b )
{
int ctr;
int r;
int _Kii1;
int _Kii4;
r = 0;
ctr = 0;
if (b < 0) {
_Kii4 = -b;
} else {
_Kii4 = b;
}
_Kii1 = _Kii4;
if (b > 0) {
if (b < 0) {
while ( ctr < _Kii1 ) {
r += a;
ctr++;
_Kii1 = -b;
}
} else {
while ( ctr < _Kii1 ) {
r += a;
ctr++;
_Kii1 = b;
}
}
} else {
if (b < 0) {
while ( ctr < _Kii1 ) {
r -= a;
ctr++;
_Kii1 = -b;
}
} else {
while ( ctr < _Kii1 ) {
r -= a;
ctr++;
_Kii1 = b;
}
}
}
return r;
}
Fairly impressively, it will also optimize this:
int mult(int a, int b) {
int ctr;
int r = 0;
for (ctr = 0; ctr < b; ++ctr)
r += a;
return r;
}
into this:
int mult( int a, int b )
{
int ctr;
int r;
int _Kii1;
r = 0;
for ( ctr = 0; ctr<=b - 4; ctr+=4 ) {
r += a;
r += a;
r += a;
r += a;
}
_Kii1 = ctr;
for ( ctr = _Kii1; ctr<b; ctr++ ) {
r += a;
}
return ((((b)>(0) ? (b) : (0)) - 1) * a + a);
}
Note that it has figured out the return value - the loops are now dead
code. Pretty impressive.
> Many compilers for cheap microcontrollers churn out awful
> code. Since I cannot depend on these compilers to produce adequate
> code, I would like a compiler which optimizes the C code into
> unintelligible, yet fast, C code. Then I can use the compiler for
> the microcontroller to simply churn out object code. Of course this
> isn't ideal, but without an adequate compiler, I don't know of any
> other way to improve things.
Unfortunately, something like copt probably isn't going to help you much,
since it does high-level optimizations, and it looks like your compilers
are having trouble doing basic low-level optimizations, such as even decent
instruction selection. This kind of stuff really can't be done at the C
source level. You're probably best off looking for a better compiler, a
faster microprocessor, or an assembler and many free hours.
Seth
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.