精华内容
下载资源
问答
  • 下列属于生成性目标的是
    千次阅读
    2020-06-13 10:47:00

    概念

    目标代码生成是编译的最后一个阶段。目标代码生成器把语法分析后或优化后的中间代码变换成目标代码。
    目标代码(object code)指计算机科学中编译器或汇编器处理源代码后所生成的代码,它一般由机器代码或接近于机器语言的代码组成。

    实际目标代码

    实际机器上的指令序列,绝对地址机器代码;可重定位的机器代码; 汇编代码:

    虚拟目标代码

    虚拟机上的目标程序。在本地机器上具备虚拟机的解释器。

    1
    【单选题】下列关于绝对机器语言目标代码说法错误的是()?

    A、
    在目标机上可以直接运行
    B、
    代码中所有地址均已经完成了定位
    C、
    各个程序模块可以分别独立地编译
    D、
    适合需要快速编译执行的小型程序
    正确答案: C 我的答案:C

    答案解析:
    绝对机器语言目标代码中的地址已经完成了定位,可以直接执行,但是由于不能重定位,这种形式缺乏灵活性。在编译过程中,通常要把整个源程序一起编译,而不能独立地编译源程序中的各个程序模块。一般只适用于需要快速编译执行的小型程序。
    2
    【单选题】下列选项中,负责对可重定位目标代码中的地址进行重定位的是()?

    A、
    装入程序
    B、
    连接程序
    C、
    编译器
    D、
    以上都不是
    正确答案: A 我的答案:A

    答案解析:
    装入程序负责把代码加载到内存储器中,以便执行。装入程序可处理所有的与指定的基地址或起始地址有关的可重定位的地址,它使得可执行代码更加灵活。
    3
    【单选题】以下说法不正确的是( )。

    A、
    源程序到目标程序的变换是等价变换,即两者结构不同,但语义是一致的
    B、
    源程序和目标程序是等价关系
    C、
    目标代码生成时,需要考虑目标计算机的指令系统
    D、
    窥孔优化是在中间代码层次上进行的优化工作
    正确答案: D 我的答案:D

    答案解析:
    窥孔优化是在目标代码层次上进行的优化工作。其它三个选项的说法都是正确的。
    4
    【单选题】在目标代码生成阶段,符号表的主要用途是( )?

    A、
    中间代码优化
    B、
    语义检查
    C、
    语法检查
    D、
    地址分配
    正确答案: D 我的答案:D

    答案解析:
    在目标代码生成阶段,需要根据符号表进行地址分配,其余三个选项不是目标代码生成阶段的任务。
    5
    【单选题】在下面类别语句的目标代码生成过程中,不需要使用回填技术的是?。

    A、
    赋值语句
    B、
    goto语句
    C、
    条件语句
    D、
    循环语句
    正确答案: A 我的答案:A

    答案解析:
    B,C,D中的三种语句在生成目标代码的过程中,都需要使用跳转指令,并且跳转指令目的地址暂时无法确定,所以只能空缺,等待以后回填;而赋值语句无需使用跳转指令。

    更多相关内容
  • 编译原理(二十)——目标代码生成

    千次阅读 多人点赞 2020-11-04 22:36:44
    一、目标代码 二、虚拟目标机的指令系统 三、虚拟目标机的寄存器 四、四元式转化为目标指令 五、多寄存器的分配 六、对目标程序的评价

    一、目标代码

    1. 实际目标代码:实际机器上的指令序列
      绝对地址机器代码;可重定位的机器代码; 汇编代码:

    2. 虚拟目标代码:虚拟机上的目标程序。
      在本地机器上具备虚拟机的解释器。

    • 目标程序的生成和目标机是密切相关联的,也就是说目标机的结构、能力会直接影响我们生成目标程序的难易程度和质量。在实际中也有很多程序设计语言的编译过程并不是直接对具体的目标机生成目标代码,而是产生到一种类似于汇编的虚拟目标机上,然后由虚拟目标机的虚拟指令到具体目标机的转换。比如java语言,编译完到一个中间语言的形式,然后利用相对应的解释程序在不同的目标机进行解释和执行。
    • 当前考虑的四元式的生成对象中没有具体的目标机,所以这里也使用虚拟目标机

    二、虚拟目标机的指令系统

    目标机指令系统的指令分成如下的形式:(汇编类似)

    存取指令:LD ST
    输入输出:IN OUT
    运算型指令:ADD SUB MUL DIV GT GE...
    转移型指令:JMP  JMPT JMPF
    地址运算指令和块传递指令:LEA  MOVEB
    
    1. 存取指令:
      假定有若干通用的寄存器是可用的,可以把内存单元中的内容取到寄存器中,比如LD,另一个是把寄存器中的内容存到内存中,如ST
    2. 运算型指令:
      ADD R X,表示寄存器R中的内容+X中的内容,结果存在R中,其他的运算类似
    3. 转移性指令:
      要进行转移性操作,JUMP 地址 表示无条件转移,另外还有条件为真进行转移和条件为假进行转移,比方说 JUMPT R 地址L表示寄存器R中值为真的时候转移到L这个地址去执行,JUMPF R L表示R中为假的时候转移到L去执行
    4. 地址运算指令和块传递指令:
      一个起始位置和个数,对数组传送非常方便。给一个起始位置,然后给定一个数组的大小,这样通过一条语句就可以把数组的内容都传递过去
      在这里插入图片描述

    目前考虑的是如何将输入的四元式转换成目标指令,虚拟的目标指令和实际的汇编指令存在一定程度上的差别,某些语言可能不会直接提供某些运算的指令,可能通过一个宏汇编或者是其他方式来实现。但是现在都直接假定具有这种操作的方式。

    若目标机指令集中有“自增”指令INC,就可以被高效地翻译为一条指令:INC a ;否则,按照前面的模式将被翻译为指令序列:

    LD  R , a
    ADD R , 1
    ST  a , R
    

    三、虚拟目标机的寄存器

    寄存器是CPU内部的元件,寄存器拥有非常高的读写速度 ,它们可用来暂存指令、数据和位址。
    寄存器种类:累加器、变址器、通用寄存器等等
    在虚拟目标机中,取出几个寄存器作为地址计算专用的寄存器分别为SP、TOP、SP0;其他寄存器用R1、R2…表示

    要考虑目标机中有哪些通用的寄存器,哪些可以作为累加器,哪些可以作为变址寄存器,可以使用某些寄存器专门执行想要的功能:

    1. sp:程序运行时存储空间当前活动记录的首地址/调用链活动记录的首地址
    2. top:第一个可用的存储单元的地址
    3. sp0:记录静态存储器的首地址,sp0+偏移量就可以计算出静态变量分配在静态区的哪个位置
    4. 其他寄存器可以用R1、R2等表示

    四、四元式转化为目标指令

    在生成过程中,首先考虑的是单寄存器的情形,如果单寄存器的目标程序都可以完成的话,多个寄存器的目标程序的完成应该是没有任何问题的,所以只考虑单寄存器的情况,在不考虑优化的情况下,看如何将四元式等价的转化成目标指令(重复,不考虑效率,如何等价的翻译),在能够翻译过去之后,再考虑如何来提高目标程序的质量,如何来评价这些目标指令。
    四元式如何翻译?

    1. 在翻译的过程中,用到两个栈,第一个是标号定位的栈,有些定位性标号为了某些转移提供地址的,把没有用到的标号存在栈中,比方说while四元式可能是由嵌套的,在定位产生的时候,还没产生跳转指令,当前的while地址还没用到,为了让后面能用到,将这个地址保存下来,由于循环可能是嵌套的,所以用栈来保存,用L1来表示
    2. 第二个栈在有些产生跳转至零的时候,还不知道后面的转移地址,比如 do四元式,尚且不知道后面的转移地址,就要把这个指令地址存到栈里,以后知道转移地址以后,需要回填这个指令地址(回填地址技术
    1. 标号定位栈L1:
      定位性标号是为了某些转移提供地址的,需要把暂时没用到的标号存在栈中,例如while四元式可以对应一个嵌套的循环,在定位产生时还没产生跳转指令,它的地址还没用到,为了让后面能用到需要用栈把标号保存下来
    2. 目标指令地址栈L2:
      在有些产生跳转指令的时候,转移地址暂时无法确定,例如do四元式,不知道后面的转移地址,则把当前目标指令地址存到栈里,在知道转移地址以后,回填这个指令地址。回填地址是编译中的一项非常重要的技术

    每一条指令如何生成目标指令的翻译:

    在这里插入图片描述
    ⚠️这里的x和y不是真正的x和y的值,而是x和y对应的指向符号表中的地址,是一个指针。如果是正常情况下的话直接是sp+offx,如果在不是本层的就是sp+display[L]+off。
    ⚠️如果x和y是间接变量需要用间接寻址,间接寻址方式使用*x,但是这里仍然使用x来表示,所以这里的x是一种概括所有能够找到x的各种寻址方式,为了表示简便而使用。
    在这里插入图片描述
    在这里插入图片描述
    第三类是输入输出四元式
    输入四元式一般是read,x 这对应的目标指令是两条:

    1. IN R,把外部的数据输入到R中;
    2. ST R x,把r中的存到x中去。

    输出四元式是write x:

    1. 把x的值取到R中;
    2. 再用输出命令输出出去,第一条是取LD R x;OUT,R。

    在这里插入图片描述

    • then x,实际上是要产生两条指令,先是要把x的值取到寄存器中,然后根据寄存器中的值来判断转移,ld R x,把x取到寄存器R中,第二条是跳转指令,如果r中是真,执行then的部分,假就跳过去,所以是jumpF R,地址,也就是寄存器R中的内容是跳转,但是现在要转移的地址是不确定的,还没有处理后面的指令,所以要转移到哪是不知道的,所以这个四元式的翻译时,要生成一条半的指令,第二个指令的跳转地址部分没有填上。
    • 如何生成半条指令?
      指令有自己的格式,这里的操作码是确定的,第一个寄存器R地址也是确定的,即只有后面转移的地址是不确定的。所以前半部分全部生成,后半部分使用0代替,一旦后面出现合适的地址就填充进去。还要将当前这条指令保存到栈L2中,等到具体知道指令的地址时弹栈地址回填。
      ⚠️生成一条半指令;半条指令压入堆栈L2

    在这里插入图片描述

    • else四元式:
      执行到else有两种情况:
      (1)一个是按照顺序执行完then的部分该到else了,但是因为这个时候if的条件判断是正确的,所以else部分应该被跳过,这时的else部分的地址已知,所以要产生一条跳转指令,但是这时候并不知道跳转到的地址,所以压入L2栈,等待后面的地址回填。
      (2)而于此同时上面的then如果跳过了,这个时候也知道上面的then的跳转部分应该转移到哪里了,所以可以将前面的then部分的跳转地址回填了。

    回填地址具体怎么填?
    首先将L2栈顶的元素弹出,然后生成一条只有后面跳转地址部分为m+1,前面为0的一条指令,然后从L1栈中弹出之前的需要回填地址的指令两条指令相加得到完整的指令,当前地址已经回填完毕,将其从L2栈中去掉,

    • endif四元式:
      实际上不产生跳转指令,但是处理的时候要回填地址,因为出现endif的时候就知道前面的指令的跳转地址了,比如前面的else,就把endif当前的指令地址回填给L2,形成一条完整的指令然后退栈。

    综上:

    1. else就是一个完成回填指令的地址,另一个是生成半条指令,然后压栈;
    2. endif不产生跳转指令,进行回填工作

    在这里插入图片描述

    • 关于while起到定位作用的解释:
      当循环结束之后要返回去,重新计算表达式的值是否继续执行循环,所以只起到一个定位的作用,要把它的地址存储起来,压入到L1栈中

    在这里插入图片描述

    • do四元式:生成两条指令,把x取到寄存器R中,根据R中的值来决定是否进行循环,所以要产生一个跳转指令,jumpF R ,- ,假跳出循环,真执行循环体,但是注意跳出循环体跳转的地址未知,所以生成的半条指令,跟前面的一样,把这条指令的地址 ,压入L2栈。后面遇到地址再回填。

    在这里插入图片描述

    • endwhile四元式:有两个作用,一个是产生一个跳转指令,无条件转移指令,转回去,转移地址是在L1栈里存着的栈顶元素,可以生成一个完整的跳转指令;第二个是回填地址,在do四元式的指令中不知道转移地址,现在知道了,所以把L2地址取出来,把跳转指令下一条地址回填到L2中栈顶跳转地址部分,构成一个完整的指令。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    过程函数声明:

    在这里插入图片描述

    过程函数声明部分的四元式处理,有两个部分需要注意:
    1. (entry,Q,...) // q过程的入口四元式,不产生任何指令
      需要将当前的地址存到Q的过程函数信息表中的入口项,每个函数或过程的信息表中含有很多的信息,其中有一项就是函数的入口地址,这个入口地址就是处理entry指令的时候需要填入函数信息表中的,这是当前四元式需要完成的翻译工作。
    2. (endfunc,....)//过程结束的四元式

    在这里插入图片描述

    对于函数过程结束四元式,要做3类工作:
    1. 生成一组取命令,即恢复寄存器的现场信息,在过程活动记录中有一块存储区保存现场信息,存储函数调用之前的寄存器中的值,现在函数已经结束了要返回,就要把这些信息恢复回去,有若干条取寄存器指令的动作。由于目标机不一样,所以保存的寄存器数量多少也不好确定,只要知道这里是由一组取命令完成的就可以了。
    2. 由于函数已经结束了,要把当前的活动记录作废掉,也就是在栈区把栈顶元素去掉,实际上是由两个指令完成的,把sp和top两个指针挪一下位置就可以了,把当前的sp存给top,把老的sp传给sp,也就是当前活动记录中动态链指针那一项传个sp。由于对两个指针进行了调整,就相当于把这个活动记录推掉了,现在sp值的是当前的活动记录。
    3. 产生一条返回指令,根据之前存的返回地址要生成一个跳转指令。问题是sp和top都挪下来了,这个返回地址怎么找呢?原来是sp+1,现在是top+1就可以了.就产生一个jump[top+1],这样就把这个翻译工作做完了。
    函数调用的四元式处理:

    在这里插入图片描述
    函数调用四元式的处理,分成两块,一个是传参数的四元式,一个是call四元式。注意的问题是参数传递有值引用和地址引用,一个传值 一个传地址,还有实参是直接变量还是间接变量,

    在这里插入图片描述
    在调用之前需要把活动记录栈里面压一个新的活动记录,实际上这部分工作也可以在入口四元式上进行处理,在哪处理时间效率上是一样的,但是可能一个函数被调用多次的话,重复代码就多一些。
    在这里插入图片描述
    在这里插入图片描述

    五、多寄存器的分配

    在这里插入图片描述

    • 之前考虑的都是单寄存器不考虑执行效率然后生成了相应的目标代码,现在如果考虑多寄存器的情况。单寄存器能够完成的多寄存器一定能够完成,只不过希望能够产生更高效的目标程序。构造函数查找寄存器的状态表,其中有寄存器的名字、状态(1-占用;0-空闲)。
    • 现在有多个寄存器,不需要每次使用的时候都频繁的换入换出,当需要一个寄存器的时候查表寻找当前是否有空闲的寄存器然后将空闲的寄存器进行分配,按照之前的存取操作进行,把相应的寄存器的状态和占用者记录在这个表中。

    在这里插入图片描述
    按照淘汰页的算法,实际上有一个最佳算法,在最远使用点的先淘汰,但是后面的程序执行情况是没法判定的,因此这个是做不到的,但是处理四元式的时曾经把它划分成很多个基本块,由于基本块里面的程序都是顺序执行的,因此在基本块内,可以找到最远使用点的,淘汰算法就可以按照最远使用点的先淘汰,特殊情况就是最远使用点都不在这个基本块里。比方说x123,都不在基本块里,只好随机淘汰一个,这样做可以达到局部最优,但是未必能达到全局最优。所以每结束一个基本块的时候,需要把寄存器中的所有内容,都存到对应的内存中去,把所有的寄存器都倒出来,这样多寄存器就可以实现了,达到一个寄存器分配的目的。

    六、对目标程序的评价在这里插入图片描述

    在处理过程中,注意——能够不往内存中存取,是最好的。能在寄存器中,尽量不存到内存,不从内存中取值,特别是多寄存器的情形。比如x+y+z,取x到r ,r+y就还到r, 然后r+z就可以了,不用把x+y的结果存到t1,这样的话可以减少指令提高程序的效率。通过将一些运算的结果占用在寄存器里,不用往内存中存,利用在寄存器中的资源,达到减少访问内存的效果,特殊情形可能还有问题,比方说目标代码的优化和带副本的优化。因为有些变量如果是间接变量,或者是往间接变量中存一个值,可能会改变寄存器中某一个变量的值,这种时候就需要把寄存器中的值存回去,否则就可能会发生错误。

    总结

    在这里插入图片描述
    目标程序的生成

    1. 要考虑目标机的问题
    2. 如何把四元式翻译成目标程序
    3. 考虑优化的问题
    4. 如何高效的生成目标代码

    ⚠️符号表是一直存在的,到目标代码生成的过程中还一直存在,直到生成了目标代码它的作用就没有了。因为此时已经把变量都换成地址了,把该取该用的内容都取出来了,过程的入口地址已经填上了,等到call的时候,直接到那里找到生成目标指令就可以了。所以,在目标代码生成之后符号表就没用了,以后运行的就是目标程序

    展开全文
  • 默认名名探究精神的重要体现在以下哪些方面?()如果采用偶校验,的目的可的扩0101010的校验位是(),0011011的校验位是()。语言源程译后人工智能在医学方面的角色有哪些。()经件的经接后利用人工智能来获取信息的...

    系统序文常用的密钥分发技术有 CA 技术和【】 技术。

    默认名名探究精神的重要性体现在以下哪些方面?()

    如果采用偶校验,的目的可的扩0101010的校验位是(),0011011的校验位是()。

    78320.jpg

    语言源程译后人工智能在医学方面的角色有哪些。()

    经件的经接后利用人工智能来获取信息的仪器有()

    扩展扩展20世纪80年代欧共体针对《罗马条约》的一次最重要修订是()。

    过编过连为建立欧洲统一大市场提供了理论来源和法律依据的政策文件主要有()。

    生成生成( )就是新闻工作者隐藏自己身份或者隐藏自己真实采访意图的采访。

    标文下列属于网络经验平台的是( )

    经验之谈可以采取()等多种形式来表达。

    执行展名下列属于网络经验平台的有( )。

    下面选项中属于常用的避孕方法的是()。

    文件现存年代最早的古器图录是哪一本?()

    系统序文我们在做自己的规划时需要()。

    教育部在()下发通知,默认名名要求高校开设文献检索课程。

    的目的可的扩2015年6月金砖国家开发银行在()挂牌成立,对进一步完善多边开发融资体系产生重要推动作用。

    语言源程译后世界多极化,实质就是世界范围内的力量分布从一个中心向更多中心扩散和聚集。()

    从冷战结束后25年时段看,多极化趋势就是美国“一超独大”地位相对削弱,其他大国及地区强国的国际地位和影响力不断下降。()

    逐步上升型的特点是()。

    展开全文
  • 编译原理--代码生成

    千次阅读 2022-04-05 09:35:25
    编译原理--代码生成

    代码生成

    以编译器前端生成的中间表示和相关的符号表信息作为输入,输出语义等价的目标程序
    代码生成器有三个主要任务:
    指令选择,寄存器分配和指派,指令排序
    

    代码生成器设计中的问题

    代码生成器的输入

    中间表示形式,符号表
    IR的中间表示形式的选择有很多,四元式,三元式,间接三元式等三地址表示方式.
    也包括诸如字节代码和堆栈机代码的虚拟机表示方式.
    后缀表示的线性表示方式;
    语法树和DAG的图形表示方式;
    

    目标程序

    RISC机通常有很多寄存器,三地址指令,简单的寻址方式和一个相对简单的指令集体系结构.
    CISC机通常有较少寄存器,两地址指令,多种寻址方式,多种类型的寄存器,可变长度指令,具有副作用的指令.
    
    输出一个使用绝对地址的机器语言程序的优点是程序可放在内存某个固定位置,立即执行.编译和执行快.
    输出可重定位机器语言程序可使各个程序能被分别编译.一组可重定位的目标模块可被一个链接加载器链接到一起并加载运行.
    可重定位需要为链接和加载付出代价.优势是获得灵活性.
    如目标机没有自动处理重定位,编译器就需向加载器提供明确的重定位信息.
    

    指令选择

    代码生成器需把IR程序映射成为可以在目标机上运行的代码序列.
    完成映射的复杂性由如下因素决定:
    1.IR层次
    2.指令集体系结构本身特性
    3.要达到代码质量
    
    如每个形如x=y+z的三地址语句,可被翻译为如下
    LD R0, y
    ADD R0, R0, z
    ST x, R0
    大多数机器上,一个给定的IR程序可用很多种不同的代码序列来实现.
    如目标机有一个 加一 指令,则a=a+1可用一个指令INC a实现
    

    寄存器分配

    寄存器的使用常被分解为两个子问题:
    1.寄存器的分配
    2.寄存器的指派
    

    求值顺序

    目标语言

    一个简单的目标机模型

    我们的目标计算机是一个三地址机器的模型
    具有加载和保存操作,计算操作,跳转操作,条件跳转
    这个计算机的内存按字节寻址,具有n个通用寄存器R0,...,Rn-1.
    一个完成的汇编语言有几十到上百个指令.
    我们使用一个有限的指令集合.
    假设所有运算分量都是整数.
    大部分指令含一个运算符,然后是一个目标地址,最后是一个源运算分量列表.
    指令之前可能有一个标号.
    假设有如下种类的指令可用
    1.加载运算
    指令LD dst, addr把位置addr上的值加载到位置dst.
    表示dst = addr.
    最常见形式是LD r, x
    把位置x中的值加载到寄存器r中.
    形如LD r1, r2的指令是一个寄存器到寄存器的拷贝运算.
    把寄存器r2的内容拷贝到寄存器r1
    2.保存运算
    ST x, r把寄存器r中的值保存到位置x.
    表示x = r
    3.计算运算
    OP dst, src1, src2
    dst = src1 op src2
    单目运算符没src2
    4.无条件跳转
    BR L使得控制流转向标号为L的机器指令
    5.条件跳转
    Bcond r, L
    r是一个寄存器,L是一个标号
    cond代表了对寄存器r中的值所做的某个常见测试
    
    假设目标机具有多种寻址模式
    1.在指令中,一个位置可是一个变量名x,它指向分配给x的内存位置
    2.一个位置也可是一个带有下标的形如a(r)的地址,其中a是一个变量,r是一个寄存器.a(r)表示的内存位置按如下方式计算得到:a的左值加上存放寄存器r中的值.
    如指令LD R1, a(R2)的效果是R1 = contents(a + contents(R2)),其中contents(x)表示x所代表的寄存器或内存位置中存放的内容.
    3.一个内存位置可是一个以寄存器作为下标的整数.
    如LD R1, 100(R2)的效果就是使得R1 = contents(100+contents(R2))
    也即首先计算寄存器R2的值加上100得到的和
    然后把这个和所指向的位置中的值加载到R1中
    4.还支持另外两种间接寻址模式
    *r表示寄存器r的内容所代表的位置上存放的内存位置
    *100(r)表示在r中内容加上100的和所代表的位置上的内容所代表的位置
    如LD R1, *100(R2)效果是把R1设置为contents(contents(100+contents(R2)))
    5.最后,支持一个直接常数寻址模式.
    在常数面前有一个前缀#.
    指令LD R1, #100把整数100加载到R1中.
    而ADD R1, R1, #100则把100加到寄存器R1中.
    

    程序和指令的代价

    目标代码中的地址

    将说明如何用静态和栈式内存分配为简单的过程调用和返回生成代码,以此将IR中的名字转换成为目标代码中的地址.
    这个空间被划分成为四个代码及数据区域
    1.一个静态确定的代码区Code.
    这个区存放可执行的目标代码.
    目标代码大小可在编译时确定
    2.一个静态确定的静态数据区Static.
    这个区存放全局常量和编译器生成的其他数据.
    全局常量和编译器数据的大小也可在编译时刻确定
    3.一个动态管理的堆区Heap.
    这个区存放程序运行时刻分配和释放的数据对象.
    4.一个动态管理的栈区Stack.
    

    静态分配

    关注下面的三地址语句
    call callee
    return
    halt
    action
    先说明如何在过程调用时在一个活动记录中存放返回地址,及如何在过程调用结束把控制返回到这个地址.
    假设活动记录的第一个位置存放返回地址.
    ST callee.staticArea, #here+20
    BR callee.codeArea
    ST指令把返回地址保存到callee的活动记录的开始处
    BR把控制传递到被调用过程callee的目标代码上
    
    BR *callee.staticAction
    

    栈分配

    名字的运行时刻地址

    基本块和流图

    本节介绍一种用图来表示中间代码的方法
    这个表示方法可按照如下方法构造
    1.把中间代码划分为基本块
    每个基本块是满足下列条件的最大的连续三地址指令序列
    1.1.控制流只能从基本块中的第一个指令进入该块
    即没跳转到基本块中间的转移指令
    1.2.除了基本块的最后一个指令,控制流在离开基本块之前不会停机或跳转
    2.基本块形成了流图的结点
    流图的边指明了哪些基本块可紧随一个基本块之后运行
    

    基本块

    把一个三地址指令序列分割成为基本块
    以第一个指令作为一个新基本块的开始,
    不断把后续指令加进去
    直到碰到无条件跳转,条件跳转或下一个指令前面的标号为止
    
    // 把三地址指令序列划分成为基本块
    输入:一个三地址指令序列
    输出:输入序列对应的一个基本块列表,其中每个指令恰好被分配给一个基本块
    方法:
    确定中间代码序列中哪些指令是首指令
    即某个基本块的第一个指令
    跟在中间程序末端之后的指令的不包含在首指令集合中.
    选择首指令的规则如下:
    1.中间代码的第一个三地址指令是一个首指令
    2.任意一个条件或无条件转移指令的目标指令是一个首指令
    3.紧跟在一个条件或无条件转移指令之后的指令是一个首指令
    每个首指令对应的基本块包括了从它自己开始,直到下一个首指令[不含]或中间程序的结尾指令间的所有指令.
    

    请添加图片描述

    请添加图片描述

    每个首指令对应的基本块包括了从它开始直到下一个首指令之前的所有指令
    

    后续使用信息

    一个三地址语句中对一个名字的使用的定义如下.
    假设三地址语句i给x赋了一个值.
    如语句j的一个运算分量为x,且从语句i开始可通过未对x进行赋值的路径到达语句j,
    则说语句j使用了在语句i处计算得到的x的值.
    可进一步说x在语句i处活跃.
    
    用来确定活跃性和后续使用信息的算法对每个基本块进行一次反向的遍历
    把得到的信息存放到符号表
    假设每个过程调用的指令是一个新的基本块的开始
    
    // 对一个基本块中的每一个语句确定活跃性与后续使用信息
    输入:一个三地址语句的基本块B,假设开始时候符号表显示B中的所有非临时变量都是活跃的.
    输出:对B的每一个语句i:x=y+z,将x,y及z的活跃性信息及后续使用信息关联到i
    方法:
    从B的最后一个语句开始,反向扫描到B的开始处
    对每个语句i:x=y+z
    做下面的处理:
    1.把在符号表中找到的有关x,y和z的当前后续使用和活跃性信息与语句i关联起来
    2.在符号表中,设置x为不活跃和无后续使用
    3.在符号表中,设置y和z为活跃,并把它们的下一次使用设置为语句i
    

    流图

    当将一个中间代码程序划分为基本块后,
    用一个流图来表示它们之间的控制流
    流图的结点是这些基本块.
    从基本块B到基本块C间有一条边当且仅当基本块C的第一个指令可能紧跟在B的最后一个指令之后.存在这样一条边原因:
    1.有一个从B的结尾跳到C的开头的跳转语句
    2.按原来三地址语句序列的顺序,C紧跟在B后,B的结尾无跳转
    
    从入口到流图的第一个可执行结点有一条边
    从任何包含了可能是程序的最后执行指令的基本块到出口有一条边
    如程序的最后指令不是无条件转移,则包含了程序最后一条指令的基本块是出口结点的前驱.任何包含了跳到程序外的跳转指令的基本块也是出口结点的前驱.
    

    请添加图片描述

    流图的表示方式

    循环

    如下列条件成立,我们就说流图中的一个结点集合L是一个循环
    1.在L中有一个被称为循环入口的结点
    它是唯一的其前驱可能在L之外的结点.
    也即从整个流图的入口结点开始到L中的任何结点的路径都必然经过循环入口结点
    且这个循环入口结点不是整个流图的入口结点本身
    2.L中的每个结点都有一个到达L的入口结点的非空路径,且该路径全部在L中
    

    基本块的优化

    基本块的DAG表示

    把一个基本块转换为一个DAG
    按如下方式为一个基本块构造DAG
    1.基本块中出现的每个变量都有一个对应的DAG结点表示其初始值
    2.基本块中的每个语句s都有一个相关的结点N.N的子结点是基本块中的其他语句的对应结点.这些语句在s之前,最后一个对s所使用的某个运算分量进行定值的语句.
    3.结点N的标号是s中的运算符;同时还有一组变量被关联到N,表示s是在此基本块内最晚对这些变量进行定值的语句
    4.某些结点被指明为输出结点.这些结点的变量在基本块的出口处活跃.
    这些变量的值可能以后会在流图的另一个基本块被用到.
    
    基本块的DAG表示使我们可对基本块所代表的代码进行一些转换,以改进代码质量
    1.可消除局部公共子表达式
    公共子表达式就是重复计算一个已经计算得到的值的指令
    2.可消除死代码,即计算得到的值不会被使用的指令
    3.可对相互独立的语句重新排序,重排序可降低一个临时值需保持在寄存器中的时间
    4.可用代数规则重新排列三地址指令的运算分量顺序
    

    寻找局部公共子表达式

    一个新结点M将被加入DAG中时,
    检查是否存在一个结点N,它和M有同样的运算符和子结点,且子结点顺序相同.
    如存在,N计算的值和M计算的值一样.可用N替换M.
    

    请添加图片描述
    请添加图片描述

    消除死代码

    在DAG上消除死代码操作可按如下方式实现
    从一个DAG上删除所有没有附加活跃变量的根结点
    重复应用,即可消除DAG中死代码对应结点
    

    代数恒等式使用

    1.代数恒等式
    

    请添加图片描述

    2.局部强度消减
    

    请添加图片描述

    3.常量合并
    

    数组引用的表示

    在DAG中表示数组访问的正确方法如下
    1.从一个数组取值并赋给其他变量的运算[如x=a[i]]用一个新创建的运算符为=[]的结点表示.
    这个结点的左右子结点分别代表数组初始值和下标i.
    变量x是这个结点的标号之一.
    2.对数组的赋值[如a[j]=y]用一个新创建的运算符[]=结点来表示.这个结点的三个子结点分别表示a0,j和y.没有变量用这个结点标号.
    
    此结点的创建杀死了所有当前已经建立的,其值依赖于a0的结点.一个被杀死的结点不能在获得任何标号,不可能成为一个公共子表达式.
    

    请添加图片描述
    请添加图片描述

    请添加图片描述
    请添加图片描述

    指针赋值和过程调用

    运算符=*需把当前所有带有附加标识符的结点当做其参数.
    这么做会影响死代码消除过程.
    *=运算符会把迄今构造出的DAG中的其他结点全部杀死
    

    从DAG到基本块的重组

    一个简单的代码生成器

    寄存器和地址描述符

    代码生成算法

    运算的机器指令
    复制语句的机器指令
    基本块的收尾处理
    管理寄存器和地址描述符
    

    函数getReg的设计

    窥孔优化

    消除冗余的加载和保存指令

    消除不可达代码

    控制流优化

    代数化简和强度消减

    使用机器特有的指令

    寄存器分配和指派

    全局寄存器分配

    使用计数

    外层循环的寄存器指派

    通过图着色方法进行寄存器分配

    通过树重写来选择指令

    树翻译方案

    通过覆盖一个输入树来生成代码

    通过扫描进行模式匹配

    用于语义检查的例程

    通用的树匹配算法

    表达式的优化代码的生成

    Ershov数

    从带标号的表达式树生成代码

    寄存器数量不足时的表达式求值

    使用动态规划的代码生成

    连续求值

    动态规划算法

    展开全文
  • 机器学习习题(19)

    千次阅读 2020-02-18 12:10:30
    本文我们主要讲解以下几个知识点:线性规划、评估指标、伴随矩阵、过拟合以及判别模型与生成模型等知识点。 设线性规划的约束条件为: 则基本可行解为 () A.(0, 0, 4, 3) B.(3, 4, 0, 0) C.(2, 0, 1, 0) D.(3, ...
  • 从人类视觉推理显著性目标检测

    千次阅读 2021-01-15 10:26:11
    目前关于视觉显著性的研究主要集中在两个方面: 注视点的预测和SOD(显著性目标检测),然后这两者之间的关系并没有很好的探索,论文提出了一种利用注视点预测模型辨别显著性目标。通过利用注视点预测推理显著目标,...
  • 目标跟踪综述

    千次阅读 2022-03-21 17:25:12
    1 主要流程(见下图): 初始化目标框 下一帧生成多个候选框 提取候选框特征 对候选框评分 选择评分最高的候选框(即预测目标) 对多个预测值进行融合得到更优预测目标 2 一般优化环节 对应主要流程中的各个环节,...
  • 监督学习:生成模型和判别模型

    千次阅读 2017-03-19 21:52:47
    生成模型与判别模型 http://blog.csdn.net/zouxy09  一直在看论文的过程中遇到这个问题,折腾了不少时间,然后是下面的一点理解,不知道正确否。若有错误,还望各位前辈不吝指正,以免小弟一错再错。在此谢过。   ...
  • 目标检测 - 搜索结果 - 知乎 目标检测的指标AP与mAP - 知乎 1. 目标检测常用指标 FPS:每秒处理的图像帧数 IoU:重叠度,真实边框和预测边框的交集面积与并集面积的比值 P R AP:把每一个R的P都求出来,取...
  • 目标检测网络(RCNN系列,SSD,Yolo系列)

    万次阅读 多人点赞 2019-08-22 22:49:23
    深度学习相关的目标检测方法也可以大致分为两派 发展历程 基于区域提名的R-CNN家族对比总括 R-CNN(2014) SPP-Net Fast R-CNN(2015) Faster-RCNN Yolo:you only look once SSD: Single Shot MultiBox ...
  • 各种目标检测网络

    千次阅读 2021-02-06 23:44:04
    候选区域生成: 一张图像生成1K~2K个候选区域 (采用Selective Search 方法) 特征提取: 对每个候选区域,使用深度卷积网络提取特征 (CNN) 类别判断: 特征送入每一类的SVM 分类器,判别是否属于该类 位置精修: ...
  • 生成式对抗网络(Generative adversarial networks, GAN)是当前人工智能学界最为重要的研究热点之一。其突出的生成能力不仅可用于生成各类图像和自然语言数据,还启发和推动了各类半监督学习和无监督学习任务的发展...
  • 生成对抗网络(Generative adversarial nets,GAN)是Goodfellow等人在2014年提出的一种生成式模型。...其优化过程类似于极小极大游戏,通过反向传播算法,最终目标可实现纳什均衡,即生成器完全获得真实数据样本的分...
  • 机器学习模型可解释的详尽介绍

    万次阅读 多人点赞 2019-11-20 17:30:00
    机器之心平台来源:腾讯技术工程模型可解释方面的研究,在近两年的科研会议上成为关注热点,因为大家不仅仅满足于模型的效果,更对模型效果的原因产生更多的思考,这样的思考有助于...
  • R-CNN算法学习(步骤一:候选区域生成

    万次阅读 多人点赞 2018-12-27 15:55:28
    R-CNN算法学习 ...算法整体思想 总体分为 四个步骤(下文讲逐步骤分析...1.候选区域生成: 一张图像生成1K~2K个候选区域 (采用Selective Search 方法) 2.特征提取: 对每个候选区域,使用深度卷积网络提取特征 (CNN)...
  • 目标跟踪从两个维度来展开: 基于视觉的目标跟踪和基于多传感器融合的目标跟踪。 1.基于视觉的目标跟踪 一般将目标跟踪分为两个部分:特征提取、目标跟踪算法。目标跟踪的算法大致可以分为以下五种: 均值漂移算法...
  • 本篇笔记对数学建模中常见的多目标规划问题提供了解法:在建立传统的多目标规划的常用模型的基础上,使用智能优化算法对多目标规划问题进行求解,通过Pareto Front直观展现非劣解的分布情况,以解决传统的多目标规划...
  • 下列模型属于机器学习生成式模型的是() A.朴素贝叶斯 B.隐马尔科夫模型(HMM) C.马尔科夫随机场(Markov Random Fields) D.深度信念网络(DBN) 答案:ABCD 3.EM算法用于无监督学习时执行流程为() A初始化模型参数;...
  • 重排序与数据依赖

    千次阅读 多人点赞 2019-10-04 15:14:07
    上一篇博客我们了解了Java内存模型,下面我们来了解一下重排序和数据依赖的相关知识。 为什么需要重排序 现在的CPU一般采用流水线来执行指令。一个指令的执行被分成:取指、译码、访存、执行、写回、等若干个阶段...
  • (5):添加passthrough层:即将低层大区域特征转化成小区域和高层小区域融合以达到特征融合的目的解决小目标问题。具体流程如下:     对于一个26X26的特征,抽取2X2的区域将转化为通道数(变成4个通道...
  • 比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。 给出两种基本实现: /* 静态顺序存储线性表的基本实现 */ #include #include #include #...
  • 目标跟踪评价指标

    千次阅读 2019-01-06 12:51:00
    也就是说,正确跟踪目标的轨迹,每个目标生成一个轨迹。 此外,我们还期望指标具有一些其他性质: 自由参数少、阈值可调整等等,尽可能的使得评估直截了当,且使得结果具有可比。 清晰易懂,符合人类...
  • 目标检测中的Two-stage的检测算法

    千次阅读 2020-04-12 18:32:36
    比较详细,作个备份 什么是目标检测(object detection): 目标检测(object detection),就是在给定的一张图片中精确找到物体所在的位置,并标注出物体的类别。所以,...
  • 点击上方“机器学习与生成对抗网络”,关注"星标"获取有趣、好玩的前沿干货!文章来源:淘系技术背景基于生成对抗网络(GAN)的动漫人物生成近年来兴起的动漫产业新技术。传统的...
  • 背景基于生成对抗网络(GAN)的动漫人物生成近年来兴起的动漫产业新技术。传统的GAN模型利用反向传播算法,通过生成器和判别器动态对抗,得到一个目标生成模型。由于训练过程不稳定,网络难以收...
  • 机器学习的可解释

    千次阅读 2020-12-09 19:00:00
    1.3 可解释的分类 根据可解释方法的作用时间、可解释方法与模型的匹配关系、可解释方法的作用范围,我们可以将机器学习的可解释方法分为:本质可解释和事后可解释、针对特定模型的可解释和模型无关...
  • kalilinux生成安卓木马(仅供学习使用)

    千次阅读 多人点赞 2021-07-27 17:28:01
    kalilinux生成安卓木马——盗取手机数据、控制后台拍照、录像 一、前期准备工作 1.1虚拟机安装好kalilinux 链接:https://pan.baidu.com/s/10rcLYOGYKQb0pETqJLbD4A 提取码:p4dq (本身是想要给你们网站的但是那个...
  • 虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础文章对你有所帮助,在Python和安全路上与大家一起进步。 监督学习(Supervised Learning)包括分类算法(Classification)和回归算法...
  • YOLO YOLO是与SSD齐名的one_stage目标检测算法...由于yolo属于one_stage的目标检测算法,所以网络结构比较简单。固定输入448x448大小的图片,最后输出7x7x30大小的特征图。 作者的主干网络受GoogLeNet的启发,共有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,565
精华内容 29,026
热门标签
关键字:

下列属于生成性目标的是