9.6 后端
后端的全部就是 C 代码生成器。这个模块打开输出文件,给予扩展名.b (b 表示 beta),为它编写程序头,然后调用代码生成器。一旦为整个的图生成全部代码以后,就把文件关闭。图 9-12 显示后端子过程的代码。
void BackEnd (char *fileName, CALL_GRAPH *callGraph) { FILE *fp; /* Output C file */ /* Open output file with extension .b */ openFile (fp, filename, ".b", "wt"); printf ("dcc: Writing C beta file %s.b\n", fileName); /* Header information */ writeHeader (fp, fileName); /* Process each procedure at a time */ writeCallGraph (fileName, callGraph, fp); /* Close output file */ fclose (fp); printf ("dcc: Finished writing C beta file\n"); } |
图 9-12: 后端子过程
9.6.1 代码生成
dcc 实现第 7 章第 7.1 节描述的 C 代码生成器。程序的调用图以深度优先方式遍历,首先为叶子代表的子程序生成 C 代码 (亦即,如果该图是可归约的,就按照逆调用顺序)。根据每个子程序的控制流向图的结构,为它生成相应的代码;条件结构和循环的边界已经由结构化阶段在图中做了标记。代码是通过递归方式生成的,所以,在递归中如果一个结点不是第一次被到达,就用一个 goto 跳转以转移控制到与这个结点相关联的代码。
由于从表达式叶子里发现的寄存器在代码生成期间才给予命名 (即,在所有局部变量都已经被定义在局部变量定义区之后),而且已经生成代码的那些指令可能会有一个与之关联的标签,以便作为后面可能产生的某个 goto 跳转目标,所以代码不能被直接生成并输出一个文件,而是需要先储存在一个中间的数据结构中直至一个完整的子程序代码全部已经生成;然后它可以被复制到目标输出文件,而且该结构给调用图中的下一个子程序重复使用。dcc 用来管理子程序声明和代码的数据结构名叫 bundle (包裹)。一个 bundle 由两个行数组(array of lines) 组成,一个用于子程序声明,另一个用于子程序代码。子程序声明不仅包括子程序头,而且包括注解和局部变量定义。如果最初分配的数组尺寸太小,行数组可以动态增长。数据结构 bundle 的定义见图 9-13 所示。
typedef struct { Int numLines; /* Number of lines in the table */ Int allocLines; /* Number of lines allocated in the table */ char **str; /* Table of strings */ } strTable; typedef struct { strTable decl; /* Declarations */ strTable code; /* C code */ } bundle; |
图 9-13: 数据结构 bundle 的定义
dcc 所显示的注解和错误信息在附录 E 列表。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论