From: ceriel Date: Wed, 5 Aug 1987 09:46:38 +0000 (+0000) Subject: fixed another bug with header blocks, and modified to use existing header X-Git-Tag: release-5-5~3950 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=040495ff56f536c811bedb05bb0354e6b194bc8a;p=ack.git fixed another bug with header blocks, and modified to use existing header block when possible --- diff --git a/util/ego/sr/sr.c b/util/ego/sr/sr.c index 51a6ea811..00cea57ba 100644 --- a/util/ego/sr/sr.c +++ b/util/ego/sr/sr.c @@ -155,6 +155,27 @@ STATIC opt_proc(p) +STATIC bblock_p header(lp) + loop_p lp; +{ + /* Try to determine the 'header' block of loop lp. + * If 'e' is the entry block of loop L, then block 'b' is + * called the header block of L, iff: + * SUCC(b) = {e} & b dominates e. + * If lp has no header block, 0 is returned. + */ + + bblock_p x = lp->lp_entry->b_idom; + + if (x != (bblock_p) 0 && Lnrelems(x->b_succ) == 1 && + (bblock_p) Lelem(Lfirst(x->b_succ)) == lp->lp_entry) { + return x; + } + return (bblock_p) 0; +} + + + STATIC sr_extproc(p) proc_p p; { @@ -167,11 +188,14 @@ STATIC sr_extproc(p) pi = Lnext(pi,p->p_loops)) { lp = (loop_p) Lelem(pi); lp->lp_extend = newsrlpx(); + lp->LP_HEADER = header(lp); + if (lp->LP_HEADER) { + lp->LP_INSTR = last_instr(lp->LP_HEADER); + } } } - STATIC sr_cleanproc(p) proc_p p; { diff --git a/util/ego/sr/sr_reduce.c b/util/ego/sr/sr_reduce.c index 2d287ff50..a82361111 100644 --- a/util/ego/sr/sr_reduce.c +++ b/util/ego/sr/sr_reduce.c @@ -146,6 +146,25 @@ STATIC replcode(code,text) /* Note that the old code is still accessible via code->co_lfirst */ } +STATIC line_p add_code(pl, l) + line_p pl, l; +{ + if (! pl) { + PREV(l) = 0; + } + else { + line_p n = pl->l_next; + + DLINK(pl, l); + if (n) { + while (l->l_next) l = l->l_next; + DLINK(l, n); + } + l = pl; + } + return l; +} + STATIC init_code(code,tmp) @@ -193,21 +212,20 @@ STATIC init_code(code,tmp) 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) { + 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 = - code->co_lfirst; - } else { - (*p)->l_next = code->co_lfirst; - PREV(code->co_lfirst) = *p; + add_code(code->co_loop->LP_HEADER->b_start, code->co_lfirst); + } else if (INSTR((*p)) == op_bra) { + add_code(PREV((*p)), code->co_lfirst); } - *p = l->l_next; /* new last instruction */ + else add_code(*p, code->co_lfirst); + while (l->l_next) l = l->l_next; + *p = l; /* new last instruction */ } - - STATIC incr_code(code,tmp) code_p code; offset tmp; diff --git a/util/ego/sr/sr_xform.c b/util/ego/sr/sr_xform.c index 2b10e0e97..977feff37 100644 --- a/util/ego/sr/sr_xform.c +++ b/util/ego/sr/sr_xform.c @@ -116,17 +116,25 @@ STATIC adjust_jump(newtarg,oldtarg,c) * start of the new target. */ - line_p l; + 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 */ - l = last_instr(c); - assert(l != (line_p) 0); 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); + } }