第十一章 代码生成

31
第第 第第第第 第第 第第第第 代代代代代代代代代代代代 代代代代代代代代( 代代代代代代代代代代代代代代代代代代代代代) dag 代代代代

description

第十一章 代码生成. 代码生成要考虑的主要问题 基本块的代码生成 ( 在一个基本块范围内考虑如何充分利用寄存器的问题 ) 从 dag 生成代码. 11.1 代码生成要考虑的主要问题. —— 具体细节依赖于目标机器和操作系统. 共同的问题:. 充分利用寄存器基本块中全局寄存器分配: 不把寄存器平均分配给各个变量使用,而是从可用的寄存器中分出几个,固定分配给几个变量单独使用。 标准: 以各变量在 循环内 需要访问 主存单元 的 次数 为标准。 选择计算机指令系统 选择计算次序. 目标代码的三种形式. 地址代真的机器代码 待装配的机器代码模块 - PowerPoint PPT Presentation

Transcript of 第十一章 代码生成

Page 1: 第十一章    代码生成

第十一章 代码生成第十一章 代码生成

代码生成要考虑的主要问题

基本块的代码生成(在一个基本块范围内考虑如何充分利用寄存器的问题)

从dag生成代码

Page 2: 第十一章    代码生成

11.1 11.1 代码生成要考虑的主要问题代码生成要考虑的主要问题—— 具体细节依赖于目标机器和操作系统

共同的问题:共同的问题:充分利用寄存器基本块中全局寄存器分配:充分利用寄存器基本块中全局寄存器分配:

不把寄存器平均分配给各个变量使用,而是从不把寄存器平均分配给各个变量使用,而是从可用的寄存器中分出几个,固定分配给几个变量可用的寄存器中分出几个,固定分配给几个变量单独使用。单独使用。标准:标准:以各变量在以各变量在循环内循环内需要访问需要访问主存单元主存单元的的次次数数为标准。为标准。

选择计算机指令系统选择计算机指令系统

选择计算次序选择计算次序

Page 3: 第十一章    代码生成

目标代码的三种形式目标代码的三种形式

地址代真的机器代码地址代真的机器代码待装配的机器代码模块待装配的机器代码模块汇编语言(宏汇编)汇编语言(宏汇编)

机器指令形式机器指令形式(op source ,destination)(op source ,destination)ADD s,d // d+s ADD s,d // d+s SUB s,d //d-s SUB s,d //d-s MOV s,d //s MOV s,d //s d d

机器指令开销 机器指令开销 (cost)(cost)

MOV R,M MOV R,M 开销 开销 22ADD #1 ,R ADD #1 ,R 开销 开销 22MOV R0,R1 MOV R0,R1 开销 开销 11

Page 4: 第十一章    代码生成

目标机器的地址方式目标机器的地址方式

地址方式地址方式 汇编形式汇编形式 地址地址 增加的开销增加的开销

直接地址方式直接地址方式 MM MM 11

寄存器方式寄存器方式 RR RR 00

间接寄存器方式间接寄存器方式 *R*R contents(R)contents(R) 00

索引方式索引方式 c(R)c(R) c+contents(R)c+contents(R) 11

间接索引方式间接索引方式 *c(R)*c(R) contents(contents(c+contents(R))c+contents(R)) 11

Page 5: 第十一章    代码生成

例例 11 :: a:=b+ca:=b+c

1. 1. MOVMOV    b, b, RR00

ADDADD    c,c, RR00 cost=6cost=6MOVMOV    RR00, , aa

2.2. MOVMOV    b,b, aaADD ADD    c,c, aa cost=6cost=6

假定假定 RR00, R, R11 和和 RR22 中分别存放了中分别存放了 a, ba, b 和和 cc 的地址的地址 , , 采用采用 ::3.3. MOVMOV *R *R11,, *R*R00

ADDADD *R *R22,, *R*R00 cost=2 cost=2

假定假定 RR11 和和 RR22 中分别包含中分别包含 bb 和和 cc 的值的值 , , 并且并且 bb 的值在的值在这个赋值以后不再需要这个赋值以后不再需要 , , 则还可有则还可有4.4. ADDADD R R22,, RR11

MOVMOV R R11,, aa cost=3cost=3

Page 6: 第十一章    代码生成

例例 22 : : T4:=A+B-(E-(C+D))T4:=A+B-(E-(C+D))

MOV A,R0MOV A,R0ADD B,R0ADD B,R0MOV C,R1MOV C,R1ADD D,R1ADD D,R1MOV R0,T1MOV R0,T1MOV E, R0MOV E, R0SUB R1,R0SUB R1,R0MOV T1,R1MOV T1,R1SUB R0,R1SUB R0,R1MOV R1, T4MOV R1, T4

T1:= A+BT1:= A+BT2:= C+DT2:= C+DT3:= E-T2T3:= E-T2T4:= T1-T3T4:= T1-T3

T2:= C+DT2:= C+DT3:= E-T2T3:= E-T2T1:= A+BT1:= A+BT4:= T1-T3T4:= T1-T3

MOV C,R0 MOV C,R0

ADD D,R0ADD D,R0

MOV E,R1MOV E,R1

SUB R0,R1SUB R0,R1

MOV A,R0MOV A,R0

ADD B, R0ADD B, R0

SUB R1,R0SUB R1,R0

MOV R0,T4 MOV R0,T4

或或

Page 7: 第十一章    代码生成

11.2 11.2 简单的代码生成器 (基本块简单的代码生成器 (基本块内)内)

在一个基本块范围内考虑如何充分利用寄存器的问题:在一个基本块范围内考虑如何充分利用寄存器的问题:尽可能地让该变量的值保留在寄存器中尽可能地让该变量的值保留在寄存器中尽可能引用变量在寄存器中的值尽可能引用变量在寄存器中的值

待用信息:待用信息:若在一个基本块中,变量若在一个基本块中,变量 AA 在四元式在四元式 ii 中被定中被定值,在值,在 ii 后面的四元式后面的四元式 jj 中要引用中要引用 AA 值,且从值,且从 ii 到到 jj 之间之间没有其它对没有其它对 AA 的定值点,这时我们称的定值点,这时我们称 jj 是四元式是四元式 ii 中对变中对变量量 AA 的的待用信息待用信息或称或称下次引用信息下次引用信息,同时也称,同时也称 AA 是活跃的是活跃的,,若若 AA 被多次引用则可构成被多次引用则可构成待用信息链待用信息链与与活跃信息链活跃信息链。。

可从基本块的可从基本块的出口出口由后向前由后向前扫描,对每个变量建立相应扫描,对每个变量建立相应的待用信息链和活跃变量信息链。的待用信息链和活跃变量信息链。

Page 8: 第十一章    代码生成

计算待用信息的算法:计算待用信息的算法:

1 1 符号表中增加“待用信息”栏和“活跃信息”栏符号表中增加“待用信息”栏和“活跃信息”栏

对各基本块的符号表中的“待用信息”栏和“活跃信对各基本块的符号表中的“待用信息”栏和“活跃信息”栏置初值,即把息”栏置初值,即把“待用信息”栏“待用信息”栏置“置“非待用非待用”,”,对对“活跃信息”栏“活跃信息”栏按在基本块按在基本块出口处出口处是否为活跃而置是否为活跃而置成“成“活跃活跃”或“”或“非活跃非活跃”。”。

这里假定这里假定变量变量都是活跃的,都是活跃的,临时变量临时变量都是非活跃的。都是非活跃的。

Page 9: 第十一章    代码生成

2 2 从基本块从基本块出口出口到基本块到基本块入口入口由后向前由后向前依次处理每个四元依次处理每个四元式。对每个四元式式。对每个四元式 i: i: A:=B op CA:=B op C ,依次执行下述步骤:,依次执行下述步骤:

1)1) 把符号表中变量把符号表中变量 AA 的的待用信息待用信息和和活跃信息活跃信息附加到四附加到四元式上。元式上。

2)2) 把符号表中变量把符号表中变量 AA 的待用信息栏和活跃信息栏分别的待用信息栏和活跃信息栏分别置为置为““非待用非待用”和“”和“非活跃非活跃”。(”。(由于在由于在 ii 中对中对 AA的定值只能在的定值只能在 ii 以后的四元式才能引用,因而对以后的四元式才能引用,因而对 ii 以以前的四元式来说前的四元式来说 AA 是不活跃也不可能是待用的是不活跃也不可能是待用的))

3)3) 把符号表中变量把符号表中变量 BB 和和 CC 的待用信息和活跃信息附加的待用信息和活跃信息附加到四元式到四元式 ii 上。 上。

4)4) 把符号表中变量把符号表中变量 BB 和和 CC 的待用信息栏置为“的待用信息栏置为“ i” i” ,,活跃信息栏置为“活跃”。活跃信息栏置为“活跃”。

注意,以上注意,以上 1)1) 和和 2)2) ,, 3)3) 和和 4)4) 的次序不能颠倒。的次序不能颠倒。

Page 10: 第十一章    代码生成

例: 若用 A , B , C , D 表示变量,用 T ,U , V 表示中间变量,有四元式如下:( 1 ) T:=A-B( 2 ) U:=A-C( 3 ) V:=T+U( 4 ) D:=V+U

其名字表中的待用信息和活跃信息如下表,用“ F” 表示“非待用”“非活跃”,用“ L” 表示活跃。(1)(2)(3)(4) 表示四元式序号。

Page 11: 第十一章    代码生成

待用信息和活跃信息 变变量量名名

待用信息待用信息 活跃信息活跃信息初值初值 待用信息链待用信息链 初值初值 活跃信息链活跃信息链

AA FF     

(2)(2) (1)(1) LL     

LL LL

BB FF        

(1)(1) LL        

LL

CC FF     

(2)(2)  

LL     

LL  

DD FF FF        

LL FF        

TT FF  

(3)(3)  

FF FF  

LL  

FF

UU FF (4)(4) (3)(3) FF  

FF LL LL FF  

VV FF (4)(4) FF     

FF LL FF     

表中“待用信息链”与“活跃信息链”的表中“待用信息链”与“活跃信息链”的每列每列从左至右从左至右为每从后为每从后向前扫描一个四元式时相应变量的信息变化情况,空白处为没变向前扫描一个四元式时相应变量的信息变化情况,空白处为没变化。化。 待用信息和活跃信息在四元式上的标记如下所示:待用信息和活跃信息在四元式上的标记如下所示:

(1) T(1) T(3)L(3)L:=A:=A(2)L(2)L-B-BFLFL (2) U(2) U(3)L(3)L:=A:=AFLFL-C-CFLFL

(3) V(3) V(4)L(4)L:=T:=TFFFF+U+U(4)L(4)L (4) D(4) DFLFL:=V:=VFFFF+U+UFFFF

Page 12: 第十一章    代码生成

  寄存器描述和地址描述 为随时掌握各寄存器的情况, 寄存器描述数组 RVALUE: 描述每个寄存器当前的状况 变量地址描述数组 AVALUE :表示变量的存放情况     基本块的代码生成算法 假设只有 A:=B op C 的四元式序列

A) 对每个四元式 i: A:=B op C ,依次执行下述步骤:

a)    以四元式 i: A:=B op C 为参数,调用过程 getreg(i: A:=B op C) 。从 getreg 返回时,得到一寄存器 R ,用它作存放 A 现行值的寄存器;b)    利用 AVALUE[B] 和 AVALUE[C] ,确定出 B 和C 现行值存放位置 B` 和 C` ,如果其现行值在寄存器中,则把寄存器取作 B` 和 C` ;

Page 13: 第十一章    代码生成

       1) 如 B`≠R ,则生成目标代码 LD R , B` op R , C` 否则,生成目标代码 op R , C`

如 B` 或 C` 为 R ,则删除 AVALUE[B] 或 AVALUE[C] 中的 R

2) 令 AVALUE[B]={R} ,并令 RVALUE[R]={A} ,以表示变量 A 的现行值只在 R 中并且 R 中的值只代表 A 的现行值;

3) 如 B 或 C 的现行值在基本块中不再被引用,它们也不是基本块出口之后的活跃变量 ( 由四元式 i 上的附加信息知道 ), 并且其现行值在某个寄存器 Rk 中,则删除 RVALUE[Rk] 中的 B 或 C 以及 AVALUE[B] 或 AVALUE[C] 中的Rk ,使该寄存器不再为 B 或 C 所占用。

B) 处理完基本块中所有四元式之后,对现行值在某寄存器 R 中的每个变量 M ,若它在出口之后使活跃的,则生成 STR, M ,放到主存中。

Page 14: 第十一章    代码生成

d:=(a-b)+(a-c)+(a-c)d:=(a-b)+(a-c)+(a-c)

t:=a-bt:=a-b

u:=a-cu:=a-c

v:=t+uv:=t+u

d:=v+ud:=v+u

其中假定其中假定 dd 在基本块的出口是活跃的。在基本块的出口是活跃的。

Page 15: 第十一章    代码生成

代码序列代码序列

语句语句 生成的代码生成的代码 寄存器描述器寄存器描述器 地址描述器地址描述器

t: = at: = a -- bbMOV a,RMOV a,R

00

SUB b,RSUB b,R00

空寄存器空寄存器RR00 包含包含 tt

tt 在在 RR00 中中

u: = au: = a -- ccMOV a,RMOV a,R

11

SUB c,R1SUB c,R1

RR00 包含包含 tt

RR11 包含包含 uutt 在在 RR00 中中uu 在在 RR11 中中

v: = tv: = t ++ uu ADD RADD R11,R,R00

RR00 包含包含 vv

RR11 包含包含 uuuu 在在 RR11 中中vv 在在 RR00 中中

d: = vd: = v ++ uuADD RADD R

11,R,R00

MOV RMOV R00,d,d

RR00 包含包含 dddd 在在 RR00 中中

dd 在在 RR00 中和存储器中中和存储器中

Page 16: 第十一章    代码生成

11. 3 11. 3 从从 dagdag 生成目标代码生成目标代码例:赋值语句例:赋值语句 T4:=A+B-(E-(C+D))T4:=A+B-(E-(C+D))

四元式序列四元式序列 GGT1:=A+BT1:=A+BT2:=C+DT2:=C+DT3:=E-T2T3:=E-T2T4:=T1-T3T4:=T1-T3

DAGDAG

A B EA B E

C DC D

n9n9

n3n3 n8n8

n1n1 n2n2 n7n7 n6n6

n4n4 n5n5

T4T4

T1T1 T3T3

T2T2

++

--

--

++

MOV A,R0MOV A,R0

ADD B,R0ADD B,R0

MOV C,R1MOV C,R1

ADD D,R1ADD D,R1

MOV R0,T1MOV R0,T1

MOV E, R0MOV E, R0

SUB R1,R0SUB R1,R0

MOV T1,R1MOV T1,R1

SUB R0,R1SUB R0,R1

MOV R1, T4MOV R1, T4

Page 17: 第十一章    代码生成

T2:=C+D MOV C,R0 T2:=C+D MOV C,R0 T3:=E-T2 ADD D,R0T3:=E-T2 ADD D,R0T1:= A+B MOV E,R1T1:= A+B MOV E,R1T4:=T1-T3 SUB R0,R1T4:=T1-T3 SUB R0,R1 MOV A,R0MOV A,R0 ADD B, R0ADD B, R0 SUB R1,R0SUB R1,R0 MOV R0,T4MOV R0,T4

T4T4 的计算紧跟在的计算紧跟在 T1T1 之后之后

Page 18: 第十一章    代码生成

尽可能使尽可能使一个结点的求值一个结点的求值紧接着紧接着它的它的最左变量最左变量的求值之的求值之后后启发式排序算法启发式排序算法(1) while(1) while 存在未列入表的内部结点存在未列入表的内部结点 dodo

(2) begin(2) begin 选取一个未列入表的但其全部父结点均已列 选取一个未列入表的但其全部父结点均已列 入表的结点入表的结点 n; n;

(3) (3) 将将 nn 列入表中列入表中 ; ;

(4) while n(4) while n 的最左子结点的最左子结点 mm 不是叶结点并且其所有不是叶结点并且其所有 父结点均已列入表中父结点均已列入表中 dodo

(5) begin(5) begin 将将 mm 列入表中列入表中 ;;

(6) (6) n: =mn: =m

(7) end(7) end

(8) end(8) end

Page 19: 第十一章    代码生成

3t2t:1t4t6t:2t

e4t:3t8t5t:4t

c6t:5t

ba:6t

ed:8t

Page 20: 第十一章    代码生成

基于树重写的代码生成

例 :: =: =

indind ++

MembMemb const1const1

indind

++

consticonsti regspregsp

constaconsta regspregsp

++

++

Page 21: 第十一章    代码生成

regiregi ++ {ADD R{ADD Rjj,R,Rii}}

regiregi regjregj

Page 22: 第十一章    代码生成

(1) regi constc {MOV #c, Ri} (2) regi mema {MOV a, Ri} (3) mem

{MOV Ri, a}

(4) mem

{MOV Rj, *Ri}

(5) regi

{MOV c(Rj), Ri}

: =

mema regi

: =

mema regj

ind

constc regj

regi

+

Page 23: 第十一章    代码生成

(6) regi

{ADD c(Rj), Ri}

(7) regi

{ADD Rj, Ri}

(8) regi

{INC Ri}

+

regi ind

constc regj

+

+

regi cost1

+

regi regj

Page 24: 第十一章    代码生成

(1) Reg0 consta {MOV #a, R0}

(7) reg0

{ADD SP, R0}

+

reg0 regSP : =: =

indind ++

MemMembb constconst11

indind

++

constconstii regregSPSP

regreg00

++

Page 25: 第十一章    代码生成

ind

consti regSP

+

+

reg0 ind

consti regSP

+

: =

ind

reg0

+

memb

const1

Page 26: 第十一章    代码生成

+

reg1 const1

: =

ind reg1

reg0

MOV #a, RMOV #a, R00

ADD ADD SP, R SP, R00

ADD ADD i(SP),R i(SP),R00

MOV b,RMOV b,R11

INC INC R R11

MOV RMOV R11, *R, *R00

Page 27: 第十一章    代码生成

编译程序要求:编译程序要求:1. 1. 概述概述 : : 源、目标语言源、目标语言

实现工具(平台)实现工具(平台)运行平台运行平台

2. 2. 结构设计说明结构设计说明各功能模块描述各功能模块描述

3. 3. 主要成分描述主要成分描述(1) (1) 符号表符号表(2) (2) 运行时存储组织和管理运行时存储组织和管理(3) (3) 语法分析方法语法分析方法(4) (4) 中间代码表示中间代码表示

4. 4. 开发过程和完成情况开发过程和完成情况

Page 28: 第十一章    代码生成

补充 1 :程序设计语言的计算模型            命令式或过程式语言命令式或过程式语言            应用式应用式 (Applicative)(Applicative) 或函数式或函数式

应用式语言应用式语言 :Lisp:Lisp 和和 ML ML

语法语法 :function n(……function 2(function 1(data))……):function n(……function 2(function 1(data))……)

一个个函数应用在数据上的变换,最终得到一个结果。一个个函数应用在数据上的变换,最终得到一个结果。          基于规则基于规则 (rule_based)(rule_based) 的和面向对象的的和面向对象的

(object_oriented)(object_oriented)程序的执行式通过检查使能条件,决定执行一个适当的程序的执行式通过检查使能条件,决定执行一个适当的

动作。如动作。如 prologprolog ,, yaccyacc

语法:使能条件语法:使能条件 1 →1 → 动作动作 11

使能条件使能条件 2 →2 → 动作动作 22 ....

使能条件 使能条件 n →n → 动作动作 nn

Page 29: 第十一章    代码生成

O-OO-O 程序设计程序设计已经变成越来越重要的已经变成越来越重要的计算模式;面向对象的程序设计语言计算模式;面向对象的程序设计语言支持支持抽抽象数据类型象数据类型和和继承性继承性,即将数据和对数据的,即将数据和对数据的操作放在一起,定义一组具有公共行为属性操作放在一起,定义一组具有公共行为属性和数据类型的对象,由和数据类型的对象,由类类机制将这组对象给机制将这组对象给予抽象表示。予抽象表示。

  

Page 30: 第十一章    代码生成

补充 2 :语言应用环境四种应用环境:批处理环境,交互环境,嵌入式系统四种应用环境:批处理环境,交互环境,嵌入式系统

和编程环境和编程环境          批处理环境批处理环境:一个程序输入一组数据文件,处理:一个程序输入一组数据文件,处理

这些数据,然后生成一组输出文件。这些数据,然后生成一组输出文件。          交互环境交互环境:程序在执行过程中直接和用户在显示:程序在执行过程中直接和用户在显示

控制台上交互,不断从键盘或鼠标接受输入,将输控制台上交互,不断从键盘或鼠标接受输入,将输出发送到显示器上。出发送到显示器上。

          嵌入式系统环境嵌入式系统环境::1.1.            没有操作系统,没有文件,直接和非标准的没有操作系统,没有文件,直接和非标准的 I/OI/O

设备交互;设备交互;2.2.            出错处理非常重要;出错处理非常重要;3.3.            常常是实时地操作;常常是实时地操作;4.4.            常常是一个分布式系统(并行)常常是一个分布式系统(并行)描述并行任务的语言——并行编译系统描述并行任务的语言——并行编译系统

Page 31: 第十一章    代码生成

       程序设计实现环境环境包括环境包括 编辑器编辑器 (editors) (editors) 调试器调试器 (debuggers)(debuggers)

验证验证 (verifiers)(verifiers) 测试数据测试数据 (test data generator)(test data generator) 打印 打印 (pretty printers)(pretty printers)

语言设计语言设计::1.1.            帮助独立编译(帮助独立编译( seperate compilationseperate compilation )和)和

成分(成分( componentcomponent )汇编)汇编 (assemblly)(assemblly)2.2.            可设断点,追踪执行,帮助程序测试和可设断点,追踪执行,帮助程序测试和 debdeb

uggingugging