中间代码基本块划分

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中间代码基本块的划分
任务要求
在理解代码优化原理的基础上,实现将中间代码序列划分基本块的程序
1.理解编译过程中代码优化的定义
2.掌握各种代码优化的方法
3.定义程序流图中的基本块
4.明确程序流图的形式及功能
5.程序设计及调试
一.原理阐述
1.代码优化的定义:
代码优化的实质就是提高代码质量从而加快代码执行速度的一种技术。

根据代码优化是否涉及具体的计算机,又将代码优化分为⑴与机器有关的优化(即窥孔优化),一般在目标代码上进行;⑵与机器无关的优化,常在中间代码上进行。

又根据优化范围分成局部优化、循环优化、全局优化。

2.代码优化的方法:
1)删除公共子表达式
2)代码外提
3)强度削弱
4)删除归纳变量5)合并已知量
6)复写传播
7)删除无用赋值
3.基本块和划分基本块的定义和方法:
定义:基本块就是代码序列中一组顺序执行的语句序列,只有一个入口和一个出口。

而划分基本块的实质就是定义入口和出口语句。

划分基本块的方法:
1)定义入口语句
①四元式的第一个语句;
②由条件转移语句或无条件转移语句能转到的语句;
③紧跟在条件转移语句后面的语句。

2)定义出口语句
①下一个入口语句的前导语句;
②转移语句(包括转移语句本身);
③停语句(包括停语句本身)。

构造基本块,删除不属于任何基本块的语句
二.流程示意图
按四元式序列,给出如下程序流图
⑴ read x ; ⑵ read y ; ⑶ L1:c=c+1;
⑷ if c=0 goto L2; ⑸ x=y ; ⑹ y=c ;
⑺ goto L1; ⑻ L2: write y ; ⑼ halt (以“~ ”表示)
三. 部分代码:
入口条件1
int i=0,j=-1,back_i=0,in_num=0,out_num=0;
char g[200];
cout<<"请输入要进行基本块划分的四元式(按回车表示四元式输入完毕):"<<endl; for(i=0;i<200;i++)
{g[i]=' ';c[i]=' ';} //g[](局部),c[](全局),清零
gets(g); //输入四元式
for(i=0;i<200;i++) {c[i]=g[i];} //将输入的四元式备份到c[]
in[in_num++]='1'; //首句为入口语句,将语句序号放入in[]
(3) L1: c=c+1
(4) if c=0 goto L2
⑴ read x
⑵ read y
(5) x=y
(6) y=c
(7) goto L1
⑻ L2: write x ⑼ halt (以“~ ”表Block 3
Block 2
Block 4 Block 1
入口条件2
for(i=0;*(g+i)!='~';i++) //由条件转移语句或无条件转移语句能转到的语句为入口语句{
if(*(g+i)==':') //找到转移语句能转到的语句
{
back_i=i; //i是指针,back_i记录当前位置,用于搜索语句序号
for (;*(g+back_i)!=')';back_i--)
{continue;}
in[in_num++]=*(g+back_i-1); //得到入口语句序号,将其放入in[]
出口条件1
out[out_num++]=(char)((int)*(g+back_i-1)-1);break;
//入口语句的上一句是出口语句,将其序号放入out[] }
}
cout<<"_______________________________"<<endl<<endl;
cout<<"判定输出语句/输入语句过程(输出语句—>输入语句):"<<endl<<endl;
for(;j!=0;j++)
{cout<<"sentence ("<<out[out_num-1]<<") --> ("<<in[in_num-1]<<")"<<endl;}
入口条件3
for(i=0;*(g+i)!='~';i++) //紧跟在条件语句后面的语句为入口语句{
if(*(g+i)=='i'&&*(g+i+1)=='f') //找到条件语句关键字if
{
back_i=i;
for(;*(g+back_i)!='(';back_i++) //找到条件语句的下一句,即入口语句
{continue;}
in[in_num++]=*(g+back_i+1); //将入口语句序号放入in[] }
}
出口条件2
for(i=0;*(g+i)!='~';i++) //转移语句为出口语句
{
if(*(g+i)=='g'&&*(g+i+1)=='o') //找到转移语句的关键字goto
{
back_i=i;
for(;*(g+back_i)!=')';back_i--)
{continue;}
out[out_num++]=*(g+back_i-1); //将语句序号放入out[]
in[in_num++]=(char)((int)*(g+back_i-1)+1);
//其下一句是入口语句,将语句序号放入in[]
for(;j<1;j++)
{cout<<"sentence ("<<out[out_num-1]<<") --> ("<<in[in_num-1]<<")"<<endl;}
for(;*(g+back_i)!='L';back_i++) //找到转移语句能够转到的语句序号
{continue;}
for(;*(c+ch)!='~';ch++)
{
for(;*(c+ch)!='L';ch++) {continue;}
if(*(g+back_i+1)==*(c+ch+1)&&back_i!=ch)
//根据语句序号找到相应的语句
{
back_ch=ch;
for(;*(c+back_ch)!=')';back_ch--)
{continue;}
cout<<"sentence ("<<out[out_num-1]<<")--> ("<<*(c+back_ch-1)<<")"<<endl;
break; //输出转移
}
}
ch=0;
}
}
出口条件3
for(i=0;*(g+i)!='~';i++) //停语句为出口语句,找到停语句
{continue;}
back_i=i;
for(;*(g+back_i)!=')';back_i--)
{continue;}
out[out_num++]=*(g+back_i-1); //将语句序号放入out[] cout<<"_______________________________"<<endl<<endl;
cout<<"划分好的代码块:"<<endl;
for(i=0;i<4;i++)
{cout<<"Block[ "<<i+1<<" ]: ("<<in[i]<<") -- ("<<out[i]<<")"<<endl;}
//输出各基本块内的语句四.程序运行结果
1. 运行输入的四元式:
2. 输出结果:划分好的基本代码块
五.总结
这次我主要负责中间代码基本块的划分。

有了上次词法分析器的程序设计的经验,我以书中的实例为参考模型,进行编程,这样就避免了由空想带来的不必要的麻烦。

整个设计还是以c++中的模块化设计为主。

特别是在语句类型判断上,在编写代码时,虽然只要遵守判断规则,但仍然遇上了不困难,为了能方便的分块,使程序能更加简便、易懂,我还自行将语句按规则分为三类。

同时在这次设计过程中,也加强了我们的团队合作力,大家互相帮助,在交流过程中,也学习到不少他人在思考过程中的长处,弥补了自己不少欠考虑的地方,受益良多。

最后非常感谢卜老师给予的指导。

相关文档
最新文档