cs_vnm.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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. /* V A L U E N U M B E R I N G M E T H O D */
  7. #include <em_mnem.h>
  8. #include "../share/types.h"
  9. #include "../share/global.h"
  10. #include "../share/debug.h"
  11. #include "../share/aux.h"
  12. #include "cs.h"
  13. #include "cs_alloc.h"
  14. #include "cs_aux.h"
  15. #include "cs_entity.h"
  16. #include "cs_avail.h"
  17. #include "cs_stack.h"
  18. #include "cs_kill.h"
  19. #include "cs_partit.h"
  20. #include "cs_getent.h"
  21. STATIC push_entity(enp, lfirst)
  22. entity_p enp;
  23. line_p lfirst;
  24. {
  25. /* Build token and Push it. */
  26. struct token tk;
  27. tk.tk_vn = enp->en_vn;
  28. tk.tk_size = enp->en_size;
  29. tk.tk_lfirst = lfirst;
  30. Push(&tk);
  31. }
  32. STATIC put_expensive_load(bp, lnp, lfirst, enp)
  33. bblock_p bp;
  34. line_p lnp, lfirst;
  35. entity_p enp;
  36. {
  37. struct avail av;
  38. occur_p ocp;
  39. av.av_instr = INSTR(lnp);
  40. av.av_size = enp->en_size;
  41. av.av_operand = enp->en_vn;
  42. ocp = newoccur(lfirst, lnp, bp);
  43. av_enter(&av, ocp, EXPENSIVE_LOAD);
  44. }
  45. STATIC put_aar(bp, lnp, lfirst, enp)
  46. bblock_p bp;
  47. line_p lnp, lfirst;
  48. entity_p enp;
  49. {
  50. /* Enp points to an ENARRELEM. We do as if its address was computed. */
  51. struct avail av;
  52. occur_p ocp;
  53. assert(enp->en_kind == ENARRELEM);
  54. av.av_instr = op_aar;
  55. av.av_size = ps;
  56. av.av_ofirst = enp->en_arbase;
  57. av.av_osecond = enp->en_index;
  58. av.av_othird = enp->en_adesc;
  59. ocp = newoccur(lfirst, lnp, bp);
  60. av_enter(&av, ocp, TERNAIR_OP);
  61. }
  62. STATIC push_avail(avp, lfirst)
  63. avail_p avp;
  64. line_p lfirst;
  65. {
  66. struct token tk;
  67. tk.tk_vn = avp->av_result;
  68. tk.tk_size = avp->av_size;
  69. tk.tk_lfirst = lfirst;
  70. Push(&tk);
  71. }
  72. STATIC push_unair_op(bp, lnp, tkp1)
  73. bblock_p bp;
  74. line_p lnp;
  75. token_p tkp1;
  76. {
  77. struct avail av;
  78. occur_p ocp;
  79. av.av_instr = INSTR(lnp);
  80. av.av_size = avsize(lnp);
  81. av.av_operand = tkp1->tk_vn;
  82. ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
  83. push_avail(av_enter(&av, ocp, UNAIR_OP), tkp1->tk_lfirst);
  84. }
  85. STATIC push_binair_op(bp, lnp, tkp1, tkp2)
  86. bblock_p bp;
  87. line_p lnp;
  88. token_p tkp1, tkp2;
  89. {
  90. struct avail av;
  91. occur_p ocp;
  92. av.av_instr = INSTR(lnp);
  93. av.av_size = avsize(lnp);
  94. av.av_oleft = tkp1->tk_vn;
  95. av.av_oright = tkp2->tk_vn;
  96. ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
  97. push_avail(av_enter(&av, ocp, BINAIR_OP), tkp1->tk_lfirst);
  98. }
  99. STATIC push_ternair_op(bp, lnp, tkp1, tkp2, tkp3)
  100. bblock_p bp;
  101. line_p lnp;
  102. token_p tkp1, tkp2, tkp3;
  103. {
  104. struct avail av;
  105. occur_p ocp;
  106. av.av_instr = INSTR(lnp);
  107. av.av_size = avsize(lnp);
  108. av.av_ofirst = tkp1->tk_vn;
  109. av.av_osecond = tkp2->tk_vn;
  110. av.av_othird = tkp3->tk_vn;
  111. ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
  112. push_avail(av_enter(&av, ocp, TERNAIR_OP), tkp1->tk_lfirst);
  113. }
  114. STATIC fiddle_stack(lnp)
  115. line_p lnp;
  116. {
  117. /* The instruction in lnp does something to the valuenumber-stack. */
  118. struct token dummy;
  119. offset size;
  120. /* Partly initialize dummy. */
  121. dummy.tk_lfirst = lnp;
  122. switch (INSTR(lnp)) {
  123. default:
  124. assert(FALSE);
  125. break;
  126. case op_lor:
  127. dummy.tk_vn = newvalnum(); dummy.tk_size = ps;
  128. Push(&dummy);
  129. break;
  130. case op_asp:
  131. if ((size = off_set(lnp)) > 0) {
  132. Pop(&dummy, size);
  133. } else {
  134. dummy.tk_vn = newvalnum();
  135. dummy.tk_size = size;
  136. Push(&dummy);
  137. }
  138. break;
  139. case op_dup:
  140. Dup(lnp);
  141. break;
  142. case op_ass:
  143. case op_dus:
  144. case op_exg:
  145. case op_los:
  146. /* Don't waste effort. */
  147. clr_stack();
  148. break;
  149. case op_sig:
  150. Pop(&dummy, (offset) ps);
  151. break;
  152. case op_lfr:
  153. dummy.tk_vn = newvalnum();
  154. dummy.tk_size = off_set(lnp);
  155. Push(&dummy);
  156. break;
  157. case op_beq:
  158. case op_bge:
  159. case op_bgt:
  160. case op_bne:
  161. case op_ble:
  162. case op_blt:
  163. Pop(&dummy, (offset) ws);
  164. Pop(&dummy, (offset) ws);
  165. break;
  166. case op_bra:
  167. case op_csa:/* ??? */
  168. case op_csb:/* ??? */
  169. case op_gto:/* ??? */
  170. case op_ret:/* ??? */
  171. case op_rtt:/* ??? */
  172. break;
  173. case op_zeq:
  174. case op_zge:
  175. case op_zgt:
  176. case op_zne:
  177. case op_zle:
  178. case op_zlt:
  179. case op_trp:
  180. Pop(&dummy, (offset) ws);
  181. break;
  182. case op_rck:
  183. Pop(&dummy, (offset) ps);
  184. break;
  185. }
  186. }
  187. STATIC proc_p find_proc(vn)
  188. valnum vn;
  189. {
  190. /* Find the procedure-identifier with valuenumber vn. */
  191. entity_p enp;
  192. enp = find_entity(vn);
  193. if (enp != (entity_p) 0 && enp->en_kind == ENPROC)
  194. return enp->en_pro;
  195. return (proc_p) 0;
  196. }
  197. STATIC side_effects(lnp)
  198. line_p lnp;
  199. {
  200. /* Lnp contains a cai or cal instruction. We try to find the callee
  201. * and see what side-effects it has.
  202. */
  203. struct token tk;
  204. proc_p pp;
  205. if (INSTR(lnp) == op_cai) {
  206. Pop(&tk, (offset) ps);
  207. pp = find_proc(tk.tk_vn);
  208. } else {
  209. assert(INSTR(lnp) == op_cal);
  210. pp = PROC(lnp);
  211. }
  212. if (pp != (proc_p) 0) {
  213. kill_call(pp);
  214. } else {
  215. kill_much();
  216. }
  217. }
  218. hopeless(instr)
  219. int instr;
  220. {
  221. /* The effect of `instr' is too difficult to
  222. * compute. We assume worst case behaviour.
  223. */
  224. switch (instr) {
  225. default:
  226. assert(FALSE);
  227. break;
  228. case op_mon:
  229. case op_str:
  230. case op_nop: /* for volatiles */
  231. /* We can't even trust "static" entities. */
  232. kill_all();
  233. clr_stack();
  234. break;
  235. case op_blm:
  236. case op_bls:
  237. case op_sts:
  238. kill_much();
  239. clr_stack();
  240. break;
  241. }
  242. }
  243. vnm(bp)
  244. bblock_p bp;
  245. {
  246. register line_p lnp;
  247. register entity_p rep;
  248. line_p lfirst;
  249. struct token tk, tk1, tk2, tk3;
  250. for (lnp = bp->b_start; lnp != (line_p) 0; lnp = lnp->l_next) {
  251. rep = getentity(lnp, &lfirst);
  252. switch (instrgroup(lnp)) {
  253. case SIMPLE_LOAD:
  254. push_entity(rep, lfirst);
  255. break;
  256. case LOAD_ARRAY:
  257. put_aar(bp, lnp, lfirst, rep);
  258. /* Fall through ... */
  259. case EXPENSIVE_LOAD:
  260. push_entity(rep, lfirst);
  261. put_expensive_load(bp, lnp, lfirst, rep);
  262. break;
  263. case STORE_DIRECT:
  264. kill_direct(rep);
  265. Pop(&tk, rep->en_size);
  266. rep->en_vn = tk.tk_vn;
  267. break;
  268. case STORE_ARRAY:
  269. put_aar(bp, lnp, lfirst, rep);
  270. /* Fall through ... */
  271. case STORE_INDIR:
  272. kill_indir(rep);
  273. Pop(&tk, rep->en_size);
  274. rep->en_vn = tk.tk_vn;
  275. break;
  276. case UNAIR_OP:
  277. Pop(&tk1, op11size(lnp));
  278. push_unair_op(bp, lnp, &tk1);
  279. break;
  280. case BINAIR_OP:
  281. Pop(&tk2, op22size(lnp));
  282. Pop(&tk1, op12size(lnp));
  283. push_binair_op(bp, lnp, &tk1, &tk2);
  284. break;
  285. case TERNAIR_OP:
  286. Pop(&tk3, op33size(lnp));
  287. Pop(&tk2, op23size(lnp));
  288. Pop(&tk1, op13size(lnp));
  289. push_ternair_op(bp, lnp, &tk1, &tk2, &tk3);
  290. break;
  291. case KILL_ENTITY:
  292. kill_direct(rep);
  293. break;
  294. case SIDE_EFFECTS:
  295. side_effects(lnp);
  296. break;
  297. case FIDDLE_STACK:
  298. fiddle_stack(lnp);
  299. break;
  300. case IGNORE:
  301. break;
  302. case HOPELESS:
  303. hopeless(INSTR(lnp));
  304. break;
  305. case BBLOCK_END:
  306. fiddle_stack(lnp);
  307. break;
  308. default:
  309. assert(FALSE);
  310. break;
  311. }
  312. }
  313. }