⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c12.c

📁 unix v6 的c compiler 很老了
💻 C
字号:
#/* *		C compiler part 2 -- expression optimizer * */#include "c1h.c"optim(atree)struct tnode *atree;{	register op, dope;	int d1, d2;	struct tnode *t;	register struct tnode *tree;	if ((tree=atree)==0)		return(0);	if ((op = tree->op)==0)		return(tree);	if (op==NAME && tree->class==AUTO) {		tree->class = OFFS;		tree->regno = 5;		tree->offset = tree->nloc;	}	dope = opdope[op];	if ((dope&LEAF) != 0)		return(tree);	if ((dope&BINARY) == 0)		return(unoptim(tree));	/* is known to be binary */	if (tree->type==CHAR)		tree->type = INT;	if ((dope&COMMUTE)!=0) {	acomm:	d1 = tree->type;		tree = acommute(tree);		tree->type = d1;		/*		 * PDP-11 special:		 * replace a&b by a NAND ~ b.		 * This will be undone when in		 * truth-value context.		 */		if (tree->op!=AND)			return(tree);		tree->op = NAND;		tree->tr2 = block(1, COMPL, tree->tr2->type, 0, tree->tr2);	}    again:	tree->tr1 = optim(tree->tr1);	tree->tr2 = optim(tree->tr2);	if ((dope&RELAT) != 0) {		if ((d1=degree(tree->tr1)) < (d2=degree(tree->tr2))		 || d1==d2 && tree->tr1->op==NAME && tree->tr2->op!=NAME) {			t = tree->tr1;			tree->tr1 = tree->tr2;			tree->tr2 = t;			tree->op = maprel[op-EQUAL];		}		if (tree->tr1->type==CHAR && tree->tr2->op==CON		 && (dcalc(tree->tr1) <= 12 || tree->tr1->op==STAR)		 && tree->tr2->value <= 127 && tree->tr2->value >= 0)			tree->tr2->type = CHAR;	}	d1 = max(degree(tree->tr1), islong(tree->type));	d2 = max(degree(tree->tr2), 0);	if (tree->tr1->type==LONG && dope&RELAT)		d1 = 10;	switch (op) {	case LTIMES:	case LDIV:	case LMOD:	case LASTIMES:	case LASDIV:	case LASMOD:		tree->degree = 10;		break;	/*	 * PDP-11 special:	 * generate new =&~ operator out of =&	 * by complementing the RHS.	 */	case ASSAND:		op = ASSNAND;		tree->op = op;		tree->tr2 = block(2, COMPL, tree->tr2->type, 0, tree->tr2);		goto again;	case NAND:		if (isconstant(tree->tr2) && tree->tr2->value==0)			return(tree->tr1);		goto def;	case CALL:		tree->degree = 10;		break;	case QUEST:	case COLON:		tree->degree = max(d1, d2);		break;	case MINUS:		if (t = isconstant(tree->tr2)) {			tree->op = PLUS;			if (t->type==DOUBLE)				/* PDP-11 FP representation */				t->value =^ 0100000;			else				t->value = -t->value;			goto acomm;		}		goto def;	case DIVIDE:	case ASDIV:	case ASTIMES:		if (tree->tr2->op==CON && tree->tr2->value==1)			return(tree->tr1);		if (ispow2(tree) == 0) {		case MOD:		case ASMOD:			d1 =+ 2;			d2 =+ 2;		}		if (tree->type==LONG)			return(hardlongs(tree));		goto constant;	case LSHIFT:	case RSHIFT:	case ASRSH:	case ASLSH:		if (tree->tr2->op==CON && tree->tr2->value==0)			return(tree->tr1);		/*		 * PDP-11 special: turn right shifts into negative		 * left shifts		 */		if (op==LSHIFT||op==ASLSH)			goto constant;		if (tree->tr2->op==CON && tree->tr2->value==1)			goto constant;		op =+ (LSHIFT-RSHIFT);		tree->op = op;		tree->tr2 = block(1, NEG, tree->type, 0, tree->tr2);		goto again;	constant:		if (tree->tr1->op==CON && tree->tr2->op==CON) {			const(op, &tree->tr1->value, tree->tr2->value);			return(tree->tr1);		}	def:	default:		tree->degree = d1==d2? d1+islong(tree->type): max(d1, d2);		break;	}	return(tree);}unoptim(atree)struct tnode *atree;{	register struct tnode *subtre, *tree;	register int *p;	double static fv;	struct { int integer; };	if ((tree=atree)==0)		return(0);	if (tree->op==CBRANCH) {		tree->btree = optim(tree->btree);		return(tree);	}	subtre = tree->tr1 = optim(tree->tr1);	switch (tree->op) {	case FSEL:		tree->tr1 = block(2, RSHIFT, INT, 0, subtre,		    block(1, CON, INT, 0, tree->bitoffs));		tree->op = AND;		tree->type = INT;		tree->tr2 = block(1, CON, INT, 0, (1<<tree->flen)-1);		return(optim(tree));	case AMPER:		if (subtre->op==STAR)			return(subtre->tr1);		if (subtre->op==NAME && subtre->class == OFFS) {			p = block(2, PLUS, tree->type, 1, subtre, tree);			subtre->type = tree->type;			tree->op = CON;			tree->type = INT;			tree->degree = 0;			tree->value = subtre->offset;			subtre->class = REG;			subtre->nloc = subtre->regno;			subtre->offset = 0;			return(p);		}		break;	case STAR:		if (subtre->op==AMPER)			return(subtre->tr1);		if (subtre->op==NAME && subtre->class==REG) {			subtre->type = tree->type;			subtre->class = OFFS;			subtre->regno = subtre->nloc;			return(subtre);		}		p = subtre->tr1;		if ((subtre->op==INCAFT||subtre->op==DECBEF)&&tree->type!=LONG		 && p->op==NAME && p->class==REG && p->type==subtre->type) {			p->type = tree->type;			p->op = subtre->op==INCAFT? AUTOI: AUTOD;			return(p);		}		if (subtre->op==PLUS && p->op==NAME && p->class==REG) {			if (subtre->tr2->op==CON) {				p->offset =+ subtre->tr2->value;				p->class = OFFS;				p->type = tree->type;				p->regno = p->nloc;				return(p);			}			if (subtre->tr2->op==AMPER) {				subtre = subtre->tr2->tr1;				subtre->class =+ XOFFS-EXTERN;				subtre->regno = p->nloc;				subtre->type = tree->type;				return(subtre);			}		}		break;	case EXCLA:		if ((opdope[subtre->op]&RELAT)==0)			break;		tree = subtre;		tree->op = notrel[tree->op-EQUAL];		break;	case NEG:	case COMPL:		if (tree->type==CHAR)			tree->type = INT;		if (tree->op == subtre->op)			return(subtre->tr1);		if (subtre->op==ITOL) {			subtre->op = tree->op;			subtre->type = INT;			tree->op = ITOL;		}	}	if (subtre->op == CON) switch(tree->op) {	case NEG:		subtre->value = -subtre->value;		return(subtre);	case COMPL:		subtre->value = ~subtre->value;		return(subtre);	case ITOF:		fv = subtre->value;		p = &fv;		p++;		if (*p++==0 && *p++==0 && *p++==0) {			subtre->type = DOUBLE;			subtre->value = fv.integer;			subtre->op = SFCON;			return(subtre);		}		break;	}	tree->degree = max(islong(tree->type), degree(subtre));	return(tree);}struct acl {	int nextl;	int nextn;	struct tnode *nlist[20];	struct tnode *llist[21];};acommute(atree){	struct acl acl;	int d, i, op, flt;	register struct tnode *t1, **t2, *tree;	struct tnode *t;	acl.nextl = 0;	acl.nextn = 0;	tree = atree;	op = tree->op;	flt = isfloat(tree);	insert(op, tree, &acl);	acl.nextl--;	t2 = &acl.llist[acl.nextl];	if (!flt) {		/* put constants together */		for (i=acl.nextl;i>0&&t2[0]->op==CON&&t2[-1]->op==CON;i--) {			acl.nextl--;			t2--;			const(op, &t2[0]->value, t2[1]->value);		}	}	if (op==PLUS || op==OR) {		/* toss out "+0" */		if (acl.nextl>0 && (t1 = isconstant(*t2)) && t1->value==0) {			acl.nextl--;			t2--;		}		if (acl.nextl <= 0)			return(*t2);		/* subsume constant in "&x+c" */		if (op==PLUS && t2[0]->op==CON && t2[-1]->op==AMPER) {			t2--;			t2[0]->tr1->offset =+ t2[1]->value;			acl.nextl--;		}	} else if (op==TIMES || op==AND) {		t1 = acl.llist[acl.nextl];		if (t1->op==CON) {			if (t1->value==0)				return(t1);			if (op==TIMES && t1->value==1 && acl.nextl>0)				if (--acl.nextl <= 0)					return(acl.llist[0]);		}	}	if (op==PLUS && !flt)		distrib(&acl);	tree = *(t2 = &acl.llist[0]);	d = max(degree(tree), islong(tree->type));	if (op==TIMES && !flt)		d++;	for (i=0; i<acl.nextl; i++) {		t1 = acl.nlist[i];		t1->tr2 = t = *++t2;		t1->degree = d = d==degree(t)? d+islong(t1->type): max(d, degree(t));		t1->tr1 = tree;		tree = t1;		if (tree->type==LONG) {			if (tree->op==TIMES)				tree = hardlongs(tree);			else if (tree->op==PLUS && (t = isconstant(tree->tr1))			       && t->value < 0) {				tree->op = MINUS;				t->value = - t->value;				t = tree->tr1;				tree->tr1 = tree->tr2;				tree->tr2 = t;			}		}	}	if (tree->op==TIMES && ispow2(tree))		tree->degree = max(degree(tree->tr1), islong(tree->type));	return(tree);}distrib(list)struct acl *list;{/* * Find a list member of the form c1c2*x such * that c1c2 divides no other such constant, is divided by * at least one other (say in the form c1*y), and which has * fewest divisors. Reduce this pair to c1*(y+c2*x) * and iterate until no reductions occur. */	register struct tnode **p1, **p2;	struct tnode *t;	int ndmaj, ndmin;	struct tnode **dividend, **divisor;	struct tnode **maxnod, **mindiv;    loop:	maxnod = &list->llist[list->nextl];	ndmaj = 1000;	dividend = 0;	for (p1 = list->llist; p1 <= maxnod; p1++) {		if ((*p1)->op!=TIMES || (*p1)->tr2->op!=CON)			continue;		ndmin = 0;		for (p2 = list->llist; p2 <= maxnod; p2++) {			if (p1==p2 || (*p2)->op!=TIMES || (*p2)->tr2->op!=CON)				continue;			if ((*p1)->tr2->value == (*p2)->tr2->value) {				(*p2)->tr2 = (*p1)->tr1;				(*p2)->op = PLUS;				(*p1)->tr1 = (*p2);				*p1 = optim(*p1);				squash(p2, maxnod);				list->nextl--;				goto loop;			}			if (((*p2)->tr2->value % (*p1)->tr2->value) == 0)				goto contmaj;			if (((*p1)->tr2->value % (*p2)->tr2->value) == 0) {				ndmin++;				mindiv = p2;			}		}		if (ndmin > 0 && ndmin < ndmaj) {			ndmaj = ndmin;			dividend = p1;			divisor = mindiv;		}    contmaj:;	}	if (dividend==0)		return;	t = list->nlist[--list->nextn];	p1 = dividend;	p2 = divisor;	t->op = PLUS;	t->type = (*p1)->type;	t->tr1 = (*p1);	t->tr2 = (*p2)->tr1;	(*p1)->tr2->value =/ (*p2)->tr2->value;	(*p2)->tr1 = t;	t = optim(*p2);	if (p1 < p2) {		*p1 = t;		squash(p2, maxnod);	} else {		*p2 = t;		squash(p1, maxnod);	}	list->nextl--;	goto loop;}squash(p, maxp)struct tnode **p, **maxp;{	register struct tnode **np;	for (np = p; np < maxp; np++)		*np = *(np+1);}const(op, vp, av)int *vp;{	register int v;	v = av;	switch (op) {	case PLUS:		*vp =+ v;		return;	case TIMES:		*vp =* v;		return;	case AND:		*vp =& v;		return;	case OR:		*vp =| v;		return;	case EXOR:		*vp =^ v;		return;	case DIVIDE:	case MOD:		if (v==0)			error("Divide check");		else			if (op==DIVIDE)				*vp =/ v;			else				*vp =% v;		return;	case RSHIFT:		*vp =>> v;		return;	case LSHIFT:		*vp =<< v;		return;	case NAND:		*vp =& ~ v;		return;	}	error("C error: const");}insert(op, atree, alist)struct acl *alist;{	register d;	register struct acl *list;	register struct tnode *tree;	int d1, i;	struct tnode *t;	tree = atree;	list = alist;	if (tree->op == op) {	ins:	list->nlist[list->nextn++] = tree;		insert(op, tree->tr1, list);		insert(op, tree->tr2, list);		return;	}	tree = optim(tree);	if (tree->op == op)		goto ins;	if (!isfloat(tree)) {		/* c1*(x+c2) -> c1*x+c1*c2 */		if ((tree->op==TIMES||tree->op==LSHIFT)		  && tree->tr2->op==CON && tree->tr2->value>0		  && tree->tr1->op==PLUS && tree->tr1->tr2->op==CON) {			d = tree->tr2->value;			if (tree->op==TIMES)				tree->tr2->value =* tree->tr1->tr2->value;			else				tree->tr2->value = tree->tr1->tr2->value << d;			tree->tr1->tr2->value = d;			tree->tr1->op = tree->op;			tree->op = PLUS;			if (op==PLUS)				goto ins;		}	}	d = degree(tree);	for (i=0; i<list->nextl; i++) {		if ((d1=degree(list->llist[i]))<d) {			t = list->llist[i];			list->llist[i] = tree;			tree = t;			d = d1;		}	}	list->llist[list->nextl++] = tree;}block(an, args){	register int *p;	int *oldp;	register *argp, n;	oldp = p = spacep;	n = an+3;	argp = &args;	do		*p++ = *argp++;	while (--n);	if (p >= &treespace[ossiz]) {		error("Exp. ov. pass 2");		exit(1);	}	spacep = p;	return(oldp);}islong(t){	if (t==LONG)		return(2);	return(1);}isconstant(at)struct tnode *at;{	register struct tnode *t;	t = at;	if (t->op==CON || t->op==SFCON)		return(t);	if (t->op==ITOL && t->tr1->op==CON)		return(t->tr1);	return(0);}hardlongs(at)struct tnode *at;{	register struct tnode *t;	t = at;	switch(t->op) {	case TIMES:	case DIVIDE:	case MOD:		t->op =+ LTIMES-TIMES;		break;	case ASTIMES:	case ASDIV:	case ASMOD:		t->op =+ LASTIMES-ASTIMES;		t->tr1 = block(1, AMPER, LONG+PTR, 0, t->tr1);		break;	default:		return(t);	}	return(optim(t));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -