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 for (m
=0; m
<p
->narg
; m
++)
151 assert(rtype(p
->to
) == RTmp
);
152 a
= &fn
->tmp
[p
->to
.val
].alias
;
153 assert(a
->type
== ABot
);
159 for (i
=b
->ins
; i
<&b
->ins
[b
->nins
]; ++i
) {
161 if (!req(i
->to
, R
)) {
162 assert(rtype(i
->to
) == RTmp
);
163 a
= &fn
->tmp
[i
->to
.val
].alias
;
164 assert(a
->type
== ABot
);
165 if (Oalloc
<= i
->op
&& i
->op
<= Oalloc1
) {
169 if (rtype(i
->arg
[0]) == RCon
) {
170 c
= &fn
->con
[i
->arg
[0].val
];
172 if (c
->type
== CBits
)
173 if (0 <= x
&& x
<= NBit
)
183 if (i
->op
== Ocopy
) {
185 getalias(a
, i
->arg
[0], fn
);
188 getalias(&a0
, i
->arg
[0], fn
);
189 getalias(&a1
, i
->arg
[1], fn
);
190 if (a0
.type
== ACon
) {
192 a
->offset
+= a0
.offset
;
194 else if (a1
.type
== ACon
) {
196 a
->offset
+= a1
.offset
;
199 if (req(i
->to
, R
) || a
->type
== AUnk
)
200 if (i
->op
!= Oblit0
) {
207 if (i
->op
== Oblit0
) {
209 assert(i
->op
== Oblit1
);
210 assert(rtype(i
->arg
[0]) == RInt
);
211 sz
= abs(rsval(i
->arg
[0]));
212 store((i
-1)->arg
[1], sz
, fn
);
215 store(i
->arg
[1], storesz(i
), fn
);
217 if (b
->jmp
.type
!= Jretc
)