5 adduse(
Tmp *tmp,
int ty,
Blk *b, ...)
68 assert(rtype(p->
to) ==
RTmp);
73 for (a=0; a<p->
narg; a++)
76 adduse(&tmp[t], UPhi, b, p);
84 assert(rtype(i->
to) ==
RTmp);
90 if (w == Wsw || w == Wuw)
101 adduse(&tmp[t], UIns, b, i);
110 refindex(
int t,
Fn *fn)
119 Blk *a, *b, **blist, **be, **bp;
130 be = &blist[fn->
nblk];
132 for (t=
Tmp0; t<nt; t++) {
144 if (req(i->
arg[0],
TMP(t)))
146 if (req(i->
arg[1],
TMP(t)))
149 if (req(i->
to,
TMP(t))) {
150 if (!bshas(b->
out, t)) {
157 if (!bshas(u, b->
id)) {
162 die(
"invalid input");
174 for (n=0; n<b->
nfron; n++) {
177 if (bshas(a->
in, t)) {
178 p =
alloc(
sizeof *p);
183 if (!bshas(defs, a->
id))
184 if (!bshas(u, a->
id)) {
239 r1 = refindex(t, fn);
241 stk[t] = nnew(r1, b, stk[t]);
246 getstk(
int t,
Blk *b,
Name **stk)
251 while (n && !
dom(n->
b, b)) {
269 Blk *s, **ps, *succ[3];
273 rendef(&p->
to, b, stk, fn);
275 for (m=0; m<2; m++) {
279 i->
arg[m] = getstk(t, b, stk);
281 rendef(&i->
to, b, stk, fn);
286 b->
jmp.
arg = getstk(t, b, stk);
288 succ[1] = b->
s2 == b->
s1 ? 0 : b->
s2;
290 for (ps=succ; (s=*ps); ps++)
296 die(
"renblk, too many phi args");
297 p->
arg[m] = getstk(t, b, stk);
314 stk =
emalloc(nt *
sizeof stk[0]);
319 fprintf(stderr,
"\n> Dominators:\n");
323 fprintf(stderr,
"%10s:", b1->
name);
325 fprintf(stderr,
" %s", b->
name);
326 fprintf(stderr,
"\n");
332 renblk(fn->
start, stk, fn);
334 while ((n=stk[nt])) {
341 fprintf(stderr,
"\n> After SSA construction:\n");
352 for (n=0; n<p->
narg; n++)
353 if (req(p->
arg[n], t)) {
355 if (b1 != b && !
sdom(b, b1))
374 err(
"ssa temporary %%%s defined more than once",
387 if (u->
type == UPhi) {
388 if (phicheck(u->
u.
phi, b, r))
391 if (bu != b && !
sdom(b, bu))
402 if (u->
type == UPhi) {
403 if (phicheck(u->
u.
phi, b, r))
420 die(
"%%%s violates ssa invariant", t->
name);
422 err(
"ssa temporary %%%s is used undefined in @%s",
Blk * start
Указатель на блок функции, являющийся её входной точкой
Структура, хранящая информацию об инструкциях.
int clsmerge(short *, short)
void * vnew(ulong, size_t, Pool)
uint ndef
Количество блоков, в которых есть объявление переменной
void bsinit(BSet *, uint)
void bscopy(BSet *, BSet *)
Структура, хранящая описание переменных (более подробное описание переменной ищите в Tmp)...
Содержит информацию о переменной
void err(char *,...) __attribute__((noreturn))
Tmp * tmp
Массив используемых функцией переменных
Use * use
Содержит информацию об использовании переменной
int ntmp
Размер массива tmp.
Непосредственно информация о базовом блоке.
void printfn(Fn *, FILE *)
char name[NString]
Имя переменной
void vgrow(void *, ulong)
uint nblk
Количество блоков в функции
Blk ** rpo
Ссылка на массив блоков, пронумерованных в порядке Reverse-Post Order, заполняется функцией fillrpo...
Номер (в массиве Fn->tmp) первой не регистровой переменной
void filluse(Fn *fn)
Заполняет информацию об использовании переменных в функции
Ref newtmp(char *, int, Fn *)
Структура, хранящая в себе информацию о функции
uint nuse
Количество блоков, в которых переменная используется
Структура, хранящая информацию об одном "использовании" переменной.