921e5a0eb4
From-SVN: r14840
289 lines
8.5 KiB
C
289 lines
8.5 KiB
C
/* ----------------------------------------------------- *
|
|
| |
|
|
| PC Tech Journal Benchmark Series |
|
|
| C Code Optimization Benchmark |
|
|
| |
|
|
| Copyright (c) 1988 Ziff-Davis Publishing Company |
|
|
| |
|
|
| This benchmark code is designed to test the |
|
|
| code optimization techniques applied by a C |
|
|
| compiler. It does not produce meaningful results |
|
|
| when executed, or represent good style. |
|
|
| |
|
|
* ----------------------------------------------------- */
|
|
|
|
#include <string.h>
|
|
|
|
#define max_vector 2
|
|
#define constant5 5
|
|
|
|
typedef unsigned char uchar;
|
|
|
|
int i, j, k , l, m;
|
|
int i2, j2, k2;
|
|
int g3, h3, i3, k3, m3;
|
|
int i4, j4;
|
|
int i5, j5, k5;
|
|
|
|
double flt_1, flt_2, flt_3, flt_4, flt_5, flt_6;
|
|
|
|
int ivector[ 3 ];
|
|
uchar ivector2[ 3 ];
|
|
short ivector4[ 6 ];
|
|
int ivector5[ 203 ];
|
|
|
|
#ifndef NO_PROTOTYPES
|
|
void dead_code( int, char * );
|
|
void unnecessary_loop( void );
|
|
void loop_jamming( int );
|
|
void loop_unrolling( int );
|
|
int jump_compression ( int, int, int, int, int );
|
|
#else
|
|
void dead_code();
|
|
void unnecessary_loop();
|
|
void loop_jamming();
|
|
void loop_unrolling();
|
|
int jump_compression();
|
|
#endif
|
|
|
|
|
|
int main( argc, argv ) /* optbench */
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
/* ------------------------------ *
|
|
| Constant and copy propagation |
|
|
* ------------------------------ */
|
|
|
|
j4 = 2;
|
|
if( i2 < j4 && i4 < j4 )
|
|
i5 = 2;
|
|
|
|
j4 = k5;
|
|
if( i2 < j4 && i4 < j4 )
|
|
i5 = 3;
|
|
|
|
/* ---------------------------------------- *
|
|
| Constant folding, arithmetic identities |
|
|
| and redundant load/store operations |
|
|
* ---------------------------------------- */
|
|
|
|
i3 = 1 + 2;
|
|
flt_1 = 2.4 + 6.3;
|
|
i2 = 5;
|
|
j2 = i + 0;
|
|
k2 = i / 1;
|
|
i4 = i * 1;
|
|
i5 = i * 0;
|
|
|
|
#ifndef NO_ZERO_DIVIDE
|
|
/*
|
|
* Some compilers correctly recognize a zero divide
|
|
* error and do not generate any object code.
|
|
*/
|
|
/*
|
|
i2 = i / 0;
|
|
flt_2 = flt_1 / 0.0;
|
|
*/
|
|
#else
|
|
/*
|
|
printf( "This compiler handles divide-by-zero as an
|
|
error\n");
|
|
*/;
|
|
#endif
|
|
flt_3 = 2.4 / 1.0;
|
|
flt_4 = 1.0 + 0.0000001;
|
|
flt_5 = flt_6 * 0.0;
|
|
flt_6 = flt_2 * flt_3;
|
|
|
|
/* ------------ *
|
|
| Dead store |
|
|
* ------------ */
|
|
|
|
k3 = 1;
|
|
k3 = 1;
|
|
|
|
/* --------------------- *
|
|
| Strength reduction |
|
|
* --------------------- */
|
|
|
|
k2 = 4 * j5;
|
|
for( i = 0; i <= 5; i++ )
|
|
ivector4[ i ] = i * 2;
|
|
|
|
/* ----------- *
|
|
| Simple loop |
|
|
* ----------- */
|
|
|
|
j5 = 0;
|
|
k5 = 10000;
|
|
do {
|
|
k5 = k5 - 1;
|
|
j5 = j5 + 1;
|
|
i5 = ( k5 * 3 ) / ( j5 * constant5 );
|
|
} while ( k5 > 0 );
|
|
|
|
/* ----------------------------------- *
|
|
| Loop induction variable handling |
|
|
* ----------------------------------- */
|
|
|
|
for( i = 0; i < 100; i++)
|
|
ivector5[ i * 2 + 3 ] = 5;
|
|
|
|
/* ----------------------------- *
|
|
| Very busy expression handling |
|
|
* ----------------------------- */
|
|
|
|
if( i < 10 )
|
|
j5 = i5 + i2;
|
|
else
|
|
k5 = i5 + i2;
|
|
|
|
/* -------------------------------------------- *
|
|
| Check how the compiler generates the address |
|
|
| of a variable with a constant subscript, |
|
|
| copy propagation, and register propagation. |
|
|
* -------------------------------------------- */
|
|
|
|
ivector[ 0 ] = 1; /* constant address generation */
|
|
ivector[ i2 ] = 2; /* i2 should be a propagated value
|
|
*/
|
|
ivector[ i2 ] = 2; /* register propagation */
|
|
ivector[ 2 ] = 3; /* constant address generation */
|
|
|
|
|
|
/* ---------------------------------- *
|
|
| Common subexpression elimination |
|
|
* ---------------------------------- */
|
|
|
|
if(( h3 + k3 ) < 0 || ( h3 + k3 ) > 5 )
|
|
/*
|
|
printf("Common subexpression elimination\n");
|
|
|
|
*/;
|
|
else {
|
|
m3 = ( h3 + k3 ) / i3;
|
|
g3 = i3 + (h3 + k3);
|
|
}
|
|
/* --------------------------------------- *
|
|
| Invariant code motion |
|
|
| (j * k) can be moved outside the loop. |
|
|
* --------------------------------------- */
|
|
|
|
for( i4 = 0; i4 <= max_vector; i4++ )
|
|
ivector2[ i4 ] = j * k;
|
|
|
|
/* ---------------------------- *
|
|
| Function call with arguments |
|
|
* ---------------------------- */
|
|
|
|
dead_code( 1, "This line should not be printed" );
|
|
|
|
/* ------------------------------- *
|
|
| Function call without arguments |
|
|
* ------------------------------- */
|
|
|
|
unnecessary_loop();
|
|
|
|
exit (0);
|
|
|
|
} /* end of main */
|
|
|
|
|
|
/* --------------------------------------------- *
|
|
| Function: dead_code |
|
|
| Test for dead code and dead stores. |
|
|
| NO code should be generated. |
|
|
* ----------------------------------------------*/
|
|
|
|
void dead_code( a, b )
|
|
int a;
|
|
char *b;
|
|
{
|
|
int idead_store;
|
|
|
|
idead_store = a;
|
|
if( 0 )
|
|
/*
|
|
printf( "%s\n", b );
|
|
*/;
|
|
} /* end of dead_code */
|
|
|
|
/* ----------------------------------------------- *
|
|
| Function: unnecessary_loop |
|
|
| The loop in the following function is |
|
|
| not necessary since the value of the |
|
|
| assignment is constant. Ideally, the |
|
|
| loop should be optimized out. |
|
|
* ----------------------------------------------- */
|
|
|
|
void unnecessary_loop()
|
|
{
|
|
int x;
|
|
|
|
x = 0;
|
|
for( i = 0; i < 5; i++ ) /* loop should not be generated */
|
|
k5 = x + j5;
|
|
} /* end of unnecessary_loop */
|
|
|
|
/* --------------------------------------------- *
|
|
| Function: loop_jamming |
|
|
| The two loop in this function share |
|
|
| the same loop conditions and could |
|
|
| be coalesced together. |
|
|
* --------------------------------------------- */
|
|
|
|
void loop_jamming( x )
|
|
int x;
|
|
{
|
|
for( i = 0; i < 5; i++ )
|
|
k5 = x + j5 * i;
|
|
for( i = 0; i < 5; i++ )
|
|
i5 = x * k5 * i;
|
|
} /* end of loop_jamming */
|
|
|
|
/* ------------------------------------------------ *
|
|
| Function: loop_unrolling |
|
|
| The loop in this function should be |
|
|
| replaced with three inline word stores |
|
|
| using constant array arithmetic or by |
|
|
| specialized machine instructions used |
|
|
| for block memory initializiation. |
|
|
* ------------------------------------------------ */
|
|
|
|
void loop_unrolling( x )
|
|
int x;
|
|
{
|
|
for( i = 0; i < 6; i++ )
|
|
ivector4[ i ] = 0;
|
|
} /* end of loop_unrolling */
|
|
|
|
/* ------------------------------------------------------ *
|
|
| Function: jump_compression |
|
|
| This awkward code is useful to illustrate |
|
|
| jump chain compression. The goto 'end_1' can |
|
|
| be replaced by a direct jump to 'beg_1'. |
|
|
*------------------------------------------------------ */
|
|
|
|
int jump_compression ( i, j, k, l, m )
|
|
int i,j ,l, m;
|
|
{
|
|
beg_1:
|
|
if( i < j )
|
|
if( j < k )
|
|
if( k < l )
|
|
if ( l < m )
|
|
l += m;
|
|
else
|
|
goto end_1;
|
|
else
|
|
k += l;
|
|
else {
|
|
j += k;
|
|
end_1: goto beg_1;
|
|
}
|
|
else
|
|
i += j;
|
|
return( i + j + k + l + m );
|
|
} /* end of jump_compression */
|