LCC编译器的源程序分析(59)代码生成的源程序注释

下面详细地注释了gen.c的源程序,这样看起来就比较容易理解,希望对你有所帮助。
#001 #include "c.h"
#002 
#003 static char rcsid[] = "$Id: gen.c 355 2007-02-18 22:08:49Z drh $";
#004 
#005 #define readsreg(p) /
#006     (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P)
#007 #define setsrc(d) ((d) && (d)->x.regnode && /
#008     (d)->x.regnode->set == src->x.regnode->set && /
#009     (d)->x.regnode->mask&src->x.regnode->mask)
#010 
#011 #define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b))
#012 
#013 static Symbol   askfixedreg(Symbol);
#014 static Symbol   askreg(Symbol, unsigned*);
#015 static void     blkunroll(int, int, int, int, int, int, int[]);
#016 static void     docall(Node);
#017 static void     dumpcover(Node, int, int);
#018 static void     dumpregs(char *, char *, char *);
#019 static void     dumprule(int);
#020 static void     dumptree(Node);
#021 static void     genreload(Node, Symbol, int);
#022 static void     genspill(Symbol, Node, Symbol);
#023 static Symbol   getreg(Symbol, unsigned*, Node);
#024 static int      getrule(Node, int);
#025 static void     linearize(Node, Node);
#026 static int      moveself(Node);
#027 static void     prelabel(Node);
#028 static Node*    prune(Node, Node*);
#029 static void     putreg(Symbol);
#030 static void     ralloc(Node);
#031 static void     reduce(Node, int);
#032 static int      reprune(Node*, int, int, Node);
#033 static int      requate(Node);
#034 static Node     reuse(Node, int);
#035 static void     rewrite(Node);
#036 static Symbol   spillee(Symbol, unsigned mask[], Node);
#037 static void     spillr(Symbol, Node);
#038 static int      uses(Node, Regnode);
#039 
#040 
#041 //保存栈分配的偏移位置。
#042 int offset;
#043 
#044 //所有代码块使用栈的最大值。
#045 int maxoffset;
#046 
#047 //大于或者等于maxoffset,由于作内存对齐的处理。
#048 //用来输出栈的使用大小。
#049 int framesize;
#050 
#051 //保存下一块参数使用内存开始。
#052 int argoffset;
#053 
#054 //保存参数使用最大值。
#055 int maxargoffset;
#056 
#057 int dalign, salign;
#058 int bflag = 0; /* omit */
#059 int dflag = 0;
#060 
#061 int swap;
#062 
#063 //设置后面输出汇编代码的函数.
#064 unsigned (*emitter)(Node, int) = emitasm;
#065 
#066 //定义需要寄存器的中间代码类型。
#067 static char NeedsReg[] =
#068 {
#069     0,                      /* unused */
#070     1,                      /* CNST */
#071     0, 0,                   /* ARG ASGN */
#072     1,                      /* INDIR */
#073     0, 0, 1, 1,             /* - - CVF CVI */
#074     1, 0, 1, 1,             /* CVP - CVU NEG */
#075     1,                      /* CALL */
#076     1,                      /* LOAD */
#077     0,                      /* RET */
#078     1, 1, 1,                /* ADDRG ADDRF ADDRL */
#079     1, 1, 1, 1, 1,          /* ADD SUB LSH MOD RSH */
#080     1, 1, 1, 1,             /* BAND BCOM BOR BXOR */
#081     1, 1,                   /* DIV MUL */
#082     0, 0, 0, 0, 0, 0,       /* EQ GE GT LE LT NE */
#083     0, 0                   /* JUMP LABEL   */
#084 };
#085 Node head;
#086 
#087 //保存空闲的寄存器
#088 unsigned freemask[2];
#089 
#090 //保存已经使用的寄存器。
#091 unsigned usedmask[2];
#092 
#093 //临时变量使用的寄存器
#094 unsigned tmask[2];
#095 
#096 //变量使用的寄存器.
#097 unsigned vmask[2];
#098 
#099 //创建并初始化寄存器。
#100 Symbol mkreg(char *fmt, int n, int mask, int set)
#101 {
#102     Symbol p;
#103 
#104     NEW0(p, PERM);
#105     p->name = p->x.name = stringf(fmt, n);
#106     NEW0(p->x.regnode, PERM);
#107     p->x.regnode->number = n;
#108     p->x.regnode->mask = mask<<n;
#109     p->x.regnode->set = set;
#110     return p;
#111 }
#112 
#113 //创建寄存器链表。
#114 Symbol mkwildcard(Symbol *syms)
#115 {
#116     Symbol p;
#117 
#118     NEW0(p, PERM);
#119     p->name = p->x.name = "wildcard";
#120     //保存寄存器列表。
#121     p->x.wildcard = syms;
#122     return p;
#123 }
#124 
#125 //保持栈分配对齐。
#126 //
#127 //蔡军生 2007/07/21
#128 //
#129 void mkauto(Symbol p)
#130 {
#131     assert(p->sclass == AUTO);
#132     offset = roundup(offset + p->type->size, p->type->align);
#133     p->x.offset = -offset;
#134     p->x.name = stringd(-offset);
#135 }
#136 
#137 //每块代码开始都需要保存栈位置和寄存器状态。
#138 void blockbeg(Env *e)
#139 {
#140     e->offset = offset;
#141     e->freemask[IREG] = freemask[IREG];
#142     e->freemask[FREG] = freemask[FREG];
#143 }
#144 
#145 //每块代码结束都需要查看栈使用的最大值,
#146 //恢复寄存器的使用情况。
#147 void blockend(Env *e)
#148 {
#149     //查看使用栈的最大位置。
#150     if (offset > maxoffset)
#151     {
#152          maxoffset = offset;
#153     }   
#154 
#155     //恢复栈的大小。
#156     offset = e->offset;
#157 
#158     //恢复寄存器状态。
#159     freemask[IREG] = e->freemask[IREG];
#160     freemask[FREG] = e->freemask[FREG];
#161 }
#162 
#163 //
#164 //计算参数块下一块的开始位置。
#165 //
#166 //蔡军生 2007/07/21 QQ: 9073204
#167 //
#168 //
#169 int mkactual(int align, int size)
#170 {
#171     int n = roundup(argoffset, align);
#172 
#173     //保存一块参数块的开始位置。
#174     argoffset = n + size;
#175     return n;
#176 }
#177 
#178 //准备下一次调用的参数块。
#179 static void docall(Node p)
#180 {
#181     //保存参数偏移地址。
#182     p->syms[1] = p->syms[0];
#183     p->syms[0] = intconst(argoffset);
#184     if (argoffset > maxargoffset)
#185     {
#186          maxargoffset = argoffset;
#187     }   
#188 
#189     argoffset = 0;
#190 }
#191 
#192 //块复制代码。
#193 //
#194 //蔡军生 2007/07/22 QQ: 9073204
#195 //
#196 void blkcopy(int dreg, int doff, int sreg, int soff, int size, int tmp[])
#197 {
#198     assert(size >= 0);
#199     if (size == 0)
#200     {
#201          //没有字节复制。
#202          return;
#203     }   
#204     else if (size <= 2)
#205     {
#206          //两个或者一个字节复制。
#207          blkunroll(size, dreg, doff, sreg, soff, size, tmp);
#208     }   
#209     else if (size == 3)
#210     {
#211          blkunroll(2, dreg, doff,   sreg, soff,   2, tmp);
#212          blkunroll(1, dreg, doff+2, sreg, soff+2, 1, tmp);
#213     }
#214     else if (size <= 16)
#215     {
#216          //每次拷贝4个字节。
#217          blkunroll(4, dreg, doff, sreg, soff, size&~3, tmp);
#218          //递归处理
#219          blkcopy(dreg, doff+(size&~3),
#220                     sreg, soff+(size&~3), size&3, tmp);
#221     }
#222     else
#223     {
#224          (*IR->x.blkloop)(dreg, doff, sreg, soff, size, tmp);
#225     }   
#226 }
#227 
#228 //小块复制。
#229 static void blkunroll(int k, int dreg, int doff, int sreg, int soff, int size, int tmp[])
#230 {
#231     int i;
#232 
#233     assert(IR->x.max_unaligned_load);
#234     if (k > IR->x.max_unaligned_load &&
#235          (k > salign || k > dalign))
#236     {
#237          k = IR->x.max_unaligned_load;
#238     }
#239 
#240     for (i = 0; i+k < size; i += 2*k)
#241     {
#242          //取回数据。
#243          (*IR->x.blkfetch)(k, soff+i,   sreg, tmp[0]);
#244          (*IR->x.blkfetch)(k, soff+i+k, sreg, tmp[1]);
#245 
#246          //保存数据。
#247          (*IR->x.blkstore)(k, doff+i,   dreg, tmp[0]);
#248          (*IR->x.blkstore)(k, doff+i+k, dreg, tmp[1]);
#249     }
#250 
#251     if (i < size)
#252     {
#253          (*IR->x.blkfetch)(k, i+soff, sreg, tmp[0]);
#254          (*IR->x.blkstore)(k, i+doff, dreg, tmp[0]);
#255     }
#256 }
#257 
#258 //分析输入给后端的参数。
#259 void parseflags(int argc, char *argv[])
#260 {
#261     int i;
#262 
#263     for (i = 0; i < argc; i++)
#264     {         
#265          if (strcmp(argv[i], "-d") == 0)
#266          {
#267                //调试标志。
#268                dflag = 1;
#269          }   
#270          else if (strcmp(argv[i], "-b") == 0)     /* omit */
#271          {
#272                bflag = 1;               /* omit */
#273          }   
#274     }
#275 }
#276 
#277 //获取指令编码。
#278 static int getrule(Node p, int nt)
#279 {
#280     int rulenum;
#281 
#282     assert(p);
#283 
#284     //返回指令编码。
#285     rulenum = (*IR->x._rule)(p->x.state, nt);
#286     if (!rulenum)
#287     {
#288          fprint(stderr, "(%x->op=%s at %w is corrupt.)/n", p, opname(p->op), &src);
#289          assert(0);
#290     }
#291 
#292     return rulenum;
#293 }
#294 
#295 //选择代价最小的实现。
#296 static void reduce(Node p, int nt)
#297 {
#298     int rulenum, i;
#299     short *nts;
#300     Node kids[10];
#301 
#302     p = reuse(p, nt);
#303 
#304     //获取指令编码。
#305     rulenum = getrule(p, nt);
#306 
#307     //获取非终结符数组。
#308     nts = IR->x._nts[rulenum];
#309 
#310     //根据指令模板保存子节点到kids中
#311     (*IR->x._kids)(p, rulenum, kids);
#312 
#313     //遍历所有非终结符。
#314     for (i = 0; nts[i]; i++)
#315     {
#316          //递归处理子节点。
#317          reduce(kids[i], nts[i]);
#318     }   
#319 
#320     //是否是指令。
#321     if (IR->x._isinstruction[rulenum])
#322     {
#323          assert(p->x.inst == 0 || p->x.inst == nt);
#324          //保存指令类型。
#325          p->x.inst = nt;
#326          if (p->syms[RX] && p->syms[RX]->temporary)
#327          {
#328                //计算临时变量使用的次数。
#329                debug(fprint(stderr, "(using %s)/n", p->syms[RX]->name));
#330                p->syms[RX]->x.usecount++;
#331          }
#332     }
#333 }
#334 
#335 //
#336 //化简函数。
#337 //
#338 static Node reuse(Node p, int nt)
#339 {
#340     struct _state
#341     {
#342          short cost[1];
#343     };
#344 
#345     Symbol r = p->syms[RX];
#346 
#347     if (generic(p->op) == INDIR &&
#348          p->kids[0]->op == VREG+P &&
#349          r->u.t.cse && p->x.mayrecalc &&
#350          ((struct _state*)r->u.t.cse->x.state)->cost[nt] == 0)
#351     {
#352          //返回公共表达式。
#353          return r->u.t.cse;
#354     }
#355     else
#356     {
#357          return p;
#358     }   
#359 }
#360 
#361 //判断公共表达式可以重新计算
#362 int mayrecalc(Node p)
#363 {
#364     int nOperater;
#365 
#366     assert(p && p->syms[RX]);
#367     if (p->syms[RX]->u.t.cse == NULL)
#368     {
#369          //不是公共表达式返回。
#370          return 0;
#371     }   
#372 
#373     nOperater = generic(p->syms[RX]->u.t.cse->op);
#374     if (nOperater == CNST || nOperater == ADDRF ||
#375          nOperater == ADDRG || nOperater == ADDRL)
#376     {
#377          //公共表达式可以重新计算。
#378          p->x.mayrecalc = 1;
#379          return 1;
#380     }
#381     else
#382     {
#383          //公共表达式不可以重新计算。
#384          return 0;
#385     }   
#386 }
#387 
#388 //删除某些子指令。
#389 static Node *prune(Node p, Node pp[])
#390 {
#391     if (p == NULL)
#392     {
#393          return pp;
#394     }   
#395 
#396     p->x.kids[0] = p->x.kids[1] = p->x.kids[2] = NULL;
#397     if (p->x.inst == 0)
#398     {
#399          //如果节点不是指令,就递归到下一个节点。
#400          return prune(p->kids[1], prune(p->kids[0], pp));
#401     }
#402     else if (p->syms[RX] && p->syms[RX]->temporary &&
#403          p->syms[RX]->x.usecount < 2)
#404     {
#405          //删除没有用的临时变量的指令。
#406          p->x.inst = 0;
#407          debug(fprint(stderr, "(clobbering %s)/n", p->syms[RX]->name));
#408         
#409          return prune(p->kids[1], prune(p->kids[0], pp));
#410     }
#411     else
#412     {
#413          prune(p->kids[1], prune(p->kids[0], &p->x.kids[0]));
#414          *pp = p;
#415          return pp + 1;
#416     }
#417 }
#418 
#419 #define ck(i) return (i) ? 0 : LBURG_MAX
#420 
#421 //代价值计算.
#422  int range(Node p, int lo, int hi)
#423 {
#424     Symbol s = p->syms[0];
#425 
#426     switch (specific(p->op))
#427     {
#428     case ADDRF+P:
#429     case ADDRL+P: ck(s->x.offset >= lo && s->x.offset <= hi);
#430     case CNST+I: ck(s->u.c.v.i >= lo && s->u.c.v.i <= hi);
#431     case CNST+U: ck(s->u.c.v.u >= lo && s->u.c.v.u <= hi);
#432     case CNST+P: ck(s->u.c.v.p == 0 && lo <= 0 && hi >= 0);
#433     }
#434     return LBURG_MAX;
#435 }
#436 
#437 //调试输出指令树
#438 static void dumptree(Node p)
#439 {
#440     if (p->op == VREG+P && p->syms[0])
#441     {
#442          fprint(stderr, "VREGP(%s)", p->syms[0]->name);
#443          return;
#444     }
#445     else if (generic(p->op) == LOAD)
#446     {
#447          fprint(stderr, "LOAD(");
#448          dumptree(p->kids[0]);
#449          fprint(stderr, ")");
#450          return;
#451     }
#452 
#453     fprint(stderr, "%s(", opname(p->op));
#454     switch (generic(p->op)) {
#455     case CNST: case LABEL:
#456     case ADDRG: case ADDRF: case ADDRL:
#457          if (p->syms[0])
#458                fprint(stderr, "%s", p->syms[0]->name);
#459          break;
#460     case RET:
#461          if (p->kids[0])
#462                dumptree(p->kids[0]);
#463          break;
#464     case CVF: case CVI: case CVP: case CVU: case JUMP:
#465     case ARG: case BCOM: case NEG: case INDIR:
#466          dumptree(p->kids[0]);
#467          break;
#468     case CALL:
#469          if (optype(p->op) != B) {
#470                dumptree(p->kids[0]);
#471                break;
#472          }
#473          /* else fall thru */
#474     case EQ: case NE: case GT: case GE: case LE: case LT:
#475     case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
#476     case ADD: case SUB: case DIV: case MUL: case MOD:
#477          dumptree(p->kids[0]);
#478          fprint(stderr, ", ");
#479          dumptree(p->kids[1]);
#480          break;
#481     default: assert(0);
#482     }
#483     fprint(stderr, ")");
#484 }
#485 
#486 static void dumpcover(Node p, int nt, int in)
#487 {
#488     int rulenum, i;
#489     short *nts;
#490     Node kids[10];
#491 
#492     p = reuse(p, nt);
#493     rulenum = getrule(p, nt);
#494     nts = IR->x._nts[rulenum];
#495     fprint(stderr, "dumpcover(%x) = ", p);
#496     for (i = 0; i < in; i++)
#497          fprint(stderr, " ");
#498     dumprule(rulenum);
#499     (*IR->x._kids)(p, rulenum, kids);
#500     for (i = 0; nts[i]; i++)
#501          dumpcover(kids[i], nts[i], in+1);
#502 }
#503 
#504 //调试输出指令的规则.
#505 static void dumprule(int rulenum)
#506 {
#507     assert(rulenum);
#508     fprint(stderr, "%s / %s", IR->x._string[rulenum],
#509          IR->x._templates[rulenum]);
#510     if (!IR->x._isinstruction[rulenum])
#511          fprint(stderr, "/n");
#512 }
#513 
#514 //输出一个节点的汇编代码。
#515 //
#516 // 格式如下:
#517 // %% 输出 %
#518 // %F 输出 framesize
#519 // %数字 输出对应 非终结符的第几个子树。
#520 // %字母 输出变量所在的地址
#521 // #开头 调用emit2函数输出.
#522 // ?开头 如果源寄存器和目标寄存器一样,就忽略第一条指令。
#523 //
#524 unsigned emitasm(Node p, int nt)
#525 {
#526     int rulenum;
#527     short *nts;
#528     char *fmt;
#529 
#530     //保存子节点。
#531     Node kids[10];
#532 
#533 
#534     p = reuse(p, nt);
#535 
#536     //取得指令编码。
#537     rulenum = getrule(p, nt);
#538 
#539     nts = IR->x._nts[rulenum];
#540 
#541     //获取指令模板。
#542     fmt = IR->x._templates[rulenum];
#543 
#544     assert(fmt);
#545     if (IR->x._isinstruction[rulenum] && p->x.emitted)
#546     {
#547          //已经输出过代码。
#548          print("%s", p->syms[RX]->x.name);
#549     }   
#550     else if (*fmt == '#')
#551     {
#552          //复杂的指令输出。
#553          (*IR->x.emit2)(p);
#554     }   
#555     else
#556     {
#557          //如果源寄存器和目标寄存器一样,就忽略第一条指令。
#558          if (*fmt == '?')
#559          {
#560                fmt++;
#561                assert(p->kids[0]);
#562                if (p->syms[RX] == p->x.kids[0]->syms[RX])
#563                {
#564                     while (*fmt++ != '/n');
#565                }
#566          }
#567 
#568          //先根据模板保存两子节点到kids中。
#569          for ((*IR->x._kids)(p, rulenum, kids); *fmt; fmt++)
#570          {
#571                if (*fmt != '%')
#572                {
#573                     //输出指令字符。
#574                     (void)putchar(*fmt);
#575                }   
#576                else
#577                {
#578                     //跳过%号。
#579                     ++fmt;
#580 
#581                     //
#582                     if (*fmt == 'F')
#583                     {
#584                           //输出帧内存的大小。
#585                           print("%d", framesize);
#586                     }   
#587                     else if (*fmt >= '0' && *fmt <= '9')
#588                     {
#589                           //递归地输出子节点的指令代码。
#590                           emitasm(kids[*fmt - '0'], nts[*fmt - '0']);
#591                     }   
#592                     else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms))
#593                     {
#594                           //输出变量所在的地址。
#595                           fputs(p->syms[*fmt - 'a']->x.name, stdout);
#596                     }   
#597                     else
#598                     {
#599                           (void)putchar(*fmt);
#600                     }   
#601                }
#602          }
#603     }
#604 
#605     return 0;
#606 }
#607 
#608 //
#609 //把中间代码输出汇编代码。
#610 //
#611 void emit(Node p)
#612 {
#613     //遍历代码表节点。
#614     for (; p; p = p->x.next)
#615     {
#616          assert(p->x.registered);
#617          if (p->x.equatable && requate(p) || moveself(p))
#618          {
#619                //跳过这些不需要生成指的节点。
#620                ;
#621          }   
#622          else
#623          {
#624                //调用输出汇编代码函数。
#625                (*emitter)(p, p->x.inst);
#626          }   
#627 
#628          //标识已经输出指令
#629          p->x.emitted = 1;
#630     }
#631 }
#632 
#633 //检查是否自己复制自己的寄存器。
#634 static int moveself(Node p)
#635 {
#636     return p->x.copy
#637     && p->syms[RX]->x.name == p->x.kids[0]->syms[RX]->x.name;
#638  }
#639 
#640 //设置寄存器到寄存器的拷贝。
#641 int move(Node p)
#642 {
#643     p->x.copy = 1;
#644     return 1;
#645 }
#646 
#647 //寄存器是否相等判断。
#648 static int requate(Node q)
#649 {
#650     Symbol src = q->x.kids[0]->syms[RX];
#651     Symbol tmp = q->syms[RX];
#652     Node p;
#653     int n = 0;
#654 
#655     debug(fprint(stderr, "(requate(%x): tmp=%s src=%s)/n", q, tmp->x.name, src->x.name));
#656     for (p = q->x.next; p; p = p->x.next)
#657     {
#658          if (p->x.copy && p->syms[RX] == src && 
#659                p->x.kids[0]->syms[RX] == tmp)
#660          {
#661                debug(fprint(stderr, "(requate arm 0 at %x)/n", p)),
#662                p->syms[RX] = tmp;
#663          }
#664          else if (setsrc(p->syms[RX]) && !moveself(p) && !readsreg(p))
#665          {
#666                return 0;
#667          }   
#668          else if (p->x.spills)
#669          {
#670                return 0;
#671          }   
#672          else if (generic(p->op) == CALL && p->x.next)
#673          {
#674                return 0;
#675          }   
#676          else if (p->op == LABEL+V && p->x.next)
#677          {
#678                return 0;
#679          }   
#680          else if (p->syms[RX] == tmp && readsreg(p))
#681          {
#682                debug(fprint(stderr, "(requate arm 5 at %x)/n", p)),
#683                n++;
#684          }
#685          else if (p->syms[RX] == tmp)
#686          {
#687                break;
#688          }   
#689     }   
#690    
#691     debug(fprint(stderr, "(requate arm 7 at %x)/n", p));
#692     assert(n > 0);
#693     for (p = q->x.next; p; p = p->x.next)
#694     {
#695          if (p->syms[RX] == tmp && readsreg(p))
#696          {
#697                p->syms[RX] = src;
#698                if (--n <= 0)
#699                     break;
#700          }
#701     }
#702 
#703     return 1;
#704 }
#705 
#706 //后序遍历代码树,根据不同类型设置寄存器。
#707 //
#708 static void prelabel(Node p)
#709 {
#710     //树节点为空就返回。
#711     if (p == NULL)
#712          return;
#713 
#714     //递归遍历
#715     prelabel(p->kids[0]);
#716     prelabel(p->kids[1]);
#717 
#718     //查找是否需要寄存器。
#719     if (NeedsReg[opindex(p->op)])
#720     {
#721          //设置需要寄存器的类型。
#722          setreg(p, (*IR->x.rmap)(opkind(p->op)));
#723     }   
#724 
#725     //
#726     switch (generic(p->op))
#727     {
#728     case ADDRF:
#729     case ADDRL:
#730          if (p->syms[0]->sclass == REGISTER)
#731          {
#732                //如果引用是寄存器变量,就修改操作码。
#733                p->op = VREG+P;
#734          }
#735          break;
#736     case INDIR:
#737          if (p->kids[0]->op == VREG+P)
#738          {
#739                setreg(p, p->kids[0]->syms[0]);
#740          }
#741          break;
#742     case ASGN:
#743          if (p->kids[0]->op == VREG+P)
#744          {
#745                rtarget(p, 1, p->kids[0]->syms[0]);
#746          }
#747          break;
#748     case CVI:
#749     case CVU:
#750     case CVP:
#751          if (optype(p->op) != F && 
#752                opsize(p->op) <= p->syms[0]->u.c.v.i)
#753          {
#754                p->op = LOAD + opkind(p->op);
#755          }
#756          break;
#757     }
#758 
#759     //调整寄存器的类型。
#760     (IR->x.target)(p);
#761 }
#762 
#763 //保存寄存器类型指针。
#764 void setreg(Node p, Symbol r)
#765 {
#766     p->syms[RX] = r;
#767 }
#768 
#769 //计算那些需要放到特定寄存器的树节点。
#770 void rtarget(Node p, int n, Symbol r)
#771 {
#772     Node q = p->kids[n];
#773 
#774     assert(q);
#775     assert(r);
#776     assert(r->sclass == REGISTER || !r->x.wildcard);
#777     assert(q->syms[RX]);
#778 
#779      if (r != q->syms[RX] && !q->syms[RX]->x.wildcard)
#780     {
#781          //当子节点与父节点的寄存器不相同时要产生寄存器复制。
#782          q = newnode(LOAD + opkind(q->op),
#783                q, NULL, q->syms[0]);
#784         
#785          if (r->u.t.cse == p->kids[n])
#786          {
#787                r->u.t.cse = q;
#788          }   
#789 
#790          p->kids[n] = p->x.kids[n] = q;
#791          q->x.kids[0] = q->kids[0];
#792     }
#793 
#794     //设置寄存器类型.
#795     setreg(q, r);
#796 
#797     debug(fprint(stderr, "(targeting %x->x.kids[%d]=%x to %s)/n", p, n, p->kids[n], r->x.name));
#798  }
#799 
#800 //完成单棵树的寄存器定位和指令选择。
#801 static void rewrite(Node p)
#802 {
#803     assert(p->x.inst == 0);
#804     //设置寄存器类型和重定位目标。
#805     prelabel(p);
#806 
#807     debug(dumptree(p));
#808     debug(fprint(stderr, "/n"));
#809 
#810     //设置每个节点的指令选择。
#811     (*IR->x._label)(p);
#812 
#813     debug(dumpcover(p, 1, 0));
#814 
#815     //
#816     reduce(p, 1);
#817 }
#818 
#819 //生成代码。
#820 Node gen(Node forest)
#821 {
#822     int i;
#823     struct node sentinel;
#824     Node dummy, p;
#825 
#826     head = forest;
#827 
#828     //为整个森林选择指令。
#829     for (p = forest; p; p = p->link)
#830     {
#831          assert(p->count == 0);
#832          //调用参数块分配。
#833          if (generic(p->op) == CALL)
#834          {
#835                docall(p);
#836          }
#837          else if (   generic(p->op) == ASGN &&
#838                generic(p->kids[1]->op) == CALL)
#839          {
#840                docall(p->kids[1]);
#841          }   
#842          else if (generic(p->op) == ARG)
#843          {
#844                (*IR->x.doarg)(p);
#845          }   
#846 
#847          //为一个节点选择指令。
#848          rewrite(p);
#849 
#850          ///标记已经遍历过。
#851          p->x.listed = 1;
#852     }
#853 
#854     //构造指令树,并从指令树中删除一些子指令。
#855     for (p = forest; p; p = p->link)
#856     {
#857          prune(p, &dummy);
#858     }   
#859 
#860     //为指令树进行线性化处理.
#861     relink(&sentinel, &sentinel);
#862     for (p = forest; p; p = p->link)
#863     {
#864          //输出指令排序。
#865          linearize(p, &sentinel);
#866     }
#867 
#868     forest = sentinel.x.next;
#869     assert(forest);
#870     sentinel.x.next->x.prev = NULL;
#871     sentinel.x.prev->x.next = NULL;
#872 
#873     //为所有临时变量建立一个列表.
#874     for (p = forest; p; p = p->x.next)
#875     {
#876          for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
#877          {
#878                assert(p->x.kids[i]->syms[RX]);
#879                if (p->x.kids[i]->syms[RX]->temporary)
#880                {
#881                     p->x.kids[i]->x.prevuse =
#882                           p->x.kids[i]->syms[RX]->x.lastuse;
#883                     p->x.kids[i]->syms[RX]->x.lastuse = p->x.kids[i];
#884                }
#885          }
#886     }
#887 
#888     //为每个节点分配一个寄存器.
#889     for (p = forest; p; p = p->x.next)
#890     {
#891          //分配寄存器。         
#892          ralloc(p);
#893 
#894          if (p->x.listed && NeedsReg[opindex(p->op)] &&
#895                (*IR->x.rmap)(opkind(p->op)))
#896          {
#897                assert(generic(p->op) == CALL || generic(p->op) == LOAD);
#898                putreg(p->syms[RX]);
#899          }
#900     }
#901     return forest;
#902 }
#903 
#904 int notarget(Node p)
#905 {
#906     return p->syms[RX]->x.wildcard ? 0 : LBURG_MAX;
#907 }
#908 
#909 //释放一个寄存器。
#910 static void putreg(Symbol r)
#911 {
#912     assert(r && r->x.regnode);
#913     freemask[r->x.regnode->set] |= r->x.regnode->mask;
#914     debug(dumpregs("(freeing %s)/n", r->x.name, NULL));
#915 }
#916 
#917 //
#918 //请求分配一个固定的寄存器。
#919 //蔡军生 2007/07/17
#920 //
#921 static Symbol askfixedreg(Symbol s)
#922 {
#923     Regnode r = s->x.regnode;
#924     int n = r->set;
#925 
#926     //判断请求这个寄存器是否有空,
#927     //如果没有空的寄存器就返回NULL。
#928     if (r->mask&~freemask[n])
#929     {
#930          return NULL;
#931     }   
#932     else
#933     {
#934          //保存已经使用的寄存器。
#935          freemask[n] &= ~r->mask;
#936          usedmask[n] |= r->mask;
#937          return s;
#938     }
#939 }
#940 
#941 //请求分配一个寄存器。
#942 static Symbol askreg(Symbol rs, unsigned rmask[])
#943 {
#944     int i;
#945 
#946     if (rs->x.wildcard == NULL)
#947     {
#948          return askfixedreg(rs);
#949     }   
#950 
#951     for (i = 31; i >= 0; i--)
#952     {
#953          Symbol r = rs->x.wildcard[i];
#954          if (r != NULL &&
#955                !(r->x.regnode->mask&~rmask[r->x.regnode->set])    &&
#956                askfixedreg(r))
#957          {
#958                return r;
#959          }   
#960     }
#961 
#962     return NULL;
#963 }
#964 
#965  //获取一个寄存器。
#966 static Symbol getreg(Symbol s, unsigned mask[], Node p)
#967 {
#968     //尝试请求一个寄存器。
#969     Symbol r = askreg(s, mask);
#970     if (r == NULL)
#971     {
#972          //请求寄存器不成功,接着把寄存器空出来。
#973          //下面先找到最近不使用的寄存器r.
#974          r = spillee(s, mask, p);
#975          assert(r && r->x.regnode);
#976 
#977          //溢出这个寄存器。
#978          spill(r->x.regnode->mask, r->x.regnode->set, p);
#979          r = askreg(s, mask);
#980     }
#981 
#982     assert(r && r->x.regnode);
#983     r->x.regnode->vbl = NULL;
#984 
#985     return r;
#986 }
#987 
#988 //为一个局部变量或者参数分配一个寄存器.
#989 int askregvar(Symbol p, Symbol regs)
#990 {
#991     Symbol r;
#992 
#993     assert(p);
#994     if (p->sclass != REGISTER)
#995     {
#996          //非寄存器类型,不分配寄存器.
#997          return 0;
#998     }
#999     else if (!isscalar(p->type))
#1000  {
#1001         //聚合类型不分配寄存器.
#1002         p->sclass = AUTO;
#1003         return 0;
#1004  }
#1005  else if (p->temporary)
#1006  {
#1007         //如果变量是一个临时变量,延时分配.
#1008         p->x.name = "?";
#1009         return 1;
#1010  }
#1011  else if ((r = askreg(regs, vmask)) != NULL)
#1012  {
#1013         p->x.regnode = r->x.regnode;
#1014         p->x.regnode->vbl = p;
#1015         p->x.name = r->x.name;
#1016         debug(dumpregs("(allocating %s to symbol %s)/n", p->x.name, p->name));
#1017         return 1;
#1018  }
#1019  else
#1020  {
#1021         //如果分配不成功,就强制地放到栈空间里.
#1022         p->sclass = AUTO;
#1023         return 0;
#1024  }
#1025 }
#1026 
#1027 //把指令树线性化.
#1028 static void linearize(Node p, Node next)
#1029 {
#1030  int i;
#1031 
#1032  for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
#1033  {
#1034         linearize(p->x.kids[i], next);
#1035  }   
#1036 
#1037  relink(next->x.prev, p);
#1038  relink(p, next);
#1039 
#1040  debug(fprint(stderr, "(listing %x)/n", p));
#1041 }
#1042 
#1043 //为一条指令分配一个寄存器或者释放一个寄存器。
#1044 static void ralloc(Node p)
#1045 {
#1046  int i;
#1047  unsigned mask[2];
#1048 
#1049  //获取所有可能使用的寄存器。
#1050  mask[0] = tmask[0];
#1051  mask[1] = tmask[1];
#1052 
#1053  assert(p);
#1054  debug(fprint(stderr, "(rallocing %x)/n", p));
#1055 
#1056  //释放最近不使用的寄存器。
#1057  for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
#1058  {
#1059         Node kid = p->x.kids[i];
#1060         Symbol r = kid->syms[RX];
#1061         assert(r && kid->x.registered);
#1062         if (r->sclass != REGISTER && r->x.lastuse == kid)
#1063         {
#1064              putreg(r);
#1065         }
#1066  }
#1067 
#1068  if (!p->x.registered && NeedsReg[opindex(p->op)] &&
#1069         (*IR->x.rmap)(opkind(p->op)))
#1070  {
#1071         Symbol sym = p->syms[RX], set = sym;
#1072         assert(sym);
#1073 
#1074         if (sym->temporary)
#1075              set = (*IR->x.rmap)(opkind(p->op));
#1076 
#1077         assert(set);
#1078         if (set->sclass != REGISTER)
#1079         {
#1080              Symbol r;
#1081              //是否需要两条指令完成的模板代码.
#1082              if (*IR->x._templates[getrule(p, p->x.inst)] == '?')
#1083              {
#1084                    //如果是就需要从第一个寄存器开始.
#1085                    for (i = 1; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
#1086                    {
#1087                         Symbol r = p->x.kids[i]->syms[RX];
#1088                         assert(p->x.kids[i]->x.registered);
#1089                         assert(r && r->x.regnode);
#1090                         assert(sym->x.wildcard || sym != r);
#1091                         mask[r->x.regnode->set] &= ~r->x.regnode->mask;
#1092                    }
#1093              }
#1094 
#1095              //获取一个寄存器。
#1096              r = getreg(set, mask, p);
#1097 
#1098              //临时变量的处理。
#1099              if (sym->temporary)
#1100              {
#1101                    Node q;
#1102                    r->x.lastuse = sym->x.lastuse;
#1103                    for (q = sym->x.lastuse; q; q = q->x.prevuse)
#1104                    {
#1105                         q->syms[RX] = r;
#1106                         q->x.registered = 1;
#1107 
#1108                         if (sym->u.t.cse && q->x.copy)
#1109                         {
#1110                               q->x.equatable = 1;
#1111                         }
#1112                    }
#1113              }
#1114              else
#1115              {
#1116                    p->syms[RX] = r;
#1117                    r->x.lastuse = p;
#1118              }
#1119              debug(dumpregs("(allocating %s to node %x)/n", r->x.name, (char *) p));
#1120         }
#1121  }
#1122 
#1123  //标记已经做过寄存器分配。
#1124  p->x.registered = 1;
#1125 
#1126  //寄存器溢出后,重新加载内存单元数据到寄存器。
#1127  (*IR->x.clobber)(p);
#1128 }
#1129 
#1130 //标记一个寄存器溢出。
#1131 static Symbol spillee(Symbol set, unsigned mask[], Node here)
#1132 {
#1133  Symbol bestreg = NULL;
#1134  int bestdist = -1, i;
#1135 
#1136  assert(set);
#1137  if (!set->x.wildcard)
#1138         bestreg = set;
#1139  else
#1140  {
#1141         //寻找最近不使用的寄存器来溢出。
#1142         for (i = 31; i >= 0; i--)
#1143         {
#1144              Symbol ri = set->x.wildcard[i];
#1145              if (
#1146                    ri != NULL &&
#1147                    ri->x.lastuse &&
#1148                    (ri->x.regnode->mask&tmask[ri->x.regnode->set]&mask[ri->x.regnode->set])
#1149              )
#1150              {
#1151                    Regnode rn = ri->x.regnode;
#1152                    Node q = here;
#1153                    int dist = 0;
#1154                   
#1155                    for (; q && !uses(q, rn); q = q->x.next)
#1156                         dist++;
#1157 
#1158                    if (q && dist > bestdist)
#1159                    {
#1160                         bestdist = dist;
#1161                         bestreg = ri;
#1162                    }
#1163              }
#1164         }
#1165  }
#1166 
#1167  assert(bestreg); /* Must be able to spill something. Reconfigure the register allocator
#1168         to ensure that we can allocate a register for all nodes without spilling
#1169         the node's necessary input regs. */  
#1170  assert(bestreg->x.regnode->vbl == NULL); /* Can't spill register variables because
#1171         the reload site might be in other blocks. Reconfigure the register allocator
#1172         to ensure that this register is never allocated to a variable. */
#1173  return bestreg;
#1174 }
#1175 
#1176 //判断节点p是否使用rn的寄存器.
#1177 static int uses(Node p, Regnode rn)
#1178 {
#1179  int i;
#1180 
#1181  for (i = 0; i < NELEMS(p->x.kids); i++)
#1182         if (
#1183              p->x.kids[i] &&
#1184              p->x.kids[i]->x.registered &&
#1185              rn->set == p->x.kids[i]->syms[RX]->x.regnode->set &&
#1186              (rn->mask&p->x.kids[i]->syms[RX]->x.regnode->mask)
#1187         )
#1188              return 1;
#1189 
#1190  return 0;
#1191 }
#1192 
#1193 //溢出一个寄存器。
#1194 static void spillr(Symbol r, Node here)
#1195 {
#1196  int i;
#1197  Symbol tmp;
#1198  Node p = r->x.lastuse;
#1199  assert(p);
#1200 
#1201  while (p->x.prevuse)
#1202  {
#1203         assert(r == p->syms[RX]),
#1204         p = p->x.prevuse;
#1205  }
#1206 
#1207  assert(p->x.registered && !readsreg(p));
#1208 
#1209  tmp = newtemp(AUTO, optype(p->op), opsize(p->op));
#1210 
#1211  //生成溢出代码.
#1212  genspill(r, p, tmp);
#1213 
#1214  for (p = here->x.next; p; p = p->x.next)
#1215  {
#1216         for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
#1217         {
#1218              Node k = p->x.kids[i];
#1219              if (k->x.registered && k->syms[RX] == r)
#1220              {
#1221                    //生成重新加载代码.
#1222                    genreload(p, tmp, i);
#1223              }   
#1224         }
#1225  }
#1226 
#1227  //释放这个寄存器可以使用.
#1228  putreg(r);
#1229 }
#1230 
#1231 //生成保存寄存器到储存器的代码.
#1232 static void genspill(Symbol r, Node last, Symbol tmp)
#1233 {
#1234  Node p, q;
#1235  Symbol s;
#1236  unsigned ty;
#1237 
#1238  debug(fprint(stderr, "(spilling %s to local %s)/n", r->x.name, tmp->x.name));
#1239  debug(fprint(stderr, "(genspill: "));
#1240  debug(dumptree(last));
#1241  debug(fprint(stderr, ")/n"));
#1242 
#1243  ty = opkind(last->op);
#1244  NEW0(s, FUNC);
#1245  s->sclass = REGISTER;
#1246  s->name = s->x.name = r->x.name;
#1247  s->x.regnode = r->x.regnode;
#1248  q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, s);
#1249  q = newnode(INDIR + ty, q, NULL, NULL);
#1250  p = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp);
#1251  p = newnode(ASGN + ty, p, q, NULL);
#1252 
#1253  //寄存器溢出标志
#1254  p->x.spills = 1;
#1255 
#1256  rewrite(p);
#1257  prune(p, &q);
#1258  q = last->x.next;
#1259  linearize(p, q);
#1260  for (p = last->x.next; p != q; p = p->x.next) 
#1261  {
#1262         ralloc(p);
#1263         assert(!p->x.listed || !NeedsReg[opindex(p->op)] || !(*IR->x.rmap)(opkind(p->op)));
#1264  }
#1265 }
#1266 
#1267 //产生代码重新加载被溢出的寄存器值。
#1268 static void genreload(Node p, Symbol tmp, int i)
#1269 {
#1270  Node q;
#1271  int ty;
#1272 
#1273  debug(fprint(stderr, "(replacing %x with a reload from %s)/n", p->x.kids[i], tmp->x.name));
#1274  debug(fprint(stderr, "(genreload: "));
#1275  debug(dumptree(p->x.kids[i]));
#1276  debug(fprint(stderr, ")/n"));
#1277 
#1278  ty = opkind(p->x.kids[i]->op);
#1279  q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp);
#1280  p->x.kids[i] = newnode(INDIR + ty, q, NULL, NULL);
#1281  
#1282  rewrite(p->x.kids[i]);
#1283  
#1284  prune(p->x.kids[i], &q);
#1285  
#1286  reprune(&p->kids[1], reprune(&p->kids[0], 0, i, p), i, p);
#1287  
#1288  prune(p, &q);
#1289  
#1290  linearize(p->x.kids[i], p);
#1291 }
#1292 
#1293 //寄存器溢出后,重新调整x.kids的节点关系.
#1294 static int reprune(Node *pp, int k, int n, Node p)
#1295 {
#1296  struct node x, *q = *pp;
#1297 
#1298  if (q == NULL || k > n)
#1299  {
#1300         return k;
#1301  }   
#1302  else if (q->x.inst == 0)
#1303  {
#1304         return reprune(&q->kids[1], reprune(&q->kids[0], k, n, p), n, p);
#1305  }   
#1306 
#1307  if (k == n)
#1308  {
#1309         debug(fprint(stderr, "(reprune changes %x from %x to %x)/n", pp, *pp, p->x.kids[n]));
#1310         *pp = p->x.kids[n];
#1311         x = *p;
#1312 
#1313         (IR->x.target)(&x);
#1314  }
#1315 
#1316  return k + 1;
#1317 }
#1318 
#1319 //溢出一个寄存器。
#1320 void spill(unsigned mask, int n, Node here)
#1321 {
#1322  int i;
#1323  Node p;
#1324 
#1325  //设置这个寄存器被溢出。
#1326  here->x.spills = 1;
#1327  usedmask[n] |= mask;
#1328 
#1329  if (mask&~freemask[n])
#1330  {
#1331 
#1332         assert( /* It makes no sense for a node to clobber() its target. */
#1333              here->x.registered == 0 || /* call isn't coming through clobber() */
#1334              here->syms[RX] == NULL ||
#1335              here->syms[RX]->x.regnode == NULL ||
#1336              here->syms[RX]->x.regnode->set != n ||
#1337              (here->syms[RX]->x.regnode->mask&mask) == 0
#1338         );
#1339 
#1340         for (p = here; p; p = p->x.next)
#1341         {
#1342              for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
#1343              {
#1344                    Symbol r = p->x.kids[i]->syms[RX];
#1345                    assert(r);
#1346                    if (p->x.kids[i]->x.registered &&
#1347                         r->x.regnode->set == n &&
#1348                         r->x.regnode->mask&mask)
#1349                    {
#1350                         spillr(r, here);
#1351                    }
#1352              }
#1353         }
#1354  }//
#1355 }
#1356 
#1357 //输出空闲的寄存器.
#1358 static void dumpregs(char *msg, char *a, char *b)
#1359 {
#1360  fprint(stderr, msg, a, b);
#1361  fprint(stderr, "(free[0]=%x)/n", freemask[0]);
#1362  fprint(stderr, "(free[1]=%x)/n", freemask[1]);
#1363 }
#1364 
#1365 //获取节点的寄存器号.
#1366 int getregnum(Node p)
#1367 {
#1368  assert(p && p->syms[RX] && p->syms[RX]->x.regnode);
#1369  return p->syms[RX]->x.regnode->number;
#1370 }
#1371 
#1372 
#1373 unsigned regloc(Symbol p)
#1374 {
#1375  assert(p && p->sclass == REGISTER && p->sclass == REGISTER && p->x.regnode);
#1376  return p->x.regnode->set<<8 | p->x.regnode->number;
#1377 }
#1378 
#1379 
 
这里是公用的生成代码,其实还有不同目标的指令模块,这里没有列出来。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

caimouse

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

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

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

打赏作者

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

抵扣说明:

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

余额充值