decaf-doc
  • Introduction
  • pa1a
    • 实验内容
    • lalr1使用指导
      • 编写lexer
      • impl块的可选属性
      • 产生式和语法动作
      • 解决冲突
      • 一个完整的例子
    • 抽象语法树
    • 框架中部分实现的解释
    • 文件结构
  • pa1b
    • 实验内容
    • lalr1使用指导
    • 错误恢复
    • 文件结构
  • pa2
    • 实验内容
    • 语义分析
    • 符号表
    • 语句的返回类型
    • visitor模式
    • 框架中部分实现的解释
  • pa3
    • 实验内容
    • 中间代码
    • 中间代码中的类型信息
    • 运行时存储布局
    • 面向对象机制
    • tacvm介绍
  • pa4
    • 实验内容
    • 基本块
    • 数据流分析概述
    • 数据流优化概述
    • 公共表达式提取
    • 复写传播
    • 常量传播
    • 死代码消除
  • pa5
    • 实验内容
    • 图着色基本原理
    • 改进干涉图节点
    • 着色算法
    • 预着色节点
    • 干涉图节点合并
    • 调用约定
Powered by GitBook
On this page

Was this helpful?

  1. pa4

复写传播

复写(复制,赋值)传播的目的是借助复写语句,尽可能将tac中对复写左端项的引用替换成对右端项的引用。虽然表面上没有减少指令的条数,但这样做的好处在于优化后复写左端项有可能不再活跃,从而让死代码消除可以删除这条复写语句。

复写传播的实现方法与公共表达式提取是类似的,与可用表达式对应,它考虑的是可用复写语句。一条复写语句生成一条可用复写语句,一条带有定值的语句可以杀死与被定值的虚拟寄存器相关的所有复写语句(包括它出现在左端项或者右端项的)。除此之外,复写传播的数据流方向,交汇运算和初始值均与可用表达式的数据流相同。

按照老套路计算出每条语句处所有的可用复写语句后,考察一条语句使用的虚拟寄存器a,如果存在一条可用的复写语句,它的左端项是a,那么a可以被替换成它的右端项。这个过程还可以递归地进行下去:设这个右端项为b,如果存在一条可用的复写语句,它的左端项是b,则a可以进一步被替换成它的右端项c。这样就可以一步传播多层。

一个例子如下:

  b = a
  c = b
  d = c
  x = y + d

计算可用复写语句,每个语句后的方括号内的内容是这条语句执行前的可用复写语句集合:

  b = a []
  c = b [b = a]
  a = x [b = a, c = b]
  d = c [c = b, a = x] // 上一条语句杀死了b = a
  x = y + d [c = b, a = x, d = c]

执行转换:

  b = a
  c = a # 因为b = a可用,所以b被替换成a
  a = x
  d = b # 因为c = b可用,所以c被替换成b
  x = y + b # 因为d = c,c = b可用,所以d被替换成b
Previous公共表达式提取Next常量传播

Last updated 5 years ago

Was this helpful?