[comp.bugs.4bsd] c2 optimiser refers to nonexistent labels

chris@trantor.umd.edu (Chris Torek) (04/18/88)

Index: lib/c2/c21.c 4.3BSD Fix

Description:
	When rearranging a branch to branch past a test whose result
	is already known, the optimiser forgets to update the label
	number in the branch node.  If the test itself is later
	deleted, the label disappears entirely.  Hence given input like

			movl	r9,r8
		L2:
			tstl	r8
			movl	r7,r8
			jbr	L2

	it removes the label L2, replacing it with the internal
	label L2000001, but never generates L2000001s, and winds
	up producing

		movl	r9,r8
		movl	r7,r8
		jbr	L2

	instead of the correct infinite loop

		movl	r9,r8
		L2000000:movl	r7,r8
		jbr	L2000000

Repeat-by:
	See above.

Fix:
	Someone (jfr?) simply forgot one statement: `p->labno = p1->labno'.
	Every other place that alters p->ref also carefully fixes p->labno.
	While I was verifying this, I also added comments, and reformatted
	a few lines.

RCS file: RCS/c21.c,v
retrieving revision 1.2
diff -c2 -r1.2 c21.c
*** /tmp/,RCSt1007542	Mon Apr 18 01:39:55 1988
--- c21.c	Mon Apr 18 01:39:08 1988
***************
*** 1296,1299 ****
--- 1296,1300 ----
  */
  
+ /* find branches to comparisons whose result is already known */
  redunbr(p)
  register struct node *p;
***************
*** 1306,1310 ****
  		return;
  	p1 = nonlab(p1);
! 	if (p1->op==TST) {
  		splitrand(p1);
  		savereg(RT2, "$0", p1->subop);
--- 1307,1311 ----
  		return;
  	p1 = nonlab(p1);
! 	if (p1->op==TST) {	/* test == compare $0 */
  		splitrand(p1);
  		savereg(RT2, "$0", p1->subop);
***************
*** 1314,1317 ****
--- 1315,1319 ----
  		return;
  	if (p1->forw->op==CBR) {
+ 		/* branching to compare+branch ... can we short circuit? */
  		ap1 = findcon(RT1, p1->subop);
  		ap2 = findcon(RT2, p1->subop);
***************
*** 1318,1321 ****
--- 1320,1324 ----
  		p1 = p1->forw;
  		if (compare(p1->subop, ap1, ap2)) {
+ 			/* p1 always branches, so go to p1's dst, not p's */
  			nredunj++;
  			nchange++;
***************
*** 1331,1337 ****
  		}
  	} else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
! 			equtype(ccloc[0],p1->subop)) {
! 		p1=insertl(p1->forw); decref(p->ref); p->ref=p1; 
! 		nrtst++; nchange++;
  	}
  }
--- 1334,1345 ----
  		}
  	} else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
! 	    equtype(ccloc[0],p1->subop)) {
! 		/* branch past the test, since ccodes already set properly */
! 		p1 = insertl(p1->forw);
! 		decref(p->ref);
! 		p->ref = p1;
! 		p->labno = p1->labno;
! 		nrtst++;
! 		nchange++;
  	}
  }
***************
*** 1483,1485 ****
  	if (*--p == '+' && *--p == ')') return(1);
  	return(0);
!   }
--- 1491,1493 ----
  	if (*--p == '+' && *--p == ')') return(1);
  	return(0);
! }
-- 
In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163
Domain: chris@mimsy.umd.edu		Path: ...!uunet!mimsy!chris