




已阅读5页,还剩46页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
8目标代码生成 学时 6知识点 涉及的问题基本块 程序流图下次引用信息代码生成算法 李文生制作 版权所有 2 8目标代码生成 目标代码生成程序的任务将前端产生的中间代码转换为等价的目标代码对目标代码生成器的要求 正确高质量 1 有效地利用目标机器的资源2 所生成的目标代码应高效地运行 本章目标 介绍一个简单的代码生成器算法 产生最优化代码问题是不可判定的 实践中能够产生好的 虽不是最优的 代码的启发式技术就很令人满意了 李文生制作 版权所有 3 本章主要内容 8 1代码生成器设计中的问题8 2目标机器8 3运行时的存储管理8 4基本块和流图8 5下次引用信息8 6简单的代码生成器小结作业 李文生制作 版权所有 4 8 1代码生成器设计中的问题 代码生成器的具体细节依赖于目标机器和操作系统所有的代码生成器固有的问题代码生成器的输入代码生成器的输出存储管理指令选择寄存器分配计算顺序选择代码生成器的设计 李文生制作 版权所有 5 一 代码生成器的输入 中间代码经过语法分析 语义检查之后得到的正确的符号表记录了与名字有关的信息决定中间表示中的名字所代表的数据对象的运行地址假定 前期工作结果正确 可信中间代码足够详细必要的类型转换符已正确插入明显的语义错误已经发现 且正确恢复 李文生制作 版权所有 6 二 代码生成器的输出 目标代码形式绝对机器代码可把代码放在内存中固定的地方 立即执行可重定位机器代码 obj DOS o UNIX 开发灵活 允许各子模块单独编译需要由连接装配程序将它们连接在一起 生成可执行文件汇编代码代码生成过程容易 但需要汇编 李文生制作 版权所有 7 三 存储管理 从名字到存储单元的映射由前端和代码生成器共同完成三地址代码中的名字指向该名字在符号表中位置的指针符号表中的信息在处理声明语句时填入 类型 决定了它的域宽 地址 确定该名字在过程的数据区域中的相对位置上述信息用于确定中间代码中的名字对应的数据对象在运行时的地址生成机器代码时 指令地址通过计数器来实现 李文生制作 版权所有 8 例如 中间代码与目标代码的对应 对于四元式j gotoiij n 12 n 12 n 12 8 n 20 n 20 16 n 36 n 36 4 n 40 将四元式j的地址记入与i相关的链表中 等待回填 四元式i的地址已有 可以直接生成机器指令 李文生制作 版权所有 9 四 指令选择 机器指令系统的性质决定了指令选择的难易程度代码质量取决于它的执行速度和长度对每一类三地址语句 可以设计它的代码框架如 x y z的代码框架可以是 MOVy R0ADDz R0MOVR0 x a b cd a e a a 1 MOVb R0ADDc R0MOVR0 aMOVa R0ADDe R0MOVR0 d MOVa R0ADD 1 R0MOVR0 a INCa 李文生制作 版权所有 10 五 寄存器分配 充分利用寄存器可以生成好的代码寄存器使用的两个问题哪些变量要放在寄存器中指定的变量放在哪个寄存器中寄存器指派的困难可用寄存器专用寄存器通用寄存器寄存器对把寄存器指派给相应的变量变量需要什么样的寄存器操作需要什么样的寄存器选择最优的寄存器指派方案是一个NP完全问题 李文生制作 版权所有 11 六 计算顺序的选择 计算顺序影响目标代码的效率选择最佳计算次序是一个NP完全问题 七 代码生成器的设计 设计原则能够正确地生成代码易于实现 便于测试和维护只介绍一个简单的代码生成算法主要考虑寄存器的有效使用 李文生制作 版权所有 12 8 2目标机器 设计代码生成器的必要条件 熟悉目标机器一般信息编址方式 按字节编址每个字有4个字节寄存器 n个通用寄存器 R0 R1 Rn 1指令形式 OPS D其中OP MOV ADD SUBS 源操作数D 目的操作数 李文生制作 版权所有 13 寻址方式 地址形式汇编方式地址占用存储空间绝对地址MM1寄存器RR0变址c R c contents R 1间接寄存器 Rcontents R 0间接变址 c R contents c contents R 1立即数 c常数c1 指令代价指令所占用存储单元字数 1 S寻址方式占用字数 D寻址方式占用字数 李文生制作 版权所有 14 举例 MOVR0 R1将寄存器R0的内容复制到R1中代价 1MOVR5 M将寄存器R5的内容放到存储单元M中代价 2ADD 1 R3将寄存器R3的内容增加1代价 2SUB4 R0 12 R1 将地址为 contents 12 contents R1 的单元中的值减去contents 4 contents R0 结果仍存放到地址为 contents 12 contents R1 的单元中 代价 3 李文生制作 版权所有 15 三地址语句a b c的代码 1 MOVb R0ADDc R0指令代价为6MOVR0 a 2 MOVb aADDc a指令代价为6 3 假定R0 R1和R2中分别存放了a b和c的地址 MOV R1 R0ADD R2 R0指令代价为2 4 假定R1和R2中分别包含b和c的值 b的值以后不再需要 ADDR2 R1MOVR1 a指令代价为3 李文生制作 版权所有 16 过程的语义决定了运行时名字如何与存储单元相联系 存储分配策略静态存储分配存储器中活动记录的位置在编译时刻已经确定栈式存储分配当开始执行一个过程时 一个新的活动记录压入栈顶当该过程的活动结束时 其活动记录从栈中弹出活动记录的内容参数 返回值控制链 访问链 机器状态局部数据 临时变量 8 3运行时的存储管理 活动记录的分配和释放是调用序列和返回序列的一部分 讨论三地址语句callreturnhaltaction 李文生制作 版权所有 17 静态存储分配情况 三地址代码 S的代码 action1callpaction2halt P的代码 action3return S的活动记录 64字节 0 4 56 60 j P的活动记录 88字节 0 4 84 n 李文生制作 版权所有 18 三地址语句call的目标机器指令 MOV指令 存放返回地址GOTO指令 将控制转移到被调用过程的目标代码MOV here 20 callee static areaGOTOcallee code area here 该MOV指令的地址20 call的机器指令的代价 here 20 返回地址 被调用过程活动记录的开始地址 被调用过程代码的第一条指令地址 三地址语句return的目标机器指令 GOTO callee static area 代码结构 李文生制作 版权所有 19 静态存储分配举例 100 action1120 MOV 140 364132 GOTO200140 action2160 HALT 200 action3220 GOTO 364 300 304 364 368 保存返回地址 调用过程P 返回到364存储单元里存放的地址 140 李文生制作 版权所有 20 栈式存储分配情况 活动记录分配在栈中活动记录在栈中的位置 直到运行时才能确定这个位置常被存放在一个寄存器中寄存器SP保存指向栈顶活动记录开始位置的指针当发生过程调用时 调用过程给SP一个增量 使之指向被调用过程的活动记录的开始位置 同时将控制转移到被调用过程 当控制返回到调用过程时 再将SP减去原来的增量 从而释放了被调用过程的活动记录 李文生制作 版权所有 21 代码结构 主程序的代码MOV stackstart SP第一个过程的代码HALT 初始化控制栈 三地址语句call的机器代码ADD caller recordsize SPMOV here 16 SPGOTOcallee code area SP指向下一个活动记录 三地址语句return的机器代码GOTO 0 SP SUB caller recordsize SP 间接变址 返回调用过程该指令在被调用过程的代码中 SP指回调用过程的活动记录该指令在调用过程的代码中 李文生制作 版权所有 22 程序说明 三地址代码 S的代码 action1callqaction2halt P的代码 action3return q的代码 action4callpaction5callqaction6callqreturn 各过程目标代码的起址 s 100p 200q 300活动记录的大小 ssize 20psize 40qsize 60控制栈的开始位置 600 李文生制作 版权所有 23 100 MOV 600 SP108 action1128 ADD ssize SP136 MOV 152 SP144 GOTO300152 SUB ssize SP160 action2180 HALT 200 action3220 GOTO 0 SP 栈式存储分配举例 300 action4320 ADD qsize SP328 MOV 344 SP336 GOTO200344 SUB qsize SP352 action5372 ADD qsize SP380 MOV 396 SP388 GOTO300396 SUB qsize SP404 action6424 ADD qsize SP432 MOV 448 SP440 GOTO300448 SUB qsize SP456 GOTO 0 SP 600 初始化栈 callq callp return callq callq return 李文生制作 版权所有 24 程序执行及栈的变化情况 S callq 返回地址152 q callp 返回地址344 p return 返回地址344 callq 返回地址396 q return 返回地址396 callq 返回地址448 q return 返回地址448 return 返回地址152 halt 李文生制作 版权所有 25 运行时名字的地址 假定三地址语句为 x 0静态存储分配情况静态数据区的基址 staticx在数据区中的位置是12x的实际地址应为 static 12 尽管在编译时可确定static 12的值 但在生成中间代码时 static的值可能并不知道 这样 必须生成相应的三地址代码以 计算 static 12的值 赋值语句x 0被翻译为如下三地址代码 static 12 0若static 100 则相应的目标代码为 MOV 0 112 李文生制作 版权所有 26 用display表存取非局部名字 该表存放在寄存器中x局部于一个活动记录 该活动记录的display表指针在寄存器R3中将语句x 0翻译成为如下三地址语句 t1 12 R3 t1 0 栈式存储分配情况 t1中存放的是x的地址 这个序列可由如下机器指令来实现 MOV 0 12 R3 李文生制作 版权所有 27 8 4基本块和流图 基本块具有原子性的一组连续语句序列 控制从第一条语句流入 从最后一条语句流出 中途没有停止或分支 末尾除外 划分基本块的方法确定入口语句三地址代码的第一条语句条件 无条件语句转移到的语句紧跟在条件 无条件语句后面的语句确定基本块从一个入口语句 含该语句 到下一个入口语句 不含 从一个入口语句 含该语句 到停止语句 含该语句 李文生制作 版权所有 28 举例 基本块 t1 a at2 a bt3 2 t2t4 t1 t3t5 b bt6 t4 t5 1 i m 1 2 j n 3 t1 4 n 4 v a t1 5 i i 1 6 t2 4 i 7 t3 a t2 8 ift3vgoto 9 13 ifi jgoto 23 14 t6 4 i 15 x a t6 16 t7 4 i 17 t8 4 j 18 t9 a t8 19 a t7 t9 20 t10 4 j 21 a t10 x 22 goto 5 23 t11 4 i 24 x a t11 25 t12 4 i 26 t13 4 n 27 t14 a t13 28 a t12 t14 29 t15 4 n 30 a t15 x 基本块划分 B1 B2 B3 B4 B5 B6 李文生制作 版权所有 29 流图 定义 把控制流信息加到基本块集合中 形成程序的有向图 称为流图 控制流图 构造 流图的结点是基本块如果一个结点基本块的入口语句是程序的第一条语句 则称此基本块结点为首结点 如果在某个执行序列中 基本块B2紧跟在基本块B1之后执行 则从B1到B2有一条有向边 B1是B2的前驱 B2是B1的后继 即如果 有一个条件 无条件转移语句从B1的最后一条语句转移到B2的第一条语句 B1的最后一条语句不是无条件转移语句 并且在程序的语句序列中 B2紧跟在B1之后 实现 用记录 用链表转移语句指向块而不是指向三地址语句因为基本块变换后 语句会发生变化循环的定义 强连通 唯一入口 李文生制作 版权所有 30 举例 1 i m 1 2 j n 3 t1 4 n 4 v a t1 5 i i 1 6 t2 4 i 7 t3 a t2 8 ift3 vgoto 5 9 j j 1 10 t4 4 j 11 t5 a t4 12 ift5 vgoto 9 13 ifi jgoto 23 14 t6 4 i 15 x a t6 16 t7 4 i 17 t8 4 j 18 t9 a t8 19 a t7 t9 20 t10 4 j 21 a t10 x 22 goto 5 23 t11 4 i 24 x a t11 25 t12 4 i 26 t13 4 n 27 t14 a t13 28 a t12 t14 29 t15 4 n 30 a t15 x B1 B2 B3 B4 B5 B6 B2 B3 B6 B2 李文生制作 版权所有 31 8 5下次引用信息 在把三地址代码转换成为目标代码时 遇到的一个重要问题 如何充分利用寄存器 作用 如果存于寄存器的名字的值以后不再需要 那么该寄存器可以分配给其它名字基本思路 在一个基本块范围内考虑把在基本块内还要被引用的变量的值尽可能保存在寄存器中把在基本块内不再被引用的变量所占用的寄存器尽早地释放如 翻译语句x yopzx y z在基本块中是否还会被引用 在哪些三地址语句中被引用 李文生制作 版权所有 32 计算下次引用信息 三地址语句序列 i x 1j y xopz j是三地址语句i中x的下次引用信息假定讨论在一个基本块内的引用信息所有的变量在基本块出口处都是活跃的符号表中含有记录下次引用信息和活跃信息的域 语句i对变量x定值 没有对变量x定值的其他语句 语句j引用x在语句i处定的值 李文生制作 版权所有 33 算法 输入 组成基本块的三地址语句序列输出 基本块中各名字的下次引用信息方法 1 把基本块中各变量在符号表中的下次引用信息域置为 无下次引用 活跃信息域置为 活跃 2 从基本块出口到入口由后向前依次处理各语句 对每个三地址语句i x yopz 依次执行下述步骤 a 把当前符号表中变量x的下次引用信息和活跃信息附加到语句i上 b 把符号表中x的下次引用信息和活跃信息分别置为 无下次引用 和 非活跃 c 把当前符号表中变量y和z的下次引用信息和活跃信息附加到语句i上 d 把符号表中y和z的下次引用信息均置为i 活跃信息均置为 活跃 abcd次序不能颠倒 李文生制作 版权所有 34 举例 计算向量点积的程序beginprod 0 i 1 dobeginprod prod a i b i i i 1endwhilei 20end 程序的控制流图 B1 1 prod 0 2 i 1 3 t1 4 i 4 t2 a 4 5 t3 t2 t1 6 t4 4 i 7 t5 b 4 8 t6 t5 t4 9 t7 t3 t6 10 t8 prod t7 11 prod t8 12 t9 i 1 13 i t9 14 ifi 20gotoB2 B2 李文生制作 版权所有 35 计算B2中变量的下次引用信息 初始化符号表 变量下次活跃i无活prod无活a无活b无活t1无活t2无活t3无活t4无活t5无活t6无活t7无活t8无活t9无活 从出口到入口依次检查每条三地址语句 14 ifi 20 i无活 14活 13 i t9 i14活 无非活 t9无活 13活 12 t9 i 1 t913活 无非活 i无非活 12活 11 prod t8 prod无活 无非活 t8无活 11活 10 t8 prod t7 t811活 无非活 prod无非活 10活 t7无活 10活 李文生制作 版权所有 36 9 t7 t3 t6 t710活 无非活 t3无活 9活 t6无活 9活 8 t6 t5 t4 t69活 无非活 t5无活 8活 t4无活 8活 7 t5 b 4 t58活 无非活 b无活 7活 6 t4 4 i t48活 无非活 i12活 6活 5 t3 t2 t1 t39活 无非活 t2无活 5活 t1无活 5活 4 t2 a 4 t25活 无非活 a无活 4活 3 t1 4 i t15活 无非活 i6活 3活 李文生制作 版权所有 37 8 6简单的代码生成器 思想 在基本块内充分利用寄存器方法 尽可能让变量的值保存在寄存器中 只有在下面两种情况下存储它们如果此寄存器要用于其它计算已到达基本块出口后续的代码尽可能引用变量在寄存器中的值 而不访问主存在基本块之间如何充分利用寄存器的困难 一个基本块可能有多个后继 而每个后继又可能有多个前驱 因而后继基本块不易判断变量的值是否存放在寄存器中 以及存放在那个寄存器中假定 三地址语句中的每个算符都对应一个相应目标语言算符 李文生制作 版权所有 38 考虑引用信息 代码生成时 要考察不同的情况不同的情况下 生成的目标代码也不同如a b c 1 b的值在Ri中 c的值在Rj中 且b不再活跃ADDRj Ri代价为1 2 b的值在Ri中 c的值在存储单元Mc中 且b不再活跃ADDMc Ri代价为2或MOVMc RjADDRj Ri代价为3 李文生制作 版权所有 39 数据结构 寄存器描述器记录每个寄存器的当前内容开始时 寄存器描述器指示所有的寄存器均为空代码生成过程中 每个寄存器在任一给定时刻将保留0个或多个名字的值 地址描述器记录某时刻一个名字的当前值存放的位置 可能是 一个寄存器地址一个栈地址一个存储单元地址或这些地址的一个集合这些信息可以存放在符号表中 用来确定对一个名字的存取方式 李文生制作 版权所有 40 寄存器分配函数getreg 输入 三地址语句x yopz寄存器描述器和名字的地址描述器输出 地址L L或者是寄存器 或者是存储单元 算法 1 若y的值在R中 且该R中不含其它名字的值 并且以后y不再活跃 没有下次引用信息 则返回R作为L 2 若 1 失败 有空R时 就返回一个空R作为L 3 若 2 失败 x在块中有下次引用 或op是一个需要寄存器的算符 则找一个已被占用的R 如果R的值尚未在存储单元中 用指令MOVR M将R的值存放到一个存储单元中 如果R同时保存有几个变量的值 则对每一个需要存储的变量值都应产生一条MOV指令 并且更新地址描述器为 返回R 4 如x在块中不再被引用 或找不到合适的被占用的寄存器 则返回x的存储单元Mx作为L 李文生制作 版权所有 41 代码生成算法 输入 基本块的三地址语句输出 基本块的目标代码方法 对基本块中每个三地址语句x yopz执行以下操作 1 确定工作单元L getreg i x yopz 2 查看y的地址描述器 以确定y的值存放的当前位置y 若y的值同时存放在存储器和寄存器中 那么选择寄存器作为y 如果y的值在寄存器L中 更新y的地址描述器 y不在L中 和L的寄存器描述器 L中不含y的值 如果y的值不在L中 则生成指令 MOVy L 3 生成指令 opz L更新x的地址描述器 x的值在L中 如果L为寄存器 更新L的寄存器描述器 L中只含x的值 4 若y z的当前值没有下次引用 在块的出口非活跃 并且在寄存器中 则更新寄存器描述器及y z的地址描述器 此后 这些寄存器不再包含y和 或z的值 李文生制作 版权所有 42 特殊情况 若三地址语句是x opy与x yopz类似若三地址语句是x y 复写语句 若y的值在R中 更新R的寄存器描述器和x的地址描述器 以记录x的值仅在保存y的那个寄存器中 若y没有下次引用 且在块的出口非活跃 则该寄存器不再保留y的值 若y的值仅在存储器My中 原则上可以在地址描述器中指出X在My中 但是这样会复杂代码生成算法 因为以后若要改变y的值必须先保存x的值 调用函数getreg来找一个存放x值的寄存器R 生成指令MOVy R 并更新R的寄存器描述器和x y的地址描述器 或者 若X无下次引用信息 生成指令MOVMy Mx 更新x的地址描述器 李文生制作 版权所有 43 处理 使用MOV指令把那些在块出口是活跃的 且当前值还不在存储单元中的名字的值存储到它们的存储器地址中 方法 使用寄存器描述器确定哪些名字的当前值仍保留在寄存器中使用地址描述器确定其中哪些名字的当前值还不在存储单元里使用活跃变量信息来确定是否需要存储其当前值在没有进行数据流分析的情况下 需要假定用户定义的所有变量在基本块出口处都是活跃变量在计算下次引用信息的算法中 第一步要把活跃信息域置为 活跃 基本块的出口处 李文生制作 版权所有 44 举例 考虑赋值语句d a b a c a c 三地址语句序列 t a bu a cv t ud v u假定在基本块的出口d是活跃的有两个寄存器R0和R1 李文生制作 版权所有 45 翻译过程 t a b
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 第一章声现象 单元试卷(含解析)2025-2026学年苏科版(2024)物理八年级上册
- 考研真题历年题库及答案
- 红磷燃烧的题目及答案
- 2025年汽车自动采样设备项目建议书
- 扶贫知识培训内容课件
- 羧酸衍生物2讲解
- 压力式温度计行业员工职业发展规划与管理
- 2025年播音主持证考试真题及答案
- 2025年会计考试题基础题及答案
- 2025年焊工车间考试题目及答案
- 2024年麻精药品培训考核试题(含答案)
- 2025循环水处理试题及答案
- 2025年交社保免责协议书
- 2025年度机动车检验检测机构授权签字人考试题卷(含答案)
- 2025-2026学年北师大版小学数学六年级上册教学计划及进度表
- 2024-2025学年度辽宁现代服务职业技术学院单招《语文》检测卷有完整答案详解
- 2025秋统编版八年级上册语文教学计划
- 语文开学第一课课件2025-2026学年统编版语文七年级上册
- 飞书使用培训课件
- DB42T 900-2013 公路隧道监控量测技术规程
- 《现代供电技术》课件(共八章)
评论
0/150
提交评论