141 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*  I N L I N E   S U B S T I T U T I O N
 | |
|  *
 | |
|  *  I L 1 _ F O R M A L . C
 | |
|  */
 | |
| 
 | |
| #include "../share/types.h"
 | |
| #include "il.h"
 | |
| #include "../share/debug.h"
 | |
| #include "../share/alloc.h"
 | |
| #include "../share/global.h"
 | |
| #include "../share/lset.h"
 | |
| #include "il1_aux.h"
 | |
| #include "il1_formal.h"
 | |
| 
 | |
| #define NOT_USED(f)	(!(f->f_flags & USEMASK))
 | |
| #define USED_ONCE(f)	f->f_flags |= FF_ONCEUSED
 | |
| #define USED_OFTEN(f)	f->f_flags |= FF_OFTENUSED
 | |
| #define BADFORMAL(f)	f->f_flags |= FF_BAD
 | |
| 
 | |
| #define OUTSIDE_LOOP(b)	(Lnrelems(b->b_loops) == 0)
 | |
| #define IS_FORMAL(x)	(x >= 0)
 | |
| 
 | |
| 
 | |
| 
 | |
| formal_p find_formal(p,type,off)
 | |
| 	proc_p  p;
 | |
| 	int	type;
 | |
| 	offset  off;
 | |
| {
 | |
| 	/* Find a formal parameter of p
 | |
| 	 * If the formal overlaps with an existing formal
 | |
| 	 * or has an unknown type (i.e. its address is used)
 | |
| 	 * 0 is returned.
 | |
| 	 */
 | |
| 
 | |
| 	formal_p f,prev,nf;
 | |
| 
 | |
| 	if (type == UNKNOWN) return (formal_p) 0;
 | |
| 	prev = (formal_p) 0;
 | |
| 	for (f = p->P_FORMALS; f != (formal_p) 0; f = f->f_next) {
 | |
| 		if (f->f_offset >= off) break;
 | |
| 		prev = f;
 | |
| 	}
 | |
| 	if (f != (formal_p) 0 && f->f_offset == off) {
 | |
| 		return (same_size(f->f_type,type) ? f : (formal_p) 0);
 | |
| 	}
 | |
| 	if (f != (formal_p) 0 && par_overlap(off,type,f->f_offset,f->f_type)) {
 | |
| 		return (formal_p) 0;
 | |
| 	}
 | |
| 	if (prev != (formal_p) 0 && par_overlap(prev->f_offset,prev->f_type,
 | |
| 					off,type)) {
 | |
| 		return (formal_p) 0;
 | |
| 	}
 | |
| 	nf = newformal();
 | |
| 	nf->f_type = type;
 | |
| 	nf->f_offset = off;
 | |
| 	if (prev == (formal_p) 0) {
 | |
| 		p->P_FORMALS = nf;
 | |
| 	} else {
 | |
| 		prev->f_next = nf;
 | |
| 	}
 | |
| 	nf->f_next = f;
 | |
| 	return nf;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| STATIC no_inl_pars(p)
 | |
| 	proc_p p;
 | |
| {
 | |
| 	/* p may not have any in line parameters */
 | |
| 
 | |
| 	p->p_flags2 |= PF_NO_INLPARS;
 | |
| 	remov_formals(p);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| STATIC inc_use(f,b)
 | |
| 	formal_p f;
 | |
| 	bblock_p b;
 | |
| {
 | |
| 	/* Increment the use count of formal f.
 | |
| 	 * The counter has only three states: not used,
 | |
| 	 * used once, used more than once.
 | |
| 	 * We count the number of times the formal
 | |
| 	 * is used dynamically (rather than statically),
 | |
| 	 * so if it is used in a loop, the counter
 | |
| 	 * is always set to more than once.
 | |
| 	 */
 | |
| 
 | |
| 	if (NOT_USED(f) && OUTSIDE_LOOP(b)) {
 | |
| 		USED_ONCE(f);
 | |
| 	} else {
 | |
| 		USED_OFTEN(f);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| formal(p,b,off,type,usage)
 | |
| 	proc_p    p;
 | |
| 	bblock_p  b;
 | |
| 	offset    off;
 | |
| 	int       type,
 | |
| 		  usage;
 | |
| {
 | |
| 	/* Analyze a reference to a parameter of p
 | |
| 	 * (occurring within basic block b).
 | |
| 	 * The parameter has offset off. If this
 | |
| 	 * offset is less than 0, it is not a
 | |
| 	 * parameter, but a local.
 | |
| 	 * The type can be SINGLE (1 word), DOUBLE
 | |
| 	 * (2 words), POINTER or UNKNOWN.
 | |
| 	 */
 | |
| 
 | |
| 	formal_p f;
 | |
| 
 | |
| 	if (!IS_FORMAL(off) || !SUITABLE(p) || !INLINE_PARS(p)) return;
 | |
| 	/* We are not interested in formal parameters of
 | |
| 	 * proccedures that will never be expanded in line,
 | |
| 	 * or whose parameters will not be expanded in line.
 | |
| 	 */
 | |
| 	f = find_formal(p,type,off);
 | |
| 	/* Find the formal; if not found, create one;
 | |
| 	 * if inconsistent with previous formals (e.g.
 | |
| 	 * overlapping formals) then return 0;
 | |
| 	 * also fills in its type.
 | |
| 	 */
 | |
| 	if (f == (formal_p) 0) {
 | |
| 		no_inl_pars(p);
 | |
| 		/* parameters of p may not be expanded in line */
 | |
| 	} else {
 | |
| 		if (usage == CHANGE) {
 | |
| 			/* don't expand f in line */
 | |
| 			BADFORMAL(f);
 | |
| 		} else {
 | |
| 			inc_use(f,b); /* increment use count */
 | |
| 		}
 | |
| 	}
 | |
| }
 |