fixed another bug with header blocks, and modified to use existing header
block when possible
This commit is contained in:
parent
3c6a9b2b96
commit
040495ff56
3 changed files with 62 additions and 12 deletions
|
@ -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)
|
STATIC sr_extproc(p)
|
||||||
proc_p p;
|
proc_p p;
|
||||||
{
|
{
|
||||||
|
@ -167,11 +188,14 @@ STATIC sr_extproc(p)
|
||||||
pi = Lnext(pi,p->p_loops)) {
|
pi = Lnext(pi,p->p_loops)) {
|
||||||
lp = (loop_p) Lelem(pi);
|
lp = (loop_p) Lelem(pi);
|
||||||
lp->lp_extend = newsrlpx();
|
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)
|
STATIC sr_cleanproc(p)
|
||||||
proc_p p;
|
proc_p p;
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,6 +146,25 @@ STATIC replcode(code,text)
|
||||||
/* Note that the old code is still accessible via code->co_lfirst */
|
/* 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)
|
STATIC init_code(code,tmp)
|
||||||
|
@ -193,21 +212,20 @@ STATIC init_code(code,tmp)
|
||||||
PREV(l->l_next) = l;
|
PREV(l->l_next) = l;
|
||||||
/* Now insert the code at the end of the header block */
|
/* Now insert the code at the end of the header block */
|
||||||
p = &code->co_loop->LP_INSTR;
|
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,
|
/* LP_INSTR points to last instruction of header block,
|
||||||
* so if it is 0, the header block is empty yet.
|
* so if it is 0, the header block is empty yet.
|
||||||
*/
|
*/
|
||||||
code->co_loop->LP_HEADER->b_start =
|
code->co_loop->LP_HEADER->b_start =
|
||||||
code->co_lfirst;
|
add_code(code->co_loop->LP_HEADER->b_start, code->co_lfirst);
|
||||||
} else {
|
} else if (INSTR((*p)) == op_bra) {
|
||||||
(*p)->l_next = code->co_lfirst;
|
add_code(PREV((*p)), code->co_lfirst);
|
||||||
PREV(code->co_lfirst) = *p;
|
|
||||||
}
|
}
|
||||||
*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)
|
STATIC incr_code(code,tmp)
|
||||||
code_p code;
|
code_p code;
|
||||||
offset tmp;
|
offset tmp;
|
||||||
|
|
|
@ -116,17 +116,25 @@ STATIC adjust_jump(newtarg,oldtarg,c)
|
||||||
* start of the new target.
|
* 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 (INSTR(oldtarg->b_start) == op_lab) {
|
||||||
/* If old target has no label, it cannot be jumped to */
|
/* If old target has no label, it cannot be jumped to */
|
||||||
l = last_instr(c);
|
|
||||||
assert(l != (line_p) 0);
|
|
||||||
if (TYPE(l) == OPINSTRLAB &&
|
if (TYPE(l) == OPINSTRLAB &&
|
||||||
INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) {
|
INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) {
|
||||||
INSTRLAB(l) = label(newtarg);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue