alias.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "all.h"
  2. void
  3. getalias(Alias *a, Ref r, Fn *fn)
  4. {
  5. Con *c;
  6. switch (rtype(r)) {
  7. default:
  8. die("unreachable");
  9. case RTmp:
  10. *a = fn->tmp[r.val].alias;
  11. if (astack(a->type))
  12. a->type = a->slot->type;
  13. assert(a->type != ABot);
  14. break;
  15. case RCon:
  16. c = &fn->con[r.val];
  17. if (c->type == CAddr) {
  18. a->type = ASym;
  19. a->u.sym = c->sym;
  20. } else
  21. a->type = ACon;
  22. a->offset = c->bits.i;
  23. a->slot = 0;
  24. break;
  25. }
  26. }
  27. int
  28. alias(Ref p, int op, int sp, Ref q, int sq, int *delta, Fn *fn)
  29. {
  30. Alias ap, aq;
  31. int ovlap;
  32. getalias(&ap, p, fn);
  33. getalias(&aq, q, fn);
  34. ap.offset += op;
  35. /* when delta is meaningful (ovlap == 1),
  36. * we do not overflow int because sp and
  37. * sq are bounded by 2^28 */
  38. *delta = ap.offset - aq.offset;
  39. ovlap = ap.offset < aq.offset + sq && aq.offset < ap.offset + sp;
  40. if (astack(ap.type) && astack(aq.type)) {
  41. /* if both are offsets of the same
  42. * stack slot, they alias iif they
  43. * overlap */
  44. if (ap.base == aq.base && ovlap)
  45. return MustAlias;
  46. return NoAlias;
  47. }
  48. if (ap.type == ASym && aq.type == ASym) {
  49. /* they conservatively alias if the
  50. * symbols are different, or they
  51. * alias for sure if they overlap */
  52. if (!symeq(ap.u.sym, aq.u.sym))
  53. return MayAlias;
  54. if (ovlap)
  55. return MustAlias;
  56. return NoAlias;
  57. }
  58. if ((ap.type == ACon && aq.type == ACon)
  59. || (ap.type == aq.type && ap.base == aq.base)) {
  60. assert(ap.type == ACon || ap.type == AUnk);
  61. /* if they have the same base, we
  62. * can rely on the offsets only */
  63. if (ovlap)
  64. return MustAlias;
  65. return NoAlias;
  66. }
  67. /* if one of the two is unknown
  68. * there may be aliasing unless
  69. * the other is provably local */
  70. if (ap.type == AUnk && aq.type != ALoc)
  71. return MayAlias;
  72. if (aq.type == AUnk && ap.type != ALoc)
  73. return MayAlias;
  74. return NoAlias;
  75. }
  76. int
  77. escapes(Ref r, Fn *fn)
  78. {
  79. Alias *a;
  80. if (rtype(r) != RTmp)
  81. return 1;
  82. a = &fn->tmp[r.val].alias;
  83. return !astack(a->type) || a->slot->type == AEsc;
  84. }
  85. static void
  86. esc(Ref r, Fn *fn)
  87. {
  88. Alias *a;
  89. assert(rtype(r) <= RType);
  90. if (rtype(r) == RTmp) {
  91. a = &fn->tmp[r.val].alias;
  92. if (astack(a->type))
  93. a->slot->type = AEsc;
  94. }
  95. }
  96. static void
  97. store(Ref r, int sz, Fn *fn)
  98. {
  99. Alias *a;
  100. int64_t off;
  101. bits m;
  102. if (rtype(r) == RTmp) {
  103. a = &fn->tmp[r.val].alias;
  104. if (a->slot) {
  105. assert(astack(a->type));
  106. off = a->offset;
  107. if (sz >= NBit
  108. || (off < 0 || off >= NBit))
  109. m = -1;
  110. else
  111. m = (BIT(sz) - 1) << off;
  112. a->slot->u.loc.m |= m;
  113. }
  114. }
  115. }
  116. void
  117. fillalias(Fn *fn)
  118. {
  119. uint n;
  120. int t, sz;
  121. int64_t x;
  122. Blk *b;
  123. Phi *p;
  124. Ins *i;
  125. Con *c;
  126. Alias *a, a0, a1;
  127. for (t=0; t<fn->ntmp; t++)
  128. fn->tmp[t].alias.type = ABot;
  129. for (n=0; n<fn->nblk; ++n) {
  130. b = fn->rpo[n];
  131. for (p=b->phi; p; p=p->link) {
  132. assert(rtype(p->to) == RTmp);
  133. a = &fn->tmp[p->to.val].alias;
  134. assert(a->type == ABot);
  135. a->type = AUnk;
  136. a->base = p->to.val;
  137. a->offset = 0;
  138. a->slot = 0;
  139. }
  140. for (i=b->ins; i<&b->ins[b->nins]; ++i) {
  141. a = 0;
  142. if (!req(i->to, R)) {
  143. assert(rtype(i->to) == RTmp);
  144. a = &fn->tmp[i->to.val].alias;
  145. assert(a->type == ABot);
  146. if (Oalloc <= i->op && i->op <= Oalloc1) {
  147. a->type = ALoc;
  148. a->slot = a;
  149. a->u.loc.sz = -1;
  150. if (rtype(i->arg[0]) == RCon) {
  151. c = &fn->con[i->arg[0].val];
  152. x = c->bits.i;
  153. if (c->type == CBits)
  154. if (0 <= x && x <= NBit)
  155. a->u.loc.sz = x;
  156. }
  157. } else {
  158. a->type = AUnk;
  159. a->slot = 0;
  160. }
  161. a->base = i->to.val;
  162. a->offset = 0;
  163. }
  164. if (i->op == Ocopy) {
  165. assert(a);
  166. getalias(a, i->arg[0], fn);
  167. }
  168. if (i->op == Oadd) {
  169. getalias(&a0, i->arg[0], fn);
  170. getalias(&a1, i->arg[1], fn);
  171. if (a0.type == ACon) {
  172. *a = a1;
  173. a->offset += a0.offset;
  174. }
  175. else if (a1.type == ACon) {
  176. *a = a0;
  177. a->offset += a1.offset;
  178. }
  179. }
  180. if (req(i->to, R) || a->type == AUnk)
  181. if (i->op != Oblit0) {
  182. if (!isload(i->op))
  183. esc(i->arg[0], fn);
  184. if (!isstore(i->op))
  185. if (i->op != Oargc)
  186. esc(i->arg[1], fn);
  187. }
  188. if (i->op == Oblit0) {
  189. ++i;
  190. assert(i->op == Oblit1);
  191. assert(rtype(i->arg[0]) == RInt);
  192. sz = abs(rsval(i->arg[0]));
  193. store((i-1)->arg[1], sz, fn);
  194. }
  195. if (isstore(i->op))
  196. store(i->arg[1], storesz(i), fn);
  197. }
  198. if (b->jmp.type != Jretc)
  199. esc(b->jmp.arg, fn);
  200. }
  201. for (b=fn->start; b; b=b->link)
  202. for (p=b->phi; p; p=p->link)
  203. for (n=0; n<p->narg; n++)
  204. esc(p->arg[n], fn);
  205. }