4 iscopy(Ins
*i
, Ref r
, Tmp
*tmp
)
6 static bits extcpy
[] = {
8 [Wsb
] = BIT(Wsb
) | BIT(Wsh
) | BIT(Wsw
),
9 [Wub
] = BIT(Wub
) | BIT(Wuh
) | BIT(Wuw
),
10 [Wsh
] = BIT(Wsh
) | BIT(Wsw
),
11 [Wuh
] = BIT(Wuh
) | BIT(Wuw
),
20 if (!isext(i
->op
) || rtype(r
) != RTmp
)
22 if (i
->op
== Oextsw
|| i
->op
== Oextuw
)
27 assert(KBASE(t
->cls
) == 0);
28 if (i
->cls
== Kl
&& t
->cls
== Kw
)
31 return (BIT(Wsb
+ (i
->op
-Oextsb
)) & b
) != 0;
35 copyof(Ref r
, Ref
*cpy
)
37 if (rtype(r
) == RTmp
&& !req(cpy
[r
.val
], R
))
42 /* detects a cluster of phis/copies redundant with 'r';
43 * the algorithm is inspired by Section 3.2 of "Simple
44 * and Efficient SSA Construction" by Braun M. et al.
47 phisimpl(Phi
*p
, Ref r
, Ref
*cpy
, Use
***pstk
, BSet
*ts
, BSet
*as
, Tmp
*tmp
)
58 stk
[0] = &(Use
){.type
= UPhi
, .u
.phi
= p
};
61 if (u
->type
== UIns
&& iscopy(u
->u
.ins
, r
, tmp
)) {
62 p
= &(Phi
){.narg
= 0};
65 else if (u
->type
== UPhi
) {
74 for (a
=0; a
<p
->narg
; a
++) {
75 r1
= copyof(p
->arg
[a
], cpy
);
78 if (rtype(r1
) != RTmp
)
84 vgrow(pstk
, nstk
+(u1
-u
));
91 for (t
=0; bsiter(ts
, &t
); t
++)
96 subst(Ref
*pr
, Ref
*cpy
)
98 assert(rtype(*pr
) != RTmp
|| !req(cpy
[pr
->val
], R
));
99 *pr
= copyof(*pr
, cpy
);
102 /* requires use and rpo, breaks use */
115 bsinit(ts
, fn
->ntmp
);
116 bsinit(as
, fn
->ntmp
);
117 cpy
= emalloc(fn
->ntmp
* sizeof cpy
[0]);
118 stk
= vnew(10, sizeof stk
[0], Pheap
);
120 /* 1. build the copy-of map */
121 for (n
=0; n
<fn
->nblk
; n
++) {
123 for (p
=b
->phi
; p
; p
=p
->link
) {
124 assert(rtype(p
->to
) == RTmp
);
125 if (!req(cpy
[p
->to
.val
], R
))
128 for (a
=0; a
<p
->narg
; a
++)
129 if (p
->blk
[a
]->id
< n
)
130 r
= copyof(p
->arg
[a
], cpy
);
132 cpy
[p
->to
.val
] = p
->to
;
133 phisimpl(p
, r
, cpy
, &stk
, ts
, as
, fn
->tmp
);
135 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
136 assert(rtype(i
->to
) <= RTmp
);
137 if (!req(cpy
[i
->to
.val
], R
))
139 r
= copyof(i
->arg
[0], cpy
);
140 if (iscopy(i
, r
, fn
->tmp
))
143 cpy
[i
->to
.val
] = i
->to
;
147 /* 2. remove redundant phis/copies
148 * and rewrite their uses */
149 for (b
=fn
->start
; b
; b
=b
->link
) {
150 for (pp
=&b
->phi
; (p
=*pp
);) {
152 if (!req(r
, p
->to
)) {
156 for (a
=0; a
<p
->narg
; a
++)
157 subst(&p
->arg
[a
], cpy
);
160 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
162 if (!req(r
, i
->to
)) {
163 *i
= (Ins
){.op
= Onop
};
166 subst(&i
->arg
[0], cpy
);
167 subst(&i
->arg
[1], cpy
);
169 subst(&b
->jmp
.arg
, cpy
);
173 fprintf(stderr
, "\n> Copy information:");
174 for (t
=Tmp0
; t
<fn
->ntmp
; t
++) {
175 if (req(cpy
[t
], R
)) {
176 fprintf(stderr
, "\n%10s not seen!",
179 else if (!req(cpy
[t
], TMP(t
))) {
180 fprintf(stderr
, "\n%10s copy of ",
182 printref(cpy
[t
], fn
, stderr
);
185 fprintf(stderr
, "\n\n> After copy elimination:\n");