123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /* $Id$ */
- /*
- * (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 L I N E S U B S T I T U T I O N
- *
- * I L 1 _ A N A L . C
- */
- #include <stdio.h>
- #include <em_mnem.h>
- #include <em_pseu.h>
- #include "../share/types.h"
- #include "il.h"
- #include "../share/debug.h"
- #include "../share/alloc.h"
- #include "../share/global.h"
- #include "../share/lset.h"
- #include "../share/aux.h"
- #include "il1_aux.h"
- #include "il1_formal.h"
- #include "il1_cal.h"
- #include "il1_anal.h"
- #include "il_aux.h"
- #include "../share/put.h"
- #define ENVIRON(p) (p->p_flags1 & (byte) PF_ENVIRON)
- #define RETURN_BLOCK(b) (Lnrelems(b->b_succ) == 0)
- #define LAST_BLOCK(b) (b->b_next == (bblock_p) 0)
- /* Daisy chain recursion not yet accounted for: */
- #define RECURSIVE(p) (Cis_elem(p->p_id,p->p_calling))
- /*
- #define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN)
- */
- #define CALLS_UNKNOWN(p) (FALSE)
- apriori(proctab)
- proc_p proctab;
- {
- /* For every procedure, see if we can determine
- * from the information provided by the previous
- * phases of the optimizer that it cannot or should not
- * be expanded in line. This will reduce the length
- * of the call list.
- */
- register proc_p p;
- for (p = proctab; p != (proc_p) 0; p = p->p_next) {
- if (!BODY_KNOWN(p) ||
- ENVIRON(p) || RECURSIVE(p) ||
- PARAMS_UNKNOWN(p) || MANY_LOCALS(p) ||
- IS_ENTERED_WITH_GTO(p)) {
- UNSUITABLE(p);
- #ifdef VERBOSE
- if (BODY_KNOWN(p)) {
- if (ENVIRON(p)) Senv++;
- if (RECURSIVE(p)) Srecursive++;
- if (MANY_LOCALS(p)) Slocals++;
- }
- #endif
- }
- }
- }
- STATIC check_labels(p,arglist)
- proc_p p;
- arg_p arglist;
- {
- /* Check if any of the arguments contains an instruction
- * label; if so, make p unsuitable.
- */
- arg_p arg;
- for (arg = arglist; arg != (arg_p) 0; arg = arg->a_next) {
- if (arg->a_type == ARGINSTRLAB) {
- UNSUITABLE(p);
- #ifdef VERBOSE
- Sinstrlab++;
- #endif
- break;
- }
- }
- }
- STATIC anal_instr(p,b,cf)
- proc_p p;
- bblock_p b;
- FILE *cf;
- {
- /* Analyze the instructions of block b
- * within procedure p.
- * See which parameters are used, changed
- * or have their address taken. Recognize
- * the actual parameter expressions of
- * the CAL instructions.
- */
- register line_p l;
- for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
- switch(INSTR(l)) {
- case op_cal:
- anal_cal(p,l,b,cf);
- break;
- case op_stl:
- case op_inl:
- case op_del:
- case op_zrl:
- formal(p,b,off_set(l),SINGLE,CHANGE);
- /* see if the local is a parameter.
- * If so, it is a one-word parameter
- * that is stored into.
- */
- break;
- case op_sdl:
- formal(p,b,off_set(l),DOUBLE,CHANGE);
- break;
- case op_lol:
- formal(p,b,off_set(l),SINGLE,USE);
- break;
- case op_ldl:
- formal(p,b,off_set(l),DOUBLE,USE);
- break;
- case op_sil:
- case op_lil:
- formal(p,b,off_set(l),POINTER,USE);
- break;
- case op_lal:
- formal(p,b,off_set(l),UNKNOWN,ADDRESS);
- break;
- case ps_rom:
- case ps_con:
- case ps_bss:
- case ps_hol:
- check_labels(p,ARG(l));
- break;
- case op_nop: /* volatile */
- UNSUITABLE(p);
- break;
- }
- }
- }
- anal_proc(p,cf,ccf)
- proc_p p;
- FILE *cf,*ccf;
- {
- /* Analyze a procedure; use information
- * stored in its basic blocks or in
- * its instructions.
- */
- register bblock_p b;
- bool fallthrough = TRUE;
- cchead = (calcnt_p) 0;
- for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
- if (RETURN_BLOCK(b) && !LAST_BLOCK(b)) {
- fallthrough = FALSE;
- /* p contains a RET instruction somewhere
- * in the middle of its code.
- */
- }
- anal_instr(p,b,cf); /* analyze instructions */
- }
- if (fallthrough) {
- p->p_flags2 |= PF_FALLTHROUGH;
- }
- rem_indir_acc(p);
- /* don't expand formal that may be accessed indirectly */
- p->P_CCADDR = putcc(cchead,ccf);
- /* write calcnt info and remember disk address */
- remcc(cchead);
- }
|