138 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *   R E G I S T E R    A L L O C A T I O N
 | |
|  *
 | |
|  */
 | |
| 
 | |
| /* TEMPORARY: should be put in ../../../h/em_mes.h: */
 | |
| #define ms_liv 9
 | |
| #define ms_ded 10
 | |
| 
 | |
| #define INFINITE	10000
 | |
| #define NRREGTYPES	(reg_float+1)
 | |
| 
 | |
| int nrinstrs;  /* number of instructions of current procedure */
 | |
| line_p *instrmap;  /* Dynamic array: instrmap[i] points to i'th instruction */
 | |
| 
 | |
| extern cond_p alocaltab[NRREGTYPES][NRREGTYPES],
 | |
| 	alocaddrtab[NRREGTYPES][NRREGTYPES], aconsttab,
 | |
| 	adconsttab,aglobaltab,aproctab;
 | |
| extern cond_p olocaltab[NRREGTYPES],olocaddrtab[NRREGTYPES],
 | |
| 	oconsttab,odconsttab,oglobaltab,oproctab;
 | |
| extern cond_p regsav_cost;
 | |
| 
 | |
| /* Register Allocation */
 | |
| typedef struct item *item_p;
 | |
| typedef struct allocation *alloc_p;
 | |
| typedef struct interval *interv_p;
 | |
| typedef struct time *time_p;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| extern short regs_available[];  /* contains #registers of every type */
 | |
| 
 | |
| 
 | |
| /* A thing that can be put in a register is called an "item". The are several
 | |
|  * types of items: a local variable, the address of a local variable,
 | |
|  * the address of a global variable, the address of a procedure,
 | |
|  * a word-size constant and a doubleword- size constant.
 | |
|  */
 | |
| 
 | |
| #define LOCALVAR	0
 | |
| #define LOCAL_ADDR	1
 | |
| #define GLOBL_ADDR	2
 | |
| #define PROC_ADDR	3
 | |
| #define CONST		4
 | |
| #define DCONST		5
 | |
| 
 | |
| #define NO_ITEM		6
 | |
| #define NRITEMTYPES	6
 | |
| 
 | |
| struct item {
 | |
| 	item_p	  it_next;	/* link to next item is list		*/
 | |
| 	short	  it_type;	/* its type; see above			*/
 | |
| 	short	  it_regtype;	/* preferred type of register		*/
 | |
| 	short	  it_size;	/* its size (in bytes)			*/
 | |
| 	short	  it_lastlive;	/* temporary, used to build livetime	*/
 | |
| 	lset	  it_usage;	/* all points in text where item is used*/
 | |
| 	interv_p  it_lives;	/* intervals during which item is live	*/
 | |
| 	bool	  it_desirable; /* should this item be put in reg.?	*/
 | |
| 	union {
 | |
| 		obj_p	it_obj;		/* for GLOBL_ADDR 		*/
 | |
| 		proc_p	it_proc;	/* for PROC_ADDR		*/
 | |
| 		offset	it_off;		/* for others	  		*/
 | |
| 	} i_t;
 | |
| };
 | |
| 
 | |
| 
 | |
| /* A 'point in time' is defined by a (line,basic block) pair */
 | |
| 
 | |
| struct time {
 | |
| 	line_p	  t_line;	/* point in EM text			*/
 | |
| 	bblock_p  t_bblock;	/* its basic block			*/
 | |
| };
 | |
| 
 | |
| 
 | |
| struct interval {
 | |
| 	short	 i_start;	/* number of first instruction		*/
 | |
| 	short	 i_stop;	/* number of last instruction		*/
 | |
| 	interv_p i_next;
 | |
| };
 | |
| 
 | |
| 
 | |
| /* An item may be put in a register for the duration of a whole procedure
 | |
|  * or part of a procedure (e.g. a loop). So a possible "allocation" looks
 | |
|  * like: put item X in a register during the timespan T (which is a subset
 | |
|  * of the timespan of the entire procedure). The packing process deals
 | |
|  * with allocations, rather than items. One item may be part of several
 | |
|  * possible allocations.
 | |
|  */
 | |
| 
 | |
| struct allocation {
 | |
| 	item_p	  al_item;	/* the item to be put in a register	  */
 | |
| 	short	  al_id;	/* unique identifying number		  */
 | |
| 	short	  al_regtype;	/* the register type to be used		  */
 | |
| 	interv_p  al_timespan;	/* timespan during which item is in reg.  */
 | |
| 	short	  al_profits;	/* gains of putting item in register	  */
 | |
| 	cset	  al_rivals;	/* set of allocations competing with it	  */
 | |
| 	short	  al_susecount;	/* #usages during timespan (statically)   */
 | |
| 	short	  al_dusecount;	/* #usages (dynamically, estimate)	  */
 | |
| 	lset	  al_inits;	/* points where reg. must be initialized  */
 | |
| 	interv_p  al_busy;	/* used to compute rivals		  */
 | |
| 	short	  al_regnr;	/* register nr.,if it is granted a reg.   */
 | |
| 	offset	  al_dummy;	/* dummy local variable,if granted a reg  */
 | |
| 	alloc_p	  al_mates;	/* link to allocations packed in same reg */
 | |
| 	alloc_p	  al_wholeproc;	/* alloc. for whole proc as timespan  	  */
 | |
| 	short	  al_cntrivals; /* # unpacked rivals ; used for cost estim. */
 | |
| 	bool	  al_isloop;	/* true if timespan consists of loop	  */
 | |
| 	bool	  al_iswholeproc;/*true if timespan consists of whole proc*/
 | |
| 	alloc_p	  al_next;	/* link to next one in a list		  */
 | |
| };
 | |
| 
 | |
| extern short alloc_id;  /* last al_id used for current procedure */
 | |
| 
 | |
| #define LP_BLOCKS	lp_extend->lpx_ra.lpx_blocks
 | |
| #define LP_HEADER	lp_extend->lpx_ra.lpx_header
 | |
| #define B_BEGIN		b_extend->bx_ra.bx_begin
 | |
| #define B_END		b_extend->bx_ra.bx_end
 | |
| #define B_DIST		b_extend->bx_ra.bx_dist
 | |
| #define B_USECNT	b_extend->bx_ra.bx_usecnt
 | |
| #define B_MARK		b_extend->bx_ra.bx_mark
 | |
| 
 | |
| #define DLINK(l1,l2)	l1->l_next=l2; l2->l_prev=l1
 | |
| 
 | |
| struct item_descr {
 | |
| 	int	id_type;
 | |
| 	int	id_replindex;
 | |
| } ;
 | |
| 
 | |
| extern struct item_descr itemtab[];
 | |
| 
 | |
| #define newalloc()	(alloc_p) newstruct(allocation)
 | |
| #define  oldalloc(a)	oldstruct(allocation,a)
 | |
| #define newitem()	(item_p) newstruct(item)
 | |
| #define olditem(i)	oldstruct(item,i)
 | |
| #define newtime()	(time_p) newstruct(time)
 | |
| #define oldtime(t)	oldstruct(time,t)
 | |
| #define newinterval()	(interv_p) newstruct(interval)
 | |
| #define oldinterval(i)	oldstruct(interval,i)
 |