+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;
{
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;
{
/* 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)
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;
* 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);
+ }
}