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

来源:互联网 发布:欧几里德算法证明 编辑:程序博客网 时间:2024/05/21 22:49
 
上一次说到赋值表达式转换为有向无环图的函数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节点,并构造成有向无环图。下一次分析处理赋值树的几个类型操作树节点。