当前课程知识点:Compilers Techniques > 7 Code Generation > 7.1 Issues in the Design of Code Generator > 7.1 Issues in the Design of Code Generator
返回《Compilers Techniques》慕课在线视频课程列表
返回《Compilers Techniques》慕课在线视频列表
各位同学大家好
这一章我们来学习代码生成
我们看到源程序
经过前端的处理之后
会得到中间代码
然后在代码优化之后
需要来进行代码的生成
才能得到目标程序
在这一章
我们来学习一个简单的代码生成算法
它会涉及到存储的管理、
指定的选择、寄存器的分配、
计算次序的选择等等问题
接下来我们来讨论一下
代码生成器中的设计碰到的问题
我们不针对具体的语言
也不针对具体的目标机器
我们首先来看一下
目标程序可能的形式有哪几种
可以是绝对机器语言程序
可以是可重定位目标模块
当然也可以作为汇编语言程序
作为绝对机器语言程序
这是早期编译器采取的形式
目标程序
它需要装入到内存的固定的地方
粗略的说
得到的语句
相当于是现在的可执行目标模块
那么对于可重定位目标程序来说
代码当中还有重定位的信息
这样我们就可以
每次得到目标代码之后
装入到不同的机器中来进行执行
允许程序模块
分别来进行编译
同时我们可以调用其他编译好的模块
第三种是汇编语言程序
汇编语言程序
免去编译器重复汇编器的工作
相对来说增加了我们的可读性
接下来我们需要讨论指令的选择
我们知道需要针对目标机器来
选择对应的指令系统
那么指令系统
我们选择出来的性质
决定了它的难易程度
我们要求指令系统
必须具备统一性和完备性
同时指令的速度以及机器的特点
是我们另外需要讨论的一些因素
如果不考虑目标程序的效率
我们知道指令的选择
其实是很容易的
比如说对于三地址代码来说
x=y+z
假设x、y、z都是静态分配
那么我们就可以使用
对应的汇编语句
如下三条
第一条MOV y, R0
相当于把y装入到寄存器R0中
第二条ADD z , R0
我们将Z加入到R0中
第三条MOV R0, x
我们将R0存入到x中
通过这样三条语句
我们就完成了x=y+z这条指令
但是我们会观察到
如果我们只是把三地址代码
逐条的去进行翻译
我们得到的常常是低质量的代码
我们再来看一个例子
假设我们有一个语句序列
a=b+c
d=a+e
如果我们逐条的去翻译它
我们得到的指令序列
是如下的这六行代码
首先我们将b移动到R0当中
第二条语句
我们将c累加到R0中
第三条语句
我们将R0移动到a中
第四条语句
我们将a移动到R0中
第五条语句
我们将e累加到R0上
第六条语句
我们将R0移动到d中
当然这个指令序列是正确的
最终 d得到了我们想要的结果
我们会观察到
第四条语句
实际上是一条多余的语句
因为R0中已经存放了a的值
假设a的值不再使用
我们会观察到第三条语句
也是一条多余的一句
接下来我们来讨论寄存器的分配问题
我们知道对于运算对象来说
处于寄存器当中
和处于内存当中相比
指令要短一些
运行的速度也要快一些
所以我们主要讨论
寄存器的分配和寄存器的指派
这两个问题
对于寄存器的分配
我们主要讨论
选择哪一些变量
驻留在寄存器当中
对于寄存器的指派
我们主要讨论
挑选哪些变量要驻存在
具体的寄存器当中
下一个问题是
计算次序的选择问题
对于程序当中
计算的执行次序
会影响程序的执行效率
对于表达式的计算而言
一种计算次序
可能比另外一种计算次序
需要更少的寄存器来保存结果
如何选择一个最佳的计算次序
是一个NP完全问题
这一小节就到这
谢谢大家
-1.1 Overview of Compilers Techniques
--Chapter 1 Overview of Compilers Techniques
--Overview of Compilers Techniques
-2.1 Lexical Tokens, Strings and Language
--2.1 Lexical Tokens, Strings and Language
--2.1 Lexical Tokens, Strings and Language
-2.2 Regular form
--2.2 Regular form
-2.3 Finite automata
--2.3 Finite automata
-2.4 DFA construction, Subset construction, Simpleset DFA
--2.4 DFA construction, Subset construction, Simpleset DFA
-2.5 Lex
--2.5 Lex
-3.1 Context-free Grammars
--3.1.1 The Role of the Parser
--3.1.2 The Formal Definition of a Context-free Grammar
-3.2 Writing a Grammar
--3.2.1 Elimination of Left Recursion
--3.2 Top-Down Parsing
-3.3 Languages and Grammars
--3.3 Language and Grammars
-3.4 Top-Down Parsing
--3.4.3 Recursive Descent Analysis
--3.4.4 Nonrecursive Descent Analysis
-3.5 Bottom-up Parsing
--Bottom-up Parsing
-3.6 LR Parsing
--3.6.6 Characteristics of LR Parsing
--3.6.7 Non Ambiguous and Not LR Context-Free Grammars
-4.1 Syntax-Directed Definitions
--4.1.2 Attribute Dependency Graphs and Ordering the Evaluation of Attributes
--Syntax-Directed Definitions
-4.2 Bottom-Up Calculation of S Attribute
--4.2.1 Bottom-Up Calculation of S-Attributed
-4.3 L-Attributed Definitions
--4.3.1 L-Attributed Definitions
--4.3.3 Design of Predictive Translator
--L-Attributed Definitions
-4.4 Bottom-Up Parsing of L-Attributed Translation
--4.4.1 Bottom-Up Parsing of L-Attributed Translation
--4.4.2 Simulate the Parsing of Inherited Properties
--Bottom-Up Parsing of L-Attributed Translation
-5.1 Overview
--Overview
-5.2 Global Stack Storage
-5.3 Calling Sequences
-5.4 Non Local Names
--5.4 Non Local Names and dynamic scope
--Non Local Name
-6.1 Overview of Intermediate Code Generation
--6.1 Overview of Intermediate Code Generation
-6.2 Declaration Statements
-7.1 Issues in the Design of Code Generator
--7.1 Issues in the Design of Code Generator
-7.2 Target Machine
--Target Machine
-7.3 Basic Blocks and Flow Graphs
--7.3 Basic Blocks and Flow Graphs
-7.4 A Simple Code Generator
-8.1 Demonstration of Compiler Framework based on Python
--8.1 Demonstration of Compiler Framework based on Python
-8.2 Basic
--8.2.4 SA
-8.3 SimpleJava