cs_avail.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. /* M O D U L E F O R A C C E S S S I N G T H E L I S T
  7. *
  8. * O F A V A I L A B L E E X P R E S S I O N S
  9. */
  10. #include <em_mnem.h>
  11. #include "../share/types.h"
  12. #include "../share/debug.h"
  13. #include "../share/aux.h"
  14. #include "../share/lset.h"
  15. #include "../share/global.h"
  16. #include "cs.h"
  17. #include "cs_aux.h"
  18. #include "cs_debug.h"
  19. #include "cs_alloc.h"
  20. #include "cs_getent.h"
  21. avail_p avails; /* The list of available expressions. */
  22. STATIC bool commutative(instr)
  23. int instr;
  24. {
  25. /* Is instr a commutative operator? */
  26. switch (instr) {
  27. case op_adf: case op_adi: case op_adu: case op_and:
  28. case op_cms: case op_ior: case op_mlf: case op_mli:
  29. case op_mlu:
  30. return TRUE;
  31. default:
  32. return FALSE;
  33. }
  34. }
  35. STATIC bool same_avail(kind, avp1, avp2)
  36. byte kind;
  37. avail_p avp1, avp2;
  38. {
  39. /* Two expressions are the same if they have the same operator,
  40. * the same size, and their operand(s) have the same value.
  41. * Only if the operator is commutative, the order of the operands
  42. * does not matter.
  43. */
  44. if (avp1->av_instr != avp2->av_instr) return FALSE;
  45. if (avp1->av_size != avp2->av_size) return FALSE;
  46. switch (kind) {
  47. default:
  48. assert(FALSE);
  49. break;
  50. case EXPENSIVE_LOAD:
  51. case UNAIR_OP:
  52. return avp1->av_operand == avp2->av_operand;
  53. case BINAIR_OP:
  54. if (commutative(avp1->av_instr & BMASK))
  55. return avp1->av_oleft == avp2->av_oleft &&
  56. avp1->av_oright == avp2->av_oright
  57. ||
  58. avp1->av_oleft == avp2->av_oright &&
  59. avp1->av_oright == avp2->av_oleft
  60. ;
  61. else
  62. return avp1->av_oleft == avp2->av_oleft &&
  63. avp1->av_oright == avp2->av_oright;
  64. case TERNAIR_OP:
  65. return avp1->av_ofirst == avp2->av_ofirst &&
  66. avp1->av_osecond == avp2->av_osecond &&
  67. avp1->av_othird == avp2->av_othird;
  68. }
  69. /* NOTREACHED */
  70. }
  71. STATIC check_local(avp)
  72. avail_p avp;
  73. {
  74. /* Check if the local in which the result of avp was stored,
  75. * still holds this result. Update if not.
  76. */
  77. if (avp->av_saveloc == (entity_p) 0) return; /* Nothing to check. */
  78. if (avp->av_saveloc->en_vn != avp->av_result) {
  79. OUTTRACE("save local changed value", 0);
  80. avp->av_saveloc = (entity_p) 0;
  81. }
  82. }
  83. STATIC entity_p result_local(size, l)
  84. offset size;
  85. line_p l;
  86. {
  87. /* If the result of an expression of size bytes is stored into a
  88. * local for which a registermessage was generated, return a pointer
  89. * to this local.
  90. */
  91. line_p dummy;
  92. entity_p enp;
  93. if (l == (line_p) 0)
  94. return (entity_p) 0;
  95. if (INSTR(l)==op_stl && size==ws || INSTR(l)==op_sdl && size==2*ws) {
  96. enp = getentity(l, &dummy);
  97. if (is_regvar(enp->en_loc)) {
  98. OUTTRACE("save local found, %ld(LB)", enp->en_loc);
  99. return enp;
  100. }
  101. }
  102. return (entity_p) 0;
  103. }
  104. STATIC copy_avail(kind, src, dst)
  105. int kind;
  106. avail_p src, dst;
  107. {
  108. /* Copy some attributes from src to dst. */
  109. dst->av_instr = src->av_instr;
  110. dst->av_size = src->av_size;
  111. switch (kind) {
  112. default:
  113. assert(FALSE);
  114. break;
  115. case EXPENSIVE_LOAD:
  116. case UNAIR_OP:
  117. dst->av_operand = src->av_operand;
  118. break;
  119. case BINAIR_OP:
  120. dst->av_oleft = src->av_oleft;
  121. dst->av_oright = src->av_oright;
  122. break;
  123. case TERNAIR_OP:
  124. dst->av_ofirst = src->av_ofirst;
  125. dst->av_osecond = src->av_osecond;
  126. dst->av_othird = src->av_othird;
  127. break;
  128. }
  129. }
  130. avail_p av_enter(avp, ocp, kind)
  131. avail_p avp;
  132. occur_p ocp;
  133. int kind;
  134. {
  135. /* Put the available expression avp in the list,
  136. * if it is not already there.
  137. * Add ocp to the set of occurrences of this expression.
  138. */
  139. register avail_p ravp;
  140. line_p last = ocp->oc_llast;
  141. for (ravp = avails; ravp != (avail_p) 0; ravp = ravp->av_before) {
  142. if (same_avail(kind, ravp, avp)) { /* It was there. */
  143. Ladd(ocp, &ravp->av_occurs);
  144. /* Can we still use the local in which
  145. * the result was stored?
  146. */
  147. check_local(ravp);
  148. return ravp;
  149. }
  150. }
  151. /* A new available axpression. */
  152. ravp = newavail();
  153. /* Remember local, if any, that holds result. */
  154. if (avp->av_instr != (byte) INSTR(last)) {
  155. /* Only possible when instr is the implicit AAR in
  156. * a LAR or SAR.
  157. */
  158. ravp->av_saveloc = (entity_p) 0;
  159. } else {
  160. ravp->av_saveloc = result_local(avp->av_size, last->l_next);
  161. }
  162. ravp->av_found = last;
  163. ravp->av_result = kind == EXPENSIVE_LOAD? avp->av_operand: newvalnum();
  164. copy_avail(kind, avp, ravp);
  165. oldoccur(ocp);
  166. ravp->av_before = avails;
  167. avails = ravp;
  168. return ravp;
  169. }
  170. clr_avails()
  171. {
  172. /* Throw away the information about the available expressions. */
  173. register avail_p ravp, next;
  174. register Lindex i;
  175. register lset s;
  176. for (ravp = avails; ravp != (avail_p) 0; ravp = next) {
  177. next = ravp->av_before;
  178. s = ravp->av_occurs;
  179. for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i, s)) {
  180. oldoccur(occ_elem(i));
  181. }
  182. Ldeleteset(s);
  183. oldavail(ravp);
  184. }
  185. avails = (avail_p) 0;
  186. }