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

 
上一次说到赋值表达式转换为有向无环图的函数 listnodes ,下面继续来分析这个函数代码。
当赋值树处理时,就运行下面的分支来处理:
#256  case ASGN: 
#257         {
#258               assert(tlab == 0 && flab == 0);
#259               if (tp->kids[0]->op == FIELD)
#260               {
#261                    Tree x = tp->kids[0]->kids[0];
#262                    Field f = tp->kids[0]->u.field;
#263                    assert(generic(x->op) == INDIR);
#264                    reset();
#265                     l = listnodes(lvalue(x), 0, 0);
#266 
#267                    if (fieldsize(f) < 8*f->type->size)
#268                    {
#269                          unsigned int fmask = fieldmask(f);
#270                          unsigned int mask = fmask<<fieldright(f);
#271                          Tree q = tp->kids[1];
#272                          if (q->op == CNST+I && q->u.v.i == 0
#273                               || q->op == CNST+U && q->u.v.u == 0)
#274                               q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask));
#275                          else if (q->op == CNST+I && (q->u.v.i&fmask) == fmask
#276                               ||       q->op == CNST+U && (q->u.v.u&fmask) == fmask)
#277                               q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask));
#278                          else
#279                          {
#280                               listnodes(q, 0, 0);
#281                               q = bittree(BOR,
#282                                     bittree(BAND, rvalue(lvalue(x)),
#283                                     cnsttree(unsignedtype, (unsigned long)~mask)),
#284                                     bittree(BAND, shtree(LSH, cast(q, unsignedtype),
#285                                     cnsttree(unsignedtype, (unsigned long)fieldright(f))),
#286                                     cnsttree(unsignedtype, (unsigned long)mask)));
#287                          }
#288                          r = listnodes(q, 0, 0);
#289                          op = ASGN + ttob(q->type);
#290                    }
#291                    else
#292                    {
#293                          r = listnodes(tp->kids[1], 0, 0);
#294                          op = ASGN + ttob(tp->kids[1]->type);
#295                    }
#296 
#297               }
#298               else
#299               {
#300                     l = listnodes(tp->kids[0], 0, 0);
#301                    r = listnodes(tp->kids[1], 0, 0);
#302               }
#303 
259 行是处理结构里字段操作,在这个赋值表达式里没有字段操作,先把它放下。
300 行处理非字段操作的左子树,然后生成有向无环图的左子树,这里递归调用 listnodes 函数来实现下一层树,其实这里是采用后序遍历二叉树的算法来构造 DAG 图。
301 行递归处理右子树的节点。
 
#304               list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL));
#305               forest->syms[0] = intconst(tp->kids[1]->type->size);
#306               forest->syms[1] = intconst(tp->kids[1]->type->align);
#307              
#308               if (isaddrop(tp->kids[0]->op)
#309                    && !tp->kids[0]->u.sym->computed)
#310                    killnodes(tp->kids[0]->u.sym);
#311               else
#312                    reset();
#313 
#314               p = listnodes(tp->kids[1], 0, 0);
#315         }
#316         break;
304 行是创建一个 DAG 森林的根节点,保存在全局变量 forest 那里。
305 行和第 306 行设置符号属性。
308 行和第 309 行判断是否需要调用函数 killnodes 来删除公共表达式。如果不需要就直接调用函数 reset 复位。
314 行调用函数 listnodes 递归处理兄弟树节点。
上面是采用后序遍历的算法把所有树节点转换到 DAG 节点,并构造成有向无环图。下一次分析处理赋值树的几个类型操作树节点。
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

caimouse

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

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

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

打赏作者

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

抵扣说明:

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

余额充值