sr_xform.c 4.2 KB

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