locals.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /*
  7. * L O C A L S . C
  8. */
  9. #include <stdio.h>
  10. #include <em_mnem.h>
  11. #include <em_spec.h>
  12. #include <em_pseu.h>
  13. #include <em_mes.h>
  14. #include "types.h"
  15. #include "debug.h"
  16. #include "global.h"
  17. #include "lset.h"
  18. #include "cset.h"
  19. #include "def.h"
  20. #include "get.h"
  21. #include "aux.h"
  22. #include "alloc.h"
  23. #include "locals.h"
  24. short nrglobals;
  25. short nrlocals;
  26. local_p *locals; /* dynamic array */
  27. static void localvar(offset off, short size, local_p *locs, bool reg, offset score)
  28. {
  29. /* process a reference to a local variable.
  30. * A local is characterized by a (offset,size) pair.
  31. * We first collect all locals in a list, sorted
  32. * by offset. Later we will construct a table
  33. * out of this list.
  34. */
  35. local_p lc, x, *prevp;
  36. prevp = locs;
  37. for (lc = *locs; lc != (local_p) 0; lc = lc->lc_next) {
  38. if (lc->lc_off == off && lc->lc_size == size) {
  39. if (reg) {
  40. REGVAR(lc); /* register variable */
  41. lc->lc_score = score;
  42. }
  43. return; /* local already present */
  44. }
  45. if (lc->lc_off > off) break;
  46. prevp = &lc->lc_next;
  47. }
  48. /* the local was not seen before; create an entry
  49. * for it in the list.
  50. */
  51. x = *prevp = newlocal();
  52. x->lc_off = off;
  53. x->lc_size = size;
  54. x->lc_next = lc;
  55. if (reg) {
  56. REGVAR(x);
  57. x->lc_score = score;
  58. }
  59. }
  60. static void check_message(line_p l, local_p *locs)
  61. {
  62. /* See if l is a register message */
  63. arg_p arg;
  64. arg = ARG(l);
  65. if (aoff(arg,0) == ms_reg && arg->a_next != (arg_p) 0) {
  66. localvar(aoff(arg,1), (short) aoff(arg,2), locs, TRUE,
  67. aoff(arg,4));
  68. }
  69. }
  70. static void check_local_use(line_p l, local_p *locs)
  71. {
  72. short sz;
  73. switch(INSTR(l)) {
  74. case op_lol:
  75. case op_stl:
  76. case op_inl:
  77. case op_del:
  78. case op_zrl:
  79. sz = ws;
  80. break;
  81. case op_ldl:
  82. case op_sdl:
  83. sz = 2 * ws;
  84. break;
  85. case op_lil:
  86. case op_sil:
  87. sz = ps;
  88. break;
  89. case ps_mes:
  90. check_message(l,locs);
  91. /* fall through .. */
  92. default:
  93. return;
  94. }
  95. if (l->l_next && INSTR(l->l_next) == op_nop) {
  96. /* volatile */
  97. return;
  98. }
  99. localvar(off_set(l),sz,locs,FALSE,(offset) 0);
  100. }
  101. void make_localtab(proc_p p)
  102. {
  103. /* Make a table of local variables.
  104. * This table is used to associate a
  105. * unique number with a local. If two
  106. * locals overlap (e.g. LDL 4 and LDL 2)
  107. * none of them is considered any further,
  108. * i.e. we don't compute ud-info for them.
  109. */
  110. local_p prev = 0, next, lc;
  111. local_p locallist = (local_p) 0;
  112. short cnt = 0;
  113. offset x, ill_zone = 0;
  114. bblock_p b;
  115. line_p l;
  116. /* first make a list of all locals used */
  117. for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
  118. for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
  119. check_local_use(l,&locallist);
  120. }
  121. }
  122. /* Now remove overlapping locals, count useful ones on the fly */
  123. for (lc = locallist; lc != (local_p) 0; lc = lc->lc_next) {
  124. if (ill_zone != 0 && lc->lc_off < ill_zone) {
  125. /* this local overlaps with a previous one */
  126. BADLC(lc);
  127. if (!IS_BADLC(prev)) {
  128. BADLC(prev);
  129. cnt--;
  130. }
  131. } else {
  132. cnt++;
  133. }
  134. x = lc->lc_off + lc->lc_size;
  135. if (ill_zone == 0 || x > ill_zone) {
  136. ill_zone = x;
  137. }
  138. prev = lc;
  139. }
  140. /* Now we know how many local variables there are */
  141. nrlocals = cnt;
  142. locals = (local_p *) newmap(cnt);
  143. cnt = 1;
  144. for (lc = locallist; lc != (local_p) 0; lc = next) {
  145. next = lc->lc_next;
  146. if (IS_BADLC(lc)) {
  147. oldlocal(lc);
  148. } else {
  149. locals[cnt++] = lc;
  150. lc->lc_next = (local_p) 0;
  151. }
  152. }
  153. assert (cnt == nrlocals+1);
  154. }
  155. void find_local(offset off, short *nr_out, bool *found_out)
  156. {
  157. /* Try to find the local variable at the given
  158. * offset. Return its local-number.
  159. */
  160. short v;
  161. for (v = 1; v <= nrlocals; v++) {
  162. if (locals[v]->lc_off > off) break;
  163. if (locals[v]->lc_off == off) {
  164. *found_out = TRUE;
  165. *nr_out = v;
  166. return;
  167. }
  168. }
  169. *found_out = FALSE;
  170. }
  171. void var_nr(line_p l, short *nr_out, bool *found_out)
  172. {
  173. /* Determine the number of the variable referenced
  174. * by EM instruction l.
  175. */
  176. offset off = 0;
  177. short nr;
  178. switch(TYPE(l)) {
  179. case OPOBJECT:
  180. /* global variable */
  181. if (OBJ(l)->o_globnr == 0) {
  182. /* We don't maintain ud-info for this var */
  183. *found_out = FALSE;
  184. } else {
  185. *nr_out = GLOB_TO_VARNR(OBJ(l)->o_globnr);
  186. *found_out = TRUE;
  187. }
  188. return;
  189. case OPSHORT:
  190. off = (offset) SHORT(l);
  191. break;
  192. case OPOFFSET:
  193. off = OFFSET(l);
  194. break;
  195. default:
  196. assert(FALSE);
  197. }
  198. /* Its's a local variable */
  199. find_local(off,&nr,found_out);
  200. if (*found_out) {
  201. *nr_out = LOC_TO_VARNR(nr);
  202. }
  203. }