QBE
rega.c
См. документацию.
1 #include "all.h"
2 
3 #ifdef TEST_PMOV
4  #undef assert
5  #define assert(x) assert_test(#x, x)
6 #endif
7 
8 typedef struct RMap RMap;
9 
10 struct RMap {
11  int t[Tmp0];
12  int r[Tmp0];
13  int w[Tmp0]; /* wait list, for unmatched hints */
14  BSet b[1];
15  int n;
16 };
17 
18 static bits regu; /* registers used */
19 static Tmp *tmp; /* function temporaries */
20 static Mem *mem; /* function mem references */
21 static struct {
23  int cls;
24 } pm[Tmp0]; /* parallel move constructed */
25 static int npm; /* size of pm */
26 static int loop; /* current loop level */
27 
28 static uint stmov; /* stats: added moves */
29 static uint stblk; /* stats: added blocks */
30 
31 static int *
32 hint(int t)
33 {
34  return &tmp[phicls(t, tmp)].hint.r;
35 }
36 
37 static void
38 sethint(int t, int r)
39 {
40  Tmp *p;
41 
42  p = &tmp[phicls(t, tmp)];
43  if (p->hint.r == -1 || p->hint.w > loop) {
44  p->hint.r = r;
45  p->hint.w = loop;
46  tmp[t].visit = -1;
47  }
48 }
49 
50 static void
51 rcopy(RMap *ma, RMap *mb)
52 {
53  memcpy(ma, mb, sizeof *ma);
54  bscopy(ma->b, mb->b);
55 }
56 
57 static int
58 rfind(RMap *m, int t)
59 {
60  int i;
61 
62  for (i=0; i<m->n; i++)
63  if (m->t[i] == t)
64  return m->r[i];
65  return -1;
66 }
67 
68 static Ref
69 rref(RMap *m, int t)
70 {
71  int r, s;
72 
73  r = rfind(m, t);
74  if (r == -1) {
75  s = tmp[t].slot;
76  assert(s != -1 && "should have spilled");
77  return SLOT(s);
78  } else
79  return TMP(r);
80 }
81 
82 static void
83 radd(RMap *m, int t, int r)
84 {
85  assert((t >= Tmp0 || t == r) && "invalid temporary");
86  assert(((T.gpr0 <= r && r < T.gpr0 + T.ngpr)
87  || (T.fpr0 <= r && r < T.fpr0 + T.nfpr))
88  && "invalid register");
89  assert(!bshas(m->b, t) && "temporary has mapping");
90  assert(!bshas(m->b, r) && "register already allocated");
91  assert(m->n <= T.ngpr+T.nfpr && "too many mappings");
92  bsset(m->b, t);
93  bsset(m->b, r);
94  m->t[m->n] = t;
95  m->r[m->n] = r;
96  m->n++;
97  regu |= BIT(r);
98 }
99 
100 static Ref
101 ralloctry(RMap *m, int t, int try)
102 {
103  bits regs;
104  int h, r, r0, r1;
105 
106  if (t < Tmp0) {
107  assert(bshas(m->b, t));
108  return TMP(t);
109  }
110  if (bshas(m->b, t)) {
111  r = rfind(m, t);
112  assert(r != -1);
113  return TMP(r);
114  }
115  r = tmp[t].visit;
116  if (r == -1 || bshas(m->b, r))
117  r = *hint(t);
118  if (r == -1 || bshas(m->b, r)) {
119  if (try)
120  return R;
121  regs = tmp[phicls(t, tmp)].hint.m;
122  regs |= m->b->t[0];
123  if (KBASE(tmp[t].cls) == 0) {
124  r0 = T.gpr0;
125  r1 = r0 + T.ngpr;
126  } else {
127  r0 = T.fpr0;
128  r1 = r0 + T.nfpr;
129  }
130  for (r=r0; r<r1; r++)
131  if (!(regs & BIT(r)))
132  goto Found;
133  for (r=r0; r<r1; r++)
134  if (!bshas(m->b, r))
135  goto Found;
136  die("no more regs");
137  }
138 Found:
139  radd(m, t, r);
140  sethint(t, r);
141  tmp[t].visit = r;
142  h = *hint(t);
143  if (h != -1 && h != r)
144  m->w[h] = t;
145  return TMP(r);
146 }
147 
148 static inline Ref
149 ralloc(RMap *m, int t)
150 {
151  return ralloctry(m, t, 0);
152 }
153 
154 static int
155 rfree(RMap *m, int t)
156 {
157  int i, r;
158 
159  assert(t >= Tmp0 || !(BIT(t) & T.rglob));
160  if (!bshas(m->b, t))
161  return -1;
162  for (i=0; m->t[i] != t; i++)
163  assert(i+1 < m->n);
164  r = m->r[i];
165  bsclr(m->b, t);
166  bsclr(m->b, r);
167  m->n--;
168  memmove(&m->t[i], &m->t[i+1], (m->n-i) * sizeof m->t[0]);
169  memmove(&m->r[i], &m->r[i+1], (m->n-i) * sizeof m->r[0]);
170  assert(t >= Tmp0 || t == r);
171  return r;
172 }
173 
174 static void
175 mdump(RMap *m)
176 {
177  int i;
178 
179  for (i=0; i<m->n; i++)
180  if (m->t[i] >= Tmp0)
181  fprintf(stderr, " (%s, R%d)",
182  tmp[m->t[i]].name,
183  m->r[i]);
184  fprintf(stderr, "\n");
185 }
186 
187 static void
188 pmadd(Ref src, Ref dst, int k)
189 {
190  if (npm == Tmp0)
191  die("cannot have more moves than registers");
192  pm[npm].src = src;
193  pm[npm].dst = dst;
194  pm[npm].cls = k;
195  npm++;
196 }
197 
199 
200 static int
201 pmrec(enum PMStat *status, int i, int *k)
202 {
203  int j, c;
204 
205  /* note, this routine might emit
206  * too many large instructions
207  */
208  if (req(pm[i].src, pm[i].dst)) {
209  status[i] = Moved;
210  return -1;
211  }
212  assert(KBASE(pm[i].cls) == KBASE(*k));
213  assert((Kw|Kl) == Kl && (Ks|Kd) == Kd);
214  *k |= pm[i].cls;
215  for (j=0; j<npm; j++)
216  if (req(pm[j].dst, pm[i].src))
217  break;
218  switch (j == npm ? Moved : status[j]) {
219  case Moving:
220  c = j; /* start of cycle */
221  emit(Oswap, *k, R, pm[i].src, pm[i].dst);
222  break;
223  case ToMove:
224  status[i] = Moving;
225  c = pmrec(status, j, k);
226  if (c == i) {
227  c = -1; /* end of cycle */
228  break;
229  }
230  if (c != -1) {
231  emit(Oswap, *k, R, pm[i].src, pm[i].dst);
232  break;
233  }
234  /* fall through */
235  case Moved:
236  c = -1;
237  emit(Ocopy, pm[i].cls, pm[i].dst, pm[i].src, R);
238  break;
239  }
240  status[i] = Moved;
241  return c;
242 }
243 
244 static void
245 pmgen()
246 {
247  int i;
248  enum PMStat *status;
249 
250  status = alloc(npm * sizeof status[0]);
251  assert(!npm || status[npm-1] == ToMove);
252  for (i=0; i<npm; i++)
253  if (status[i] == ToMove)
254  pmrec(status, i, (int[]){pm[i].cls});
255 }
256 
257 static void
258 move(int r, Ref to, RMap *m)
259 {
260  int n, t, r1;
261 
262  r1 = req(to, R) ? -1 : rfree(m, to.val);
263  if (bshas(m->b, r)) {
264  /* r is used and not by to */
265  assert(r1 != r);
266  for (n=0; m->r[n] != r; n++)
267  assert(n+1 < m->n);
268  t = m->t[n];
269  rfree(m, t);
270  bsset(m->b, r);
271  ralloc(m, t);
272  bsclr(m->b, r);
273  }
274  t = req(to, R) ? r : to.val;
275  radd(m, t, r);
276 }
277 
278 static int
279 regcpy(Ins *i)
280 {
281  return i->op == Ocopy && isreg(i->arg[0]);
282 }
283 
284 static Ins *
285 dopm(Blk *b, Ins *i, RMap *m)
286 {
287  RMap m0;
288  int n, r, r1, t, s;
289  Ins *i1, *ip;
290  bits def;
291 
292  m0 = *m; /* okay since we don't use m0.b */
293  m0.b->t = 0;
294  i1 = ++i;
295  do {
296  i--;
297  move(i->arg[0].val, i->to, m);
298  } while (i != b->ins && regcpy(i-1));
299  assert(m0.n <= m->n);
300  if (i != b->ins && (i-1)->op == Ocall) {
301  def = T.retregs((i-1)->arg[1], 0) | T.rglob;
302  for (r=0; T.rsave[r]>=0; r++)
303  if (!(BIT(T.rsave[r]) & def))
304  move(T.rsave[r], R, m);
305  }
306  for (npm=0, n=0; n<m->n; n++) {
307  t = m->t[n];
308  s = tmp[t].slot;
309  r1 = m->r[n];
310  r = rfind(&m0, t);
311  if (r != -1)
312  pmadd(TMP(r1), TMP(r), tmp[t].cls);
313  else if (s != -1)
314  pmadd(TMP(r1), SLOT(s), tmp[t].cls);
315  }
316  for (ip=i; ip<i1; ip++) {
317  if (!req(ip->to, R))
318  rfree(m, ip->to.val);
319  r = ip->arg[0].val;
320  if (rfind(m, r) == -1)
321  radd(m, r, r);
322  }
323  pmgen();
324  return i;
325 }
326 
327 static int
328 prio1(Ref r1, Ref r2)
329 {
330  /* trivial heuristic to begin with,
331  * later we can use the distance to
332  * the definition instruction
333  */
334  (void) r2;
335  return *hint(r1.val) != -1;
336 }
337 
338 static void
339 insert(Ref *r, Ref **rs, int p)
340 {
341  int i;
342 
343  rs[i = p] = r;
344  while (i-- > 0 && prio1(*r, *rs[i])) {
345  rs[i+1] = rs[i];
346  rs[i] = r;
347  }
348 }
349 
350 static void
351 doblk(Blk *b, RMap *cur)
352 {
353  int t, x, r, rf, rt, nr;
354  bits rs;
355  Ins *i, *i1;
356  Mem *m;
357  Ref *ra[4];
358 
359  for (r=0; bsiter(b->out, &r) && r<Tmp0; r++)
360  radd(cur, r, r);
361  if (rtype(b->jmp.arg) == RTmp)
362  b->jmp.arg = ralloc(cur, b->jmp.arg.val);
363  curi = &insb[NIns];
364  for (i1=&b->ins[b->nins]; i1!=b->ins;) {
365  emiti(*--i1);
366  i = curi;
367  rf = -1;
368  switch (i->op) {
369  case Ocall:
370  rs = T.argregs(i->arg[1], 0) | T.rglob;
371  for (r=0; T.rsave[r]>=0; r++)
372  if (!(BIT(T.rsave[r]) & rs))
373  rfree(cur, T.rsave[r]);
374  break;
375  case Ocopy:
376  if (regcpy(i)) {
377  curi++;
378  i1 = dopm(b, i1, cur);
379  stmov += i+1 - curi;
380  continue;
381  }
382  if (isreg(i->to))
383  if (rtype(i->arg[0]) == RTmp)
384  sethint(i->arg[0].val, i->to.val);
385  /* fall through */
386  default:
387  if (!req(i->to, R)) {
388  assert(rtype(i->to) == RTmp);
389  r = i->to.val;
390  if (r < Tmp0 && (BIT(r) & T.rglob))
391  break;
392  rf = rfree(cur, r);
393  if (rf == -1) {
394  assert(!isreg(i->to));
395  curi++;
396  continue;
397  }
398  i->to = TMP(rf);
399  }
400  break;
401  }
402  for (x=0, nr=0; x<2; x++)
403  switch (rtype(i->arg[x])) {
404  case RMem:
405  m = &mem[i->arg[x].val];
406  if (rtype(m->base) == RTmp)
407  insert(&m->base, ra, nr++);
408  if (rtype(m->index) == RTmp)
409  insert(&m->index, ra, nr++);
410  break;
411  case RTmp:
412  insert(&i->arg[x], ra, nr++);
413  break;
414  }
415  for (r=0; r<nr; r++)
416  *ra[r] = ralloc(cur, ra[r]->val);
417 
418  /* try to change the register of a hinted
419  * temporary if rf is available */
420  x = 1;
421  if (rf != -1 && (t = cur->w[rf]) != 0)
422  if (!bshas(cur->b, rf) && *hint(t) == rf
423  && (rt = rfree(cur, t)) != -1) {
424  tmp[t].visit = -1;
425  ralloc(cur, t);
426  assert(bshas(cur->b, rf));
427  emit(Ocopy, tmp[t].cls, TMP(rt), TMP(rf), R);
428  stmov += 1;
429  cur->w[rf] = 0;
430  for (r=0; r<nr; r++)
431  if (req(*ra[r], TMP(rt)))
432  *ra[r] = TMP(rf);
433  /* one could iterate this logic with
434  * the newly freed rt, but in this case
435  * the above loop must be changed */
436  }
437  }
438  b->nins = &insb[NIns] - curi;
439  idup(&b->ins, curi, b->nins);
440 }
441 
442 /* qsort() comparison function to peel
443  * loop nests from inside out */
444 static int
445 carve(const void *a, const void *b)
446 {
447  Blk *ba, *bb;
448 
449  /* todo, evaluate if this order is really
450  * better than the simple postorder */
451  ba = *(Blk**)a;
452  bb = *(Blk**)b;
453  if (ba->loop == bb->loop)
454  return ba->id > bb->id ? -1 : ba->id < bb->id;
455  return ba->loop > bb->loop ? -1 : +1;
456 }
457 
458 /* comparison function to order temporaries
459  * for allocation at the end of blocks */
460 static int
461 prio2(int t1, int t2)
462 {
463  if ((tmp[t1].visit ^ tmp[t2].visit) < 0) /* != signs */
464  return tmp[t1].visit != -1 ? +1 : -1;
465  if ((*hint(t1) ^ *hint(t2)) < 0)
466  return *hint(t1) != -1 ? +1 : -1;
467  return tmp[t1].cost - tmp[t2].cost;
468 }
469 
470 /* register allocation
471  * depends on rpo, phi, cost, (and obviously spill)
472  */
473 void
474 rega(Fn *fn)
475 {
476  int j, t, r, x, rl[Tmp0];
477  Blk *b, *b1, *s, ***ps, *blist, **blk, **bp;
478  RMap *end, *beg, cur, old, *m;
479  Ins *i;
480  Phi *p;
481  uint u, n;
482  Ref src, dst;
483 
484  /* 1. setup */
485  stmov = 0;
486  stblk = 0;
487  regu = 0;
488  tmp = fn->tmp;
489  mem = fn->mem;
490  blk = alloc(fn->nblk * sizeof blk[0]);
491  end = alloc(fn->nblk * sizeof end[0]);
492  beg = alloc(fn->nblk * sizeof beg[0]);
493  for (n=0; n<fn->nblk; n++) {
494  bsinit(end[n].b, fn->ntmp);
495  bsinit(beg[n].b, fn->ntmp);
496  }
497  bsinit(cur.b, fn->ntmp);
498  bsinit(old.b, fn->ntmp);
499 
500  loop = INT_MAX;
501  for (t=0; t<fn->ntmp; t++) {
502  tmp[t].hint.r = t < Tmp0 ? t : -1;
503  tmp[t].hint.w = loop;
504  tmp[t].visit = -1;
505  }
506  for (bp=blk, b=fn->start; b; b=b->link)
507  *bp++ = b;
508  qsort(blk, fn->nblk, sizeof blk[0], carve);
509  for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
510  if (i->op != Ocopy || !isreg(i->arg[0]))
511  break;
512  else {
513  assert(rtype(i->to) == RTmp);
514  sethint(i->to.val, i->arg[0].val);
515  }
516 
517  /* 2. assign registers */
518  for (bp=blk; bp<&blk[fn->nblk]; bp++) {
519  b = *bp;
520  n = b->id;
521  loop = b->loop;
522  cur.n = 0;
523  bszero(cur.b);
524  memset(cur.w, 0, sizeof cur.w);
525  for (x=0, t=Tmp0; bsiter(b->out, &t); t++) {
526  j = x++;
527  rl[j] = t;
528  while (j-- > 0 && prio2(t, rl[j]) > 0) {
529  rl[j+1] = rl[j];
530  rl[j] = t;
531  }
532  }
533  for (j=0; j<x; j++)
534  ralloctry(&cur, rl[j], 1);
535  for (j=0; j<x; j++)
536  ralloc(&cur, rl[j]);
537  rcopy(&end[n], &cur);
538  doblk(b, &cur);
539  bscopy(b->in, cur.b);
540  for (p=b->phi; p; p=p->link)
541  if (rtype(p->to) == RTmp)
542  bsclr(b->in, p->to.val);
543  rcopy(&beg[n], &cur);
544  }
545 
546  /* 3. emit copies shared by multiple edges
547  * to the same block */
548  for (s=fn->start; s; s=s->link) {
549  if (s->npred <= 1)
550  continue;
551  m = &beg[s->id];
552 
553  /* rl maps a register that is live at the
554  * beginning of s to the one used in all
555  * predecessors (if any, -1 otherwise) */
556  memset(rl, 0, sizeof rl);
557 
558  /* to find the register of a phi in a
559  * predecessor, we have to find the
560  * corresponding argument */
561  for (p=s->phi; p; p=p->link) {
562  r = rfind(m, p->to.val);
563  if (r == -1)
564  continue;
565  for (u=0; u<p->narg; u++) {
566  b = p->blk[u];
567  src = p->arg[u];
568  if (rtype(src) != RTmp)
569  continue;
570  x = rfind(&end[b->id], src.val);
571  assert(x != -1);
572  rl[r] = (!rl[r] || rl[r] == x) ? x : -1;
573  }
574  if (rl[r] == 0)
575  rl[r] = -1;
576  }
577 
578  /* process non-phis temporaries */
579  for (j=0; j<m->n; j++) {
580  t = m->t[j];
581  r = m->r[j];
582  if (rl[r] || t < Tmp0 /* todo, remove this */)
583  continue;
584  for (bp=s->pred; bp<&s->pred[s->npred]; bp++) {
585  x = rfind(&end[(*bp)->id], t);
586  assert(x != -1);
587  rl[r] = (!rl[r] || rl[r] == x) ? x : -1;
588  }
589  }
590 
591  npm = 0;
592  for (j=0; j<m->n; j++) {
593  t = m->t[j];
594  r = m->r[j];
595  x = rl[r];
596  assert(x != 0 || t < Tmp0 /* todo, ditto */);
597  if (x > 0) {
598  pmadd(TMP(x), TMP(r), tmp[t].cls);
599  m->r[j] = x;
600  }
601  }
602  curi = &insb[NIns];
603  pmgen();
604  j = &insb[NIns] - curi;
605  if (j == 0)
606  continue;
607  stmov += j;
608  s->nins += j;
609  i = alloc(s->nins * sizeof(Ins));
610  icpy(icpy(i, curi, j), s->ins, s->nins-j);
611  s->ins = i;
612  }
613 
614  if (debug['R']) {
615  fprintf(stderr, "\n> Register mappings:\n");
616  for (n=0; n<fn->nblk; n++) {
617  b = fn->rpo[n];
618  fprintf(stderr, "\t%-10s beg", b->name);
619  mdump(&beg[n]);
620  fprintf(stderr, "\t end");
621  mdump(&end[n]);
622  }
623  fprintf(stderr, "\n");
624  }
625 
626  /* 4. emit remaining copies in new blocks */
627  blist = 0;
628  for (b=fn->start;; b=b->link) {
629  ps = (Blk**[3]){&b->s1, &b->s2, (Blk*[1]){0}};
630  for (; (s=**ps); ps++) {
631  npm = 0;
632  for (p=s->phi; p; p=p->link) {
633  dst = p->to;
634  assert(rtype(dst)==RSlot || rtype(dst)==RTmp);
635  if (rtype(dst) == RTmp) {
636  r = rfind(&beg[s->id], dst.val);
637  if (r == -1)
638  continue;
639  dst = TMP(r);
640  }
641  for (u=0; p->blk[u]!=b; u++)
642  assert(u+1 < p->narg);
643  src = p->arg[u];
644  if (rtype(src) == RTmp)
645  src = rref(&end[b->id], src.val);
646  pmadd(src, dst, p->cls);
647  }
648  for (t=Tmp0; bsiter(s->in, &t); t++) {
649  src = rref(&end[b->id], t);
650  dst = rref(&beg[s->id], t);
651  pmadd(src, dst, tmp[t].cls);
652  }
653  curi = &insb[NIns];
654  pmgen();
655  if (curi == &insb[NIns])
656  continue;
657  b1 = blknew();
658  b1->loop = (b->loop+s->loop) / 2;
659  b1->link = blist;
660  blist = b1;
661  fn->nblk++;
662  sprintf(b1->name, "%s_%s", b->name, s->name);
663  b1->nins = &insb[NIns] - curi;
664  stmov += b1->nins;
665  stblk += 1;
666  idup(&b1->ins, curi, b1->nins);
667  b1->jmp.type = Jjmp;
668  b1->s1 = s;
669  **ps = b1;
670  }
671  if (!b->link) {
672  b->link = blist;
673  break;
674  }
675  }
676  for (b=fn->start; b; b=b->link)
677  b->phi = 0;
678  fn->reg = regu;
679 
680  if (debug['R']) {
681  fprintf(stderr, "\n> Register allocation statistics:\n");
682  fprintf(stderr, "\tnew moves: %d\n", stmov);
683  fprintf(stderr, "\tnew blocks: %d\n", stblk);
684  fprintf(stderr, "\n> After register allocation:\n");
685  printfn(fn, stderr);
686  }
687 }
Definition: all.h:215
unsigned int uint
Definition: all.h:12
char name[NString]
Definition: all.h:279
Blk * blknew(void)
Definition: cfg.c:4
void bsset(BSet *, uint)
Definition: util.c:467
Ins insb[NIns]
Definition: util.c:34
Mem * mem
Definition: all.h:388
int nfpr
Definition: all.h:46
Blk * start
Указатель на блок функции, являющийся её входной точкой
Definition: all.h:385
Blk ** pred
Definition: all.h:274
bits * t
Definition: all.h:68
uint narg
Definition: all.h:246
void emit(int, int, Ref, Ref, Ref)
Definition: util.c:229
int fpr0
Definition: all.h:45
Definition: all.h:303
int ngpr
Definition: all.h:44
Структура, хранящая информацию об инструкциях.
Definition: all.h:235
Definition: all.h:275
struct Tmp::@9 hint
#define KBASE(k)
Definition: all.h:220
int visit
Definition: all.h:350
Definition: all.h:84
Ref index
Definition: all.h:374
short slot
-1 for unset
Definition: all.h:332
Phi * link
Definition: all.h:248
Blk * s1
Definition: all.h:262
bits reg
Definition: all.h:396
#define SLOT(x)
Definition: all.h:96
Definition: all.h:214
#define BIT(n)
Definition: all.h:59
Definition: all.h:66
Ins * curi
Definition: util.c:34
void bsinit(BSet *, uint)
Definition: util.c:403
void bscopy(BSet *, BSet *)
Definition: util.c:491
Ref dst
Definition: rega.c:22
Ref arg[NPred]
Definition: all.h:244
Definition: all.h:213
Ref base
Definition: all.h:373
Структура, хранящая описание переменных (более подробное описание переменной ищите в Tmp)...
Definition: all.h:77
Содержит информацию о переменной
Definition: all.h:326
Tmp * tmp
Массив используемых функцией переменных
Definition: all.h:386
Definition: rega.c:198
Ref arg
Definition: all.h:260
Definition: rega.c:198
Definition: all.h:181
Ref to
Definition: all.h:243
BSet in[1]
Definition: all.h:276
int r
register or -1
Definition: all.h:335
int ntmp
Размер массива tmp.
Definition: all.h:389
Blk * s2
Definition: all.h:263
Непосредственно информация о базовом блоке.
Definition: all.h:254
void * alloc(size_t)
Definition: util.c:77
int bsiter(BSet *, int *)
Definition: util.c:521
void idup(Ins **, Ins *, ulong)
Definition: util.c:246
void printfn(Fn *, FILE *)
Definition: parse.c:1160
Definition: all.h:216
#define TMP(x)
Definition: all.h:93
int t[Tmp0]
Definition: rega.c:11
Blk * link
Definition: all.h:264
void bszero(BSet *)
Definition: util.c:509
uint cost
Definition: all.h:331
Definition: all.h:87
uint nins
Definition: all.h:257
Definition: all.h:89
Definition: all.h:285
int loop
Definition: all.h:278
Ref to
Definition: all.h:237
int w[Tmp0]
Definition: rega.c:13
bits m
avoid these registers
Definition: all.h:337
void bsclr(BSet *, uint)
Definition: util.c:474
Target T
int w
weight
Definition: all.h:336
uint nblk
Количество блоков в функции
Definition: all.h:392
uint npred
Definition: all.h:275
bits(* retregs)(Ref, int[2])
Definition: all.h:51
int gpr0
Definition: all.h:43
short type
Definition: all.h:259
Ins * ins
Definition: all.h:256
Phi * phi
Definition: all.h:255
Blk ** rpo
Ссылка на массив блоков, пронумерованных в порядке Reverse-Post Order, заполняется функцией fillrpo...
Definition: all.h:395
Definition: all.h:371
int isreg(Ref)
Definition: util.c:193
bits(* argregs)(Ref, int[2])
Definition: all.h:52
Ref src
Definition: rega.c:22
Ref arg[2]
Definition: all.h:238
Номер (в массиве Fn->tmp) первой не регистровой переменной
Definition: all.h:63
#define die(...)
Definition: all.h:9
PMStat
Definition: rega.c:198
Definition: rega.c:10
uint val
Definition: all.h:80
BSet b[1]
Definition: rega.c:14
void rega(Fn *fn)
Definition: rega.c:474
int n
Definition: rega.c:15
uint id
Definition: all.h:266
Definition: rega.c:198
BSet out[1]
Definition: all.h:276
int r[Tmp0]
Definition: rega.c:12
Ins * icpy(Ins *, Ins *, ulong)
Definition: util.c:253
int phicls(int, Tmp *)
Definition: util.c:313
bits rglob
Definition: all.h:47
int cls
Definition: all.h:247
#define R
Definition: all.h:92
int cls
Definition: rega.c:23
Blk * blk[NPred]
Definition: all.h:245
struct Blk::@5 jmp
Структура, хранящая в себе информацию о функции
Definition: all.h:384
Definition: all.h:36
void emiti(Ins)
Definition: util.c:240
uint op
Definition: all.h:236
char debug['Z'+1]
unsigned long long bits
Definition: all.h:14
Definition: all.h:242
int * rsave
Definition: all.h:49