代码生成中的流程图
基本块是语句的简单组合。除了入口和出口外,基本块没有像进出那样的任何分支。这意味着控制流在开始时进入并且总是在结束时离开而没有任何停止。基本块的一组指令的执行总是以序列的形式发生。
第一步是将一组三地址码分成基本块。新的基本块总是从第一条指令开始并继续添加指令,直到到达跳转或标号。如果没有识别到跳转或标签,则控制将按顺序从一条指令流向下一条指令。
下面分步描述构建基本块的算法:
算法:这里使用的算法是将三地址代码划分为基本块。
输入:一系列三地址代码将作为基本块的输入。
输出:每三个地址语句的基本块列表,恰好在一个块中,被视为输出。
方法:我们将从识别中间代码的领导者开始。以下是识别领导者的一些准则:
- 中间代码中的第一条指令一般被认为是前导。
- 以条件或无条件跳转语句为目标的指令可以被视为前导。
- 任何在有条件或无条件跳转语句之后的指令都可以被认为是领导者。
每个领导者的基本块将包含来自领导者的所有指令,直到下一个领导者开始之前的指令。
基本块示例:
表达式 a = b + c – d 的三个地址代码为:
T1 = b + c
T2 = T1 - d
a = T2
这表示一个基本块,其中所有语句一个接一个地按顺序执行。
基本块结构:
让我们通过一个例子来了解基本块的构建:
例子:
1. PROD = 0
2. I = 1
3. T2 = addr(A) – 4
4. T4 = addr(B) – 4
5. T1 = 4 x I
6. T3 = T2[T1]
7. T5 = T4[T1]
8. T6 = T3 x T5
9. PROD = PROD + T6
10. I = I + 1
11. IF I <=20 GOTO (5)
使用上面给出的算法,我们可以很容易地识别出上述三地址码中基本块的数量——
有两个基本块 在上述三地址代码中:
- B1 –声明 1 至 4
- B2 –声明 5 至 11
基本块的转换:
基本块的变换可以应用于基本块。在转换时,我们不需要更改块计算的表达式集。
有两种类型的基本块变换。这些如下:
1. 结构保持转换
结构保持变换可以通过以下方法实现:
- 公共子表达式消除
- 死码消除
- 临时变量的重命名
- 两个独立相邻语句的交换
2. 代数变换
在代数变换的情况下,我们基本上将表达式集更改为代数等价集。
例如,和表达
x:= x + 0
or x:= x *1
这可以从基本块中消除,而无需更改表达式集。
流程图:
流程图只是一个有向图。对于一组基本块,流程图显示了控制信息的流向。控制流图用于描述如何在块之间解析程序控制。一旦中间代码被划分为基本块,流程图用于说明基本块之间的控制流。当 Y 块的开始指令跟随 X 块的最后一条指令时,一条边可能从一个块 X 流向另一个块 Y。
让我们制作我们用于基本块形成的示例的流程图:
首先,我们计算基本块(上面已经完成)。其次,我们分配流量控制信息。