编译原理中间代码优化Word版
- 格式:doc
- 大小:314.00 KB
- 文档页数:22
编译器设计中的语法分析和中间代码优化在编译器的设计中,语法分析和中间代码优化是两个重要的阶段。
语法分析是将输入的源代码转化为语法树的过程,而中间代码优化则是对生成的中间代码进行改进,以提高目标代码的执行效率和代码质量。
一、语法分析语法分析是编译器设计中的一个重要环节,它的主要任务是将输入的源代码转化为一棵语法树。
语法树是编译器在进一步处理代码之前生成的一种数据结构,它以树的形式表示代码的语法结构。
在语法分析阶段,编译器会对源代码进行词法分析,并根据语法规则构建语法树。
1. 词法分析词法分析是将源代码分解为一个个的词法单元(Token)的过程。
每个Token代表着源代码中的一个有意义的单词,如变量名、操作符、关键词等等。
编译器会通过词法分析器识别出这些词法单元,并将其传递给语法分析器进行后续处理。
2. 语法规则语法规则定义了源代码中各种语句和表达式的结构和组织方式。
在语法分析阶段,编译器会根据这些语法规则来构建语法树。
语法规则一般使用上下文无关文法(Context-Free Grammar)来描述。
3. 构建语法树通过词法分析和语法规则,编译器可以逐步构建语法树。
语法树是一种树状数据结构,以根节点表示整个代码块,每个内部节点表示一个语法单元,叶节点表示一个词法单元。
编译器可以根据语法树进行后续的语义分析和代码生成。
二、中间代码优化中间代码优化是编译器设计的另一重要环节,它的主要目标是改进生成的中间代码,以提高目标代码的执行效率和代码质量。
在中间代码优化阶段,编译器会对生成的中间代码进行分析和改进。
1. 常量传播常量传播是一种中间代码优化技术,它的目标是将程序中的常量表达式计算出实际的结果,并将结果用于后续的代码生成。
常量传播可以减少运行时的计算量,提高程序的执行效率。
2. 冗余代码消除冗余代码是指程序中不会被执行的代码,它们不会对程序的结果产生任何影响。
冗余代码消除可以通过分析中间代码的控制流来判断哪些代码是冗余的,并将其消除掉。
实验三中间的代码优化某些编译程序在中间代码或目标代码生产之后要对其进行优化,所谓优化就是对代码进行等价的变换。
而变换后的代码运行结果与变换前的代码运行结果相同。
而运行速度加快或占用内存空间减少。
中间的代码优化就是对中间代码进行等价的变换。
基本块的有向图DAG(Directed Acyclic Graph)有向图中任何一条通路都不是环路,则称该有向图为无环路有向图,简称为DAG。
一、实验题目:中间代码的局部优化二、实验目的:掌握局部优化方法、提高机器的运行速度三、实验内容:1 、构造基本块内的优化DAG假设:(1)ni 为已知结点号,n为新结点号;(2)访问各结点信息时,按结点号逆序排序2、完成对下例三类表达式的优化(1)常值表达式的优化(2)公共表达式的优化(3)无用赋值的优化3、输出根据优化的DAG重组四元式四、设计概要:首先要实现表达式中间代码生成,采用递归下降子程序法实现。
E→T{ω0 “push(SYN,w)”T“QUAT” }T→F{ω1”push(SYN,w)”F“QUAT”}F→i“push(SEM,entry(w))”|(E)其中:·push(SYN,w)---当前单词w入符号栈SYN;·push(SEM,entry(w))--- 当前i在符号表中的入口值压入语义栈SEM;·QUAT---生成四元式函数①T:=newtemp;②QT[j]=(SYN[k],SEM[s-1],SEM[s],T);j++;③ pop(SYN,_);pop(SEM,_);pop(SEM,_); push(SEM,T);在对中间代码进行局部优化五、程序代码及运行结果:1.表达式中间代码生成#include<iostream>#include<cstdlib>using namespace std;char str[50];char sem[50];char syn[50];char ch;int i=0;int j=0;int n=0;int p=1;void push_sem(char w){sem[j++]=w;}void push_syn(char w){syn[n++]=w;}void Gen(){char s[2][2];char w;w=sem[--j];if(w>='1'&&w<='9'){s[0][1]=w;s[0][0]=sem[--j];}else{s[0][0]=w;s[0][1]=' ';}w=sem[--j];if(w>='1'&&w<='9'){s[1][1]=w;s[1][0]=sem[--j];}else{s[1][0]=w;s[1][1]=' ';}cout<<"("<<syn[--n]<<","<<s[1][0]<<s[1][1]<<","<<s[0][0]<<s[0][1] <<","<<'t'<<p++<<")"<<endl;push_sem('t');push_sem(p+47);}int F(){int m;int E();if(ch=='('){ch=str[i++];m=E();if(ch==')') ch=str[i++];else{//cout<<"表达式error!"<<endl;return 0;}}else{if((ch>='a'&&ch<='z')||(ch>='1'&&ch<='9')){push_sem(ch);ch=str[i++];}else{//cout<<"表达式error!"<<endl;return 0;}}return 1;}int T(){int k,m,l;k=F();if(k==0){return 0;}while(1){//push_syn(ch);if(ch=='*'){push_syn(ch);ch=str[i++];m=F();if(m==0){return 0;}Gen();}else if(ch=='/'){push_syn(ch);ch=str[i++];l=F();if(l==0){return 0;}Gen();}else break;}return 1;}int E(){int k,m,l;k=T();if(k==0){return 0;}while(1){//push_syn(ch);if(ch=='+'){push_syn(ch);ch=str[i++];m=T();if(m==0){return 0;}Gen();}else if(ch=='-'){push_syn(ch);ch=str[i++];l=T();if(l==0){return 0;}Gen();}else break;}return 1;}int main(){int k,q=0;char w1,w2,w;char s[1][2];cout<<"输入表达式(以'#'结束):";cin>>str;w1=str[i++];w2=str[i++];if(w2!='=') {i=i-2;q=1;}ch=str[i++];k=E();if(q==0){w=sem[--j];if(w>='1'&&w<='9'){s[0][1]=w;s[0][0]=sem[--j];}else{s[0][0]=w;s[0][1]=' ';}cout<<"("<<w2<<","<<s[0][0]<<s[0][1]<<","<<" "<<","<<w1<<")"<<endl;}if(k==0) cout<<"error!"<<endl;else{if(ch=='#') cout<<"OK!"<<endl;else cout<<"error!"<<endl;}return 0;}运行结果:2.代码优化:(采用递归下降子程序法判断表达式是否合法,方法如上)#include <iostream>#include <cstdlib>#include <string.h>using namespace std;int i=1;int j=0,n=0;int p;int m=1;int Ti=0;char prog[100];char ch;char syn[20],sem[50][3];void SEM(void){int i,j;for(i=0;i<50;i++)for(j=0;j<3;j++)sem[i][j]='\0';}struct quat//四元式结构{char result[8];char ag1[8];char op;char ag2[8];}quad[25],newquad[15];struct Ni//节点结构{int pre[2];char op;char bz[25][8];}N[25];void newN(void){int l,j;i++;for(j=0;j<25;j++){for(l=0;l<8;l++){N[i-1].bz[j][l]='\0';}}for(j=0;j<2;j++)N[i-1].pre[j]=0;N[i-1].op='\0';}void dagt(void);void newquat(void);void fuzhi(void);//递归语法分析生成中间代码void E(void);void T(void);void F(void);void pop0(char sz[]);void push0(char sz[],char x);void pop1(char sz[50][3]);void push1(char sz[50][3],char x[3]); void quat1(void);void quat0(char w);void print1(void);void print2(void);char *newT(void){char *p;char m[8];p=(char *)malloc(8);Ti++;itoa(Ti,m,10);strcpy(p+1,m);p[0]='t';return(p);}void main(){p=0;syn[0]='#';SEM();sem[0][0]='#';cout<<"请输入表达式:"<<endl;do{cin.get(ch);if(ch != '\n') prog[p++]=ch;}while(ch!='#');p=0;ch=prog[p++];while(ch!='#'){fuzhi();}print1();dagt();newquat();print2();}void fuzhi(void){char temp[3];temp[0]='\0';temp[1]='\0';temp[2]='\0';if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')) {temp[0]=ch;push1(sem,temp);ch=prog[p++];if(ch=='='){push0(syn,ch);ch=prog[p++];E();if(m==0){cout<<"错误1!"<<endl;system("pause"); /////return;}if(ch==';'){ch=prog[p++];quat1();}else{cout<<"错误2!"<<endl;system("pause");return;}}else{cout<<"错误3!"<<endl;system("pause");return;}}else{cout<<"错误4!"<<endl;printf("%d",ch);system("pause");return;}}//E、T、F是递归下降子程序的语法分析void E(void){char w;T();while(ch=='+'||ch=='-'){push0(syn,ch);w=syn[strlen(syn)-1];ch=prog[p++];T();quat0(w);}}void T(void){char w;F();while(ch=='*'||ch=='/'){push0(syn,ch);w=syn[strlen(syn)-1];ch=prog[p++];F();quat0(w);}}void F(void){char temp[3];temp[0]='\0';temp[1]='\0';temp[2]='\0';if(ch=='('){ch=prog[p++];E();if(ch==')'){ch=prog[p++];}else m=0;}else if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0')) {temp[0]=ch;push1(sem,temp);ch=prog[p++];}else m=0;}void push0(char sz[],char x){int top;top=strlen(sz);sz[top]=x;top++;sz[top+1]='\0';}void pop0(char sz[]){int top;top=strlen(sz)-1;sz[top]='\0';}void push1(char sz[50][3],char x[3]) {int top=1;while(sz[top][0])top++;strcpy(sz[top],x);top++;sz[top+1][0]='\0';}void pop1(char sz[50][3]){int top=1;while(sz[top][0])top++;top--;sz[top][0]='\0';sz[top][1]='\0';sz[top][2]='\0';}void quat0(char w){int top=1,i;char *p;while(sem[top][0])top++;strcpy(quad[j].ag1,sem[top-2]);strcpy(quad[j].ag2,sem[top-1]);quad[j].op=w;p=newT();for(i=0;i<8;i++)quad[j].result[i]=p[i];pop1(sem);top--;pop1(sem);top--;for(i=0;i<3;i++)sem[top][i]=quad[j].result[i];sem[top][2]='\0';j++;}void quat1(void){char ag2[8];int top,i;top=1;while(sem[top][0])top++;ag2[0]='_';for(i=1;i<8;i++)ag2[i]='\0';strcpy(quad[j].ag1,sem[top-1]);strcpy(quad[j].ag2,ag2);quad[j].op='=';strcpy(quad[j].result,sem[top-2]);pop0(syn);pop1(sem);pop1(sem);j++;}void print1(void){int i;cout<<"原来的四元组:"<<endl;for(i=0;i<j;i++)cout<<(i+1)<<"、("<<quad[i].op<<","<<quad[i].ag1<<","<<quad[i].ag2<<","<<quad[i].result<<")"<<endl;}void dagt(void){int m,n,top,l,tag=0,tag1=0,tag2=0;char temp;for(m=0;m<j;m++){tag=0;for(n=i;n>0;n--)for(l=0;l<25;l++){if(strcmp(quad[m].ag1,N[n-1].bz[l])==0){tag=n;break;}}if(tag!=0){tag1=tag-1;if('0'<quad[m].ag1[0]&&quad[m].ag1[0]<'9')goto N3;else goto N3;}else{if('0'<quad[m].ag1[0]&&quad[m].ag1[0]<'9'){if(quad[m].ag2[0]!='_'){if('0'<quad[m].ag2[0]&&quad[m].ag2[0]<'9'){quad[m].ag1[0]=quad[m].ag1[0]-'0';quad[m].ag2[0]=quad[m].ag2[0]-'0';switch(quad[m].op){case '+':temp=quad[m].ag1[0]+quad[m].ag2[0];break;case '-':temp=quad[m].ag1[0]-quad[m].ag2[0];break;case '*':temp=quad[m].ag1[0]*quad[m].ag2[0];break;case '/':temp=quad[m].ag1[0]/quad[m].ag2[0];break;default:break;}tag=0;for(n=i;n>0;n--)for(l=0;l<25;l++){if(strcmp(quad[m].result,N[n-1].bz[l])==0){tag=n;break;}}if(tag!=0)continue;else{newN();N[i-1].bz[0][0]=temp+'0' ;strcpy(N[i-1].bz[1],quad[m].result);continue;}}else{newN();tag1=i-1;strcpy(N[i-1].bz[0],quad[m].ag1);goto N2;}}else goto N1;}elseN1:{newN();strcpy(N[i-1].bz[0],quad[m].ag1);tag1=i-1;N3:if(quad[m].ag2[0]=='_'){tag=0;for(n=i;n>0;n--)for(l=0;l<25;l++){if(strcmp(quad[m].result,N[n-1].bz[l])==0){tag=n;top=l;break;}}if(tag!=0){for(l=top+1;l<25;l++){strcpy(N[tag-1].bz[l-1],N[tag-1].bz[l]);}goto N5;}else{N5:if(N[i-1].bz[0][1]){if(quad[m].result[1]){top=0;while(N[tag1].bz[top][0])top++;strcpy(N[tag1].bz[top],quad[m].result);continue;}else{temp=N[i-1].bz[0][1];strcpy(N[i-1].bz[0],quad[m].result);top=0;while(N[tag1].bz[top][0])top++;N[i-1].bz[top][0]='t';N[i-1].bz[top][1]=temp;continue;}}else{top=0;while(N[tag1].bz[top][0])top++;strcpy(N[tag1].bz[top],quad[m].result);continue;}}}elseN2:{tag=0;for(n=i;n>0;n--)for(l=0;l<25;l++){if(strcmp(quad[m].ag2,N[n-1].bz[l])==0){tag=n;break;}}if(tag!=0){tag2=tag-1;tag=0;for(n=i;n>0;n--)if((N[n-1].pre[0]==tag1)&&(N[n-1].pre[1]==tag2)){tag=n;break;}if(tag!=0){if(N[tag-1].op==quad[m].op){if(!N[tag-1].bz[0][1]){top=1;while(N[tag-1].bz[top][0])top++;strcpy(N[tag-1].bz[top],quad[m].result);}else if(!quad[m].result[1]){temp=N[tag-1].bz[0][1];strcpy(N[tag-1].bz[0],quad[m].result);top=1;while(N[tag-1].bz[top][0])top++;N[tag].bz[top][0]='t';N[tag].bz[top][1]=temp;}else{top=1;while(N[tag-1].bz[top][0])top++;strcpy(N[tag-1].bz[top],quad[m].result);}continue;}else{newN();N[i-1].op=quad[m].op;strcpy(N[i-1].bz[0],quad[m].result);N[i-1].pre[0]=tag1;N[i-1].pre[1]=tag2;}continue;}else{newN();N[i-1].op=quad[m].op;strcpy(N[i-1].bz[0],quad[m].result);N[i-1].pre[0]=tag1;N[i-1].pre[1]=tag2;continue;}}else{newN();strcpy(N[i-1].bz[0],quad[m].ag2);tag2=i-1;tag=0;for(n=i;n>0;n--)for(l=0;l<25;l++)if(strcmp(quad[m].result,N[n-1].bz[l])==0){tag=n;top=l;break;}if(tag==0){newN();strcpy(N[i-1].bz[0],quad[m].result);N[i-1].op=quad[m].op;N[i-1].pre[0]=tag1;N[i-1].pre[1]=tag2;continue;}else{for(l=top+1;l<25;l++){strcpy(N[tag-1].bz[l-1],N[tag-1].bz[l]);}newN();strcpy(N[i-1].bz[0],quad[m].result);N[i-1].op=quad[m].op;N[i-1].pre[0]=tag1;N[i-1].pre[1]=tag2;}}}}}}}void newquat(void){int l,top;for(l=1;l<i;l++){if(N[l].pre[1]==0&&N[l].pre[0]==0){if(!N[l].bz[0][1]){if(('0'<N[l].bz[0][0])&&(N[l].bz[0][0]<'9'))continue;else{for(top=1;N[l].bz[top][1];top++){if(!N[l].bz[top][0]){strcpy(newquad[n].ag1,N[l].bz[0]);newquad[n].ag2[0]='_';newquad[n].op='=';strcpy(newquad[n].result,N[l].bz[top]);n++;}}}}else continue;}else if(N[l].pre[1]!=0||N[l].pre[0]!=0){strcpy(newquad[n].ag1,N[N[l].pre[0]].bz[0]);strcpy(newquad[n].ag2,N[N[l].pre[1]].bz[0]);newquad[n].op=N[l].op;strcpy(newquad[n].result,N[l].bz[0]);n++;if(!N[l].bz[0][1]){for(top=1;N[l].bz[top][0];top++){if(!N[l].bz[top][1]){strcpy(newquad[n].ag1,N[l].bz[0]);newquad[n].ag2[0]='_';newquad[n].op='=';strcpy(newquad[n].result,N[l].bz[top]);n++;}}}}}}void print2(void){int i;cout<<"优化后的代码:"<<endl;for(i=0;i<n;i++)cout<<(i+1)<<"、("<<newquad[i].op<<","<<newquad[i].ag1<<","<<newquad[i].ag2<<","<<newquad[i].result<<")"<<endl;}运行结果:。
2.二义性文法:如果一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义性文法。
5.最左推导:任何一步α=>β都是对α中的最右非终结符替换。
6.语法:一组规则,用它可形成和产生一组合式的程序。
7.文法:描述语言的语法结构的形式规则。
8.基本块:指程序中一顺序执行的语句序列,其中只有一个入口和一个出口,入口就是其中的第一个语句,出口就是其中的最后一个语句。
10.短语:令G 是一个文法,S 划文法的开始符号,假定αβδ是文法G 的一个句型,如果有S αAδ且A β,则称β是句型αβδ相对非终结符A 的短语。
12.规范句型:由规范推导所得到的句型。
13.扫描器:执行词法分析的程序。
15.句柄:一个句型的最左直接短语。
16.语法制导翻译:在语法分析过程中,根据每个产生式所对应的语义程序进行翻译的方法 叫做语法制导翻译。
18.素短语:素短语是指这样一个短语,至少含有一个终结符,并且,除它自身外不再含任何更小的素短语。
20.语义:定义程序的意义的一组规则。
三种级别:局部优化、循环优化、全局优化21.词法分析词法分析的主要任务是从左向右扫描每行源程序的符号,按照词法规则从构成源程序的字符串中识别出一个个具有独立意义的最小语法单位,并转换成统一的内部表示(token),送给语法分析程序。
23.语法树句子的树结构表示法称为语法树(语法分析树或语法推导树)。
给定文法G=(V N ,V T ,P ,S),对于G 的任何句型都能构造与之关联的语法树。
这棵树具有下列特征:(1)根节点的标记是开始符号S 。
(2)每个节点的标记都是V 中的一个符号。
(3)若一棵子树的根节点为A ,且其所有直接子孙的标记从左向右的排列次序为A 1A 2…A R ,那么A →A 1A 2…A R 一定是P 中的一条产生式。
(4)若一标记为A 的节点至少有一个除它以外的子孙,则A ∈V N 。
(5)若树的所有叶节点上的标记从左到右排列为字符串w ,则w 是文法G 的句型;若w 中仅含终结符号,则w 为文法G 所产生的句子。
编译原理中的目标代码生成与优化编译原理是计算机科学中的一门重要课程,它研究的是将高级程序语言转化为机器语言的过程。
目标代码生成与优化是编译过程中的两个关键环节,本文将就这两个方面展开讨论。
一、目标代码生成目标代码生成是编译过程中的最后一步,它的任务是将中间代码转化为能够在目标机器上执行的机器代码。
目标代码生成的质量直接影响程序的执行效率和占用的存储空间。
1. 寄存器分配在进行目标代码生成之前,我们需要进行寄存器分配。
寄存器分配的目的是将中间代码中的临时变量分配到机器寄存器中,减少内存读写操作,提高程序的运行速度。
常用的寄存器分配算法有线性扫描算法和图着色法。
2. 目标代码生成技术目标代码生成的技术有很多,下面列举几种常见的技术:(1) 直接生成代码:直接将中间代码翻译为目标机器的指令序列。
这种方法简单直接,但生成的目标代码质量一般较低。
(2) 间接生成代码:先将中间代码翻译为一个中间形式,再将中间形式转化为目标机器的指令序列。
这种方法可以进行一些优化,生成的目标代码质量较高。
(3) 使用代码模板:事先定义一些目标机器的指令模板,并根据中间代码的特征选择合适的指令模板来生成目标代码。
这种方法可以充分利用目标机器的特性,生成的目标代码效率较高。
二、目标代码优化目标代码优化是指对生成的目标代码进行一系列的优化,以提高程序的运行效率和减少代码的空间占用。
1. 基本块优化基本块是由顺序执行的指令组成的,没有前驱指令和后继指令的指令序列。
基本块优化的目的是对基本块中的指令进行优化,以减少执行时间和空间开销。
常见的基本块优化技术有死代码删除、常量传播等。
2. 寄存器优化寄存器是计算机中的一块高速存储器,能够提供快速的数据访问速度。
寄存器优化的目的是将变量尽可能地存放在寄存器中,以减少内存读写操作,提高程序的执行效率。
常用的寄存器优化技术有寄存器分配、寄存器重命名等。
3. 循环优化循环是程序中的重要结构之一,对循环进行优化可以显著提高程序的执行效率。
编译原理之中间代码⽣产、词法优化与代码⽣成
中间代码⽣成
在把⼀个源程序翻译成⽬标代码的过程中,⼀个编译器可能构造出⼀个或多个中间表⽰。
这些中间表⽰可以有多种形式。
语法树是⼀种中间表⽰形式,它们通常在语法分析和语义分析中使⽤。
在源程序的语法分析和语义分析完成之后,很多编译器⽣成⼀个明确的低级的或类机器语⾔的中间表⽰。
我们可以把这个表⽰看作是某个抽象机器的程序。
该中间表⽰应该具有两个重要的性质:它应该易于⽣成,且能够被轻松地翻译为⽬标机器上的语⾔。
代码优化
机器⽆关的代码优化步骤试图改进中间代码,以便⽣成更好的⽬标代码。
“更好”通常意味着更快,但是也可能会有其他⽬标,如更短的或能耗更低的⽬标代码
代码⽣成
代码⽣成器以源程序的中间表⽰形式作为输⼊,并把它映射到⽬标语⾔。
如果⽬标语⾔是机器代码,那么就必须为程序使⽤的每个变量选择寄存器或内存位置。
然后,中间指令被翻译成为能够完成相同任务的机器指令序列。
代码⽣成的⼀个⾄关重要的⽅⾯是合理分配寄存器以存放变量的值。
(这⾥我觉得还存疑因为书本上下下段还说了⼀句话,上⾯对代码⽣成的讨论忽略了对源程序中的标识⾏进⾏存储分配的重要问题。
) 不过总之,运⾏时刻的存储组织⽅法依赖于被编译的语⾔。
编译器在中间代码⽣成或代码⽣成阶段做出有关存储分配的决定。
第十章代码优化某些编译程序在中间代码或目标代码生成之后要对生成的代码进行优化。
所谓优化,实质上是对代码进行等价变换,使得变换后的代码运行结果与变换前代码运行结果相同,而运行速度加大或占用存储空间少,或两者都有。
优化可在编译的不同阶段进行,对同一阶段,涉及的程序范围也不同,在同一范围内,可进行多种优化。
一般,优化工作阶段可在中间代码生成之后和(或)目标代码生成之后进行。
中间代码的优化是对中间代码进行等价变换。
目标代码的优化是在目标代码生成之后进行的,因为生成的目标代码对应于具体的计算机,因此,这一类优化在很大程度上依赖于具体的机器,我们不做详细讨论。
另外依据优化所涉及的程序范围,又可分为局部优化、循环优化和全局优化三个不同的级别。
局部优化指的是在只有一个入口、一个出口的基本程序块上进行的优化。
循环优化对循环中的代码进行的优化。
全局优化是在整个程序范围内进行的优化。
本章重点:局部优化基本块的DAG表示第一节优化技术简介为了说明问题,我们来看下面这个例子,源程序是:P :=0For I :=1 to 20 doP :=P+A[I]*B[I];经过编译得到的中间代码如图10-1-1所示,这个程序段由B1和B2两个部分组成,B2是一个循环,假定机器按字节编址。
那么,对于这个中间代码段,可进行如下这些优化。
1、删除多余运算(删除公共子表达式)优化的目的在于使目标代码执行速度较快。
图10-1-1中间代码(3)和(6)中都有4*I的运算,而从(3)到(6)没有对I赋值,显然,两次计算机的值是相等的。
所以,(6)的运算是多余的。
我们可以把(6)变换成:T4 :=T1。
这种优化称为删除多余运算或称为删除公共子表达式。
2、代码外提减少循环中代码总数的一个重要办法是代码外提。
这种变换把循环不变运算,即其结果独立于循环执行次数的表达式,提到循环的前面。
使之只在循环外计算一次,上例中,我们可以把(4)和(7)提到循环外。
经过删除多余运算和代码外提后,代码变成图10-1-2。
实验三中间的代码优化
某些编译程序在中间代码或目标代码生产之后要对其进行优化,所谓优化就是对代码进行等价的变换。
而变换后的代码运行结果与变换前的代码运行结果相同。
而运行速度加快或占用内存空间减少。
中间的代码优化就是对中间代码进行等价的变换。
基本块的有向图DAG(Directed Acyclic Graph)
有向图中任何一条通路都不是环路,则称该有向图为无环路有向图,简称为DAG。
一、实验题目:
中间代码的局部优化
二、实验目的:
掌握局部优化方法、提高机器的运行速度
三、实验内容:
1 、构造基本块内的优化DAG
假设:(1)ni 为已知结点号,n为新结点号;
(2)访问各结点信息时,按结点号逆序排序
2、完成对下例三类表达式的优化
(1)常值表达式的优化
(2)公共表达式的优化
(3)无用赋值的优化
3、输出根据优化的DAG重组四元式
四、设计概要:
首先要实现表达式中间代码生成,采用递归下降子程序法实现。
E→T{ω0 “push(SYN,w)”T“QUAT” }
T→F{ω1”push(SYN,w)”F“QUAT”}
F→i“push(SEM,entry(w))”|(E)
其中:·push(SYN,w)---当前单词w入符号栈SYN;
·push(SEM,entry(w))--- 当前i在符号表中的入口值压入语义栈SEM;·QUAT---生成四元式函数
①T:=newtemp;
②QT[j]=(SYN[k],SEM[s-1],SEM[s],T);j++;
③ pop(SYN,_);pop(SEM,_);pop(SEM,_); push(SEM,T);
在对中间代码进行局部优化
五、程序代码及运行结果:
1.表达式中间代码生成
#include<iostream>
#include<cstdlib>
using namespace std;
char str[50];
char sem[50];
char syn[50];
char ch;
int i=0;
int j=0;
int n=0;
int p=1;
void push_sem(char w)
{
sem[j++]=w;
}
void push_syn(char w)
{
syn[n++]=w;
}
void Gen()
{
char s[2][2];
char w;
w=sem[--j];
if(w>='1'&&w<='9')
{
s[0][1]=w;
s[0][0]=sem[--j];
}
else
{
s[0][0]=w;
s[0][1]=' ';
}
w=sem[--j];
if(w>='1'&&w<='9')
{
s[1][1]=w;
s[1][0]=sem[--j];
}
else
{
s[1][0]=w;
s[1][1]=' ';
}
cout<<"("<<syn[--n]<<","<<s[1][0]<<s[1][1]<<","<<s[0][0]<<s[0][1] <<","<<'t'<<p++<<")"<<endl;
push_sem('t');
push_sem(p+47);
}
int F()
{
int m;
int E();
if(ch=='(')
{
ch=str[i++];
m=E();
if(ch==')') ch=str[i++];
else
{
//cout<<"表达式error!"<<endl;
return 0;
}
}
else
{
if((ch>='a'&&ch<='z')||(ch>='1'&&ch<='9'))
{
push_sem(ch);
ch=str[i++];
}
else
{
//cout<<"表达式error!"<<endl;
return 0;
}
}
return 1;
}
int T()
{
int k,m,l;
k=F();
if(k==0){return 0;}
while(1)
{
//push_syn(ch);
if(ch=='*')
{
push_syn(ch);
ch=str[i++];
m=F();
if(m==0){return 0;}
Gen();
}
else if(ch=='/')
{
push_syn(ch);
ch=str[i++];
l=F();
if(l==0){return 0;}
Gen();
}
else break;
}
return 1;
}
int E()
{
int k,m,l;
k=T();
if(k==0){return 0;}
while(1)
{
//push_syn(ch);
if(ch=='+')
{
push_syn(ch);
ch=str[i++];
m=T();
if(m==0){return 0;}
Gen();
}
else if(ch=='-')
{
push_syn(ch);
ch=str[i++];
l=T();
if(l==0){return 0;}
Gen();
}
else break;
}
return 1;
}
int main()
{
int k,q=0;
char w1,w2,w;
char s[1][2];
cout<<"输入表达式(以'#'结束):";
cin>>str;
w1=str[i++];
w2=str[i++];
if(w2!='=') {i=i-2;q=1;}
ch=str[i++];
k=E();
if(q==0)
{
w=sem[--j];
if(w>='1'&&w<='9')
{
s[0][1]=w;
s[0][0]=sem[--j];
}
else
{
s[0][0]=w;
s[0][1]=' ';
}
cout<<"("<<w2<<","<<s[0][0]<<s[0][1]<<","<<" "<<","<<w1<<")"<<endl;
}
if(k==0) cout<<"error!"<<endl;
else
{
if(ch=='#') cout<<"OK!"<<endl;
else cout<<"error!"<<endl;。