The Decaf Book
  • Introduction
  • 语言规范
  • Java 框架分阶段指导
    • 本章导引
    • PA1-A:语法分析器的自动构造
      • 阶段任务
      • 词法分析
      • 抽象语法树
      • 文法分析
    • PA1-B:基于 LL(1) 的语法分析器半自动构造
      • 阶段任务
      • LL(1) 文法分析
      • 错误恢复
    • PA2:语义分析
      • 阶段任务
      • 类型、符号和作用域
      • 访问者模式
      • 符号表构建
      • 类型检查
    • PA3:中间代码生成
      • 阶段任务
      • TAC 程序
      • 面向对象机制
      • 控制流的翻译
    • PA4:中间代码优化
      • 实验内容
      • 基本块
      • 数据流分析概述
      • 数据流优化概述
      • 公共表达式提取
      • 复写传播
      • 常量传播
      • 死代码消除
  • Scala 框架分阶段指导
    • 本章导引
    • PA1:语法分析器的自动构造
      • 阶段任务
      • 词法分析
      • 抽象语法树
      • 文法分析
      • 访问者模式
    • PA2:语义分析
      • 阶段任务
      • 类型、符号和作用域
      • 符号表构建
      • 类型检查
    • PA3:中间代码生成
      • 阶段任务
      • TAC 程序
      • 面向对象机制
      • 控制流的翻译
    • PA3-JVM:JVM 字节码生成
      • 阶段任务
      • JVM 字节码简介
      • 翻译过程
    • PA4:中间代码优化
      • 实验内容
      • 基本块
      • 数据流分析概述
      • 数据流优化概述
      • 公共表达式提取
      • 复写传播
      • 常量传播
      • 死代码消除
  • Rust 框架分阶段指导
    • 本章导引
    • PA1-A:语法分析器的自动构造
      • 实验内容
      • lalr1使用指导
        • 编写lexer
        • impl块的可选属性
        • 产生式和语法动作
        • 解决冲突
        • 一个完整的例子
      • 抽象语法树
      • 框架中部分实现的解释
      • 文件结构
    • PA1-B:基于 LL(1) 的语法分析器半自动构造
      • 实验内容
      • lalr1使用指导
      • 错误恢复
      • 文件结构
    • PA2:语义分析
      • 实验内容
      • 语义分析
      • 符号表
      • visitor模式
    • PA3:中间代码生成
      • 实验内容
      • 中间代码
      • 中间代码中的类型信息
      • 运行时存储布局
      • 面向对象机制
      • tacvm简述
    • PA4:中间代码优化
      • 基本块
      • 数据流分析概述
      • 数据流优化概述
      • 公共表达式提取
      • 复写传播
      • 常量传播
      • 死代码消除
    • PA5:寄存器分配
      • 实验内容
      • 图着色基本原理
      • 着色算法
      • 预着色节点
      • 干涉图节点合并
      • 调用约定
Powered by GitBook
On this page

Was this helpful?

  1. Rust 框架分阶段指导
  2. 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?