QBE
live.c
См. документацию.
1 #include "all.h"
2 
3 void
4 liveon(BSet *v, Blk *b, Blk *s)
5 {
6  Phi *p;
7  uint a;
8 
9  bscopy(v, s->in);
10  for (p=s->phi; p; p=p->link)
11  if (rtype(p->to) == RTmp)
12  bsclr(v, p->to.val);
13  for (p=s->phi; p; p=p->link)
14  for (a=0; a<p->narg; a++)
15  if (p->blk[a] == b)
16  if (rtype(p->arg[a]) == RTmp) {
17  bsset(v, p->arg[a].val);
18  bsset(b->gen, p->arg[a].val);
19  }
20 }
21 
22 static void
23 bset(Ref r, Blk *b, int *nlv, Tmp *tmp)
24 {
25 
26  if (rtype(r) != RTmp)
27  return;
28  bsset(b->gen, r.val);
29  if (!bshas(b->in, r.val)) {
30  nlv[KBASE(tmp[r.val].cls)]++;
31  bsset(b->in, r.val);
32  }
33 }
34 
35 /* liveness analysis
36  * requires rpo computation
37  */
38 void
40 {
41  Blk *b;
42  Ins *i;
43  int k, t, m[2], n, chg, nlv[2];
44  BSet u[1], v[1];
45  Mem *ma;
46 
47  bsinit(u, f->ntmp);
48  bsinit(v, f->ntmp);
49  for (b=f->start; b; b=b->link) {
50  bsinit(b->in, f->ntmp);
51  bsinit(b->out, f->ntmp);
52  bsinit(b->gen, f->ntmp);
53  }
54  chg = 1;
55 Again:
56  for (n=f->nblk-1; n>=0; n--) {
57  b = f->rpo[n];
58 
59  bscopy(u, b->out);
60  if (b->s1) {
61  liveon(v, b, b->s1);
62  bsunion(b->out, v);
63  }
64  if (b->s2) {
65  liveon(v, b, b->s2);
66  bsunion(b->out, v);
67  }
68  chg |= !bsequal(b->out, u);
69 
70  memset(nlv, 0, sizeof nlv);
71  b->out->t[0] |= T.rglob;
72  bscopy(b->in, b->out);
73  for (t=0; bsiter(b->in, &t); t++)
74  nlv[KBASE(f->tmp[t].cls)]++;
75  if (rtype(b->jmp.arg) == RCall) {
76  assert((int)bscount(b->in) == T.nrglob &&
77  nlv[0] == T.nrglob &&
78  nlv[1] == 0);
79  b->in->t[0] |= T.retregs(b->jmp.arg, nlv);
80  } else
81  bset(b->jmp.arg, b, nlv, f->tmp);
82  for (k=0; k<2; k++)
83  b->nlive[k] = nlv[k];
84  for (i=&b->ins[b->nins]; i!=b->ins;) {
85  if ((--i)->op == Ocall && rtype(i->arg[1]) == RCall) {
86  b->in->t[0] &= ~T.retregs(i->arg[1], m);
87  for (k=0; k<2; k++) {
88  nlv[k] -= m[k];
89  /* caller-save registers are used
90  * by the callee, in that sense,
91  * right in the middle of the call,
92  * they are live: */
93  nlv[k] += T.nrsave[k];
94  if (nlv[k] > b->nlive[k])
95  b->nlive[k] = nlv[k];
96  }
97  b->in->t[0] |= T.argregs(i->arg[1], m);
98  for (k=0; k<2; k++) {
99  nlv[k] -= T.nrsave[k];
100  nlv[k] += m[k];
101  }
102  }
103  if (!req(i->to, R)) {
104  assert(rtype(i->to) == RTmp);
105  t = i->to.val;
106  if (bshas(b->in, i->to.val))
107  nlv[KBASE(f->tmp[t].cls)]--;
108  bsset(b->gen, t);
109  bsclr(b->in, t);
110  }
111  for (k=0; k<2; k++)
112  switch (rtype(i->arg[k])) {
113  case RMem:
114  ma = &f->mem[i->arg[k].val];
115  bset(ma->base, b, nlv, f->tmp);
116  bset(ma->index, b, nlv, f->tmp);
117  break;
118  default:
119  bset(i->arg[k], b, nlv, f->tmp);
120  break;
121  }
122  for (k=0; k<2; k++)
123  if (nlv[k] > b->nlive[k])
124  b->nlive[k] = nlv[k];
125  }
126  }
127  if (chg) {
128  chg = 0;
129  goto Again;
130  }
131 
132  if (debug['L']) {
133  fprintf(stderr, "\n> Liveness analysis:\n");
134  for (b=f->start; b; b=b->link) {
135  fprintf(stderr, "\t%-10sin: ", b->name);
136  dumpts(b->in, f->tmp, stderr);
137  fprintf(stderr, "\t out: ");
138  dumpts(b->out, f->tmp, stderr);
139  fprintf(stderr, "\t gen: ");
140  dumpts(b->gen, f->tmp, stderr);
141  fprintf(stderr, "\t live: ");
142  fprintf(stderr, "%d %d\n", b->nlive[0], b->nlive[1]);
143  }
144  }
145 }
unsigned int uint
Definition: all.h:12
char name[NString]
Definition: all.h:279
void bsset(BSet *, uint)
Definition: util.c:467
Mem * mem
Definition: all.h:388
Blk * start
Указатель на блок функции, являющийся её входной точкой
Definition: all.h:385
void liveon(BSet *v, Blk *b, Blk *s)
Definition: live.c:4
bits * t
Definition: all.h:68
uint narg
Definition: all.h:246
Definition: all.h:303
void bsunion(BSet *, BSet *)
Definition: util.c:492
Структура, хранящая информацию об инструкциях.
Definition: all.h:235
#define KBASE(k)
Definition: all.h:220
int nrsave[2]
Definition: all.h:50
Definition: all.h:84
Ref index
Definition: all.h:374
Definition: all.h:88
Phi * link
Definition: all.h:248
Blk * s1
Definition: all.h:262
BSet gen[1]
Definition: all.h:276
Definition: all.h:66
void bsinit(BSet *, uint)
Definition: util.c:403
void bscopy(BSet *, BSet *)
Definition: util.c:491
Ref arg[NPred]
Definition: all.h:244
Ref base
Definition: all.h:373
Структура, хранящая описание переменных (более подробное описание переменной ищите в Tmp)...
Definition: all.h:77
Содержит информацию о переменной
Definition: all.h:326
Tmp * tmp
Массив используемых функцией переменных
Definition: all.h:386
Ref arg
Definition: all.h:260
Ref to
Definition: all.h:243
BSet in[1]
Definition: all.h:276
int ntmp
Размер массива tmp.
Definition: all.h:389
Blk * s2
Definition: all.h:263
Непосредственно информация о базовом блоке.
Definition: all.h:254
int bsiter(BSet *, int *)
Definition: util.c:521
Blk * link
Definition: all.h:264
int bsequal(BSet *, BSet *)
Definition: util.c:497
uint nins
Definition: all.h:257
Definition: all.h:89
short cls
Definition: all.h:333
Ref to
Definition: all.h:237
void bsclr(BSet *, uint)
Definition: util.c:474
Target T
int nrglob
Definition: all.h:48
uint nblk
Количество блоков в функции
Definition: all.h:392
bits(* retregs)(Ref, int[2])
Definition: all.h:51
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
bits(* argregs)(Ref, int[2])
Definition: all.h:52
Ref arg[2]
Definition: all.h:238
uint val
Definition: all.h:80
int nlive[2]
Definition: all.h:277
BSet out[1]
Definition: all.h:276
bits rglob
Definition: all.h:47
void filllive(Fn *f)
Definition: live.c:39
#define R
Definition: all.h:92
void dumpts(BSet *, Tmp *, FILE *)
Definition: util.c:543
Blk * blk[NPred]
Definition: all.h:245
struct Blk::@5 jmp
Структура, хранящая в себе информацию о функции
Definition: all.h:384
char debug['Z'+1]
uint bscount(BSet *)
Definition: util.c:450
Definition: all.h:242