名字的运行时刻地址 在三地址语句中使用名字(实际上是指向符号表条 目)来引用变量 。语句X=0 如果x分配在静态区域,◇且静态区开始位置为static 。 static[12]=0 LD 112,#0 /static 100 如果x分配在栈区,且相对地址为12,则 。LD12(SP),#0 16
名字的运行时刻地址 • 在三地址语句中使用名字 (实际上是指向符号表条 目) 来引用变量 • 语句x = 0 – 如果x分配在静态区域,且静态区开始位置为static • static[12] = 0 LD 112, #0 // static = 100 – 如果x分配在栈区,且相对地址为12,则 • LD 12(SP), #0 16 南大编译许畅
基本块和流图 。中间代码的流图表示法 中间代码划分成为基本块Basic block) 控制流只能从基本块的第一条指令进入 除基本块的最后一条指令外,控制流不会跳转/停机 流图的结点是基本块,流图的边指明了哪些基本块可 以跟在一个基本块之后运行 ·流图可以作为优化的基础 它指出了基本块之间的控制流 可以根据流图了解到一个值是否会被使用等信息 17
基本块和流图 • 中间代码的流图表示法 – 中间代码划分成为基本块 (Basic block) • 控制流只能从基本块的第一条指令进入 • 除基本块的最后一条指令外,控制流不会跳转/停机 – 流图的结点是基本块,流图的边指明了哪些基本块可 以跟在一个基本块之后运行 • 流图可以作为优化的基础 – 它指出了基本块之间的控制流 – 可以根据流图了解到一个值是否会被使用等信息 17 南大编译许畅
划分基本块的算法 输入:三地址指令序列 。输出:基本块的列表 。方法 确定首指令leader(基本块的第一个指令) 。第一个三地址指令 任意一个(条件或无条件)转移指令的目标指令 紧跟在一个(条件或无条件)转移指令之后的指令 确定基本块 。每个首指令对应于一个基本块:从首指令开始到下一个首指令 18
划分基本块的算法 • 输入:三地址指令序列 • 输出:基本块的列表 • 方法 – 确定首指令leader (基本块的第一个指令) • 第一个三地址指令 • 任意一个 (条件或无条件) 转移指令的目标指令 • 紧跟在一个 (条件或无条件) 转移指令之后的指令 – 确定基本块 • 每个首指令对应于一个基本块:从首指令开始到下一个首指令 18 南大编译许畅
基本块划分的例子 1=1 。第一个指令 1) j=1 1 t1=10*1 4) t2= t1+j 。 跳转指令的目标指令 5) t3=8*t2 3,2,13 6 t4=t3-88 a[t4]=0.0 。 跳转指令的下一条指令 j=j + 1 9 if j<= 10 goto (3) 1012 10) i=i+ 1 11) 。 基本块 if i <10 goto (2) 12) i=1 1-1,2-2,3-9,10-11,12-12, 13) t5=1-1 14) t6=88*t5 13-17 15) a[t6]=1.0 16) i=i+1 17) if i <10 goto (13) 19
基本块划分的例子 • 第一个指令 – 1 • 跳转指令的目标指令 – 3, 2, 13 • 跳转指令的下一条指令 – 10, 12 • 基本块 – 1-1, 2-2, 3-9, 10-11, 12-12, 13-17 19 南大编译许畅
后续使用信息 。变量值的使用 三地址语句i向变量x赋值,如果另一个语句i的运算分 量为x,且从开始有一条路径到达j,且路径上没有对x 赋值,那么j就使用了i处计算得到的x的值 我们说变量x在语句后的程序点上活跃 程序执行完语句时,x中存放的值将被后面的语句使用 不活跃是指变量的值不会被使用,而不是变量不会被使用 。这些信息可以用于代码生成 如果x在处不活跃,且x占用了一个寄存器,我们可以 把这个寄存器用于其它目的 20
后续使用信息 • 变量值的使用 – 三地址语句i向变量x赋值,如果另一个语句j的运算分 量为x,且从i开始有一条路径到达j,且路径上没有对x 赋值,那么j就使用了i处计算得到的x的值 – 我们说变量x在语句i后的程序点上活跃 • 程序执行完语句i时,x中存放的值将被后面的语句使用 • 不活跃是指变量的值不会被使用,而不是变量不会被使用 • 这些信息可以用于代码生成 – 如果x在i处不活跃,且x占用了一个寄存器,我们可以 把这个寄存器用于其它目的 20 南大编译许畅