123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* S T R E N G T H R E D U C T I O N
- *
- * S R _ X F O R M . C
- *
- */
- #include <stdio.h>
- #include <em_mnem.h>
- #include <em_pseu.h>
- #include <em_spec.h>
- #include "../share/types.h"
- #include "sr.h"
- #include "../share/debug.h"
- #include "../share/global.h"
- #include "../share/alloc.h"
- #include "../share/def.h"
- #include "../share/get.h"
- #include "sr_aux.h"
- #include "../share/lset.h"
- #include "../share/aux.h"
- #include "sr_xform.h"
- /* Transformations on EM texts */
- line_p move_pointer(offset tmp, int dir)
- {
- /* Generate EM code to load/store a pointer variable
- * onto/from the stack, depending on dir(ection).
- * We accept all kinds of pointer sizes.
- */
- line_p l;
- l = int_line(tmp);
- if (ps == ws) {
- /* pointer fits in a word */
- l->l_instr = (dir == LOAD ? op_lol : op_stl);
- } else {
- if (ps == 2 * ws) {
- /* pointer fits in a double word */
- l->l_instr = (dir == LOAD ? op_ldl : op_sdl);
- } else {
- /* very large pointer size, generate code:
- * LAL tmp ; LOI/STI ps */
- l->l_instr = op_lal;
- l->l_next = newline(OPSHORT);
- SHORT(l->l_next) = ps;
- l->l_next->l_instr =
- (dir == LOAD ? op_loi : op_sti);
- PREV(l->l_next) = l;
- }
- }
- return l;
- }
- /* make_header */
- static void copy_loops(bblock_p b1, bblock_p b2, loop_p except)
- {
- /* Copy the loopset of b2 to b1, except for 'except' */
- Lindex i;
- loop_p lp;
- for (i = Lfirst(b2->b_loops); i != (Lindex) 0;
- i = Lnext(i,b2->b_loops)) {
- lp = (loop_p) Lelem(i);
- if (lp != except) {
- Ladd(lp,&b1->b_loops);
- }
- }
- }
- static lab_id label(bblock_p b)
- {
- /* Find the label at the head of block b. If there is
- * no such label yet, create one.
- */
- line_p l;
- if (b->b_start && INSTR(b->b_start) == op_lab) {
- return INSTRLAB(b->b_start);
- }
- /* The block has no label yet. */
- l = newline(OPINSTRLAB);
- l->l_instr = op_lab;
- INSTRLAB(l) = freshlabel();
- if (b->b_start) {
- DLINK(l,b->b_start); /* doubly link them */
- }
- b->b_start = l;
- return INSTRLAB(l);
- }
- static void adjust_jump(bblock_p newtarg, bblock_p oldtarg, bblock_p c)
- {
- /* If the last instruction of c is a jump to the
- * old target, then change it into a jump to the
- * start of the new target.
- */
- line_p l = last_instr(c);
- assert(l != (line_p) 0);
- if (INSTR(oldtarg->b_start) == op_lab) {
- /* If old target has no label, it cannot be jumped to */
- if (TYPE(l) == OPINSTRLAB &&
- INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) {
- INSTRLAB(l) = label(newtarg);
- }
- }
- if (c->b_next == oldtarg && INSTR(l) != op_bra) {
- line_p new = newline(OPINSTRLAB);
- INSTRLAB(new) = label(newtarg);
- new->l_instr = op_bra;
- DLINK(l, new);
- }
- }
- void make_header(loop_p lp)
- {
- /* Make sure that the loop has a header block, i.e. a block
- * has the loop entry block as its only successor and
- * that dominates the loop entry block.
- * If there is no header yet, create one.
- */
- bblock_p b,c,entry;
- Lindex i,next;
- if (lp->LP_HEADER != (bblock_p) 0) return;
- OUTTRACE("creating a new header block",0);
- /* The loop has no header yet. The main problem is to
- * keep all relations (SUCC, PRED, NEXT, IDOM, LOOPS)
- * up to date.
- */
- b = freshblock(); /* new block with new b_id */
- entry = lp->lp_entry;
- /* update succ/pred. Also take care that any jump from outside
- * the loop to the entry block now goes to b.
- */
- b->b_succ = Lempty_set();
- b->b_pred = Lempty_set();
- for (i = Lfirst(entry->b_pred); i != (Lindex) 0; i = next ) {
- next = Lnext(i,entry->b_pred);
- c = (bblock_p) Lelem(i);
- /* c is a predecessor of the entry block */
- if (!Lis_elem(c,lp->LP_BLOCKS)) {
- /* c is outside the loop */
- Lremove(c,&entry->b_pred);
- Lremove(entry,&c->b_succ);
- Ladd(b,&c->b_succ);
- Ladd(c,&b->b_pred);
- adjust_jump(b,entry,c);
- }
- }
- assert(lp->LP_INSTR == 0);
- lp->LP_INSTR = b->b_start;
- Ladd(b,&entry->b_pred);
- Ladd(entry,&b->b_succ);
- /* put header block at end of procedure */
- for (c = curproc->p_start; c->b_next != 0; c = c->b_next);
- c->b_next = b;
- /* b->b_next = 0; */
- copy_loops(b,entry,lp);
- b->b_idom = entry->b_idom;
- entry->b_idom = b;
- lp->LP_HEADER = b;
- }
|