#include "c.h"
Include dependency graph for gen.c:

Go to the source code of this file.
Defines | |
| #define | ck(i) return (i) ? 0 : LBURG_MAX |
| #define | readsreg(p) (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P) |
| #define | relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b)) |
| #define | setsrc(d) |
Functions | |
| Symbol | askfixedreg (Symbol) |
| Symbol | askreg (Symbol rs, unsigned rmask[]) |
| Symbol | askreg (Symbol, unsigned *) |
| int | askregvar (Symbol p, Symbol regs) |
| void | blkcopy (int dreg, int doff, int sreg, int soff, int size, int tmp[]) |
| void | blkunroll (int, int, int, int, int, int, int[]) |
| void | blockbeg (Env *e) |
| void | blockend (Env *e) |
| void | docall (Node) |
| void | dumpcover (Node, int, int) |
| void | dumpregs (char *, char *, char *) |
| void | dumprule (int) |
| void | dumptree (Node) |
| void | emit (Node p) |
| unsigned | emitasm (Node, int) |
| Node | gen (Node forest) |
| void | genreload (Node, Symbol, int) |
| void | genspill (Symbol, Node, Symbol) |
| Symbol | getreg (Symbol s, unsigned mask[], Node p) |
| Symbol | getreg (Symbol, unsigned *, Node) |
| int | getregnum (Node p) |
| int | getrule (Node, int) |
| void | linearize (Node, Node) |
| int | mayrecalc (Node p) |
| int | mkactual (int align, int size) |
| void | mkauto (Symbol p) |
| Symbol | mkreg (char *fmt, int n, int mask, int set) |
| Symbol | mkwildcard (Symbol *syms) |
| int | move (Node p) |
| int | moveself (Node) |
| int | notarget (Node p) |
| void | parseflags (int argc, char *argv[]) |
| void | prelabel (Node) |
| Node * | prune (Node p, Node pp[]) |
| Node * | prune (Node, Node *) |
| void | putreg (Symbol) |
| void | ralloc (Node) |
| int | range (Node p, int lo, int hi) |
| void | reduce (Node, int) |
| unsigned | regloc (Symbol p) |
| int | reprune (Node *, int, int, Node) |
| int | requate (Node) |
| Node | reuse (Node, int) |
| void | rewrite (Node) |
| void | rtarget (Node p, int n, Symbol r) |
| void | setreg (Node p, Symbol r) |
| void | spill (unsigned mask, int n, Node here) |
| Symbol | spillee (Symbol, unsigned mask[], Node) |
| void | spillr (Symbol, Node) |
| int | uses (Node, Regnode) |
Variables | |
| int | argoffset |
| int | bflag = 0 |
| int | dalign |
| int | dflag = 0 |
| unsigned(* | emitter )(Node, int) = emitasm |
| int | framesize |
| unsigned | freemask [2] |
| Node | head |
| int | maxargoffset |
| int | maxoffset |
| char | NeedsReg [] |
| int | offset |
| int | salign |
| int | swap |
| unsigned | tmask [2] |
| unsigned | usedmask [2] |
| unsigned | vmask [2] |
|
|
Definition at line 251 of file gen.c. Referenced by range(). |
|
|
|
|
|
Definition at line 10 of file gen.c. Referenced by AAS_UpdateEntity(), gen(), and linearize(). |
|
|
Value: ((d) && (d)->x.regnode && \
(d)->x.regnode->set == src->x.regnode->set && \
(d)->x.regnode->mask&src->x.regnode->mask)
Definition at line 6 of file gen.c. Referenced by requate(). |
|
|
Definition at line 533 of file gen.c. References freemask, Regnode::mask, n, r, Xsymbol::regnode, s, Regnode::set, Symbol, usedmask, and symbol::x. Referenced by askreg(). 00533 {
00534 Regnode r = s->x.regnode;
00535 int n = r->set;
00536
00537 if (r->mask&~freemask[n])
00538 return NULL;
00539 else {
00540 freemask[n] &= ~r->mask;
00541 usedmask[n] |= r->mask;
00542 return s;
00543 }
00544 }
|
|
||||||||||||
|
Definition at line 545 of file gen.c. References askfixedreg(), i, Regnode::mask, NULL, r, Xsymbol::regnode, Regnode::set, Symbol, Xsymbol::wildcard, and symbol::x. Referenced by askregvar(), and getreg(). 00545 {
00546 int i;
00547
00548 if (rs->x.wildcard == NULL)
00549 return askfixedreg(rs);
00550 for (i = 31; i >= 0; i--) {
00551 Symbol r = rs->x.wildcard[i];
00552 if (r != NULL
00553 && !(r->x.regnode->mask&~rmask[r->x.regnode->set])
00554 && askfixedreg(r))
00555 return r;
00556 }
00557 return NULL;
00558 }
|
Here is the call graph for this function:

|
||||||||||||
|
|
|
||||||||||||
|
Definition at line 572 of file gen.c. References askreg(), assert, debug, dumpregs(), isscalar, symbol::name, Xsymbol::name, p, r, Xsymbol::regnode, symbol::sclass, Symbol, symbol::temporary, symbol::type, Regnode::vbl, vmask, and symbol::x. 00572 {
00573 Symbol r;
00574
00575 assert(p);
00576 if (p->sclass != REGISTER)
00577 return 0;
00578 else if (!isscalar(p->type)) {
00579 p->sclass = AUTO;
00580 return 0;
00581 }
00582 else if (p->temporary) {
00583 p->x.name = "?";
00584 return 1;
00585 }
00586 else if ((r = askreg(regs, vmask)) != NULL) {
00587 p->x.regnode = r->x.regnode;
00588 p->x.regnode->vbl = p;
00589 p->x.name = r->x.name;
00590 debug(dumpregs("(allocating %s to symbol %s)\n", p->x.name, p->name));
00591 return 1;
00592 }
00593 else {
00594 p->sclass = AUTO;
00595 return 0;
00596 }
00597 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 129 of file gen.c. References assert, Xinterface::blkloop, blkunroll(), IR, and interface::x. 00129 {
00130 assert(size >= 0);
00131 if (size == 0)
00132 return;
00133 else if (size <= 2)
00134 blkunroll(size, dreg, doff, sreg, soff, size, tmp);
00135 else if (size == 3) {
00136 blkunroll(2, dreg, doff, sreg, soff, 2, tmp);
00137 blkunroll(1, dreg, doff+2, sreg, soff+2, 1, tmp);
00138 }
00139 else if (size <= 16) {
00140 blkunroll(4, dreg, doff, sreg, soff, size&~3, tmp);
00141 blkcopy(dreg, doff+(size&~3),
00142 sreg, soff+(size&~3), size&3, tmp);
00143 }
00144 else
00145 (*IR->x.blkloop)(dreg, doff, sreg, soff, size, tmp);
00146 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Definition at line 147 of file gen.c. References assert, Xinterface::blkfetch, Xinterface::blkstore, i, IR, k, Xinterface::max_unaligned_load, salign, and interface::x. Referenced by blkcopy(). 00147 {
00148 int i;
00149
00150 assert(IR->x.max_unaligned_load);
00151 if (k > IR->x.max_unaligned_load
00152 && (k > salign || k > dalign))
00153 k = IR->x.max_unaligned_load;
00154 for (i = 0; i+k < size; i += 2*k) {
00155 (*IR->x.blkfetch)(k, soff+i, sreg, tmp[0]);
00156 (*IR->x.blkfetch)(k, soff+i+k, sreg, tmp[1]);
00157 (*IR->x.blkstore)(k, doff+i, dreg, tmp[0]);
00158 (*IR->x.blkstore)(k, doff+i+k, dreg, tmp[1]);
00159 }
00160 if (i < size) {
00161 (*IR->x.blkfetch)(k, i+soff, sreg, tmp[0]);
00162 (*IR->x.blkstore)(k, i+doff, dreg, tmp[0]);
00163 }
00164 }
|
|
|
Definition at line 104 of file gen.c. References e, freemask, Env::freemask, and Env::offset. Referenced by asdl_init(). 00104 {
00105 e->offset = offset;
00106 e->freemask[IREG] = freemask[IREG];
00107 e->freemask[FREG] = freemask[FREG];
00108 }
|
|
|
Definition at line 109 of file gen.c. References e, Env::freemask, freemask, maxoffset, Env::offset, and offset. Referenced by asdl_init(). 00109 {
00110 if (offset > maxoffset)
00111 maxoffset = offset;
00112 offset = e->offset;
00113 freemask[IREG] = e->freemask[IREG];
00114 freemask[FREG] = e->freemask[FREG];
00115 }
|
|
|
Definition at line 122 of file gen.c. References argoffset, intconst(), maxargoffset, Node, p, and node::syms. Referenced by gen(). 00122 {
00123 p->syms[1] = p->syms[0];
00124 p->syms[0] = intconst(argoffset);
00125 if (argoffset > maxargoffset)
00126 maxargoffset = argoffset;
00127 argoffset = 0;
00128 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 307 of file gen.c. References Xinterface::_kids, Xinterface::_nts, dumprule(), fprint(), getrule(), i, in, IR, Node, p, reuse(), stderr, and interface::x. Referenced by rewrite(). 00307 {
00308 int rulenum, i;
00309 short *nts;
00310 Node kids[10];
00311
00312 p = reuse(p, nt);
00313 rulenum = getrule(p, nt);
00314 nts = IR->x._nts[rulenum];
00315 fprint(stderr, "dumpcover(%x) = ", p);
00316 for (i = 0; i < in; i++)
00317 fprint(stderr, " ");
00318 dumprule(rulenum);
00319 (*IR->x._kids)(p, rulenum, kids);
00320 for (i = 0; nts[i]; i++)
00321 dumpcover(kids[i], nts[i], in+1);
00322 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 814 of file gen.c. References a, b, fprint(), freemask, and stderr. Referenced by askregvar(), putreg(), and ralloc(). 00814 {
00815 fprint(stderr, msg, a, b);
00816 fprint(stderr, "(free[0]=%x)\n", freemask[0]);
00817 fprint(stderr, "(free[1]=%x)\n", freemask[1]);
00818 }
|
Here is the call graph for this function:

|
|
Definition at line 324 of file gen.c. References Xinterface::_isinstruction, Xinterface::_string, Xinterface::_templates, assert, fprint(), IR, stderr, and interface::x. Referenced by dumpcover(). 00324 {
00325 assert(rulenum);
00326 fprint(stderr, "%s / %s", IR->x._string[rulenum],
00327 IR->x._templates[rulenum]);
00328 if (!IR->x._isinstruction[rulenum])
00329 fprint(stderr, "\n");
00330 }
|
Here is the call graph for this function:

|
|
Definition at line 265 of file gen.c. References ADD, ADDRF, ADDRG, ADDRL, ARG, ASGN, assert, BAND, BCOM, BOR, BXOR, CALL, CNST, CVF, CVI, CVP, CVU, DIV, EQ, fprint(), GE, generic, GT, INDIR, JUMP, node::kids, LABEL, LE, LSH, LT, MOD, MUL, symbol::name, NE, NEG, Node, node::op, opname(), optype, P, p, RET, RSH, stderr, SUB, node::syms, and VREG. Referenced by dumptree(), genreload(), genspill(), and rewrite(). 00265 {
00266 if (p->op == VREG+P && p->syms[0]) {
00267 fprint(stderr, "VREGP(%s)", p->syms[0]->name);
00268 return;
00269 } else if (generic(p->op) == LOAD) {
00270 fprint(stderr, "LOAD(");
00271 dumptree(p->kids[0]);
00272 fprint(stderr, ")");
00273 return;
00274 }
00275 fprint(stderr, "%s(", opname(p->op));
00276 switch (generic(p->op)) {
00277 case CNST: case LABEL:
00278 case ADDRG: case ADDRF: case ADDRL:
00279 if (p->syms[0])
00280 fprint(stderr, "%s", p->syms[0]->name);
00281 break;
00282 case RET:
00283 if (p->kids[0])
00284 dumptree(p->kids[0]);
00285 break;
00286 case CVF: case CVI: case CVP: case CVU: case JUMP:
00287 case ARG: case BCOM: case NEG: case INDIR:
00288 dumptree(p->kids[0]);
00289 break;
00290 case CALL:
00291 if (optype(p->op) != B) {
00292 dumptree(p->kids[0]);
00293 break;
00294 }
00295 /* else fall thru */
00296 case EQ: case NE: case GT: case GE: case LE: case LT:
00297 case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
00298 case ADD: case SUB: case DIV: case MUL: case MOD:
00299 dumptree(p->kids[0]);
00300 fprint(stderr, ", ");
00301 dumptree(p->kids[1]);
00302 break;
00303 default: assert(0);
00304 }
00305 fprint(stderr, ")");
00306 }
|
Here is the call graph for this function:

|
|
Definition at line 368 of file gen.c. References assert, Xnode::equatable, Xnode::inst, moveself(), Xnode::next, Node, p, Xnode::registered, requate(), and node::x. Referenced by asdl_init(). 00368 {
00369 for (; p; p = p->x.next) {
00370 assert(p->x.registered);
00371 if (p->x.equatable && requate(p) || moveself(p))
00372 ;
00373 else
00374 (*emitter)(p, p->x.inst);
00375 p->x.emitted = 1;
00376 }
00377 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 331 of file gen.c. References Xinterface::_isinstruction, Xinterface::_kids, Xinterface::_nts, Xinterface::_templates, assert, Xinterface::emit2, Xnode::emitted, fputs(), framesize, getrule(), IR, Xnode::kids, node::kids, Xsymbol::name, NELEMS, Node, p, print(), putchar, reuse(), RX, stdout, node::syms, symbol::x, node::x, and interface::x. 00331 {
00332 int rulenum;
00333 short *nts;
00334 char *fmt;
00335 Node kids[10];
00336
00337 p = reuse(p, nt);
00338 rulenum = getrule(p, nt);
00339 nts = IR->x._nts[rulenum];
00340 fmt = IR->x._templates[rulenum];
00341 assert(fmt);
00342 if (IR->x._isinstruction[rulenum] && p->x.emitted)
00343 print("%s", p->syms[RX]->x.name);
00344 else if (*fmt == '#')
00345 (*IR->x.emit2)(p);
00346 else {
00347 if (*fmt == '?') {
00348 fmt++;
00349 assert(p->kids[0]);
00350 if (p->syms[RX] == p->x.kids[0]->syms[RX])
00351 while (*fmt++ != '\n')
00352 ;
00353 }
00354 for ((*IR->x._kids)(p, rulenum, kids); *fmt; fmt++)
00355 if (*fmt != '%')
00356 (void)putchar(*fmt);
00357 else if (*++fmt == 'F')
00358 print("%d", framesize);
00359 else if (*fmt >= '0' && *fmt <= '9')
00360 emitasm(kids[*fmt - '0'], nts[*fmt - '0']);
00361 else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms))
00362 fputs(p->syms[*fmt - 'a']->x.name, stdout);
00363 else
00364 (void)putchar(*fmt);
00365 }
00366 return 0;
00367 }
|
Here is the call graph for this function:

|
|
Definition at line 479 of file gen.c. References ASGN, assert, CALL, Xinterface::doarg, docall(), generic, head, i, IR, Xnode::kids, Xsymbol::lastuse, linearize(), node::link, Xnode::listed, LOAD, NeedsReg, NELEMS, Xnode::next, Node, opindex, opkind, p, Xnode::prev, Xnode::prevuse, prune(), putreg(), ralloc(), relink, rewrite(), Xinterface::rmap, RX, node::syms, symbol::x, node::x, and interface::x. Referenced by asdl_init(). 00479 {
00480 int i;
00481 struct node sentinel;
00482 Node dummy, p;
00483
00484 head = forest;
00485 for (p = forest; p; p = p->link) {
00486 assert(p->count == 0);
00487 if (generic(p->op) == CALL)
00488 docall(p);
00489 else if ( generic(p->op) == ASGN
00490 && generic(p->kids[1]->op) == CALL)
00491 docall(p->kids[1]);
00492 else if (generic(p->op) == ARG)
00493 (*IR->x.doarg)(p);
00494 rewrite(p);
00495 p->x.listed = 1;
00496 }
00497 for (p = forest; p; p = p->link)
00498 prune(p, &dummy);
00499 relink(&sentinel, &sentinel);
00500 for (p = forest; p; p = p->link)
00501 linearize(p, &sentinel);
00502 forest = sentinel.x.next;
00503 assert(forest);
00504 sentinel.x.next->x.prev = NULL;
00505 sentinel.x.prev->x.next = NULL;
00506 for (p = forest; p; p = p->x.next)
00507 for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
00508 assert(p->x.kids[i]->syms[RX]);
00509 if (p->x.kids[i]->syms[RX]->temporary) {
00510 p->x.kids[i]->x.prevuse =
00511 p->x.kids[i]->syms[RX]->x.lastuse;
00512 p->x.kids[i]->syms[RX]->x.lastuse = p->x.kids[i];
00513 }
00514 }
00515 for (p = forest; p; p = p->x.next) {
00516 ralloc(p);
00517 if (p->x.listed && NeedsReg[opindex(p->op)]
00518 && (*IR->x.rmap)(opkind(p->op))) {
00519 assert(generic(p->op) == CALL || generic(p->op) == LOAD);
00520 putreg(p->syms[RX]);
00521 }
00522 }
00523 return forest;
00524 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 755 of file gen.c. References ADDRL, debug, dumptree(), fprint(), i, INDIR, IR, node::kids, Xnode::kids, linearize(), Xsymbol::name, newnode(), Node, NULL, node::op, opkind, P, p, prune(), interface::ptrmetric, q, reprune(), rewrite(), metrics::size, sizeop, stderr, Symbol, symbol::x, and node::x. Referenced by spillr(). 00755 {
00756 Node q;
00757 int ty;
00758
00759 debug(fprint(stderr, "(replacing %x with a reload from %s)\n", p->x.kids[i], tmp->x.name));
00760 debug(fprint(stderr, "(genreload: "));
00761 debug(dumptree(p->x.kids[i]));
00762 debug(fprint(stderr, ")\n"));
00763 ty = opkind(p->x.kids[i]->op);
00764 q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp);
00765 p->x.kids[i] = newnode(INDIR + ty, q, NULL, NULL);
00766 rewrite(p->x.kids[i]);
00767 prune(p->x.kids[i], &q);
00768 reprune(&p->kids[1], reprune(&p->kids[0], 0, i, p), i, p);
00769 prune(p, &q);
00770 linearize(p->x.kids[i], p);
00771 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 726 of file gen.c. References ADDRL, ASGN, assert, debug, dumptree(), fprint(), FUNC, INDIR, IR, linearize(), Xnode::listed, symbol::name, Xsymbol::name, NeedsReg, NEW0, newnode(), Xnode::next, Node, NULL, node::op, opindex, opkind, p, P, prune(), interface::ptrmetric, q, r, ralloc(), Xsymbol::regnode, rewrite(), Xinterface::rmap, s, symbol::sclass, metrics::size, sizeop, Xnode::spills, stderr, Symbol, interface::x, node::x, and symbol::x. Referenced by spillr(). 00726 {
00727 Node p, q;
00728 Symbol s;
00729 unsigned ty;
00730
00731 debug(fprint(stderr, "(spilling %s to local %s)\n", r->x.name, tmp->x.name));
00732 debug(fprint(stderr, "(genspill: "));
00733 debug(dumptree(last));
00734 debug(fprint(stderr, ")\n"));
00735 ty = opkind(last->op);
00736 NEW0(s, FUNC);
00737 s->sclass = REGISTER;
00738 s->name = s->x.name = r->x.name;
00739 s->x.regnode = r->x.regnode;
00740 q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, s);
00741 q = newnode(INDIR + ty, q, NULL, NULL);
00742 p = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp);
00743 p = newnode(ASGN + ty, p, q, NULL);
00744 p->x.spills = 1;
00745 rewrite(p);
00746 prune(p, &q);
00747 q = last->x.next;
00748 linearize(p, q);
00749 for (p = last->x.next; p != q; p = p->x.next) {
00750 ralloc(p);
00751 assert(!p->x.listed || !NeedsReg[opindex(p->op)] || !(*IR->x.rmap)(opkind(p->op)));
00752 }
00753 }
|