5.4.1 中间代码生成与优化_UCC编译器的优化_删除无用的临时变量和优化跳转目标

5.4.1  删除无用的临时变量和优化跳转目标

UCC编译器在优化方面做的工作不多,其中与优化有关的函数主要有以下几个:

(1)    Symbol  Simplify(Type ty, int opcode, Symbol src1,Symbol src2);

用于进行“代数恒等式”的简化,例如表达式“a<<0”可简化为a。

(2)    Symbol  TryAddValue(Type ty, int op, Symbol src1,Symbol src2);

用于处理“公共子表达式”。

(3)    void Optimize(FunctionSymbolfsym);

用于对“C源代码中的某一函数”进行优化。

在前面的章节中,我们已经对函数Simplify和TryAddValue做过讨论,在这一小节中,我们主要讨论函数Optimize。我们在中间代码生成阶段,产生了许多临时变量,用来存放表达式的值,在优化时,如果发现有些临时变量的值并没有在其他地方被使用(即该临时变量的引用计数为1),则可删除该临时变量。如图5.4.1所示,对于第14至18行的C程序而言,优化前的中间代码在第24至28行,其中的临时变量t0至t4并没有在其他地方被使用,优化时,我们可删除t1、t2、t3和t4,第31和32行是优化后的中间代码。

图5.4.1 删除无用的临时变量

我们注意到,图5.4.1第24行的t0在优化后仍然得到了保留,其原因在于函数GetData()的返回值为结构体对象。为第24行的中间代码“t0:GetData();”生成汇编代码时,UCC编译器将其视为“GetData(&t0);”,我们会在主调函数main的栈中为t0分配内存,然后把t0的首地址传递给被调函数GetData()。对UCC编译器而言,第5行的函数GetData的接口相当于是:

void  GetData(Data * ptr);

按照C的语义,函数的返回值可以是整数、浮点数和结构体对象,但不可以是数组。如果返回值是整数,这些值可以暂存于X86的通用寄存器eax和edx中;而如果返回值是浮点数,则可暂存于浮点协处理器X87的寄存器中;但对于图5.4.1第4行的结构体来说,其结构体对象要占16字节的空间,如果CPU中的寄存器无法存放结构体对象,UCC编译器在生成汇编代码时,就会隐式地按照GetData(&t0)来处理第31行的函数调用。C标准要为“在x86平台上,函数调用的返回值应如何传递等细节”进行统一约定,即“调用约定
Calling Convention”。在后续的“目标代码生成”章节中,我们会遇到用于为“函数调用生成汇编代码”的EmitCall(),到时我们再进一步展开讨论。图5.4.1第34至38行是与函数调用“(GetData(&t0));”对应的汇编代码。

接下来,我们来看一下“删除无用临时变量”的函数EliminateCode,如图5.3.2第17至50行所示,第25至30行用于删除形如“t4:f();”中的无用临时变量t4,而第31至41行用于删除形如“t2:~a;”的无用临时变量t2,由于表达式“~a”没有副作用,不仅可删去临时变量t2,同时还可在第38至39行删去整条中间代码。而函数调用f()有副作用,我们就只能在第29行删去临时变量t4。

图5.4.2 Optimize()

图5.4.2第1至16行的函数Optimize用于对C源代码中的某一函数进行优化,第4行调用的PeepHole会对基本块进行窥孔优化,我们已在前面的章节中介绍过这个函数,第8行调用的EliminateCode函数用于删除无用的临时变量,第9行调用的ExamineJump函数用于优化跳转语句的跳转目标,而第14行调用的TryMergeBBlock则尝试进行相邻基本块之间的合并。

图5.4.3给出了函数ExamineJump的代码,当我们面对形如第2至10行的中间代码时,第4行的跳转语句是基本块BB的最末一条指令,其跳转目标为BB1,而基本块BB1又只有一条跳往BB2的无条件跳转指令,此时我们可把基本块BB最末一条指令的跳转目标优化为BB2,如第14行所示。图5.4.3第26行用于获取基本块BB的最后一条指令,当该指令不是跳转指令时,我们从第29行直接返回。对基本块BB而言,当我们将第4行的跳转目标BB1改为第14行的BB2后,基本块BB、BB1和BB2之间的“前驱与后继的关系”发生了变化,我们要从BB基本块的后继链表中找到BB1,将该链表元素改为BB2,第31至37行的do语句用于在后继链表bb->succs中查找BB1,之后在第42行将其改为BB2,这样BB2就成了BB基本块的后继结点。而第43行的代码用于从BB1基本块的前驱链表中删去BB基本块,第44行用于在基本块BB2的前驱链表中添加基本块BB。第47行实现了将BB基本块最末一条指令的跳转目标从BB1改为BB2的优化操作。

图5.4.3 ExamineJump()

在下一小节中,我们会对图5.4.2第14行调用的TryMergeBBlock函数进行分析,该函数用于基本块的合并。

时间: 2024-10-09 19:26:25

5.4.1 中间代码生成与优化_UCC编译器的优化_删除无用的临时变量和优化跳转目标的相关文章

Oracle性能优化之执行计划管理_超越OCP精通Oracle视频教程培训31

Oracle性能优化之执行计划管理_超越OCP精通Oracle视频教程培训31 本课程介绍: Oracle视频教程,风哥本套oracle教程培训<<Oracle数据库性能优化培训教程>>的第1/10套:Oracle性能优化之执行计划管理.主要学习Oracle性能优化简介,SQL 语句处理流程,软解析和硬解析,绑定变量及案例,游标的介绍,Oracle的优化器,执行计划的查看,SQL语句访问路径,SQL语句的连接方式,Oracle驱动表,执行计划的干预,常用hint提示的使用. 视频教

Oracle性能优化之性能诊断工具_超越OCP精通Oracle视频教程培训33

Oracle性能优化之性能诊断工具_超越OCP精通Oracle视频教程培训33 课程介绍 Oracle视频教程,风哥本套oracle教程培训<<Oracle数据库性能优化培训教程>>的第3/10套:Oracle性能优化之性能诊断工具.主要学习Oracle性能优化,Oracle自带性能诊断工具介绍,日常维护中的性能工具操作过程,awr性能数据的收集时间,awr自动收集性能报告如何实现,awr手工快照如何实现,awr baseline的手工调整与管理,awr性能相关的视图介绍,awr性

Oracle性能优化之性能跟踪工具_超越OCP精通Oracle视频教程培训34

Oracle性能优化之性能跟踪工具_超越OCP精通Oracle视频教程培训34 课程介绍 Oracle视频教程,风哥本套oracle教程培训<<Oracle数据库性能优化培训教程>>的第4/10套:Oracle性能优化之性能跟踪工具.主要学习Oracle性能优化,如何获取跟踪文件,sql_trace及案例,10046事件及案例,trace内容分析,oradebug及案例,dbms_system,dbms_monitor及案例,dbms_support,10053事件及案例,综合案例

代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码

告诉你一些简单的技巧来优化JavaScript编译器工作,从而让你的JavaScript代码运行的更快.尤其是在你游戏中发现帧率下降或是当垃圾回收器有大量的工作要完成的时候. 单一同态: 当你定义了一个两个参数的函数,编译器会接受你的定义,如果函数参数的类型.个数或者返回值的类型改变编译器的工作会变得艰难.通常情况下,单一同态的数据结构和个数相同的参数会让你的程序会更好的工作. function example(a, b) { // 期望a,b都为数值类型 console.log(++a * +

SSE图像算法优化系列十:简单的一个肤色检测算法的SSE优化。

在很多场合需要高效率的肤色检测代码,本人常用的一个C++版本的代码如下所示: void IM_GetRoughSkinRegion(unsigned char *Src, unsigned char *Skin, int Width, int Height, int Stride) { for (int Y = 0; Y < Height; Y++) { unsigned char *LinePS = Src + Y * Stride; // 源图的第Y行像素的首地址 unsigned char

Mysql优化(出自官方文档) - 第八篇(索引优化系列)

目录 Mysql优化(出自官方文档) - 第八篇(索引优化系列) Optimization and Indexes 1 Foreign Key Optimization 2 Column Indexes 3 Column Indexes && Multiple-Column Indexes 4 Comparison of B-Tree and Hash Indexes 5 Use of Index Extensions 6 Invisible Indexes 7 Descending In

Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)

目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods 2 Metadata Locking 3 External Locking Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods 这里介绍Mysql的几种锁,该锁由Mysql自行进行管理,用户不需要处理该锁. Row-Level Locking 对于InnoDB,行锁可以通过SELECT ... FOR UPDAT

优化tomcat配置(从内存、并发、缓存4个方面)优化

Tomcat内存优化 Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh 中设置 java_OPTS 参数. JAVA_OPTS参数说明 -server 启用jdk 的 server 版: -Xms Java虚拟机初始化时的最小内存: -Xmx java虚拟机可使用的最大内存: -XX: PermSize 内存永久保留区域 -XX:MaxPermSize 内存最大永久保留区域 服务器参数配置 现公司服务器内存一般都可以加到最大2

Hibernate批处理操作优化 (批量插入、更新与删除)

问题描述 我开发的网站加了个新功能:需要在线上处理表数据的批量合并和更新,昨天下午发布上线,执行该功能后,服务器的load突然增高,变化曲线异常,SA教育了我一番,让我尽快处理,将CPU负载降低. 工作所需,我经常要写些程序批量处理数据,每次执行几十万数据处理的时候,我机子的CPU都会飙高,而且数据处理速度会越来越慢.比如第一个1W条要5分钟,第二个1W条就要10分钟,要干其他事情的时候机子也卡的不行,只能等着处理完数据. 其实我一直认为是数据量太大,从来不认为是程序问题,所以一直没怎么关注过.