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
[1], 1, fn
);
32 return iscon(i
->arg
[1], 1, fn
);
34 return 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
)
75 p0
= &(Phi
){.narg
= 0};
78 stk
[0] = &(Use
){.type
= UPhi
, .u
.phi
= p
};
81 if (u
->type
== UIns
&& iscopy(u
->u
.ins
, r
, fn
)) {
85 else if (u
->type
== UPhi
) {
94 for (a
=0; a
<p
->narg
; a
++) {
95 r1
= copyof(p
->arg
[a
], cpy
);
98 if (rtype(r1
) != RTmp
)
103 u1
= &u
[fn
->tmp
[t
].nuse
];
104 vgrow(pstk
, nstk
+(u1
-u
));
111 for (t
=0; bsiter(ts
, &t
); t
++)
116 subst(Ref
*pr
, Ref
*cpy
)
118 assert(rtype(*pr
) != RTmp
|| !req(cpy
[pr
->val
], R
));
119 *pr
= copyof(*pr
, cpy
);
122 /* requires use and rpo, breaks use */
135 bsinit(ts
, fn
->ntmp
);
136 bsinit(as
, fn
->ntmp
);
137 cpy
= emalloc(fn
->ntmp
* sizeof cpy
[0]);
138 stk
= vnew(10, sizeof stk
[0], Pheap
);
140 /* 1. build the copy-of map */
141 for (n
=0; n
<fn
->nblk
; n
++) {
143 for (p
=b
->phi
; p
; p
=p
->link
) {
144 assert(rtype(p
->to
) == RTmp
);
145 if (!req(cpy
[p
->to
.val
], R
))
148 for (a
=0; a
<p
->narg
; a
++)
149 if (p
->blk
[a
]->id
< n
)
150 r
= copyof(p
->arg
[a
], cpy
);
152 cpy
[p
->to
.val
] = p
->to
;
153 phisimpl(p
, r
, cpy
, &stk
, ts
, as
, fn
);
155 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
156 assert(rtype(i
->to
) <= RTmp
);
157 if (!req(cpy
[i
->to
.val
], R
))
159 r
= copyof(i
->arg
[0], cpy
);
160 if (iscopy(i
, r
, fn
))
163 cpy
[i
->to
.val
] = i
->to
;
167 /* 2. remove redundant phis/copies
168 * and rewrite their uses */
169 for (b
=fn
->start
; b
; b
=b
->link
) {
170 for (pp
=&b
->phi
; (p
=*pp
);) {
172 if (!req(r
, p
->to
)) {
176 for (a
=0; a
<p
->narg
; a
++)
177 subst(&p
->arg
[a
], cpy
);
180 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; i
++) {
182 if (!req(r
, i
->to
)) {
183 *i
= (Ins
){.op
= Onop
};
186 subst(&i
->arg
[0], cpy
);
187 subst(&i
->arg
[1], cpy
);
189 subst(&b
->jmp
.arg
, cpy
);
193 fprintf(stderr
, "\n> Copy information:");
194 for (t
=Tmp0
; t
<fn
->ntmp
; t
++) {
195 if (req(cpy
[t
], R
)) {
196 fprintf(stderr
, "\n%10s not seen!",
199 else if (!req(cpy
[t
], TMP(t
))) {
200 fprintf(stderr
, "\n%10s copy of ",
202 printref(cpy
[t
], fn
, stderr
);
205 fprintf(stderr
, "\n\n> After copy elimination:\n");