1 /* $Id: sr_xform.c,v 1.7 1994/06/24 10:32:33 ceriel Exp $ */
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".
6 /* S T R E N G T H R E D U C T I O N
18 #include "../share/types.h"
20 #include "../share/debug.h"
21 #include "../share/global.h"
22 #include "../share/alloc.h"
23 #include "../share/def.h"
24 #include "../share/get.h"
26 #include "../share/lset.h"
27 #include "../share/aux.h"
30 /* Transformations on EM texts */
32 line_p move_pointer(tmp,dir)
36 /* Generate EM code to load/store a pointer variable
37 * onto/from the stack, depending on dir(ection).
38 * We accept all kinds of pointer sizes.
45 /* pointer fits in a word */
46 l->l_instr = (dir == LOAD ? op_lol : op_stl);
49 /* pointer fits in a double word */
50 l->l_instr = (dir == LOAD ? op_ldl : op_sdl);
52 /* very large pointer size, generate code:
53 * LAL tmp ; LOI/STI ps */
55 l->l_next = newline(OPSHORT);
56 SHORT(l->l_next) = ps;
58 (dir == LOAD ? op_loi : op_sti);
69 STATIC copy_loops(b1,b2,except)
73 /* Copy the loopset of b2 to b1, except for 'except' */
77 for (i = Lfirst(b2->b_loops); i != (Lindex) 0;
78 i = Lnext(i,b2->b_loops)) {
79 lp = (loop_p) Lelem(i);
81 Ladd(lp,&b1->b_loops);
87 STATIC lab_id label(b)
90 /* Find the label at the head of block b. If there is
91 * no such label yet, create one.
96 if (b->b_start && INSTR(b->b_start) == op_lab) {
97 return INSTRLAB(b->b_start);
99 /* The block has no label yet. */
100 l = newline(OPINSTRLAB);
102 INSTRLAB(l) = freshlabel();
104 DLINK(l,b->b_start); /* doubly link them */
111 STATIC adjust_jump(newtarg,oldtarg,c)
112 bblock_p newtarg,oldtarg,c;
114 /* If the last instruction of c is a jump to the
115 * old target, then change it into a jump to the
116 * start of the new target.
119 line_p l = last_instr(c);
121 assert(l != (line_p) 0);
123 if (INSTR(oldtarg->b_start) == op_lab) {
124 /* If old target has no label, it cannot be jumped to */
125 if (TYPE(l) == OPINSTRLAB &&
126 INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) {
127 INSTRLAB(l) = label(newtarg);
131 if (c->b_next == oldtarg && INSTR(l) != op_bra) {
132 line_p new = newline(OPINSTRLAB);
134 INSTRLAB(new) = label(newtarg);
135 new->l_instr = op_bra;
144 /* Make sure that the loop has a header block, i.e. a block
145 * has the loop entry block as its only successor and
146 * that dominates the loop entry block.
147 * If there is no header yet, create one.
153 if (lp->LP_HEADER != (bblock_p) 0) return;
154 OUTTRACE("creating a new header block",0);
155 /* The loop has no header yet. The main problem is to
156 * keep all relations (SUCC, PRED, NEXT, IDOM, LOOPS)
159 b = freshblock(); /* new block with new b_id */
160 entry = lp->lp_entry;
162 /* update succ/pred. Also take care that any jump from outside
163 * the loop to the entry block now goes to b.
166 b->b_succ = Lempty_set();
167 b->b_pred = Lempty_set();
169 for (i = Lfirst(entry->b_pred); i != (Lindex) 0; i = next ) {
170 next = Lnext(i,entry->b_pred);
171 c = (bblock_p) Lelem(i);
172 /* c is a predecessor of the entry block */
173 if (!Lis_elem(c,lp->LP_BLOCKS)) {
174 /* c is outside the loop */
175 Lremove(c,&entry->b_pred);
176 Lremove(entry,&c->b_succ);
179 adjust_jump(b,entry,c);
182 assert(lp->LP_INSTR == 0);
183 lp->LP_INSTR = b->b_start;
184 Ladd(b,&entry->b_pred);
185 Ladd(entry,&b->b_succ);
186 /* put header block at end of procedure */
187 for (c = curproc->p_start; c->b_next != 0; c = c->b_next);
190 copy_loops(b,entry,lp);
191 b->b_idom = entry->b_idom;