4 getalias(Alias
*a
, Ref r
, Fn
*fn
)
12 *a
= fn
->tmp
[r
.val
].alias
;
14 a
->type
= a
->slot
->type
;
15 assert(a
->type
!= ABot
);
19 if (c
->type
== CAddr
) {
24 a
->offset
= c
->bits
.i
;
31 alias(Ref p
, int op
, int sp
, Ref q
, int sq
, int *delta
, Fn
*fn
)
39 /* when delta is meaningful (ovlap == 1),
40 * we do not overflow int because sp and
41 * sq are bounded by 2^28 */
42 *delta
= ap
.offset
- aq
.offset
;
43 ovlap
= ap
.offset
< aq
.offset
+ sq
&& aq
.offset
< ap
.offset
+ sp
;
45 if (astack(ap
.type
) && astack(aq
.type
)) {
46 /* if both are offsets of the same
47 * stack slot, they alias iif they
49 if (ap
.base
== aq
.base
&& ovlap
)
54 if (ap
.type
== ASym
&& aq
.type
== ASym
) {
55 /* they conservatively alias if the
56 * symbols are different, or they
57 * alias for sure if they overlap */
58 if (!symeq(ap
.u
.sym
, aq
.u
.sym
))
65 if ((ap
.type
== ACon
&& aq
.type
== ACon
)
66 || (ap
.type
== aq
.type
&& ap
.base
== aq
.base
)) {
67 assert(ap
.type
== ACon
|| ap
.type
== AUnk
);
68 /* if they have the same base, we
69 * can rely on the offsets only */
75 /* if one of the two is unknown
76 * there may be aliasing unless
77 * the other is provably local */
78 if (ap
.type
== AUnk
&& aq
.type
!= ALoc
)
80 if (aq
.type
== AUnk
&& ap
.type
!= ALoc
)
87 escapes(Ref r
, Fn
*fn
)
93 a
= &fn
->tmp
[r
.val
].alias
;
94 return !astack(a
->type
) || a
->slot
->type
== AEsc
;
102 assert(rtype(r
) <= RType
);
103 if (rtype(r
) == RTmp
) {
104 a
= &fn
->tmp
[r
.val
].alias
;
106 a
->slot
->type
= AEsc
;
111 store(Ref r
, int sz
, Fn
*fn
)
117 if (rtype(r
) == RTmp
) {
118 a
= &fn
->tmp
[r
.val
].alias
;
120 assert(astack(a
->type
));
123 || (off
< 0 || off
>= NBit
))
126 m
= (BIT(sz
) - 1) << off
;
127 a
->slot
->u
.loc
.m
|= m
;
144 for (t
=0; t
<fn
->ntmp
; t
++)
145 fn
->tmp
[t
].alias
.type
= ABot
;
146 for (n
=0; n
<fn
->nblk
; ++n
) {
148 for (p
=b
->phi
; p
; p
=p
->link
) {
149 assert(rtype(p
->to
) == RTmp
);
150 a
= &fn
->tmp
[p
->to
.val
].alias
;
151 assert(a
->type
== ABot
);
157 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; ++i
) {
159 if (!req(i
->to
, R
)) {
160 assert(rtype(i
->to
) == RTmp
);
161 a
= &fn
->tmp
[i
->to
.val
].alias
;
162 assert(a
->type
== ABot
);
163 if (Oalloc
<= i
->op
&& i
->op
<= Oalloc1
) {
167 if (rtype(i
->arg
[0]) == RCon
) {
168 c
= &fn
->con
[i
->arg
[0].val
];
170 if (c
->type
== CBits
)
171 if (0 <= x
&& x
<= NBit
)
181 if (i
->op
== Ocopy
) {
183 getalias(a
, i
->arg
[0], fn
);
186 getalias(&a0
, i
->arg
[0], fn
);
187 getalias(&a1
, i
->arg
[1], fn
);
188 if (a0
.type
== ACon
) {
190 a
->offset
+= a0
.offset
;
192 else if (a1
.type
== ACon
) {
194 a
->offset
+= a1
.offset
;
197 if (req(i
->to
, R
) || a
->type
== AUnk
)
198 if (i
->op
!= Oblit0
) {
205 if (i
->op
== Oblit0
) {
207 assert(i
->op
== Oblit1
);
208 assert(rtype(i
->arg
[0]) == RInt
);
209 sz
= abs(rsval(i
->arg
[0]));
210 store((i
-1)->arg
[1], sz
, fn
);
213 store(i
->arg
[1], storesz(i
), fn
);
215 if (b
->jmp
.type
!= Jretc
)
218 for (b
=fn
->start
; b
; b
=b
->link
)
219 for (p
=b
->phi
; p
; p
=p
->link
)
220 for (n
=0; n
<p
->narg
; n
++)