中间表示- 控制流图

基本概念

基本块:是语句的一个序列,从第一条执行到最后一条

  • 不能从中间进入,不能从中间退出,即跳转指令只能出现在最后

控制流图:控制流图是一个有向图G=(V,E)

  • 节点V:是基本块
  • 边E:是基本块之间的跳转关系

控制流图的定义

是更精细的三地址码

 数据结构定义(以B为例)

struct Block {
    Label_t label;
    List_t stms;
    Jump_t j;
};

如何生成控制流图?

(1)可以直接从抽象语法树生成

  • 如果高层语言具有特别规整的控制流结构的话较容易

(2)也可以先生成三地址码,然后继续生成控制流图

  • 对于像C这样的语言更合适,因为其中包含像goto这样的非结构化的控制流语句
  • 更加通用(阶段划分!)

使用控制流图的编译器结构

由三地址码生成控制流图算法(线性扫描算法)

List_t stms;            // 三地址码中所有语句
List_t blocks = {};     // 控制流图中的所有基本块
Block_t b = Block_fresh();  // 一个初始的空的基本块
scan_stms()
{
    foreach(s ∈ stms)
        if (s is "Label L")     // s是标号
            b.label = L;
        else (s is some jump)   // s是跳转
            b.j = s;
            blocks ∪= {b};
            b = Block_fresh();
        else                    // s是普通指令
            b.stms ∪= {s};
}

控制流图的基本操作

● 标准的图论算法都可以用在控制流图的操作上

  • 各种遍历算法、生成树、必经节点结构等等。

● 图节点的顺序有重要的应用

  • 拓扑序、逆拓扑序、近似拓扑序等等。

这里我们不详细展开这些算法,而是通过研究一个具体的例子来展示基本图算法的应用

  • 死基本块删除优化

例子:死基本块删除优化

int f()
{
    int i = 3;
    while (i < 10)
    {
        i = i + 1;
        printi(i);
        continue;
        printi(i);
    }
    return 0;
}

对上述程序,构建出对应的控制流图如下(L0为入口块,L2为出口块)

通过观察我们可以看出,上图中并没有任何一条边进入L3(即L3的入度为0),L3这个块是从L0出发对这个图做遍历不可达的一个块,这样的块称为死基本块。这个块是不可能被执行到的。

死基本块删除算法

  • 输入:控制流图g
  • 输出:经过死基本块删除后的控制流图
dead_blocks_elim(g)
    dfs(g);
    for (each node in g)
        if (!visited(n))
            delete(n);

### 中间表示在活性分析中的应用及原理 #### 定义与背景 中间表示(Intermediate Representation, IR)是一种用于编译器优化和静态分析的技术,在活性分析中扮演着重要角色。IR 提供了一种抽象层次,使得复杂的源代码可以被转换成更易于处理的形式。 #### 应用场景 在活性分析中,中间表示主要用于识别哪些变量或指令可能影响程序的行为。通过对程序的不同部分进行建模并构建其对应的中间表示形式,能够有效地追踪数据流以及控制依赖关系[^2]。 #### 原理说明 具体来说,活性分析利用中间表示来进行**到达定义**(reaching definitions) 的计算。例如,“到达定义”分析指出 `L_0` 块中的赋值语句 `y=3` 可以传播到后续的基本块 `L_3` 。这意味着当执行流程达到 `L_3` 时,该处使用的 `y` 的值可能是由前面的 `y=3` 赋予的。 为了实现这一点,通常会在编译期间创建一种类似于三地址码(Three Address Code) 或者 SSA 形式的中间语言描述。这些结构允许工具更容易地理解和操作原始代码逻辑,从而支持更加精确有效的活性分析算法。 ```c // 示例:简单的C语言片段及其对应的SSA形式 int a = b + c; // Original code t1 = b + c // Three-address code (TAC) a = t1 // // In Static Single Assignment form: b1 = phi(b_entry, b_after_if); // SSA version of 'b' c1 = phi(c_entry, c_after_if); // SSA version of 'c' t1 = add(b1, c1); a1 = t1; ``` 通过上述方法,可以在不改变原意的前提下简化表达方式,并且便于进一步实施各种类型的静态检查和优化措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫客36

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值