Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

gen.c File Reference

#include "c.h"

Include dependency graph for gen.c:

Include dependency graph

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)
Nodeprune (Node p, Node pp[])
Nodeprune (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]


Define Documentation

#define ck i   )     return (i) ? 0 : LBURG_MAX
 

Definition at line 251 of file gen.c.

Referenced by range().

#define readsreg p   )     (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P)
 

Definition at line 4 of file gen.c.

Referenced by requate(), and spillr().

#define relink a,
 )     ((b)->x.prev = (a), (a)->x.next = (b))
 

Definition at line 10 of file gen.c.

Referenced by AAS_UpdateEntity(), gen(), and linearize().

#define setsrc  ) 
 

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().


Function Documentation

Symbol askfixedreg Symbol   )  [static]
 

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 }

Symbol askreg Symbol  rs,
unsigned  rmask[]
[static]
 

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:

Symbol askreg Symbol  ,
unsigned * 
[static]
 

int askregvar Symbol  p,
Symbol  regs
 

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:

void blkcopy int  dreg,
int  doff,
int  sreg,
int  soff,
int  size,
int  tmp[]
 

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:

void blkunroll int  ,
int  ,
int  ,
int  ,
int  ,
int  ,
int  []
[static]
 

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 }

void blockbeg Env e  ) 
 

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 }

void blockend Env e  ) 
 

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 }

void docall Node   )  [static]
 

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:

void dumpcover Node  ,
int  ,
int 
[static]
 

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:

void dumpregs char *  ,
char *  ,
char * 
[static]
 

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:

void dumprule int   )  [static]
 

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:

void dumptree Node   )  [static]
 

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:

void emit Node  p  ) 
 

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:

unsigned emitasm Node  ,
int 
[static]
 

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:

Node gen Node  forest  ) 
 

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:

void genreload Node  ,
Symbol  ,
int 
[static]
 

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:

void genspill Symbol  ,
Node  ,
Symbol 
[static]
 

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 }

<