You are on page 1of 8

Ex.

No:9 CONSTRUCTION OF DAG

AIM:
To write a C program to implement Directed Acyclic Graph

PROGRAM

#include<stdio.h>
#include<string.h>
int main()
{
int b,c=0,st[100],b_add=1000,j=0,i=0,k=0,flag=0,m=0,count=0;
char exp[100],tk[100],str[100][100];
const char delim[2]=" ";
char *token;
char a[10][10],t1[10][10],t2[10][10];

printf("\nEnter the expression : ");


gets(exp);

token = strtok(exp,delim);

while(token!=NULL)
{
strcpy(str[i],token);
token = strtok(NULL,delim);
i++;
}

for(j=0;j<i;j++)
{

if(strcmp(str[j],"(")==0)
{

if(flag==0)
{
while(strcmp(str[j],")")!=0)
{

strcpy(t1[k],str[j]);
k++;
j++;
flag=1;
}
}

else
{

while(strcmp(str[j],")")!=0)
{
strcpy(t2[m],str[j]);
m++;
j++;
}

}
}

else if(strcmp(str[j],"+")==0||strcmp(str[j],"-
“)==0||strcmp(str[j],"*")==0||strcmp(str[j],"/'"))
{
strcpy(a[0],str[j]);

}
}

printf("Three address code:\n");

printf("t1=\t");

for(i=0;i<k;i++)
{
printf("%s",t1[i+1]);
}

printf("\nt2=\t");

for(i=0;i<m;i++)
{
printf("%s",t2[i+1]);
}

printf("\n t3 = t1 %s t2",a[0]);
printf("\nDAG code\n");

for(i=0,j=0;i<k,j<m;i++,j++)
{
if(strcmp(t1[i],t2[j])==0)
{
count=1;
}
else
{

count=0;

}
}

if(count==1)
{
printf("t1=\t");

for(i=0;i<k;i++)
{
printf("%s",t1[i+1]);
}

printf("\nt1=\t");

for(i=0;i<m;i++)
{
printf("%s",t2[i+1]);
}

printf("\n t3 = t1 %s t1",a[0]);
}

getch();
return 0;
}

OUTPUT

Enter the expression : ( a * - b ) * ( a * - b )


Three address code:
t1= a*-b
t2= a*-b
t3 = t1 * t2
DAG code
t1= a*-b
t1= a*-b
t3 = t1 * t1*/

RESULT :
Thus the program to perform DAG logic has been implemented
Ex.No:10 IMPLEMENT THE BACK END OF THE COMPILER WHICH
TAKES THE THREE ADDRESS CODE AND PRODUCES THE 8086
ASSEMBLY LANGUAGE INSTRUCTIONS THAT CAN BE ASSEMBLED
AND RUN USING A 8086 ASSEMBLER. THE TARGET ASSEMBLY
INSTRUCTIONS CAN BE SIMPLE MOVE, ADD, SUB, JUMP. ALSO
SIMPLE ADDRESSING MODES ARE USED.
ALGORITHM
1) Start the program.
2) Get the three variables from statements and stored in the text file k.txt.
3) Compile the program and give the path of the source file.
4) Execute the program.
5) Target code for the given statement was produced.
6) Stop the program.

PROGRAM
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
void main()
{
int i=2,j=0,k=2,k1=0;
char ip[10],kk[10];
FILE *fp;
clrscr();
printf("\nEnter the filename of the intermediate code");
scanf("%s",&kk);
fp=fopen(kk,"r");
if(fp==NULL)
{
printf("\nError in Opening the file");
getch();
}
clrscr();
while(!feof(fp)){
fscanf(fp,"%s\n",ip);
printf("\t\t%s\n",ip);
}
rewind(fp);
printf("\n------------------------------\n");
printf("\tStatement \t\t target code\n");
printf("\n------------------------------\n");
while(!feof(fp))
{
fscanf(fp,"%s",ip);
printf("\t%s",ip);
printf("\t\tMOV%c,R%d\n\t",ip[i+k],j);
if(ip[i+1]=='+')
printf("\t\tADD");
elseprintf("\t\tSUB");
if(islower(ip[i]))
printf("%c,R%d\n\n",ip[i+k1],j);
else
printf("%c,%c\n",ip[i],ip[i+2]);
j++;
k1=2;
k=0;
}
printf("\n-------------------------------\n");
getch();
fclose(fp);
}
OUTPUT
Enter the filename of the intermediate code k.txt
X=a-b
Y=a-c
z=a+b
C=a-b
C=a-b

Statement target code

X=a-b
MOV b,R0
SUBa,R0
Y=a-c
MOV a,R1
SUBc,R1
z=a+b
MOV a,R2
ADDb,R2
C=a-b
MOV a,R3
SUBb,R3
C=a-b
MOV a,R4
SUBb,R4
RESULT
Thus the above the program is executed and the required output is obtained.
Ex.No:11 IMPLEMENTATION OF SIMPLE CODE OPTIMIZATION
TECHNIQUES (CONSTANT FOLDING, ETC.)
CONSTANT FOLDING
Constant folding is the simplest code optimization to understand. Let us suppose that you
write the statement x = 45 * 88; in your C program. A non-optimizing compiler will generate code
to multiply 45 by 88 and store the value in x. An optimizing compiler will detect that both 45 and
88 are constants, so their product will also be a constant. Hence it will find 45 * 88 = 3960 and
generate code that simply copies 3960 into x. This is constant folding, and means the calculation
is done just once, at compile time, rather than every time the program is run.
/* Demonstration of constant propagation */
#include <stdio.h>
int main()
{
int x, y, z;
x = 10;
y = x + 45;
z = y + 4;
printf ("The value of z = %d", z);
return 0;
}
COMMON SUB EXPRESSION ELIMINATION
Many a times, it happens that the same expression is evaluated at different places in the
same program and the values of the operands in the expression do not change in between the two
evaluations of that expression. For example, the program may evaluate say a * b at the beginning
and at the end. If the values of a and b do not change in between these two evaluations of a * b,
then instead of evaluating a * b again at the end, we can save the result of the evaluation of a * b
at the beginning in some temporary variable and use it at the end. This will help eliminate
redundant computations in the program. This optimization is called as common sub expression
elimination. Consider the following program that demonstrates it.
/* common subexpression elimination, and also of constant propagation */
#include <stdio.h>
int main()
{
int a, b;
int x, y, z;
scanf("%d %d", &a, &b);
x = a * b;
if(b >= 4)
{
y = a * b;
z = 0;
}
else
{
z = a * b * 4;
y = 0;
}
printf("x = %d, y = %d, z = %d\n", x, y, z);
return 0;
}
DEAD CODE ELIMINATION
Dead code is the code in the program that will never be executed for any input or other
conditions. A common example is an if statement. If the compiler finds out that the condition
inside the if is never going to be true, then the body of the if statement will never be executed. In
that case, the compiler can completely eliminate this dead code, thus saving the memory space
occupied by the code. The following program demonstrates dead code elimination.
#include <stdio.h>
int main()
{
int x;
scanf("%d", &x);
if(x < 0 && x > 0)
{
x = 99;
printf("Hello. Inside the if!!!");
}
return 0;
}
STRENGTH REDUCTION USING INDUCTION VARIABLE
One type of code optimization is strength reduction in which a "costly" operation is
replaced by a less expensive one. For example, the evaluation of x2 is much more efficient if we
multiply x by x rather than call the exponentiation routine. One place where this optimization can
be applied is in loops. Many times in a loop, one variable changes in synchronization with the loop
variable. Such a variable is called as induction variable. Induction variables give the compiler a
chance to apply strength reduction, as can be seen from the following program.
int main()
{
int i, j;
for(i = 0; i < 10; i++)
{
j = i * 7;
printf("i = %d, j = %d", i, j);
}
return 0;
}

RESULT
Thus the program to implementation of simple code optimization techniques is executed and the
required output is obtained.

You might also like