编译课程设计报告模板.docx
- 文档编号:5786666
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:12
- 大小:69.48KB
编译课程设计报告模板.docx
《编译课程设计报告模板.docx》由会员分享,可在线阅读,更多相关《编译课程设计报告模板.docx(12页珍藏版)》请在冰豆网上搜索。
编译课程设计报告模板
编译语言课程设计报告
专业
计算机科学与技术
学生姓名
秦霞
班级
B计算机073
学号
0710604317
指导教师
张静林
完成日期
2010年9月
目录
1设计目的1
2设计任务1
3设计内容与要求1
3.1问题描述1
3.2程序要求1
4程序设计说明1
4.1设计流程图2
5源程序清单2
6小结2
7参考文献2
1.设计目的
学生在学习《编译原理》课程过程中,结合各章节的构造编译程序的基本理论,总共用一周时间完成课程设计。
要求用C或C++语言描述及上机调试,实现五个题目中的任意一个。
使学生将理论与实际应用结合起来,受到软件设计等开发过程的全面训练,从而提高学生软件开发的能力。
了解基本块的DAG表示及其应用,掌握局部优化和循环优化的基本方法,对中间代码和目标代码进行等价交换,即实现中间代码优化和目标代码的优化。
2.设计任务
优化器包括局部优化和循环优化。
编译程序在中间代码或目标代码生成之后要对生成的代码就行优化。
3.设计内容及要求
3.1问题描述
局部优化,是指基本块内的优化。
所谓基本块,是指程序中一个顺序执行的语句序列,其实只有一个入口语句和一个出口语句。
执行时只能从其入口语句进入,从其出口语句退出。
对于一个给定的程序,我们可以把它划分为一系列的基本块。
在各基本块的范围内分别进行优化。
循环优化:
在找出了程序流图中的循环之后,我们就可以针对每个循环进行优化工作。
因为循环内的指令是重复执行的,因而循环中进行的优化在整个优化工作中是非常重要的。
循环优化的三种重要技术:
代码外提,强度削弱和删除归纳变量。
减少循环中的代码数目的一个重要办法就是代码外提。
强度削弱和删除归纳变量的算法:
(1)利用循环不变运算信息,找出循环中的所有基本归纳变量。
(2)找出所有其他归纳变量a,并找出a与已知基本归纳变量x的同族线性函数关系Fa(x)。
(3)对
(2)中找出的每一归纳变量a进行强度削弱。
(4)删除对归纳变量的无用赋值。
(5)删除基本归纳变量。
总之,局部优化指的是在一个入口、一个出口的基本程序块上进行的优化,循环优化是对循环中的代码进行优化
3.2程序要求
局部优化:
设计出划分基本块的算法,在每一个基本块中实现:
合并已知量、删除多余运算和删除无用赋值三种局部优化。
设计构造基本块的DGA图的算法,以及将DGA图还原实现基本快的优化算法。
循环优化:
只做一重循环优化,完成代码外提,强度削弱和删除归纳变量等三种优化。
要求实现while循环和for循环语句的优化。
4.程序设计说明
4.1设计流程图
局部优化:
DAG的结点类型只考虑0型、1型和2型,如下表所示。
类型
四元式
DAG结点
0型
(=,B,,A)
①A
B
1型
(op,B,,A)
②
op
①
B
2型
(op,B,C,A)
(=[],B,C,A)
(jrop,B,C,s)
③A③A③(s)
op=[]rop
①②①②①②
BCBCBC
5.源程序清单
(1)由基本块构造DAG算法如下:
while(基本块中还有未处理过的四元式){
取下一个四元式Q;
newleft=newright=0;
if(getnode(B)==NULL){
makeleaf(B);
newleft=1;
}
switch(Q的类型){
case0:
n=getnode(B);
insertidset(n,A);
break;
case1:
if(isconsnode(B)){
p=calcons(Q.op,B);
if(newleft==1)/*getnode(B)是处理Q时新建结点*/
delnode(B);
if((n=getnode(p))==NULL){
makeleaf(p);
n=getnode(p);
}
}else{
if((n=findnode(Q.op,B))==NULL)
n=makenode(Q.op,B);
}
insertidset(n,A);
break;
case2:
if(getnode(C)==NULL){
makeleaf(C);
newright=1;
}
if(isconsnode(B)&&isconsnode(C)){
p=calcons(Q.op,B,C);
if(newleft==1)/*getnode(B)是处理Q时新建结点*/
delnode(B);
if(newright==1)/*getnode(C)是处理Q时新建结点*/
delnode(C);
if((n=getnode(p))==NULL){
makeleaf(p);
n=getnode(p);
}
}else{
if((n=findnode(Q.op,B,C))==NULL)
n=makenode(Q.op,B,C);
}
insertidset(n,A);
break;
}
}
上述算法中应设置如下的函数:
getnode(B):
返回B(可以是标记或附加信息)在当前DAG中对应的结点号。
makeleaf(B):
构造标记为B的叶子结点。
isconsnode(B):
检查B对应的结点是否为标记为常数的叶子结点。
calcons(Q.op,B):
计算opB的值(即合并已知量)。
它的另一种调用形式是
calcons(Q.op,B,C),计算BopC的值。
delnode(B):
删除B(结点的标记)在当前DAG中对应的结点。
findnode(Q.op,B):
在当前DAG中查找并返回这样的结点:
标记为op,后继为getnode(B)(即查找公共子表达式opB)。
它的另一种调用形式是findnode(Q.op,B,C)(即查找公共子表达式BopC)。
makenode(Q.op,B,C):
构造并返回标记为op,左右后继分别为getnode(B)、getnode(C)的内部结点。
insertidset(n,A):
若getnode(A)=NULL,则把A附加到结点n;否则,若A在getnode(A)的附加标识符集中,且getnode(A)无前驱或虽有前驱但getnode(A)附加标识符集中符号数大于1,则把A从getnode(A)的附加标识符集中删除(即删除无用赋值)。
请实现上述基本块的DAG构造算法,并添加从所得DAG按原来生成DAG各个结点的顺序,重建四元式序列的功能。
(2)全局优化
#include
#include
voidsum1()
{
intj=0;
for(unsignedi=1;i<630001;i++)j+=i;}
voidsum2()
{
intj=0;
for(unsignedi=1;i<630001;){j+=i++;j+=i++;}}
voidsum3(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;
}
}
voidsum4(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;
}
}
voidsum5(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;
}
}
voidsum6(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;
}
}
voidsum7(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;
}
}
voidsum8(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;
}
}
voidsum9(){
intj=0;
for(unsignedi=;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;
}
}
voidsum10(){
intj=0;
for(unsignedi=1;i<630001;){
j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;j+=i++;
}
}
intmain(){
Timertimer;
doublet;
for(unsignedk=0;k<3;k++){
timer.Start();
sum1();
t=timer.GetTime();
cout<<"sum1:
"< timer.Start(); sum2(); t=timer.GetTime(); cout<<"sum2: "< sum3(); t=timer.GetTime(); cout<<"sum3: "< timer.Start(); sum4(); t=timer.GetTime(); cout<<"sum4: "< timer.Start(); sum5(); t=timer.GetTime(); cout<<"sum5: "< timer.Start(); sum6(); t=timer.GetTime(); cout<<"sum6: "< timer.Start(); sum7(); t=timer.GetTime(); cout<<"sum7: "< timer.Start(); sum8(); t=timer.GetTime(); cout<<"sum8: "< timer.Start(); sum9(); t=timer.GetTime(); cout<<"sum9: "< timer.Start(); sum10(); t=timer.GetTime(); cout<<"sum10: "< }return0; } #include #include voidsum4() { intj=0; for(unsignedi=1;i<630001;) { j+=i++; j+=i++; j+=i++; j+=i++; } } voidsum5() { intj=0; for(unsignedi=1;i<630001;) { j+=i++; j+=i++; j+=i++; j+=i++; j+=i++; } } intmain() { inti,j;Timertimer; timer.Start(); for(i=0;i<5;i++)sum4(); cout<<"sum4 : "< timer.Start(); sum4();sum4();sum4();sum4();sum4(); cout<<"sum4E: "< timer.Start(); for(i=0;i<5;i++)sum5(); cout<<"sum5 : "< timer.Start(); sum5();sum5();sum5();sum5();sum5(); cout<<"sum5E: "< timer.Start(); for(i=0;i<100;i++)sum4(); cout<<"sum4H: "< timer.Start(); for(i=0;i<100;i++)sum5(); cout<<"sum5H: "< timer.Start(); for(i=0;i<1000;i++) for(j=0;j<5;j++)sum4(); cout<<"sum4T: "< timer.Start(); for(i=0;i<1000;i++) {sum4();sum4();sum4();sum4();sum4();} cout<<"sum4TE: "< for(i=0;i<1000;i++) for(j=0;j<5;j++)sum5(); cout<<"sum5T: "< timer.Start(); for(i=0;i<1000;i++) {sum5();sum5();sum5();sum5();sum5();} cout<<"sum5TE: "< return0; } 6.小结 通过为期一周的编译原理课程设计,我真的很珍惜这次机会,这可能是我们大学生涯的最后一次了,现在的我们面临就业的危机,这一次的练习可以算是我们步入社会的一次练笔,也希望好好利用这次机会。 因为编译是上学期学的课程,所以对于编译的知识,我们也大部分遗忘了,所以这次课程设计我不得不再一次的好好复习以往学过的知识,真的受益匪浅。 我这次的课题的优化器,也就是代码优化,所谓优化,实质上是对代码进行等价变换,使得变换后的代码运行结果与变换前代码运行结果相同,而运行速度加快或占用的存储空间减少,或两者都有。 优化可以在编译的不同阶段进行,对同一阶段,涉及的程度范围也有所不同,在同一范围内,可进行多种优化。 对于代码优化,我这次的课程设计任务是局部优化和循环优化。 历时一个星期的课程设计结束了,不禁有些留恋,也不禁有些欣喜。 软件的编写是一件艰难而又会令人欣喜若狂的事。 从程序连编译都不能通过到程序能运行但会抛出许多异常,从运行的结果的与我们事先预料的结果大相径庭到运行结果有些小小的错误,再到程序能够输出完全正确的结果,我们必须一步一步地分析,一段程序一段程序的检测。 有的时候为了一个错误检测半天,几乎都有崩溃的感觉,而等到最后找到原因的时候,才恍然大悟,那时的欣喜心情是值得留恋的。 等到程序最终完成,回忆那些执著的时光,真的没有白费。 这个程序的完成,首先得感谢机械工业出版社出版、贺汛编著的《编译方法学习指导与实践》一书的指导。 其中局部优化部分是花了三天的时间完成了。 虽然循环优化的局部优化困难得多,但有了对局部优化原理的理解为基础,对循环优化原理的理解就不算那末太难了。 尤其是那种分析程序的方法,值得以后借鉴和使用。 见到莫大一个程序,大体浏览一下它的函数的调用关系。 然后我们那几个简单的例子按照它的分析方法看看这个莫大的程序能否处理的了。 最好我们先从理论上分析一下,如果从理论上这个程序确实能够处理这个例子,我们再从实践上用这个程序去处理它。 但有的程序根本就不是我们所想的那样,需要我们按照自己的思路去进行修改,有时甚至改造非常大。 如在什么时候生成四元式。 通过这次课程设计,我认识到做一个程序并不难。 关键是你是否有一种灵感。 当然,对你所做的程序的理论上的把握式这个关键的前提。 在理论上把握住了,再加上你对某种编程语言的熟悉,这个灵感就会产生。 有了灵感就有了编程的激情,当你实现了你的部分设想后,你会更加的执著。 如果你对某种编程语言不是很了解,也没有关系,因为编程语言是在不断的实践中学习的。 碰到不会的,可以上网查查。 有些编程语言还有帮助文档。 查阅帮助文档可以更好的帮助你学习这门语言。 总之,这次课程设计使我在动手能力上有了很大的提高,也许这是毕业设计之前最好的一次锻炼动手能力的机会,也可能是最后一次。 我认为这次课程设计是毕业设计的前奏,不过我想我已经成功的抓住了这次机会并很好的把握住了这个前奏。 通过这次设计,我也了解到了集体的力量,大家一起讨论的情景,让我很是感动。 体会到了大家一起学习的热情,还有谢谢老师的耐心指导。 在以后的学习过程中,要相互学习,努力上进,争取得到更大的进步。 当然以后也要好好抓住这种可以好好锻炼的机会,好好磨练自己,从实践中得到知识,升华自己! 7.参考文献 《编译原理》,吕映芝,张素琴,蒋维杜编著,清华大学出版社 《编译原理》,AlfredV.Aho等,李建中译,机械工业出版社 《程序设计语言编译原理》(第3版)陈火旺主编国防工业出版社 《编译原理试题精选题解》伍春香编著华中科技大学出版社
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 课程设计 报告 模板
![提示](https://static.bdocx.com/images/bang_tan.gif)