optim.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 845 行 · 第 1/2 页

C
845
字号
#ifndef lintstatic char	*sccsid = " @(#)optim.c	1.3	(ULTRIX)	1/15/86";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//**************************************************************************			Modification History**	David Metsky		14-Jan-86** 001	Replaced old version with BSD 4.3 version as part of upgrade.**	Based on:	optim.c		5.2		6/9/85**************************************************************************//* * optim.c * * Miscellaneous optimizer routines, f77 compiler pass 1. * * UCSD Chemistry modification history: * * $Log:	optim.c,v $ * Revision 2.12  85/06/08  22:57:01  donn * Prevent core dumps -- bug in optinsert was causing lastslot to be wrong * when a slot was inserted at the end of the buffer. *  * Revision 2.11  85/03/18  08:05:05  donn * Prevent warnings about implicit conversions. *  * Revision 2.10  85/02/12  20:13:00  donn * Resurrected the hack in 2.6.1.1 to avoid creating a temporary when * there is a concatenation on the rhs of an assignment, and threw out * all the code dealing with starcat().  It seems that we can't use a * temporary because the lhs as well as the rhs may have nonconstant length. *  * Revision 2.9  85/01/18  00:53:52  donn * Missed a call to free() in the last change... *  * Revision 2.8  85/01/18  00:50:03  donn * Fixed goof made when modifying buffmnmx() to explicitly call expand(). *  * Revision 2.7  85/01/15  18:47:35  donn * Changes to allow character*(*) variables to appear in concatenations in * the rhs of an assignment statement. *  * Revision 2.6  84/12/16  21:46:27  donn * Fixed bug that prevented concatenations from being run together.  Changed * buffpower() to not touch exponents greater than 64 -- let putpower do them. *  * Revision 2.5  84/10/29  08:41:45  donn * Added hack to flushopt() to prevent the compiler from trying to generate * intermediate code after an error. *  * Revision 2.4  84/08/07  21:28:00  donn * Removed call to p2flush() in putopt() -- this allows us to make better use * of the buffering on the intermediate code file. *  * Revision 2.3  84/08/01  16:06:24  donn * Forced expand() to expand subscripts. *  * Revision 2.2  84/07/19  20:21:55  donn * Decided I liked the expression tree algorithm after all.  The algorithm * which repeatedly squares temporaries is now checked in as rev. 2.1. *  * Revision 1.3.1.1  84/07/10  14:18:18  donn * I'm taking this branch off the trunk -- it works but it's not as good as * the old version would be if it worked right. *  * Revision 1.5  84/07/09  22:28:50  donn * Added fix to buffpower() to prevent it chasing after huge exponents. *  * Revision 1.4  84/07/09  20:13:59  donn * Replaced buffpower() routine with a new one that generates trees which can * be handled by CSE later on.   *  * Revision 1.3  84/05/04  21:02:07  donn * Added fix for a bug in buffpower() that caused func(x)**2 to turn into * func(x) * func(x).  This bug had already been fixed in putpower()... *  * Revision 1.2  84/03/23  22:47:21  donn * The subroutine argument temporary fixes from Bob Corbett didn't take into * account the fact that the code generator collects all the assignments to * temporaries at the start of a statement -- hence the temporaries need to * be initialized once per statement instead of once per call. *  */#include "defs.h"#include "optim.h"/* *		Information buffered for each slot type * *  slot type	       expptr	       integer		pointer * *  IFN			expr		label		- *  GOTO		-		label		- *  LABEL		-		label		- *  EQ			expr		-		- *  CALL		expr		-		- *  CMGOTO		expr		num		labellist* *  STOP		expr		-		- *  DOHEAD		[1]		-		ctlframe* *  ENDDO		[1]		-		ctlframe* *  ARIF		expr		-		labellist* *  RETURN		expr		label		- *  ASGOTO		expr		-		labellist* *  PAUSE		expr		-		- *  ASSIGN		expr		label		- *  SKIOIFN		expr		label		- *  SKFRTEMP		expr		-		- * *     Note [1]:  the nullslot field is a pointer to a fake slot which is *     at the end of the slots which may be replaced by this slot.  In *     other words, it looks like this: *		DOHEAD slot *		slot   \ *		slot    > ordinary IF, GOTO, LABEL slots which implement the DO *		slot   / *		NULL slot */expptr expand();Slotp	firstslot = NULL;Slotp	lastslot = NULL;int	numslots = 0;/* *  turns off optimization option */optoff(){flushopt();optimflag = 0;}/* *  initializes the code buffer for optimization */setopt(){register Slotp sp;for (sp = firstslot; sp; sp = sp->next)	free ( (charptr) sp);firstslot = lastslot = NULL;numslots = 0;}/* *  flushes the code buffer */LOCAL int alreadycalled = 0;flushopt(){register Slotp sp;int savelineno;if (alreadycalled) return;	/* to prevent recursive call during errors */alreadycalled = 1;if (debugflag[1])	showbuffer ();frtempbuff ();savelineno = lineno;for (sp = firstslot; sp; sp = sp->next)	{	if (nerr == 0)		putopt (sp);	else		frexpr (sp->expr);        if(sp->ctlinfo) free ( (charptr) sp->ctlinfo);        free ( (charptr) sp);        numslots--;	}firstslot = lastslot = NULL;numslots = 0;clearbb();lineno = savelineno;alreadycalled = 0;}/* *  puts out code for the given slot (from the code buffer) */LOCAL putopt (sp)register Slotp sp;{	lineno = sp->lineno;	switch (sp->type) {	    case SKNULL:		break;	    case SKIFN:	    case SKIOIFN:		putif(sp->expr, sp->label);		break;	    case SKGOTO:		putgoto(sp->label);		break;	    case SKCMGOTO:		putcmgo(sp->expr, sp->label, sp->ctlinfo);		break;	    case SKCALL:		putexpr(sp->expr);		break;	    case SKSTOP:		putexpr (call1 (TYSUBR, "s_stop", sp->expr));		break;	    case SKPAUSE:		putexpr (call1 (TYSUBR, "s_paus", sp->expr));		break;	    case SKASSIGN:		puteq (sp->expr,		    intrconv(sp->expr->headblock.vtype, mkaddcon(sp->label)));		break;	    case SKDOHEAD:	    case SKENDDO:		break;	    case SKEQ:		putexpr(sp->expr);		break;	    case SKARIF:#define LM   ((struct Labelblock * *)sp->ctlinfo)[0]->labelno #define LZ   ((struct Labelblock * *)sp->ctlinfo)[1]->labelno #define LP   ((struct Labelblock * *)sp->ctlinfo)[2]->labelno        		prarif(sp->expr, LM, LZ, LP);		break;	    case SKASGOTO:		putbranch((Addrp) sp->expr);		break;	    case SKLABEL:		putlabel(sp->label);		break;	    case SKRETURN:		if (sp->expr)			{			putforce(TYINT, sp->expr);			putgoto(sp->label);			}		else			putgoto(sp->label);		break;	    case SKFRTEMP:		templist = mkchain (sp->expr,templist);		break;	    default:		badthing("SKtype", "putopt", sp->type);		break;	}	/*	 * Recycle argument temporaries here.  This must get done on a	 *	statement-by-statement basis because the code generator	 *	makes side effects happen at the start of a statement.	 */	argtemplist = hookup(argtemplist, activearglist);	activearglist = CHNULL;}/* *  copies one element of the control stack */LOCAL struct Ctlframe *cpframe(p)register char *p;{static int size =  sizeof (struct Ctlframe);register int n;register char *q;struct Ctlframe *q0;q0 = ALLOC(Ctlframe);q = (char *) q0;n = size;while(n-- > 0)	*q++ = *p++;return( q0);}/* *  copies an array of labelblock pointers */LOCAL struct Labelblock **cplabarr(n,arr)struct Labelblock *arr[];int n;{struct Labelblock **newarr;register char *in, *out;register int i,j;newarr = (struct Labelblock **) ckalloc (n * sizeof (char *));for (i = 0; i < n; i++)	{	newarr[i] = ALLOC (Labelblock);	out = (char *) newarr[i];	in = (char *) arr[i];	j = sizeof (struct Labelblock);	while (j-- > 0)		*out++ = *in++;	}return (newarr);}/* *  creates a new slot in the code buffer */LOCAL Slotp newslot(){register Slotp sp;++numslots;sp = ALLOC( slt );sp->next = NULL ;if (lastslot)	{	sp->prev = lastslot;	lastslot = lastslot->next = sp;	}else	{	firstslot = lastslot = sp;	sp->prev = NULL;	}sp->lineno = lineno;return (sp);}/* *  removes (but not deletes) the specified slot from the code buffer */removeslot (sl)Slotp	sl;{if (sl->next)	sl->next->prev = sl->prev;else	lastslot = sl->prev;if (sl->prev)	sl->prev->next = sl->next;else	firstslot = sl->next;sl->next = sl->prev = NULL;--numslots;}/* *  inserts slot s1 before existing slot s2 in the code buffer; *  appends to end of list if s2 is NULL. */insertslot (s1,s2)Slotp	s1,s2;{if (s2)	{	if (s2->prev)

⌨️ 快捷键说明

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