98 lines · 1.6 KB · Brainfuck
RawDownload
## "Unify" results that are produced in one basic block and consumed# in another.  I.e., ensure that producers and consumers access results# through consistent fp offsets.# pushsucc(bb: ref BB){	i: int; 	for(i = 0; i < bb.nsucc; i++) {		if(bb.succ[i].state == BB_POSTSIM)			bbput(bb.succ[i]);	}} pass1(s: ref StkSnap): int{	j: ref Jinst;	i: int;	fpoff: int; 	fpoff = -1;	for(i = 0; i < s.npc; i++) {		j = code.j[s.pc[i]];		if((isload(j) && j.movsrc.mode != byte Anone)		|| (!isload(j) && j.dst.offset != -1)) {			if(fpoff == -1)				fpoff = j.dst.offset;			else if(fpoff != j.dst.offset)				fatal("pass1: can't");		}	}	if(fpoff == -1)		fpoff = getreg(j2dtype(s.jtype));	return fpoff;} pass2(s: ref StkSnap, fpoff: int){	j: ref Jinst;	i: int; 	for(i = 0; i < s.npc; i++) {		j = code.j[s.pc[i]];		if(isload(j) && j.movsrc.mode == byte Anone) {			*j.movsrc = *j.dst;			j.dst.mode = byte Afp;		}		j.dst.offset = fpoff;	}} unifybb(bb: ref BB){	s: ref StkSnap;	n, m: int; 	if(bb.state == BB_POSTUNIFY)		fatal("unifybb: BB_POSTUNIFY"); 	if(bb.entrystk == nil) {		pushsucc(bb);		return;	} 	clearreg();	reservereg(bb.entrystk, bb.entrysz);	reservereg(bb.exitstk, bb.exitsz); 	for(n = 0; n < bb.entrysz; n++) {		s = bb.entrystk[n];		for(m = 0; m < s.npc; m++) {			reservereg(code.j[s.pc[m]].bb.entrystk,				code.j[s.pc[m]].bb.entrysz);		}	} 	for(n = 0; n < bb.entrysz; n++) {		s = bb.entrystk[n];		if(s.npc == 1)			dstreg(code.j[s.pc[0]].dst, j2dtype(s.jtype));		else			pass2(s, pass1(s));	} 	bb.state = BB_POSTUNIFY;	pushsucc(bb);} unify(){	bb: ref BB; 	bbinit();	while((bb = bbget()) != nil)		unifybb(bb);}