5 adduse(Tmp
*tmp
, int ty
, Blk
*b
, ...)
15 vgrow(&tmp
->use
, ++tmp
->nuse
);
21 u
->u
.phi
= va_arg(ap
, Phi
*);
24 u
->u
.ins
= va_arg(ap
, Ins
*);
34 /* fill usage, width, phi, and class information
35 * must not change .visit fields
47 /* todo, is this the correct file? */
49 for (t
=Tmp0
; t
<fn
->ntmp
; t
++) {
58 tmp
[t
].use
= vnew(0, sizeof(Use
), PFn
);
60 for (b
=fn
->start
; b
; b
=b
->link
) {
61 for (p
=b
->phi
; p
; p
=p
->link
) {
62 assert(rtype(p
->to
) == RTmp
);
67 tp
= phicls(tp
, fn
->tmp
);
68 for (a
=0; a
<p
->narg
; a
++)
69 if (rtype(p
->arg
[a
]) == RTmp
) {
71 adduse(&tmp
[t
], UPhi
, b
, p
);
72 t
= phicls(t
, fn
->tmp
);
77 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
79 assert(rtype(i
->to
) == RTmp
);
82 w
= Wsb
+ (i
->op
- Oparsb
);
83 if (isload(i
->op
) && i
->op
!= Oload
)
84 w
= Wsb
+ (i
->op
- Oloadsb
);
86 w
= Wsb
+ (i
->op
- Oextsb
);
87 if (iscmp(i
->op
, &x
, &x
))
89 if (w
== Wsw
|| w
== Wuw
)
100 if (rtype(i
->arg
[m
]) == RTmp
) {
102 adduse(&tmp
[t
], UIns
, b
, i
);
105 if (rtype(b
->jmp
.arg
) == RTmp
)
106 adduse(&tmp
[b
->jmp
.arg
.val
], UJmp
, b
);
111 refindex(int t
, Fn
*fn
)
113 return newtmp(fn
->tmp
[t
].name
, fn
->tmp
[t
].cls
, fn
);
120 Blk
*a
, *b
, **blist
, **be
, **bp
;
130 bsinit(defs
, fn
->nblk
);
131 blist
= emalloc(fn
->nblk
* sizeof blist
[0]);
132 be
= &blist
[fn
->nblk
];
134 for (t
=Tmp0
; t
<nt
; t
++) {
135 fn
->tmp
[t
].visit
= 0;
136 if (fn
->tmp
[t
].phi
!= 0)
138 if (fn
->tmp
[t
].ndef
== 1) {
140 defb
= fn
->tmp
[t
].bid
;
141 use
= fn
->tmp
[t
].use
;
142 for (n
=fn
->tmp
[t
].nuse
; n
--; use
++)
143 ok
&= use
->bid
== defb
;
144 if (ok
|| defb
== fn
->start
->id
)
150 for (b
=fn
->start
; b
; b
=b
->link
) {
153 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
155 if (req(i
->arg
[0], TMP(t
)))
157 if (req(i
->arg
[1], TMP(t
)))
160 if (req(i
->to
, TMP(t
))) {
161 if (!bshas(b
->out
, t
)) {
165 if (!bshas(u
, b
->id
)) {
169 if (clsmerge(&k
, i
->cls
))
170 die("invalid input");
174 if (!req(r
, R
) && req(b
->jmp
.arg
, TMP(t
)))
179 fn
->tmp
[t
].visit
= t
;
182 for (n
=0; n
<b
->nfron
; n
++) {
185 if (bshas(a
->in
, t
)) {
186 p
= alloc(sizeof *p
);
190 p
->arg
= vnew(0, sizeof p
->arg
[0], PFn
);
191 p
->blk
= vnew(0, sizeof p
->blk
[0], PFn
);
193 if (!bshas(defs
, a
->id
))
194 if (!bshas(u
, a
->id
)) {
205 typedef struct Name Name
;
215 nnew(Ref r
, Blk
*b
, Name
*up
)
223 /* could use alloc, here
224 * but namel should be reset
226 n
= emalloc(sizeof *n
);
241 rendef(Ref
*r
, Blk
*b
, Name
**stk
, Fn
*fn
)
247 if (req(*r
, R
) || !fn
->tmp
[t
].visit
)
249 r1
= refindex(t
, fn
);
250 fn
->tmp
[r1
.val
].visit
= t
;
251 stk
[t
] = nnew(r1
, b
, stk
[t
]);
256 getstk(int t
, Blk
*b
, Name
**stk
)
261 while (n
&& !dom(n
->b
, b
)) {
275 renblk(Blk
*b
, Name
**stk
, Fn
*fn
)
279 Blk
*s
, **ps
, *succ
[3];
282 for (p
=b
->phi
; p
; p
=p
->link
)
283 rendef(&p
->to
, b
, stk
, fn
);
284 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
285 for (m
=0; m
<2; m
++) {
287 if (rtype(i
->arg
[m
]) == RTmp
)
288 if (fn
->tmp
[t
].visit
)
289 i
->arg
[m
] = getstk(t
, b
, stk
);
291 rendef(&i
->to
, b
, stk
, fn
);
294 if (rtype(b
->jmp
.arg
) == RTmp
)
295 if (fn
->tmp
[t
].visit
)
296 b
->jmp
.arg
= getstk(t
, b
, stk
);
298 succ
[1] = b
->s2
== b
->s1
? 0 : b
->s2
;
300 for (ps
=succ
; (s
=*ps
); ps
++)
301 for (p
=s
->phi
; p
; p
=p
->link
) {
303 if ((t
=fn
->tmp
[t
].visit
)) {
305 vgrow(&p
->arg
, p
->narg
);
306 vgrow(&p
->blk
, p
->narg
);
307 p
->arg
[m
] = getstk(t
, b
, stk
);
311 for (s
=b
->dom
; s
; s
=s
->dlink
)
315 /* require rpo and use */
324 stk
= emalloc(nt
* sizeof stk
[0]);
329 fprintf(stderr
, "\n> Dominators:\n");
330 for (b1
=fn
->start
; b1
; b1
=b1
->link
) {
333 fprintf(stderr
, "%10s:", b1
->name
);
334 for (b
=b1
->dom
; b
; b
=b
->dlink
)
335 fprintf(stderr
, " %s", b
->name
);
336 fprintf(stderr
, "\n");
342 renblk(fn
->start
, stk
, fn
);
344 while ((n
=stk
[nt
])) {
351 fprintf(stderr
, "\n> After SSA construction:\n");
357 phicheck(Phi
*p
, Blk
*b
, Ref t
)
362 for (n
=0; n
<p
->narg
; n
++)
363 if (req(p
->arg
[n
], t
)) {
365 if (b1
!= b
&& !sdom(b
, b1
))
371 /* require use and ssa */
382 for (t
=&fn
->tmp
[Tmp0
]; t
-fn
->tmp
< fn
->ntmp
; t
++) {
384 err("ssa temporary %%%s defined more than once",
386 if (t
->nuse
> 0 && t
->ndef
== 0) {
387 bu
= fn
->rpo
[t
->use
[0].bid
];
391 for (b
=fn
->start
; b
; b
=b
->link
) {
392 for (p
=b
->phi
; p
; p
=p
->link
) {
395 for (u
=t
->use
; u
<&t
->use
[t
->nuse
]; u
++) {
396 bu
= fn
->rpo
[u
->bid
];
397 if (u
->type
== UPhi
) {
398 if (phicheck(u
->u
.phi
, b
, r
))
401 if (bu
!= b
&& !sdom(b
, bu
))
405 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
406 if (rtype(i
->to
) != RTmp
)
410 for (u
=t
->use
; u
<&t
->use
[t
->nuse
]; u
++) {
411 bu
= fn
->rpo
[u
->bid
];
412 if (u
->type
== UPhi
) {
413 if (phicheck(u
->u
.phi
, b
, r
))
430 die("%%%s violates ssa invariant", t
->name
);
432 err("ssa temporary %%%s is used undefined in @%s",