Sfoglia il codice sorgente

bug fixes: put header block at end of procedure

ceriel 37 anni fa
parent
commit
159b84ef68
2 ha cambiato i file con 53 aggiunte e 15 eliminazioni
  1. 35 0
      util/ego/sr/sr_reduce.c
  2. 18 15
      util/ego/sr/sr_xform.c

+ 35 - 0
util/ego/sr/sr_reduce.c

@@ -15,6 +15,7 @@
 #include "../../../h/em_mnem.h"
 #include "../share/debug.h"
 #include "../share/alloc.h"
+#include "../share/def.h"
 #include "../share/global.h"
 #include "../share/aux.h"
 #include "sr_aux.h"
@@ -26,6 +27,7 @@
 #include "../../../h/em_reg.h"
 #include "../../../h/em_mes.h"
 #include "../../../h/em_mnem.h"
+#include "../../../h/em_spec.h"
 
 
 
@@ -403,7 +405,39 @@ STATIC code_p available(c,vars)
 	return (code_p) 0;
 }
 
+STATIC 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 reduce(code,vars)
 	code_p code;
@@ -456,6 +490,7 @@ STATIC 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);
 	}
 }
 

+ 18 - 15
util/ego/sr/sr_xform.c

@@ -93,12 +93,17 @@ STATIC lab_id label(b)
 
 	line_p l;
 
-	assert (b->b_start != (line_p) 0);
-	if (INSTR(b->b_start) == op_lab) return INSTRLAB(b->b_start);
+	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();
-	DLINK(l,b->b_start); /* doubly link them */
+	if (b->b_start) {
+		DLINK(l,b->b_start); /* doubly link them */
+	}
+	b->b_start = l;
 	return INSTRLAB(l);
 }
 
@@ -150,6 +155,9 @@ make_header(lp)
 	 * 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);
@@ -159,23 +167,18 @@ make_header(lp)
 			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);
-	b->b_succ = Lempty_set();
-	b->b_pred = Lempty_set();
 	Ladd(entry,&b->b_succ);
-	if (curproc->p_start == entry) {
-		/* entry was the first block of curproc */
-		curproc->p_start = b;
-	} else {
-		/* find block before entry block */
-		for (c = curproc->p_start; c->b_next != entry; c = c->b_next);
-		c->b_next = b;
-		Ladd(c,&b->b_pred);
-	}
-	b->b_next = entry;
+	/* 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;