flow.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. * Author: Hans van Staveren
  6. */
  7. #include "param.h"
  8. #include "types.h"
  9. #include "tes.h"
  10. #include <em_flag.h>
  11. #include <em_spec.h>
  12. #include <em_mnem.h>
  13. #include "alloc.h"
  14. #include "line.h"
  15. #include "proinf.h"
  16. #include "optim.h"
  17. #include "ext.h"
  18. #include "flow.h"
  19. void flow()
  20. {
  21. findreach(); /* determine reachable labels */
  22. cleaninstrs(); /* throw away unreachable code */
  23. }
  24. void findreach()
  25. {
  26. num_p *npp,np;
  27. reach(instrs);
  28. for(npp=curpro.numhash;npp< &curpro.numhash[NNUMHASH]; npp++)
  29. for(np= *npp; np != (num_p) 0 ; np = np->n_next)
  30. if (np->n_flags&NUMDATA) {
  31. np->n_repl->n_flags |= NUMREACH;
  32. np->n_repl->n_jumps++;
  33. if (!(np->n_flags&NUMSCAN)) {
  34. np->n_flags |= NUMSCAN;
  35. if (np->n_line) {
  36. reach(np->n_line->l_next);
  37. continue;
  38. }
  39. if (!(np->n_repl->n_flags&NUMSCAN)) {
  40. np->n_repl->n_flags |= NUMSCAN;
  41. if (np->n_repl->n_line)
  42. reach(np->n_repl->n_line->l_next);
  43. }
  44. }
  45. }
  46. }
  47. void reach(line_p lnp)
  48. {
  49. num_p np;
  50. for (;lnp != (line_p) 0; lnp = lnp->l_next) {
  51. if(lnp->l_optyp == OPNUMLAB) {
  52. /*
  53. * Branch instruction or label
  54. */
  55. np = lnp->l_a.la_np;
  56. if ((lnp->l_instr&BMASK) != op_lab)
  57. lnp->l_a.la_np = np = np->n_repl;
  58. np->n_flags |= NUMREACH;
  59. if (!(np->n_flags&NUMSCAN)) {
  60. np->n_flags |= NUMSCAN;
  61. if (np->n_line)
  62. reach(np->n_line->l_next);
  63. else {
  64. np = np->n_repl;
  65. np->n_flags |= NUMREACH;
  66. if (!(np->n_flags & NUMSCAN)) {
  67. np->n_flags |= NUMSCAN;
  68. if (np->n_line)
  69. reach(np->n_line->l_next);
  70. }
  71. }
  72. }
  73. if ((lnp->l_instr&BMASK) == op_lab)
  74. return;
  75. else
  76. np->n_jumps++;
  77. }
  78. if ((lnp->l_instr & BMASK) > sp_lmnem) continue;
  79. if ((em_flag[(lnp->l_instr&BMASK)-sp_fmnem]&EM_FLO)==FLO_T)
  80. return;
  81. }
  82. }
  83. void cleaninstrs()
  84. {
  85. line_p *lpp, lp, *lastbra;
  86. bool reachable, superfluous;
  87. int instr;
  88. lpp = &instrs; lastbra = (line_p *) 0; reachable = TRUE;
  89. while ((lp = *lpp) != (line_p) 0) {
  90. instr = lp->l_instr&BMASK;
  91. if (instr == op_lab) {
  92. if ((lp->l_a.la_np->n_flags&NUMREACH) != 0) {
  93. reachable = TRUE;
  94. if (lastbra != (line_p *) 0
  95. && (*lastbra)->l_next == lp
  96. && (*lastbra)->l_a.la_np->n_repl==lp->l_a.la_np) {
  97. oldline(*lastbra);
  98. OPTIM(O_BRALAB);
  99. lpp = lastbra;
  100. *lpp = lp;
  101. lastbra = (line_p *) 0;
  102. lp->l_a.la_np->n_jumps--;
  103. }
  104. }
  105. if ( lp->l_a.la_np->n_repl != lp->l_a.la_np ||
  106. ((lp->l_a.la_np->n_flags&NUMDATA)==0 &&
  107. lp->l_a.la_np->n_jumps == 0))
  108. superfluous = TRUE;
  109. else
  110. superfluous = FALSE;
  111. } else
  112. superfluous = FALSE;
  113. if ( (!reachable) || superfluous) {
  114. if (instr == op_lab) {
  115. lp->l_a.la_np->n_line = 0;
  116. }
  117. else if (instr > sp_lmnem) {
  118. /* leave pseudo's */
  119. lpp = &lp->l_next;
  120. continue;
  121. }
  122. lp = lp->l_next;
  123. oldline(*lpp);
  124. OPTIM(O_UNREACH);
  125. *lpp = lp;
  126. } else {
  127. if ( instr <= sp_lmnem &&
  128. (em_flag[instr-sp_fmnem]&EM_FLO)==FLO_T) {
  129. reachable = FALSE;
  130. if ((lp->l_instr&BMASK) == op_bra)
  131. lastbra = lpp;
  132. }
  133. lpp = &lp->l_next;
  134. }
  135. }
  136. }