CS 201

Project Description

Handed Out: April 21, 2009. Due date: May 29, 2009
You are to implement the following two algorithms for redundancy elimination that were discussed in the class and compare their performance.
  1. Global common subexpression elimination: recall that this algorithm is based upon available expressions analysis.
  2. Partial redundancy elimination: recall that this algorithm requires backward down-safety analysis followed by forward earliestness analysis.
  3. Instrumentation: instrument the code to compute and output the total number of expression evaluations performed during program execution.

The input will be provided in form of the intermediate language described below. Therefore the first task you must carry out is to read the program written in this intermediate language and construct the program's control flow graph.

You are also provided with an interpreter for this intermediate language using which you can verify the correctness of the optimized code and a translator to generate intermediate code for programs written in a subset of C. By computing the number of expression evaluations performed during execution of a set of programs optimized by each of the above two optimizations, you will be able to compare their relative effectiveness in optimizing the programs.

More details about the languages, tools, and output requirements can be found in the following:

Reporting problems

Please send email to mfeng@cs.ucr.edu. Thanks.

Mini C language

This language supports a subset of the features of C language. This is an example of Mini C program.
#define read(x)         scanf("%d", &(x))
#define print(x)        printf("%d\n", (x))

int main()
{
    int a, n, m, k, j, i, s0, s1, s2, s3, s4;

    read(a);
    n = a;
    m = a;
    k = a;

    while ( n > 0 ) {
        s3 = k + a;
        a = a + 1;

        s1 = a + m;
        if ( n % 2 == 0 ) {
            m = -m;
            s0 = a + m;
        }
        else {
            s0 = a + m;
            m = -m;
        }
        s2 = a + m;
        n = n - 1;

        a = a + 1;
        s4 = k + a;
    }
    s4 = k + a;
    print(s0);
    print(s1);
    print(s2);
    print(s3);
    print(s4);
}

The Intermediate Representation (IR) Language

Below is a list of some constructs of the intermediate language we will use in our projects this semester. This intermediate language is not designed to be a complete one (for example, function definitions and calls are omitted for now; more constructs will be added later if necessary); it is intended to be simple to parse, analyze, optimize, and generate. With this in mind, you should not be surprised that one line can only contain one such statement, including label declaration statements.

The following is the IR code for the above example:

	.	_a
	.	_n
	.	_m
	.	_k
	.	_j
	.	_i
	.	_s0
	.	_s1
	.	_s2
	.	_s3
	.	_s4
	.	t0
	.	t1
	.	t2
	.	t3
	.	t4
	.	t5
	.	t6
	.	t7
	.	t8
	.	t9
	.	t10
	.	t11
	.	t12
	.	p0


: START
	.<	_a
	=	_n, _a
	=	_m, _a
	=	_k, _a
: L2
	<=	p0, _n, 0
	?:=	L3, p0
	+	t0, _k, _a
	=	_s3, t0
	+	t1, _a, 1
	=	_a, t1
	+	t2, _a, _m
	=	_s1, t2
	%	t3, _n, 2
	!=	p0, t3, 0
	?:=	L0, p0
	-	t4, 0, _m
	=	_m, t4
	+	t5, _a, _m
	=	_s0, t5
	:=	L1
: L0
	+	t6, _a, _m
	=	_s0, t6
	-	t7, 0, _m
	=	_m, t7
: L1
	+	t8, _a, _m
	=	_s2, t8
	-	t9, _n, 1
	=	_n, t9
	+	t10, _a, 1
	=	_a, t10
	+	t11, _k, _a
	=	_s4, t11
	:=	L2
: L3
	+	t12, _k, _a
	=	_s4, t12
	.>	_s0
	.>	_s1
	.>	_s2
	.>	_s3
	.>	_s4

Specifications of IR language

Syntax Semantics
Variable declaration statements:
. name declares a name for a scalar variable
.[] name, n declares a name for a vector/array variable consisting of n (must be a positive whole number) elements, with name[0] being the first element
Copy statements:
= dst, src dst = src, src can be an immediate
array access statements:
=[] dst, src, index dst = src[index], index can be an immediate
[]= dst, index, src dst[index] = src, index can be an immediate
Input/Output statements:
.< dst read a value into dst from the standard input
.[]< dst, index read a value into dst[index] from the standard input
.> src write the value of src into the standard output
.[]> src, index write the value of src[index] into the standard output
fixed-point arithmetic op statements(one or both source operands can be immediates):
+ dst, src1, src2 dst = src1 + src2
- dst, src1, src2 dst = src1 - src2
* dst, src1, src2 dst = src1 * src2
/ dst, src1, src2 dst = src1 / src2
% dst, src1, src2 dst = src1 % src2
comparison statements(one or both source operands can be immediates):
< dst, src1, src2 dst = src1 < src2
<= dst, src1, src2 dst = src1 <= src2
!= dst, src1, src2 dst = src1 != src2
== dst, src1, src2 dst = src1 == src2
>= dst, src1, src2 dst = src1 >= src2
> dst, src1, src2 dst = src1 > src2
logical-op statements(one or both source operands can be immediates):
|| dst, src1, src2 logical OR, dst = src1 || src2
&& dst, src1, src2 logical AND, dst = src1 && src2
! dst, src logical NOT, dst = ! src
label declaration statements:
: label declares a label
branch statements:
:= label goto label
?:= label, predicate if predicate is true(1) goto label

Getting the Tools

The binaries are linux-x86 executables.

Download the front end (c2ir) which turns Mini C code into IR code.

Download the interpreter (irRun) which executes IR code. The interpreter executes code written in the mini-intermediate-represeantation language. It assumes that

Statistics are written in a file named "milRun.stat" in the current directory.

Download test cases in pp_test.tar.gz and use them to test/debug your program.

Output Requirements