diff options
Diffstat (limited to 'ins.c')
| -rw-r--r-- | ins.c | 195 |
1 files changed, 0 insertions, 195 deletions
@@ -1,195 +0,0 @@ -#include "all.h" - -void -addins(Ins **pvins, uint *pnins, Ins *i) -{ - if (i->op == Onop) - return; - vgrow(pvins, ++(*pnins)); - (*pvins)[(*pnins)-1] = *i; -} - -void -addbins(Blk *b, Ins **pvins, uint *pnins) -{ - Ins *i; - - for (i = b->ins; i < &b->ins[b->nins]; i++) - addins(pvins, pnins, i); -} - -static int -unusedins(Fn *fn, Ins *i); - -static int -unusedtmp(Fn *fn, Tmp *t) -{ - if (t->nuse == 0) - return 1; - if (t->nuse == 1) - if (t->use[0].type == UIns) - return unusedins(fn, t->use[0].u.ins); - return 0; -} - -static int -unusedtmpref(Fn *fn, Ref r) -{ - if (rtype(r) != RTmp) - return 0; - return unusedtmp(fn, &fn->tmp[r.val]); -} - -static int -unusedins(Fn *fn, Ins *i) -{ - if (!INRANGE(i->op, Opar, Ocall)) - if (unusedtmpref(fn, i->to)) - return 1; - return 0; -} - -/* replace unused ins with nop */ -/* needs use; breaks use */ -void -nopunused(Fn *fn) -{ - Blk *b; - Ins *i; - - for (b = fn->start; b; b = b->link) - for (i = b->ins; i < &b->ins[b->nins]; i++) - if (unusedins(fn, i)) - *i = (Ins){.op = Onop}; -} - -typedef struct FromLoc FromLoc; -struct FromLoc { - InsLoc from; - uint ton; -}; - -static int -loccmp(InsLoc *la, InsLoc *lb) -{ - if (la->bid != lb->bid) - return (int)la->bid - (int)lb->bid; - return la->insn - lb->insn; -} - -static int -tocmp(const void *a, const void *b) -{ - InsMov *ma, *mb; - - ma = (InsMov*)a; - mb = (InsMov*)b; - return loccmp(&ma->to, &mb->to); -} - -static int -fromcmp(const void *a, const void *b) -{ - FromLoc *fa, *fb; - - fa = (FromLoc*)a; - fb = (FromLoc*)b; - return loccmp(&fa->from, &fb->from); -} - -static int -loceq(InsLoc *a, InsLoc *b) -{ - return a->bid == b->bid && a->insn == b->insn; -} - -/* after, mov is sorted by to, and to.insn, from.insn are updated */ -void -movins(Fn *fn, InsMov *mov, uint nmov, int del) -{ - Blk *b, *b2; - uint bid, n, fromn, ton, ifromn, nins; - FromLoc *from; - uint *newbnins; - Ins **newbins, *vins; - - qsort(mov, nmov, sizeof mov[0], tocmp); - - from = emalloc(nmov * sizeof from[0]); - for (n = 0; n < nmov; n++) { - from[n].from = mov[n].from; - from[n].ton = n; - } - qsort(from, nmov, sizeof from[0], fromcmp); - - nins = 0; - vins = vnew(nins, sizeof vins[0], PFn); - - newbnins = emalloc(fn->nblk * sizeof newbnins[0]); - newbins = emalloc(fn->nblk * sizeof newbins[0]); - - /* populate new ins buffers */ - /* update mov to.insn, from insn */ - fromn = ton = 0; - for (bid = 0; bid < fn->nblk; bid++) { - /* no moves to this block */ - if (nmov <= ton || mov[ton].to.bid != bid) { - while (fromn < nmov && from[fromn].from.bid == bid) - fromn++; - continue; - } - b = fn->rpo[bid]; - nins = 0; - for (ifromn = 0; ifromn < b->nins; ifromn++) { - /* insert new ins, update to */ - while (ton < nmov && loceq(&mov[ton].to, &(InsLoc){.bid = bid, .insn = ifromn})) { - b2 = fn->rpo[mov[ton].from.bid]; - assert(mov[ton].from.insn < b2->nins); - addins(&vins, &nins, &b2->ins[mov[ton].from.insn]); - mov[ton++].to.insn = nins-1; - } - /* update from */ - while (fromn < nmov && loceq(&from[fromn].from, &(InsLoc){.bid = bid, .insn = ifromn})) - from[fromn++].from.insn = nins; - /* copy original ins */ - addins(&vins, &nins, &b->ins[ifromn]); - } - /* append new ins, update to */ - while (ton < nmov && mov[ton].to.bid == bid) { - assert(mov[ton].to.insn == b->nins); - b2 = fn->rpo[mov[ton].from.bid]; - assert(mov[ton].from.insn < b2->nins); - addins(&vins, &nins, &b2->ins[mov[ton].from.insn]); - mov[ton++].to.insn = nins-1; - } - assert(ifromn == b->nins); - /* idup(&newbins[bid], vins, nins); */ - newbins[bid] = vins; - vins = vnew(0, sizeof vins[0], PFn); - newbnins[bid] = nins; - } - assert(fromn == nmov); - assert(ton == nmov); - - /* install new b->ins */ - for (bid = 0; bid < fn->nblk; bid++) { - if (newbnins[bid] == 0) - continue; - b = fn->rpo[bid]; - b->ins = newbins[bid]; - b->nins = newbnins[bid]; - } - - /* remove from ins, update mov from insn */ - for (fromn = 0; fromn < nmov; fromn++) { - b = fn->rpo[from[fromn].from.bid]; - assert(from[fromn].from.insn < b->nins); - if (del) - b->ins[from[fromn].from.insn] = (Ins){.op = Onop}; - mov[from[fromn].ton].from.insn = from[fromn].from.insn; - } - - free(from); - free(newbins); - free(newbnins); -} |
