File:  [Research Unix] / researchv9 / jerq / sgs / comp / optdir.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:22:00 2018 UTC (8 years, 3 months ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

/*	@(#) optdir.c: 1.3 6/26/84	*/
/* optdir.c
**
**	Optimization Director
**
**	The routines in this file monitor the information in
**	the machine independent portion of the compiler
**	and write comments in the assembly output informing
**      the machine dependent portion of the optimizer
**	that certain optimizations are possible.
**
*/

# include "mfile1.h"
# include "storclass.h"

extern FILE *outfile;
extern int xdebug;

#ifdef IMPREGAL

/* Register allocation
** Routines ra* direct the 'register allocation' optimization.
** The optimization attempts to assign selected quantities,
** i.e.,
** 	local variables that
**		- are simple (are not related to arrays, structures, 
**		  or unions)
**		- do not have their address taken explicitly with '&'
**	incoming arguments that
**		- are simple
**		- are in a procedure where no argument has its address taken
**		  expilitly with an '&'
** to available scratch or user registers.
**  
** An estimator is computed for each qualifying quantity by the formulas:
**
**   	local variables
**		RAPOEST * (FORWEIGHT or WHWEIGHT)**(loop depth)
**		-----------------------------------------------
**		    (BRWEIGHT)**(branch depth)
**
**	arguments
**		RAPOEST * (FORWEIGHT or WHWEIGHT)**(loop depth)
**		----------------------------------------------- - 9
**		    (BRWEIGHT)**(branch depth)
**	
** where '**' denotes exponentiation.
** The quantities are ordered by decreasing estimator and up to HIGHSZ
** are printed in the form
**	#REGAL	<estimator> <storage class> <ident> <length>
**
*/

#define RAPAYOFF	3	/* operand payoff estimator in cycles */
#define FORWEIGHT	10	/* weight to emphasize code in 'for' loops */
#define WHWEIGHT	5	/* weight to emphasize code in 'while' and
				** 'do-while' loops */
#define BRWEIGHT	10	/* weight to de-emphasize code in branches */
#define HIGHSZ		20	/* size of table for sorting estimators */

int	estimtab[SYMTSZ];	/* payoff estimator for each variable, 
				** set to -1 if address of variable is taken */
NODE 	*lastp;			/* pointer to last NAME node processed */
int	lastid;			/* index to symbol table for last NAME node */
int	dblflg = 0;		/* flag indicating presence of doubles */

struct hinode { /* ordered table of variables with highest estimators */
	int 	hiestim;		/* estimator of cycle payoff */
	int	hiscl;			/* scl of quant to put in reg */
	int	hiident;		/* identification of quantity:
					 * 	local		offset 
					 *	argument	offset*/
	int	hilen;			/* length in bytes of quantity */
} high[HIGHSZ];

/* table status */

#define	EMPTY	-2
#define	ADDRSD	-1

void
rainit()

{
	register int *p;
	struct hinode *hp;

	/* initialize estimator table */
	for( p = estimtab; p < estimtab + SYMTSZ; p++ ) *p = EMPTY;

	/* initialize hi table */
	for( hp = high; hp < high + HIGHSZ; hp++ ) hp->hiestim = EMPTY;
}

void
radbl()
{
	dblflg = 1;
#ifndef NODBG
	if (xdebug > 1 && dblflg)
		fprintf(outfile, "radbl() sets dblflg\n");
#endif
}

void
raname(p)
NODE *p;

{
	int type, class;
	int old;

	/* check for simpleness */
	type = stab[idname].stype;
	if( !( (CHAR <= type && type <= LONG) ||
		(UCHAR <= type && type <= ULONG) ||
		(ULONG < type) ) ) return;
	if( ISFTN(type) || ISARY(type) ) return;
	if( stab[idname].slevel > 2 ) return;

	/* compute per reference payoff */
	old = estimtab[idname];
#ifndef NODBG
	if (xdebug)
	{
		fprintf(outfile,
			"raname(0x%lx)\tstab[%d] `%s' sclass %s cur.est %d\n",
			p, idname, stab[idname].sname,
			scnames(stab[idname].sclass), old);
	}
#endif
	/*
	* Don't count putting the PARAM into the REGISTER
	* for REGISTER PARAM's.
	*/
	if( blevel >= 2 && estimtab[idname] != ADDRSD ) 
		switch( stab[idname].sclass ) {
		int i, weight;

		case PARAM:
		case AUTO:
			if( estimtab[idname] == EMPTY ) estimtab[idname] = 0;
			weight = RAPAYOFF;
			for( i = 1; i <= fordepth; i++ ) {
				if( weight >= 10000 ) break;
				weight *= FORWEIGHT;
			}
			for( i = 1; i <= whdepth; i++ ) {
				if( weight >= 10000 ) break;
				weight *= WHWEIGHT;
			}
			for( i = 1; i <= brdepth; i++ ) {
				weight /= BRWEIGHT;
			}
			estimtab[idname] += weight;
		}
	lastid = idname;
	lastp = p;
#ifndef NODBG
	if (xdebug > 1)
	{
		fprintf(outfile,
			"`%s' type=%d class=%d level=%d flags=%x offset=%d\n",
			stab[idname].sname, stab[idname].stype,
			stab[idname].sclass, stab[idname].slevel,
			stab[idname].sflags, stab[idname].offset);
		fprintf(outfile, "\tfordepth=%d whdepth=%d brdepth=%d change=%d estimator=%d\n",
		fordepth, whdepth, brdepth, estimtab[idname]-old,
		estimtab[idname]);
	}
#endif
}

void
raua(p)
NODE *p;

{
	/* mark variables with address taken */
	if( p == lastp )  estimtab[lastid] = ADDRSD;
}

void
raftn()

{

	register int i, j, k, ei;
	struct hinode *hp;
	struct symtab *sp;

	/* check for end of function */
	if( blevel != 2 ) return;

	/* check for doubles */
	if( dblflg == 0 ) fprintf( outfile, "#REGAL\t%d\tNODBL\n", 0 );
	else return;

	/* check for args with address taken */
	for( i = 0; i < SYMTSZ; i++ ) {
		if( stab[i].sclass == PARAM && estimtab[i] == ADDRSD ) {
			for( j = 0; j < SYMTSZ; j++ ) 
				if( stab[j].sclass == PARAM )
					estimtab[j] = ADDRSD;
			break;
		}
	}

	/* insert entries from symbol table in decreasing order */
	for( i = 0; i < SYMTSZ; i++ ) {
		ei = estimtab[i];
		if( ei < 0 ) continue;
		sp = &stab[i];

		/* include cost for arg */
		if( sp->sclass == PARAM ) ei -= 9;
		if( ei < 0 ) continue;

		/* insertion sort */
		for( j = 0; j < HIGHSZ; j++ ) {
			if( ei > high[j].hiestim ) {
				for( k = 8; k >= j; k-- ) {
					hp = &high[k];
					(hp+1)->hiestim = hp->hiestim;
					(hp+1)->hiscl = hp->hiscl;
					(hp+1)->hiident = hp->hiident;
					(hp+1)->hilen = hp->hilen;
				}
				hp = &high[j];
				hp->hiestim = ei;
				hp->hiscl = sp->sclass;
				hp->hiident = sp->offset;
				switch( sp->stype ) {
				case CHAR:
				case UCHAR:
					hp->hilen = 1; break;
				case SHORT:
				case USHORT:
					hp->hilen = 2; break;
				default:
					hp->hilen = 4; break;
				}
				break;
			}
		}
	}

	/* print entries */
	for( i = 0; i < HIGHSZ; i++ ) {
		hp = &high[i];
		if( hp->hiestim == EMPTY ) break;
		fprintf( outfile, "#REGAL\t%d", hp->hiestim );
		switch( hp->hiscl ) {
		case AUTO:
			fprintf( outfile, "\tAUTO \t%d(%%fp)", 
				hp->hiident/SZCHAR );
			break;
		case PARAM:
			fprintf( outfile, "\tPARAM\t%d(%%ap)",
				hp->hiident/SZCHAR );
			break;
		}
		fprintf( outfile, "\t%d\n", hp->hilen );
	}
}
#endif /* IMPREGAL */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.