166 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Header$ */
 | 
						|
/*
 | 
						|
 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
						|
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
						|
 */
 | 
						|
/* I N T E R N A L   D A T A S T R U C T U R E S   O F 
 | 
						|
 *
 | 
						|
 *           I N L I N E   S U B S T I T U T I O N   
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
typedef struct actual	*actual_p;
 | 
						|
typedef struct calcnt	*calcnt_p;
 | 
						|
typedef short call_id;
 | 
						|
 | 
						|
struct call {
 | 
						|
	proc_p	 cl_caller;	/* calling procedure			*/
 | 
						|
	call_id	 cl_id;		/* uniquely denotes a CAL instruction	*/
 | 
						|
	proc_p	 cl_proc;	/* the called procedure			*/
 | 
						|
	byte	 cl_looplevel;	/* loop nesting level of the CAL	*/
 | 
						|
	bool	 cl_flags;	/* flag bits				*/
 | 
						|
	short	 cl_ratio;	/* indicates 'speed gain / size lost'	*/
 | 
						|
	call_p	 cl_cdr;	/* link to next call			*/
 | 
						|
	call_p	 cl_car;	/* link to nested calls			*/
 | 
						|
	actual_p cl_actuals;	/* actual parameter expr. trees		*/
 | 
						|
};
 | 
						|
 | 
						|
#define CLF_INLPARS 017		/* min(15,nr. of inline parameters) */
 | 
						|
#define CLF_SELECTED	020	/* is call selected for expansion? */
 | 
						|
#define CLF_EVER_EXPANDED 040	/* ever expanded? e.g. in a nested call.  */
 | 
						|
#define CLF_FIRM	0100 	/* indicates if the call takes place in a
 | 
						|
				 * firm block of a loop (i.e. one that
 | 
						|
				 * is always executed, except
 | 
						|
				 * -perhaps- at the last iteration).
 | 
						|
				 * Used for heuristics only.
 | 
						|
				 */
 | 
						|
 | 
						|
struct actual {
 | 
						|
	line_p	 ac_exp;	/* copy of EM text			*/
 | 
						|
				/* 0 for actuals that are not inline	*/
 | 
						|
	offset	 ac_size;	/* number of bytes of parameter		*/
 | 
						|
	bool	 ac_inl;	/* TRUE if it may be expanded in line	*/
 | 
						|
	actual_p ac_next;	/* link					*/
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
struct formal {
 | 
						|
	offset	 f_offset;	/* offsetin bytes			*/
 | 
						|
	byte	 f_flags;	/* flags FF_BAD etc.			*/
 | 
						|
	byte	 f_type;	/* SINGLE, DOUBLE,POINTER,UNKNOWN	*/
 | 
						|
	formal_p f_next;	/* link					*/
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/* flags of formal: */
 | 
						|
 | 
						|
#define FF_BAD		01
 | 
						|
#define FF_REG		02
 | 
						|
#define	FF_ONCEUSED	04
 | 
						|
#define FF_OFTENUSED	06
 | 
						|
#define USEMASK		014
 | 
						|
 | 
						|
/* types of formals: */
 | 
						|
 | 
						|
#define SINGLE		1
 | 
						|
#define DOUBLE		2
 | 
						|
#define POINTER		3
 | 
						|
#define UNKNOWN		4
 | 
						|
 | 
						|
/* 'call-count' information keeps track of the number
 | 
						|
 * of times one procedure calls another. Conceptually,
 | 
						|
 * it may be regarded as a two dimensional array, where
 | 
						|
 * calcnt[p,q] is the number of times p calls q. As this
 | 
						|
 * matrix would be very dense, we use a more efficient
 | 
						|
 * list representation. Every procedure has a list
 | 
						|
 * of calcnt structs.
 | 
						|
 */
 | 
						|
 | 
						|
struct calcnt {
 | 
						|
	proc_p	cc_proc;	/* the called procedure */
 | 
						|
	short	cc_count;	/* # times proc. is called in the
 | 
						|
				 * original text of the caller.
 | 
						|
				 */
 | 
						|
	calcnt_p cc_next;	/* link			*/
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
extern int calnr;
 | 
						|
extern calcnt_p cchead;		/* calcnt info of current proc */
 | 
						|
 | 
						|
/* Macro's for extended data structures */
 | 
						|
 | 
						|
#define P_CALS		p_extend->px_il.p_cals
 | 
						|
#define P_SIZE		p_extend->px_il.p_size
 | 
						|
#define P_FORMALS	p_extend->px_il.p_formals
 | 
						|
#define P_NRCALLED	p_extend->px_il.p_nrcalled
 | 
						|
#define P_CCADDR	p_extend->px_il.p_ccaddr
 | 
						|
#define P_LADDR		p_extend->px_il.p_laddr
 | 
						|
#define P_ORGLABELS	p_extend->px_il.p_orglabels
 | 
						|
#define P_ORGLOCALS	p_extend->px_il.p_orglocals
 | 
						|
 | 
						|
/* flags2: */
 | 
						|
 | 
						|
#define PF_UNSUITABLE	01
 | 
						|
#define PF_NO_INLPARS	02
 | 
						|
#define PF_FALLTHROUGH	04
 | 
						|
#define PF_DISPENSABLE	010
 | 
						|
#define PF_CHANGED	020
 | 
						|
 | 
						|
 | 
						|
/* kinds of usages: */
 | 
						|
 | 
						|
#define USE	0
 | 
						|
#define CHANGE	1
 | 
						|
#define ADDRESS 2
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/* We do not expand calls if:
 | 
						|
 * - the called procedure has to many local variables
 | 
						|
 * - the calling procedure is already very large
 | 
						|
 * - the called procedure is to large.
 | 
						|
 */
 | 
						|
 | 
						|
#define MANY_LOCALS(p)	(p->p_localbytes > LOCAL_THRESHOLD)
 | 
						|
#define LOCAL_THRESHOLD		200
 | 
						|
#define BIG_CALLER(p)	(p->P_SIZE > CALLER_THRESHOLD)
 | 
						|
#define CALLER_THRESHOLD	500
 | 
						|
#define BIG_PROC(p)	(p->P_SIZE > CALLEE_THRESHOLD)
 | 
						|
#define CALLEE_THRESHOLD	100
 | 
						|
 | 
						|
#define FALLTHROUGH(p)	(p->p_flags2 & PF_FALLTHROUGH)
 | 
						|
#define DISPENSABLE(p)	p->p_flags2 |= PF_DISPENSABLE
 | 
						|
#define IS_DISPENSABLE(p) (p->p_flags2 & PF_DISPENSABLE)
 | 
						|
#define SELECTED(c)	c->cl_flags |= CLF_SELECTED
 | 
						|
#define IS_SELECTED(c)	(c->cl_flags & CLF_SELECTED)
 | 
						|
#define EVER_EXPANDED(c) c->cl_flags |= CLF_EVER_EXPANDED
 | 
						|
#define IS_EVER_EXPANDED(c) (c->cl_flags & CLF_EVER_EXPANDED)
 | 
						|
#define UNSUITABLE(p)	p->p_flags2 |= PF_UNSUITABLE
 | 
						|
#define SUITABLE(p)	(!(p->p_flags2&PF_UNSUITABLE))
 | 
						|
#define INLINE_PARS(p)	(!(p->p_flags2&PF_NO_INLPARS))
 | 
						|
#define PARAMS_UNKNOWN(p) (p->p_nrformals == UNKNOWN_SIZE)
 | 
						|
 | 
						|
extern int Ssubst;
 | 
						|
#ifdef VERBOSE
 | 
						|
extern int Senv,Srecursive,Slocals,Sinstrlab,Sparsefails,Spremoved,Scals;
 | 
						|
extern int Sbig_caller,Sdispensable,Schangedcallee,Sbigcallee,Sspace,Szeroratio;
 | 
						|
#endif
 | 
						|
 | 
						|
/* extra core-allocation macros */
 | 
						|
 | 
						|
#define newcall()	(call_p) newstruct(call)
 | 
						|
#define newactual()	(actual_p) newstruct(actual)
 | 
						|
#define newformal()	(formal_p) newstruct(formal)
 | 
						|
#define newcalcnt()	(calcnt_p) newstruct(calcnt)
 | 
						|
#define newilpx()	(pext_p) newstruct(pext_il)
 | 
						|
 | 
						|
#define oldcall(x)	oldstruct(call,x)
 | 
						|
#define oldactual(x)	oldstruct(actual,x)
 | 
						|
#define oldformal(x)	oldstruct(formal,x)
 | 
						|
#define oldcalcnt(x)	oldstruct(calcnt,x)
 | 
						|
#define oldilpx(x)	oldstruct(pext_il,x)
 |