diff --git a/util/ego/sr/sr_reduce.c b/util/ego/sr/sr_reduce.c index c78e456a1..7480f900c 100644 --- a/util/ego/sr/sr_reduce.c +++ b/util/ego/sr/sr_reduce.c @@ -171,9 +171,7 @@ STATIC line_p add_code(pl, l) -STATIC void init_code(code,tmp) - code_p code; - offset tmp; +STATIC void init_code(code_p code, offset tmp) { /* Generate code to set up the temporary local. * For multiplication, its initial value is const*iv_expr, @@ -223,20 +221,19 @@ STATIC void init_code(code,tmp) assert(FALSE); /* non-reducible instruction */ } PREV(l->l_next) = l; + /* Now insert the code at the end of the header block */ p = &code->co_loop->LP_INSTR; - if (*p == (line_p) 0 || (PREV((*p)) == 0 && INSTR((*p)) == op_bra)) { - /* LP_INSTR points to last instruction of header block, - * so if it is 0, the header block is empty yet. - */ - code->co_loop->LP_HEADER->b_start = - add_code(code->co_loop->LP_HEADER->b_start, code->co_lfirst); - } else if (INSTR((*p)) == op_bra) { + if (INSTR((*p)) == op_bra) { + /* Add code before branching to the loop. */ add_code(PREV((*p)), code->co_lfirst); + } else { + /* Add code before falling into the loop. */ + add_code(*p, code->co_lfirst); + while (l->l_next) + l = l->l_next; + *p = l; /* new last instruction */ } - else add_code(*p, code->co_lfirst); - while (l->l_next) l = l->l_next; - *p = l; /* new last instruction */ } STATIC void incr_code(code,tmp) @@ -453,43 +450,7 @@ STATIC code_p available(c,vars) return (code_p) 0; } -STATIC void fix_header(lp) - loop_p lp; -{ - /* Check if a header block was added, and if so, add a branch to - * the entry block. - * If it was added, it was added to the end of the procedure, so - * move the END pseudo. - */ - bblock_p b = curproc->p_start; - - if (lp->LP_HEADER->b_next == 0) { - line_p l = last_instr(lp->LP_HEADER); - line_p e; - - assert(l != 0); - if (INSTR(l) != op_bra) { - line_p j = newline(OPINSTRLAB); - - assert(INSTR(lp->lp_entry->b_start) == op_lab); - INSTRLAB(j) = INSTRLAB(lp->lp_entry->b_start); - j->l_instr = op_bra; - DLINK(l, j); - l = j; - } - - while (b->b_next != lp->LP_HEADER) b = b->b_next; - e = last_instr(b); - assert(INSTR(e) == ps_end); - assert(PREV(e) != 0); - PREV(e)->l_next = 0; - DLINK(l, e); - } -} - -STATIC void reduce(code,vars) - code_p code; - lset vars; +STATIC void reduce(code_p code, lset vars) { /* Perform the actual transformations. The code on the left * gets transformed into the code on the right. Note that @@ -538,7 +499,6 @@ STATIC void reduce(code,vars) incr_code(code,tmp); /* emit code to increment temp. local */ OUTTRACE("emitted increment code",0); Ladd(code,&avail); - fix_header(code->co_loop); } } diff --git a/util/ego/sr/sr_xform.c b/util/ego/sr/sr_xform.c index d48a70844..5323ceacb 100644 --- a/util/ego/sr/sr_xform.c +++ b/util/ego/sr/sr_xform.c @@ -138,9 +138,7 @@ STATIC void adjust_jump(newtarg,oldtarg,c) } -void -make_header(lp) - loop_p lp; +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 @@ -149,6 +147,7 @@ make_header(lp) */ bblock_p b,c,entry; + line_p branch,last; Lindex i,next; if (lp->LP_HEADER != (bblock_p) 0) return; @@ -160,6 +159,17 @@ make_header(lp) b = freshblock(); /* new block with new b_id */ entry = lp->lp_entry; + /* In the header, add a branch from to the entry block. */ + branch = newline(OPINSTRLAB); + assert(INSTR(entry->b_start) == op_lab); + INSTRLAB(branch) = INSTRLAB(entry->b_start); + branch->l_instr = op_bra; + b->b_start = branch; + + /* Plan to insert code before the branch. */ + assert(lp->LP_INSTR == 0); + lp->LP_INSTR = branch; + /* update succ/pred. Also take care that any jump from outside * the loop to the entry block now goes to b. */ @@ -180,14 +190,24 @@ make_header(lp) 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); + for (c = curproc->p_start; c->b_next != 0; c = c->b_next) + continue; c->b_next = b; /* b->b_next = 0; */ + + /* move the END pseudo to header block */ + last = last_instr(c); + assert(INSTR(last) == ps_end); + assert(PREV(last) != (line_p) 0); + PREV(last)->l_next = 0; + DLINK(branch, last); + + /* fix loops and dominance */ copy_loops(b,entry,lp); b->b_idom = entry->b_idom; entry->b_idom = b;