4 iscon(Ref r
, int64_t bits
, Fn
*fn
)
6 return rtype(r
) == RCon
7 && fn
->con
[r
.val
].type
== CBits
8 && fn
->con
[r
.val
].bits
.i
== bits
;
12 iscopy(Ins
*i
, Ref r
, Fn
*fn
)
14 static bits extcpy
[] = {
16 [Wsb
] = BIT(Wsb
) | BIT(Wsh
) | BIT(Wsw
),
17 [Wub
] = BIT(Wub
) | BIT(Wuh
) | BIT(Wuw
),
18 [Wsh
] = BIT(Wsh
) | BIT(Wsw
),
19 [Wuh
] = BIT(Wuh
) | BIT(Wuw
),
30 return iscon(i
->arg
[0], 1, fn
) || iscon(i
->arg
[1], 1, fn
);
32 return iscon(i
->arg
[1], 1, fn
);
34 return iscon(i
->arg
[0], 0, fn
) || iscon(i
->arg
[1], 0, fn
);
38 if (!isext(i
->op
) || rtype(r
) != RTmp
)
40 if (i
->op
== Oextsw
|| i
->op
== Oextuw
)
45 assert(KBASE(t
->cls
) == 0);
46 if (i
->cls
== Kl
&& t
->cls
== Kw
)
49 return (BIT(Wsb
+ (i
->op
-Oextsb
)) & b
) != 0;
53 copyof(Ref r
, Ref
*cpy
)
55 if (rtype(r
) == RTmp
&& !req(cpy
[r
.val
], R
))
60 /* detects a cluster of phis/copies redundant with 'r';
61 * the algorithm is inspired by Section 3.2 of "Simple
62 * and Efficient SSA Construction" by Braun M. et al.
65 phisimpl(Phi
*p
, Ref r
, Ref
*cpy
, Use
***pstk
, BSet
*ts
, BSet
*as
, Fn
*fn
)
76 stk
[0] = &(Use
){.type
= UPhi
, .u
.phi
= p
};
79 if (u
->type
== UIns
&& iscopy(u
->u
.ins
, r
, fn
)) {
80 p
= &(Phi
){.narg
= 0};
83 else if (u
->type
== UPhi
) {
92 for (a
=0; a
<p
->narg
; a
++) {
93 r1
= copyof(p
->arg
[a
], cpy
);
96 if (rtype(r1
) != RTmp
)
101 u1
= &u
[fn
->tmp
[t
].nuse
];
102 vgrow(pstk
, nstk
+(u1
-u
));
109 for (t
=0; bsiter(ts
, &t
); t
++)
114 subst(Ref
*pr
, Ref
*cpy
)
116 assert(rtype(*pr
) != RTmp
|| !req(cpy
[pr
->val
], R
));
117 *pr
= copyof(*pr
, cpy
);
120 /* requires use and rpo, breaks use */
133 bsinit(ts
, fn
->ntmp
);
134 bsinit(as
, fn
->ntmp
);
135 cpy
= emalloc(fn
->ntmp
* sizeof cpy
[0]);
136 stk
= vnew(10, sizeof stk
[0], Pheap
);
138 /* 1. build the copy-of map */
139 for (n
=0; n
<fn
->nblk
; n
++) {
141 for (p
=b
->phi
; p
; p
=p
->link
) {
142 assert(rtype(p
->to
) == RTmp
);
143 if (!req(cpy
[p
->to
.val
], R
))
146 for (a
=0; a
<p
->narg
; a
++)
147 if (p
->blk
[a
]->id
< n
)
148 r
= copyof(p
->arg
[a
], cpy
);
150 cpy
[p
->to
.val
] = p
->to
;
151 phisimpl(p
, r
, cpy
, &stk
, ts
, as
, fn
);
153 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
154 assert(rtype(i
->to
) <= RTmp
);
155 if (!req(cpy
[i
->to
.val
], R
))
157 r
= copyof(i
->arg
[0], cpy
);
158 if (iscopy(i
, r
, fn
))
161 cpy
[i
->to
.val
] = i
->to
;
165 /* 2. remove redundant phis/copies
166 * and rewrite their uses */
167 for (b
=fn
->start
; b
; b
=b
->link
) {
168 for (pp
=&b
->phi
; (p
=*pp
);) {
170 if (!req(r
, p
->to
)) {
174 for (a
=0; a
<p
->narg
; a
++)
175 subst(&p
->arg
[a
], cpy
);
178 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
180 if (!req(r
, i
->to
)) {
181 *i
= (Ins
){.op
= Onop
};
184 subst(&i
->arg
[0], cpy
);
185 subst(&i
->arg
[1], cpy
);
187 subst(&b
->jmp
.arg
, cpy
);
191 fprintf(stderr
, "\n> Copy information:");
192 for (t
=Tmp0
; t
<fn
->ntmp
; t
++) {
193 if (req(cpy
[t
], R
)) {
194 fprintf(stderr
, "\n%10s not seen!",
197 else if (!req(cpy
[t
], TMP(t
))) {
198 fprintf(stderr
, "\n%10s copy of ",
200 printref(cpy
[t
], fn
, stderr
);
203 fprintf(stderr
, "\n\n> After copy elimination:\n");