1 /* $Id: il1_anal.c,v 1.8 1994/06/24 10:25:18 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
6 /* I N L I N E S U B S T I T U T I O N
14 #include "../share/types.h"
16 #include "../share/debug.h"
17 #include "../share/alloc.h"
18 #include "../share/global.h"
19 #include "../share/lset.h"
20 #include "../share/aux.h"
22 #include "il1_formal.h"
26 #include "../share/put.h"
28 #define ENVIRON(p) (p->p_flags1 & (byte) PF_ENVIRON)
29 #define RETURN_BLOCK(b) (Lnrelems(b->b_succ) == 0)
30 #define LAST_BLOCK(b) (b->b_next == (bblock_p) 0)
32 /* Daisy chain recursion not yet accounted for: */
33 #define RECURSIVE(p) (Cis_elem(p->p_id,p->p_calling))
35 #define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN)
37 #define CALLS_UNKNOWN(p) (FALSE)
44 /* For every procedure, see if we can determine
45 * from the information provided by the previous
46 * phases of the optimizer that it cannot or should not
47 * be expanded in line. This will reduce the length
53 for (p = proctab; p != (proc_p) 0; p = p->p_next) {
55 ENVIRON(p) || RECURSIVE(p) ||
56 PARAMS_UNKNOWN(p) || MANY_LOCALS(p) ||
57 IS_ENTERED_WITH_GTO(p)) {
61 if (ENVIRON(p)) Senv++;
62 if (RECURSIVE(p)) Srecursive++;
63 if (MANY_LOCALS(p)) Slocals++;
71 STATIC check_labels(p,arglist)
75 /* Check if any of the arguments contains an instruction
76 * label; if so, make p unsuitable.
81 for (arg = arglist; arg != (arg_p) 0; arg = arg->a_next) {
82 if (arg->a_type == ARGINSTRLAB) {
94 STATIC anal_instr(p,b,cf)
99 /* Analyze the instructions of block b
100 * within procedure p.
101 * See which parameters are used, changed
102 * or have their address taken. Recognize
103 * the actual parameter expressions of
104 * the CAL instructions.
109 for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
118 formal(p,b,off_set(l),SINGLE,CHANGE);
119 /* see if the local is a parameter.
120 * If so, it is a one-word parameter
121 * that is stored into.
125 formal(p,b,off_set(l),DOUBLE,CHANGE);
128 formal(p,b,off_set(l),SINGLE,USE);
131 formal(p,b,off_set(l),DOUBLE,USE);
135 formal(p,b,off_set(l),POINTER,USE);
138 formal(p,b,off_set(l),UNKNOWN,ADDRESS);
144 check_labels(p,ARG(l));
146 case op_nop: /* volatile */
159 /* Analyze a procedure; use information
160 * stored in its basic blocks or in
165 bool fallthrough = TRUE;
167 cchead = (calcnt_p) 0;
168 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
169 if (RETURN_BLOCK(b) && !LAST_BLOCK(b)) {
171 /* p contains a RET instruction somewhere
172 * in the middle of its code.
175 anal_instr(p,b,cf); /* analyze instructions */
178 p->p_flags2 |= PF_FALLTHROUGH;
181 /* don't expand formal that may be accessed indirectly */
182 p->P_CCADDR = putcc(cchead,ccf);
183 /* write calcnt info and remember disk address */