与语义分析相关的工作
静态语义检查
•
编译期间所进行的语义检查
−
动态语义检查
•
所生成的代码在运行期间进行的语义检查:
例如:除零溢出错误
−
收集语义信息
•
为语义检查收集程序的语义信息
•
为代码生成等后续阶段收集程序的语义信息
静态语义分析
静态语义检查
−
代码生成前
程序合法性检查的最后阶段
•
静态
类型
检查
(
type checks
)
•
名字的作用域
(
scope
)
分析
•
控制流检查
(
flow-of-control checks
)
•
唯一性检查
(
uniqueness checks
)
•
名字的上下文相关性检查
(
name-related checks
)
中间代码生成
−
作用
•
源语言和目标语言之间的桥梁,避开二者之间较大的语义
跨度,
使编译程序的逻辑结构更加简单明确
•
利于编译程序的重定向
•
利于进行与目标机无关的优化
这里会考察抽象语法树和逆波兰式
运行时存储组织
一个目标程序运行所需的存储空间包括
:
存放目标代码的空间
存放数据项目的空间
存放程序运行的控制或连接数据所需单元
(
控制栈:跟
踪过程活动
)
静态分配策略
(FORTRAN)
如果在编译时能确定数据空间的大小,则可采用静态
分配方法:在编译时刻为每个数据项目确定出在运行
时刻的存储空间中的位置。
动态分配策略
(PASCAL)
如果在编译时不能确定运行时数据空间的大小,则
必须采用动态分配方法。允许递归过程和动态申请释
放内存。
栈式动态分配
堆式动态分配
size of是在编译的时候实现存储分配的
代码优化
优化目的
节省时间
节省空间
优化技术
窥孔优化 局部优化 循环优化 全局优化
优化技术举例
强度削弱 x=x*2之类的操作可以使用移位操作实现
利用特有指令 龙芯中有乘加指令以及一些向量扩展指令
删除死代码
有些代码可能用于不会被执行到
编译器优化原则
等价原则
有效原则
合算原则
软件开发优化注意事项
“不要”优化它。
如果无法得到正确的结果,那就毫无用处。
使用一个分析器。
性能分析的最佳使用方法就是识别出“热点”,然后尽可能地优
化它们
启用编译器优化。
编译器的优化设置越激进,最终编译出来的程序中出现不明
Bug
的可能性越高
调整代码。
消灭循环
加入代码审查环节。
让别人检查你的代码
目标代码生成重点要考虑的问题:
生成的目标代码较短
充分利用寄存器,减少存储单元访问次数
代码生成的输入:中间代码和符号表
目标代码的形式:汇编语言代码和
机器语言代码