中间代码基本块划分

合集下载

编译原理第十一章解析

编译原理第十一章解析
25
26
此处要用到的有向图,是一种其结点带有下述标记或附 加信息的DAG: ① 图的叶结点,即无后继的结点,以一标识符(变 量名)或常数作为标记,表示这个结点代表该变量或常数 的值。如果叶结点用来代表某变量A的地址,则用addr (A)作为这个结点的标记。通常把叶结点上作为标记的 标识符加上下标0,以表示它是该变量的初值。 ② 图的内部结点,即有后继的结点,以一运算符作为 标记,表示这个结点代表应用该运算符对其后继结点所代 表的值进行运算的结果。 ③ 图中各个结点上可能附加一个或多个标识符,表 示这些变量具有该结点所代表的值。
30
下面是仅含0,1,2型四元式的基本块的DAG构造算法。
首先,DAG为空。 对基本块的每一四元式,依次执行: 1. 如果NODE(B)无定义,则构造一标记为B的叶结点并定 义NODE(B)为这个结点; 如果当前四元式是0型,则记NODE(B)的值为n,转4。 如果当前四元式是1型,则转2.(1)。 如果当前四元式是2型,则:(Ⅰ)如果NODE(C)无定义, 则构造一标记为C的叶结点并定义NODE(C)为这个结点,(Ⅱ) 转2.(2)。 2. (1) 如果NODE(B)是标记为常数的叶结点,则转2.(3), 否则转3.(1)。 (2) 如果NODE(B)和NODE(C)都是标记为常数的叶结 点,则转2.(4),否则转3.(2 (3) 执行op B(即合并已知量),令得到的新常数为P。如 果NODE(B)是处理当前四元式时新构造出来的结点,则删除它。 如果NODE(P)无定义,则构造一用P做标记的叶结点n。置NODE (P)=n,转4.。 (4) 执行B op C(即合并已知量),令得到的新常数为P。如 果NODE(B)或NODE(C)是处理当前四元式时新构造出来的结 点,则删除它。如果NODE(P)无定义,则构造一用P做标记的叶 结点n。置NODE(P)=n,转4.。

24第二十四讲

24第二十四讲

(16) …...
B4
代码外提后 B1 (1)i:=1 B2’ (3)t1:=2*j (7)t5:=2*j (6)t4:=a0-11 (10)t8:=a0-11
(2)if i>10 goto (16)
(4)t2:=10*i (8)t6:=10*i (11)t9:=t8[t7] (13)t4[t3]:=t10 (15)goto (2) (5)t3:=t2+t1 (9)t7:=t6+t5 (12)t10:=t9+1 (14)i:=i+1
删除多余运算,代码外提
(1)PROD := 0 (2)I := 1 (4)T2 := a0 – 4 (7) T5 := b0 – 4 (3) T1 := 4 * I (5)T3 := T2[T1] (6)T4 := T1 (8) T6 := T5[T4] (9) T7 := T3 * T6 (10) PROD := PROD + T7 (11) I := I +1 (12)if I≤20 goto (3)
优化后
S1 : = R + r A : = 6.28 * S1 S2 : = R - r B : = A * S2
五. 循环优化
1. 循环的定义 循环是程序流图中有唯一入口结点 的强连通子图。
(1)入口结点 子图中满足下列条件的结点n: 或者n是流图的首结点, 或者在子图外有一 结点m, 它有一有向边mn引向结点n; (2)强连通子图。
例:
1 2
{5,6,7,8,9}是一循环 {4,5},{2,4}均不是循环
3
4 5 6 7 8
9
10 图6-3
2. 循环的查找
(1)必经结点: 从流图的首结点出发到达结点 n的任一通路都必须经过的结点d, 称为n的 必经结点,记为d DOM n 根据定义可知: 每个结点是它本身的必经结点,即n DOM n 流图的首结点是流图中任一结点的必经结点, 即n0 DOM n

杭电编译原理名词解释

杭电编译原理名词解释

名词解析1.编译器: 一个编译程序就是一个语言翻译程序,它把一种语言(称作源语言)书写的程序翻译成另一种语言(称作目标语言)书写的等价的程序。

2.词法分析:从左至右读源程序,识别单词符号3.语法分析:在词法分析的基础上将单词序列组合成各类语法短语4.语义分析:语义检查,收集语义信息,进行类型审查5.代码优化:对中间代码进行优化(提高时间与空间效率6.遍:对源程序或源程序中间表示的一次扫描,每一遍读入一个文件,执行一个或几个阶段的编译操作,并输出源程序的一个中间表示7.上下文无关文法:所定义的的语法单位是完全独立于这种语法单位可能出现的上下文环境的8.推导与归约:推导是用产生式的右部代替左部,归约是用产生式的左部代替右部,归约是推导的逆过程9.最左/右推导:对句型最左/右非终结符进行展开10.最左/右规约:最右/左推导的逆过程,即对最左/右边的可归约串进行归约11.句型:从文法的开始符号出发进行零步或多于零步的推导得到的文法符号串12.句子:只包含终结符号的句型称为句子13.句柄:最左直接短语14.句子、文法、语言的二义性:如果一个文法的句子有两棵或两棵以上的分析树,称此句子是二义的如果一个文法有一个句子是二义的,此文法称为二义文法如果一个语言的所有文法都是二义的,称此语言是二义的15.正规表达式:一个表示字符串格式的模式,可以用来描述单词符号的结构16.有限自动机:是具有离散输入与离散输出的一种数学模型,输入字符串,输出是、否17.不确定的有限自动机:由状态集合,输入符号集合,转换函数,开始状态,接受状态集合组成18.确定的有限自动机:没有ε边转移且一个状态面临一个输入符号时最多只转移到一个状态的NFA19.自顶向下分析:从根到叶子来建立句子的分析树或,给出句子的一个从开始符号出发的推导序列20.自底向上分析:从叶子到根来建立句子的分析树或,给出一个从句子出发到开始符号的归约序列21.综合属性:属性值是分析树中该结点的子结点的属性值的函数22.继承属性:属性值是分析树中该结点的父结点和/或兄弟结点的属性值的函数23.S -属性定义:只含有综合属性的语法制导定义24.L -属性定义:是一种语法制导定义L-属性定义包含S-属性定义25.代码优化:对中间代码进行优化(提高时间与空间效率)26.基本块:·一个连续的三地址(中间)代码序列·只有一个入口语句,一个出口语句·执行时从入口语句进入,从出口语句退出27.活动记录:是一段连续的存储区,用以存放过程的一次执行所需要的信息,如局部数据。

编译原理_国防科技大学中国大学mooc课后章节答案期末考试题库2023年

编译原理_国防科技大学中国大学mooc课后章节答案期末考试题库2023年

编译原理_国防科技大学中国大学mooc课后章节答案期末考试题库2023年1.对于文法G(S'),该文法识别活前缀的DFA如下图,状态I5包含的项目有G(S'):(0) S' → S(1) S → iSeS(2) S → iS(3) S → a【图片】答案:S → iSeŸS_S → ŸiSeS_S → ŸiS_S → Ÿa2.(a+b)/(c-d)对应的逆波兰式(后缀式)是答案:ab+cd-/3.表达式(a+b)/c-(a+b)*d对应的间接三元式表示如下,其中三元式表中第(3)号三元式应为间接码表三元式表(1) OP ARG1 ARG2 (2) (1) + a b (1) (2) / (1)c (3) (3) (4) (4) - (2) (3)答案:( *, (1), d)4.设AS 为文法的综合属性集, AI 为继承属性集, 则对于下面的属性文法G(P)定义中,AS和AI正确描述是产生式语义规则P → xQR Q.b:=R.d R.c:=1R.e:=Q.a Q → u Q.a:=3 R → v R.d:=R.c R.f:=R.e答案:AS={ Q.a, R.d, R.f } AI={ Q.b, R.c, R.e }5.考虑下面的属性文法G(S)【图片】过程enter(name, type)用来把名字name填入到符号表中,并给出此名字的类型type。

按照该属性文法,关于语句【图片】 , 【图片】 , 【图片】:integr的语义描述准确的是答案:说明 , , 是integer变量,把 , , 三个名字填入符号表中,并在类型栏中填上integer6.考虑下面的属性文法G(S)【图片】对于输入字符串abc进行自下而上的语法分析和属性计算,设S.u的初始值为5,属性计算完成后,S.v的值为答案:187.关于属性文法,下列说法中正确的是答案:属性文法是对上下文无关文法的扩展。

编译原理阶段练习四

编译原理阶段练习四

编译原理练习四一、填空题1.编译过程中,常见的中间语言形式有四元式、三元式、逆波兰表示和树形表示。

2、表达式x+y≤z V a>0Λ(8+z)>3的逆波兰表示为 xy+z≤a0>8z+3>ΛV。

3、在编译程序中安排中间代码生成的目的是便于代码优化和便于目标程序的移植。

4、根据所涉及程序的范围,优化可分为局部优化、循环优化和全局优化三种。

5、编译程序进行数据流分析的目的是为了进行全局优化。

6.局部优化是局限与一个基本块范围内的一种优化。

7.基本块内可进行的优化有:删除公共子表达式、删除无用代码、合并已知常量等。

8.从词法分析器到中间代码生成与被编译的源代码有关,称之为编译器的前端,而目标代码生成主要与目标机有关,称之为编译器的后端。

9.编译器通常按需要把寄存器分为三组使用:可分配寄存器、保留寄存器和零用寄存器。

10.释放寄存器的总的原则是释放代价最小的寄存器。

二、选择题1.表达式-a+b*(-c+d)的逆波兰式是 d 。

a.ab+-cd+-*b.a-b+c-d+*c.a-bc+-d+*d.a-bc-d+*+2.在编译程序中安排中间代码生成的目的是 b d 。

a.便于进行存储空间的组织b.有利于目标代码的优化c.有利于编译程序的移植d.有利于目标代码的移植e.有利于提高目标代码的质量3.-a-(b*c/(c-d)+(-b)*a)的逆波兰表示是 c 。

a.abc*cd-b-a*+/--b.a-bc*cd-b-a*+/-c.a-bc*cd-/b-a*+-d.a-bc*/cd-b-a*+-4.赋值语句X:=-(a+b)/(c-d)-(a+b*c)的逆波兰表示是 c 。

a.Xab+cd-/-bc*a+-:=b. Xab+/cd-bc*a+--:=c. Xab+-cd-/abc*+-:=d. Xab+cd-/abc*+--:=5.对任何一个编译程序来说,产生中间代码是 b .a.不可缺少的b. 不一定必要的6.逆波兰表达式ab+cd+*所代表的中缀形式的表达式是 b 。

编译原理-第十章习题答案

编译原理-第十章习题答案

上一页
下一页
12
P:=0 for I:=1 to 20 do P:=P+A[I]*B[I]
(1)P:=0 (2)I:=1 (1)P:=0 (2)I:=1 (4)T2:=addr(A)-4 (7)T5:=addr(B)-4
(3)T1:=4*I (4)T2:=addr(A)-4 (5)T3:=T2[T1] (6)T4:=4*I (7)T5:=addr(B)-4 (8)T6:=T5[T4] (9)T7:=T3*T6 (10)P:=P+T7 (11)I:=I+1 (12)if I<=20 goto(3)
例: L1: if a<b goto L2 goto Lnext L2: if c<d goto L3 goto L4 L3: t1 =y+z x =t1 goto L1 L4:t2 = y-z x =t2 goto L1 L1:if a<b goto L2 L2:if c<d goto L3 goto L4 L3:t1 = y + z x = t1 goto L1
编译原理电子教案 第十章 优化
本章的主要内容
基本块的划分和流图的构建 基本块的DAG表示及基于DAG的局部优化 循环优化
上一页
下一页
2
本章要求
知识点:优化的基本概念及方法、基本块及程序流图、 DAG及基于DAG的优化、循环优化 熟练掌握: (1)局部优化:基本块,流图,DAG优化。 (2)循环优化:代码外提,强度削弱,删除归纳变量。
优化后: _tmp0 = 56 ; _tmp1 = _tmp0 – b ; a = _tmp1 ;
上一页 下一页
8
常数传播
_tmp4 = 0 ; f0 = _tmp4 ; _tmp5 = 1 ; f1 = _tmp5 ; _tmp6 = 2 ; i = _tmp6 ;

编译中间代码优化的CAI系统

编译中间代码优化的CAI系统
维普资讯
2 0 年第 2期 06

建 电

1 C 系统 AI
陈 欣
( 州 大 学 至 诚 学 院 福 建 福 州 3 0 0 ) 福 5 0 2
【 摘
要】 本 系统 用一种动 态的方法演示 了编译 中间代码 优化 的三 个基础 工作 的过程 : 基本块 的划分、 程序 流 图
{,,,,} 一 循 环 。 56 89是 7 由 节 点 序 列 { ,l 成 的 45组
子 图 是 强 连 通 的 ,但 4 5均 , 为 子 图 的 入 口节 点 所 以 子 图 {, } 是 循 环 。 45不 由 节 点 序 列 { ,} 成 的 2 组 4 子 图不 是 强 连 通 的 . 4与 2 之 间 虽 有 通 路 4 l — 2. 一 0 但
【 关键词 】 基 本块 程序 流图 必经节点 回边
1 引 言
3 2原 理 及 基本 算 法 、
・ 循 环 的 查 找
编 译 教 学 由 于具 有 其 十分 抽 象 的特 点 .学 生 在 掌 握 时 很 难 有 一 个 直 观 的 印 象 , 通 教 学 方 法 的效 果 往 往 不 好 。 写 这 个 系 普 编 统 的 目的 就 是 将 代码 优 化 过 程在 电脑 屏 幕 上 示 出 来 ,给 学 生 直观的印象 . 强教学效果 。 增 本 系 统 主 要 演示 以下 几 个 优 化 的过 程 : 分 基 本 块 、 造 流 划 构 图 、 环 的查 找 。用 户 输 入 任 何 一 段 代 码 . 统 将 自动 对 代 码 分 循 系 析 , 分 出基 本 块 , 后 , 据 基 本 块 的 关 系 画 出程 序 流 程 图 , 划 然 根 最 后 在 流 图 中 找 出 循环 。 些 过 程 不 仅 仅 是 在后 台运 行 、 且 要 将 这 而 每 一个 步 骤 显 示 出来 。 由于 系 统 在 动态 性 和 用 户 界 面 上 有 较 高 的 要求 .作 者 采 用 了 面 向对 象 的程 序 设 计 方 法解 决 了 动 态 性 问 题 . 用 了 D lh 40作 为 开 发 工 具 设 计 了 友 好 的 用 户 界 面 。为 使 e i. p 了 配合 课 堂上 教 师 的讲 解 , 系统 采 用 了 多 线 程 技 术 , 需 要 讲 解 在 时 可 以 随 时暂 停 演 示 , 可 以从 断 点处 恢 复 。 外 为 了 与 编 译 的 并 此 上 一 步 和下 一 步 的演 示 系 统 能 够 很 好 的 连 接 .也 为 了存 储 系 统 所 涉 及 到 的 数 据 ,作 者 采 用 了使 用 广 泛 的 P rdx作 为 数 据 接 aao 口 , 强 了 通 用性 和 可扩 展 性 。 增

目标代码生成

目标代码生成
R R0 VAR MEM
R1 …
R7
15
寄存器分配算法
• 一般在生成四元式A:=B OP C的代码中,通常把左操作 数B取到寄存器 R 中,再和C 操作( C可在内存中,也可 在寄存中),R中的结果就是A的值,或者说A占用了R. • 寄存器的分配可以用RGEREG(QUAD,R)实现,QUAD是 待分配寄存器的四元式: i: A:=B OP C , (OP,B,C,A) ; R是分配的寄存器。 (算法需查看附在四元式i上的活跃与引用信息及上表中 的结构)
Jrop P’;
7
§9.3 代码生成程序的雏形
• 为每个基本块的生成高质量代码:
– 总的指令条数要少; – 尽可能利用寄存器,少产生访问内存的指令,为 此需要充分合理的利用寄存器:
• 尽可能把后面还要引用的变量仍保存在寄存器中; • 应把不再使用的变量所占用的寄存器及时释放掉; • 为此需引入两个概念:基本块内变量的引用信息和 活跃信息。
end end;
13
四元式的附加信息
序 四元式 号 1 (-, A, B, T) 2 (+ , A, B, A) 3 (-, A, C, U) 4 (+, C, D, V) 5 (+, T, B, V) 6 (+, V, U, W) 结果 (5,Y) (3,Y) (6,Y) 左变 量 (2,Y) 右变 量 (2,Y)
符号表的变化情况
A (N, Y)→(3, Y)→(N, N)→(2, Y)→(1,Y)
B (N, Y)→(5, Y)→(2, Y)→ (1, Y) T (N, N)→(5, Y)→(N, N) C (N, Y)→(4, Y)→(3, Y) U (N, Y)→(6, Y)→(N, N)

软件设计师知识点汇总

软件设计师知识点汇总

1计算机系统组成运算器:算术/逻辑运算单元ALU、累加器ACC、寄存器组、多路转换器、数据总线组成。

控制器:计数器PC、时序产生器、微操作信号发生器,指令寄存器、指令译码器。

CPU的功能:程序控制、操作控制、时间控制、数据处理(最根本的)。

CACHE高速缓存的地址映像方法:直接地址映像(主存分区,区分块)、全相联映像(主存分块)、组相联映像(主存分区,区分块、块成组,CACHE 分块成组)。

替换算法:随机、先进先出、近期最少用、优化替换算法。

性能分析:H为CACHE命中率,t c为Cache存取时间、t m为主存访问时间,Cache等效访问时间t a=H t c+(1-H) t m提高了t m/t a倍。

虚拟存储器由主存、辅存、存储管理单元和操作系统软件组成。

相联存储器是按内容访问的,用于高速缓冲存储器、在虚拟存储器中用来作段表页表或快表存储器、在数据库和知识库中。

RISC精简指令集:指令种类少、长度固定、寻址方式少、最少的访内指令、CPU内有大量寄存器、适合流水线操作。

内存与接口统一编址:都在一个公共的地址空间里,独立使用各自的地址空间。

优点是内存指令可用于接口,缺点内存地址不连续,读程序要根据参数判断访内还是访接口。

廉价冗余磁盘阵列RAID:0级不具备容错能力但提高了传输率N倍、1级镜像容错技术、2级汉明码作错误检测、3级只用一个检测盘、4级是独立地对组内各磁盘进行读写的阵列,用一个检测盘、5级无专门检测盘。

中断方式处理方法:多中断信号线法、中断软件查询法、菊花链法(硬件)、总线仲裁法、中断向量表法(保存各中断源的中断服务程序的入口地址)。

直接存储器存取DMA:内存与IO设备直接成块传送,无需CPU干涉。

根据占据总线方法不同分为CPU停止法、总线周期分时法、总线周期挪用法。

输入输出处理机用于大型机:数据传送方式有字节多路方式、选择传送方式、数组多路方式。

指令流水线:操作周期是最慢的操作的时间。

什么是代码优化优化技术简介

什么是代码优化优化技术简介

4.变换循环控制条件 5.合并已知量与复写传播
(1)P:=0 (2)I:=1 (4)T2:=addr(A)-4 (7)T5:=addr(B)-4 (3)T1:=4*I (5)T3:=T2[T1] (6)T4:=T1 (8)T6:=T5[T4] (9)T7:=T3*T6 (10)P:=P+T7 (11)I:=I+1 (3’)T1:=T1+4 (12)if I<=20 goto(5)
1、图的叶结点,即无后继的结点,以一标识 符(变量名)或常数作为标记,表示该结点代 表该变量或常数的值。如果叶结点用来代表某 变量A的地址,则用addr(A)作为该结点的标 记。通常把叶结点上作为标记的标识符加上下 标0,以表示它是该变量的初值。
2、图的内部结点,即有后继的结点以一运算 符作为标记,表示该结点代表应用该运算符 对其后继结点所代表的值进行运算的结果。 3、图中各个结点上可能附加一个或多个标识 符,表示这些变量具有该结点所代表的值。
用DAG进行基本块的优化
四元式 0 型:A:=B(:=,B,-,A) 1 型: A:=op B(op,B, —,A)
2 型: A:=B op C(op, B, C,A)
DAG 结点 n1 n1 A B n2 A op n1 n1 B n3 A n3 op n2 n1 n2 n1 C B
DAG构造算法
B2
(1)
read (C) (2) A:= 0 (3) B:= 1 (4) L1: A:=A + B (5) if B>= C goto L2 (6) B:=B+1 (7) goto L1 (8) L2: write (A) (9) halt
划分成四个基本块 B1,B2,B3,B4 B1 (1) (2) (3) 基本块内实行的优化:合并已知量 删除多余运算 B2 (4) 删除无用赋值 (5) B3 (6) (7) B4 (8) (9)

三地址码划分基本块

三地址码划分基本块

三地址码划分基本块
三地址码的划分基本块是指将一个程序或函数的三地址码序列
划分为多个基本块的过程,基本块是一个连续的、不包含跳转语句的代码片段。

基本块具有以下特点:
从入口执行到出口,没有跳转到基本块中间的语句。

基本块的入口只能是第一条语句或是上一基本块的出口。

基本块的出口只能是最后一条语句或是下一基本块的入口。

下面是一个简单的示例来说明三地址码划分基本块的过程:
原始的三地址码序列:
1: x = a + b2: if x > c goto 53: y = a - b4: if y < z goto 65: w = a * b6: print(w)
划分后的基本块:基本块1:
1: x = a + b2: if x > c goto 5
基本块2:
3: y = a - b4: if y < z goto 6
基本块3:
复制代码
5: w = a * b6: print(w)
基本块的划分通常通过遍历三地址码序列,根据跳转语句(如条件语句、无条件跳转等)的出现来确定基本块的边界。

划分基本块是许多编译器优化和代码生成算法的基础,它能够帮助对程序进行更好的分析和优化。

basic block 基本块

basic block 基本块

basic block 基本块基本块(basic block)是在程序控制流图中的一段连续的代码,它包含了一组顺序执行的指令。

在编译器优化和静态分析中,基本块是一个重要的概念。

本文将对基本块进行详细介绍,并探讨其在编译器优化和静态分析中的应用。

一、基本块的定义基本块是一段连续的代码,它由一组顺序执行的指令组成。

基本块的起始指令称为入口指令(entry instruction),结束指令称为出口指令(exit instruction)。

基本块中的每一条指令都会被执行一次,且不存在跳转指令(如条件跳转、函数调用等)。

二、基本块的特点1. 基本块是一个不可分割的执行单元,不存在内部的跳转指令。

2. 基本块的入口只有一个,即入口指令。

3. 基本块的出口只有一个,即出口指令。

4. 基本块中的指令顺序是线性的,不会出现分支或循环结构。

三、基本块的构建方法基本块的构建方法有多种,常见的有以下两种:1. 直接法(straight-line code method):根据程序的控制流图,将连续的指令序列构建为一个基本块。

当遇到跳转指令时,会将其后续的指令序列构建为一个新的基本块。

2. 划分法(partition method):通过分析程序的控制流图,将指令序列划分为多个基本块。

划分基本块的依据通常是跳转指令或标签。

四、基本块的应用基本块在编译器优化和静态分析中有着重要的应用,主要包括以下几个方面:1. 代码优化:编译器可以对基本块进行各种优化,例如循环展开、常量传播、死代码消除等。

基本块的线性结构使得这些优化可以更加精确地应用于代码中的特定区域,从而提高程序的执行效率。

2. 控制流分析:静态分析工具可以通过对基本块的分析,获取程序的控制流信息。

例如,可以检测循环结构、判断条件的复杂度、函数调用的层次等,从而帮助开发人员理解和调试程序。

3. 污点分析:基于基本块的污点分析可以跟踪程序中的敏感数据,如用户输入或密码。

中间代码基本块划分

中间代码基本块划分

中间代码基本块的划分任务要求在理解代码优化原理的基础上,实现将中间代码序列划分基本块的程序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 (以“~ ”表示)三. 部分代码:入口条件1int 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 3Block 2Block 4 Block 1入口条件2for(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[]出口条件1out[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;}入口条件3for(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[] }}出口条件2for(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;}}出口条件3for(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. 输出结果:划分好的基本代码块五.总结这次我主要负责中间代码基本块的划分。

基本块Basic

基本块Basic

基本块Basic Block(BBL)
基本块:
- 定义:
·⼀个连续的三地址(中间)代码序列
·只有⼀个⼊⼝语句,⼀个出⼝语句
·执⾏时从⼊⼝语句进⼊,从出⼝语句退出
- 基本块的划分
·寻找⼊⼝语句
1、程序的第⼀条语句
2、转移语句的⽬标语句
3、紧跟在条件转移语句后⾯的语句
1. 只有⼀个⼊⼝,表⽰程序中不会有其它任何地⽅能通过jump跳转类指令进⼊到此基本块中。

2. 只有⼀个出⼝,表⽰程序只有最后⼀条指令能导致进⼊到其它基本块去执⾏。

所以,基本块的⼀个典型特点是:只要基本块中第⼀条指令被执⾏了,那么基本块内所有执⾏都会按照顺序仅执⾏⼀次。

Compilers usually decompose programs into their basic blocks as a first step in the analysis process. Basic blocks form the vertices or nodes in a control flow graph.。

basic block划分

basic block划分

basic block划分
基本块(Basic Block)是计算机程序中的一个基本概念,它是一个连续的、不包含跳转指令(如条件分支或跳转语句)的指令序列。

在控制流图(Control Flow Graph)中,基本块通常是一段无条件分支的代码,它的执行一旦开始,就会一直执行到块的末尾。

基本块划分是程序分析和优化的一个重要步骤。

基本块划分可以通过以下几个步骤来完成:
1.识别入口点:选择程序的入口点,通常是main函数或其他
程序的起始点。

2.识别基本块首部:从入口点开始,识别每个基本块的首部。


本块的首部通常是一个目标指令(跳转或条件分支的目标)或一个入口
指令(程序的第一条指令)。

3.追踪控制流:通过分析每个指令的执行路径,追踪控制流,确
定每个基本块的边界。

这通常涉及到识别分支指令,例如条件分支、无
条件分支等。

4.构建基本块:将每个基本块的首部和尾部之间的指令序列组成
一个基本块。

5.递归处理:对于每个分支目标,递归地执行上述步骤,直到程
序的所有指令都被分配到基本块。

基本块划分完成后,控制流图将被表示为一个基本块的有向图,其中每个基本块是一个节点,图中的边表示控制流的转移。

基本块划分有助于理解程序的控制流结构,是许多程序分析和优化技术的
基础。

在编译器优化、静态分析和反汇编等领域,基本块划分都是常见的操作。

基本块的划分方法

基本块的划分方法

基本块的划分方法
基本块的划分是一种将程序代码分割成可处理单元的方法,即将
程序代码按照一定的规则划分成块,每个块单独执行。

基本块的划分
是编译器对代码进行优化的基础,它可以提高代码的执行效率和可读性。

基本块的划分方法主要有三种:源代码级基本块、汇编代码级基
本块和数据流基本块。

源代码级基本块的划分是根据程序源代码中的控制流语句,如条
件分支、循环结构等进行划分。

每个基本块包含一个入口和一个出口,只有当程序执行到基本块的入口时,才会执行整个基本块,然后跳转
到下一个基本块。

该方法适用于高级语言编译器。

汇编代码级基本块的划分是根据汇编代码中的跳转指令进行划分,例如条件分支、跳转等指令。

该方法适用于汇编代码级处理器。

数据流基本块的划分是根据程序中的数据流关系进行划分。

数据
流基本块的入口是数据的定义点,出口是数据的使用点。

该方法适用
于动态分析技术。

在实际应用过程中,可以根据具体的需求选择不同的基本块划分
方法。

基本块的划分可以为编译器进行代码优化提供基础,同时也为
程序员进行代码优化提供了思路。

在编写高质量代码时,我们应注意
控制流语句的数量,尽可能减少嵌套和重复代码的出现,这样可以有效提高代码的可读性和运行效率。

  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[]
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;}
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++中的模块化设计为主。

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

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

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

THANKS !!!
致力为企业和个人提供合同协议,策划案计划书,学习课件等等
打造全网一站式需求
欢迎您的下载,资料仅供参考。

相关文档
最新文档