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 
 
这里是公用的生成代码,其实还有不同目标的指令模块,这里没有列出来。
 

你可能感兴趣的:(struct,汇编,null,编译器,templates,wildcard)