sr_xform.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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 T R E N G T H R E D U C T I O N
  7. *
  8. * S R _ X F O R M . C
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <em_mnem.h>
  13. #include <em_pseu.h>
  14. #include <em_spec.h>
  15. #include "../share/types.h"
  16. #include "sr.h"
  17. #include "../share/debug.h"
  18. #include "../share/global.h"
  19. #include "../share/alloc.h"
  20. #include "../share/def.h"
  21. #include "../share/get.h"
  22. #include "sr_aux.h"
  23. #include "../share/lset.h"
  24. #include "../share/aux.h"
  25. #include "sr_xform.h"
  26. /* Transformations on EM texts */
  27. line_p move_pointer(tmp,dir)
  28. offset tmp;
  29. int dir;
  30. {
  31. /* Generate EM code to load/store a pointer variable
  32. * onto/from the stack, depending on dir(ection).
  33. * We accept all kinds of pointer sizes.
  34. */
  35. line_p l;
  36. l = int_line(tmp);
  37. if (ps == ws) {
  38. /* pointer fits in a word */
  39. l->l_instr = (dir == LOAD ? op_lol : op_stl);
  40. } else {
  41. if (ps == 2 * ws) {
  42. /* pointer fits in a double word */
  43. l->l_instr = (dir == LOAD ? op_ldl : op_sdl);
  44. } else {
  45. /* very large pointer size, generate code:
  46. * LAL tmp ; LOI/STI ps */
  47. l->l_instr = op_lal;
  48. l->l_next = newline(OPSHORT);
  49. SHORT(l->l_next) = ps;
  50. l->l_next->l_instr =
  51. (dir == LOAD ? op_loi : op_sti);
  52. PREV(l->l_next) = l;
  53. }
  54. }
  55. return l;
  56. }
  57. /* make_header */
  58. STATIC copy_loops(b1,b2,except)
  59. bblock_p b1,b2;
  60. loop_p except;
  61. {
  62. /* Copy the loopset of b2 to b1, except for 'except' */
  63. Lindex i;
  64. loop_p lp;
  65. for (i = Lfirst(b2->b_loops); i != (Lindex) 0;
  66. i = Lnext(i,b2->b_loops)) {
  67. lp = (loop_p) Lelem(i);
  68. if (lp != except) {
  69. Ladd(lp,&b1->b_loops);
  70. }
  71. }
  72. }
  73. STATIC lab_id label(b)
  74. bblock_p b;
  75. {
  76. /* Find the label at the head of block b. If there is
  77. * no such label yet, create one.
  78. */
  79. line_p l;
  80. if (b->b_start && INSTR(b->b_start) == op_lab) {
  81. return INSTRLAB(b->b_start);
  82. }
  83. /* The block has no label yet. */
  84. l = newline(OPINSTRLAB);
  85. l->l_instr = op_lab;
  86. INSTRLAB(l) = freshlabel();
  87. if (b->b_start) {
  88. DLINK(l,b->b_start); /* doubly link them */
  89. }
  90. b->b_start = l;
  91. return INSTRLAB(l);
  92. }
  93. STATIC adjust_jump(newtarg,oldtarg,c)
  94. bblock_p newtarg,oldtarg,c;
  95. {
  96. /* If the last instruction of c is a jump to the
  97. * old target, then change it into a jump to the
  98. * start of the new target.
  99. */
  100. line_p l = last_instr(c);
  101. assert(l != (line_p) 0);
  102. if (INSTR(oldtarg->b_start) == op_lab) {
  103. /* If old target has no label, it cannot be jumped to */
  104. if (TYPE(l) == OPINSTRLAB &&
  105. INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) {
  106. INSTRLAB(l) = label(newtarg);
  107. }
  108. }
  109. if (c->b_next == oldtarg && INSTR(l) != op_bra) {
  110. line_p new = newline(OPINSTRLAB);
  111. INSTRLAB(new) = label(newtarg);
  112. new->l_instr = op_bra;
  113. DLINK(l, new);
  114. }
  115. }
  116. make_header(lp)
  117. loop_p lp;
  118. {
  119. /* Make sure that the loop has a header block, i.e. a block
  120. * has the loop entry block as its only successor and
  121. * that dominates the loop entry block.
  122. * If there is no header yet, create one.
  123. */
  124. bblock_p b,c,entry;
  125. Lindex i,next;
  126. if (lp->LP_HEADER != (bblock_p) 0) return;
  127. OUTTRACE("creating a new header block",0);
  128. /* The loop has no header yet. The main problem is to
  129. * keep all relations (SUCC, PRED, NEXT, IDOM, LOOPS)
  130. * up to date.
  131. */
  132. b = freshblock(); /* new block with new b_id */
  133. entry = lp->lp_entry;
  134. /* update succ/pred. Also take care that any jump from outside
  135. * the loop to the entry block now goes to b.
  136. */
  137. b->b_succ = Lempty_set();
  138. b->b_pred = Lempty_set();
  139. for (i = Lfirst(entry->b_pred); i != (Lindex) 0; i = next ) {
  140. next = Lnext(i,entry->b_pred);
  141. c = (bblock_p) Lelem(i);
  142. /* c is a predecessor of the entry block */
  143. if (!Lis_elem(c,lp->LP_BLOCKS)) {
  144. /* c is outside the loop */
  145. Lremove(c,&entry->b_pred);
  146. Lremove(entry,&c->b_succ);
  147. Ladd(b,&c->b_succ);
  148. Ladd(c,&b->b_pred);
  149. adjust_jump(b,entry,c);
  150. }
  151. }
  152. assert(lp->LP_INSTR == 0);
  153. lp->LP_INSTR = b->b_start;
  154. Ladd(b,&entry->b_pred);
  155. Ladd(entry,&b->b_succ);
  156. /* put header block at end of procedure */
  157. for (c = curproc->p_start; c->b_next != 0; c = c->b_next);
  158. c->b_next = b;
  159. /* b->b_next = 0; */
  160. copy_loops(b,entry,lp);
  161. b->b_idom = entry->b_idom;
  162. entry->b_idom = b;
  163. lp->LP_HEADER = b;
  164. }