aux.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. /* S H A R E D F I L E
  7. *
  8. * A U X I L I A R Y R O U T I N E S
  9. *
  10. */
  11. #include <em_mes.h>
  12. #include <em_pseu.h>
  13. #include "types.h"
  14. #include "debug.h"
  15. #include "global.h"
  16. #include "alloc.h"
  17. #include "aux.h"
  18. #include "map.h"
  19. #include "lset.h"
  20. offset off_set(lnp)
  21. line_p lnp;
  22. {
  23. switch(lnp->l_optype) {
  24. case OPSHORT:
  25. return (offset) SHORT(lnp);
  26. case OPOFFSET:
  27. return OFFSET(lnp);
  28. default:
  29. assert(FALSE);
  30. }
  31. /* NOTREACHED */
  32. }
  33. offset aoff(ap,n)
  34. register arg_p ap;
  35. {
  36. while (n>0) {
  37. if (ap != (arg_p) 0)
  38. ap = ap->a_next;
  39. n--;
  40. }
  41. if (ap == (arg_p) 0)
  42. error("too few parameters");
  43. if (ap->a_type != ARGOFF)
  44. error("offset expected");
  45. return(ap->a_a.a_offset);
  46. }
  47. offset tmplocal(p,size)
  48. proc_p p;
  49. offset size;
  50. {
  51. /* Allocate a new local variable in the stack frame of p */
  52. p->p_localbytes += size;
  53. return -(p->p_localbytes);
  54. }
  55. line_p int_line(off)
  56. offset off;
  57. {
  58. /* Allocate a line struct of type OPSHORT or OPOFFSET,
  59. * whichever one fits best.
  60. */
  61. line_p lnp;
  62. if ((short) off == off) {
  63. /* fits in a short */
  64. lnp = newline(OPSHORT);
  65. SHORT(lnp) = (short) off;
  66. } else {
  67. lnp = newline(OPOFFSET);
  68. OFFSET(lnp) = off;
  69. }
  70. return lnp;
  71. }
  72. line_p reg_mes(tmp,size,typ,score)
  73. offset tmp;
  74. short size;
  75. int typ,score;
  76. {
  77. /* Generate a register message */
  78. line_p l;
  79. arg_p a;
  80. #define NEXTARG(a,val) a->a_next = newarg(ARGOFF); a = a->a_next; \
  81. a->a_a.a_offset = val
  82. l = newline(OPLIST);
  83. l->l_instr = ps_mes;
  84. a = ARG(l) = newarg(ARGOFF);
  85. a->a_a.a_offset = ms_reg;
  86. NEXTARG(a,tmp);
  87. NEXTARG(a,size);
  88. NEXTARG(a,typ);
  89. NEXTARG(a,score);
  90. return l;
  91. }
  92. bool dom(b1,b2)
  93. bblock_p b1,b2;
  94. {
  95. /* See if b1 dominates b2. Note that a block always
  96. * dominates itself.
  97. */
  98. register bblock_p b;
  99. for (b = b2; b != (bblock_p) 0; b = b->b_idom) {
  100. /* See if b1 is a (not necessarily proper) ancestor
  101. * of b2 in the immediate dominator tree.
  102. */
  103. if (b == b1) return TRUE;
  104. }
  105. return FALSE;
  106. }
  107. bblock_p common_dom(a,b)
  108. bblock_p a,b;
  109. {
  110. /* find a basic block that dominates a as well as b;
  111. * note that a basic block also dominates itself.
  112. */
  113. assert (a != (bblock_p) 0);
  114. assert (b != (bblock_p) 0);
  115. if (dom(a,b)) {
  116. return a;
  117. } else {
  118. if (dom(b,a)) {
  119. return b;
  120. } else {
  121. return common_dom(a->b_idom,b->b_idom);
  122. }
  123. }
  124. }
  125. #define R time_space_ratio
  126. short add_timespace(time,space)
  127. short time,space;
  128. {
  129. /* Add together a time and space, using the time_space_ratio
  130. * parameter that may be set by the user, indicating the need
  131. * to optimize for time, space or something in between.
  132. */
  133. return (R * time + (100 - R) * space) / 100;
  134. }
  135. rm_line(l,b)
  136. line_p l;
  137. bblock_p b;
  138. {
  139. if (b->b_start == l) {
  140. b->b_start = l->l_next;
  141. } else {
  142. PREV(l)->l_next = l->l_next;
  143. }
  144. if (l->l_next != (line_p) 0) {
  145. PREV(l->l_next) = PREV(l);
  146. }
  147. oldline(l);
  148. }
  149. appnd_line(l1,l2)
  150. line_p l1,l2;
  151. {
  152. /* Put l1 after l2 */
  153. PREV(l1) = l2;
  154. l1->l_next = l2->l_next;
  155. l2->l_next = l1;
  156. if (l1->l_next != (line_p) 0) {
  157. PREV(l1->l_next) = l1;
  158. }
  159. }
  160. line_p last_instr(b)
  161. bblock_p b;
  162. {
  163. /* Determine the last line of a list */
  164. register line_p l = b->b_start;
  165. if (l == (line_p) 0) return (line_p) 0;
  166. while (l->l_next != (line_p) 0) l = l->l_next;
  167. return l;
  168. }
  169. line_p find_mesreg(off)
  170. offset off;
  171. {
  172. /* Find the register message for the local with the given offset */
  173. Lindex li;
  174. line_p l;
  175. for (li = Lfirst(mesregs); li != (Lindex) 0; li = Lnext(li,mesregs)) {
  176. l = (line_p) Lelem(li);
  177. if (aoff(ARG(l),1) == off) return l;
  178. }
  179. return (line_p) 0;
  180. }
  181. bool is_regvar(off)
  182. offset off;
  183. {
  184. return find_mesreg(off) != (line_p) 0;
  185. }
  186. offset regv_arg(off,n)
  187. offset off;
  188. int n;
  189. {
  190. /* fetch the n'th argument of the register message of the
  191. * local variable at offset off;
  192. */
  193. line_p x = find_mesreg(off);
  194. assert (x != (line_p) 0);
  195. return aoff(ARG(x),n);
  196. }