LCC编译器的源程序分析(41)赋值表达式的有向无环图

前面已经介绍怎么样把赋值表达式变换到树的中间表示,接着下来编译器要做的事情就是怎么样把树变换成有向无环图。也许你会问为什么要把树变换成有向无环图,而不是直接生成最终代码呢?其实,学习过数据结构就很清楚有向无环图的应用,编译器里就是利用有向无环图的特性来进行局部代码优化的,最主要的优化就是删除公共表达式。下面就来分析 LCC 从树到有向无环图的实现代码。
上面函数 dcllocal 里调用转换函数如下:
walk(root(asgn(p, e)), 0, 0);
root 函数里返回一棵赋值树,然后就把它传递给函数 walk ,在 walk 函数里就会调用一系列函数实现到 DAG 的转换。函数 walk 的代码如下:
#001  //
#002 void walk(Tree tp, int tlab, int flab)
#003 {
#004  //
#005  listnodes(tp, tlab, flab);
#006 
#007  if (forest)
#008  {
#009         Node list = forest->link;
#010         forest->link = NULL;
#011         if (!IR->wants_dag && errcnt == 0)
#012               list = undag(list);
#013         code(Gen)->u.forest = list;
#014         forest = NULL;
#015  }
#016 
#017  reset();
#018  deallocate(STMT);
#019 }
5 行就是调用函数 listnodes 来实现 DAG 构造。
7 行是判断是否有森林生成,如果生成就把代码块放到代码链表里。这些是在第 9 行到第 14 行里做的工作。
17 行复位所有变量。
18 行删除分配的内存。
大部份的工作都是在函数 listnodes 实现的,因此这个函数比较长,有 420 多行代码。现在先分析赋值部分相关的代码,后面当遇到时再去分析它。 OK ,先来回顾一下前面的例子:
       int nTest1 = 1;
由上面这行代码就生成下面的树:
   ASGN 树:
左子树 ----- INDIR -----ADDRL
右子树 ----- 常量表达式树
listnodes 函数再由上面的树生成 DAG ,因此 listnodes 函数先会遇到 ASGN 树节点,然后再遇到 INDIR 树、 ADDRL 树,最后就是常量表达式树。有了这条主线,就可以去分析函数 listnodes 的代码了。
#001 //
#002 Node listnodes(Tree tp, int tlab, int flab)
#003 {
#004  Node p = NULL, l, r;
#005  int op;
#006 
#007  assert(tlab == 0 || flab == 0);
#008  if (tp == NULL)
#009         return NULL;
#010 
#011  if (tp->node)
#012         return tp->node;
#013 
#014  if (isarray(tp->type))
#015         op = tp->op + sizeop(voidptype->size);
#016  else
#017         op = tp->op + sizeop(tp->type->size);
#018 
#019  switch (generic(tp->op))
#020  {
2 行里函数参数 tp 就是传入来的赋值树指针, tlab flab 是当存在条件选择时才出现,因此传下来是 0
8 行是当传入来的树是空树,就直接返回,这样才能实现递归调用本函数。
11 行是当树已经变换到 DAG 节点,就不需要再进行转换,直接返回 DAG 节点。
14 行是计算操作符的类型和数据类型大小。
19 行是根据树节点不同的类型进行分别处理。比如赋值、与树等等。
 
#021   case AND:  
现在先分析到这里,下次再接着分析赋值树具体地变换到 DAG 的代码。
 
 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值