Pristine Ack-5.5
[Ack-5.5.git] / util / ego / il / il1_formal.c
1 /* $Id: il1_formal.c,v 1.4 1994/06/24 10:25:36 ceriel Exp $ */
2 /*
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".
5  */
6 /*  I N L I N E   S U B S T I T U T I O N
7  *
8  *  I L 1 _ F O R M A L . C
9  */
10
11 #include "../share/types.h"
12 #include "il.h"
13 #include "../share/debug.h"
14 #include "../share/alloc.h"
15 #include "../share/global.h"
16 #include "../share/lset.h"
17 #include "il1_aux.h"
18 #include "il1_formal.h"
19
20 #define NOT_USED(f)     (!(f->f_flags & USEMASK))
21 #define USED_ONCE(f)    f->f_flags |= FF_ONCEUSED
22 #define USED_OFTEN(f)   f->f_flags |= FF_OFTENUSED
23 #define BADFORMAL(f)    f->f_flags |= FF_BAD
24
25 #define OUTSIDE_LOOP(b) (Lnrelems(b->b_loops) == 0)
26 #define IS_FORMAL(x)    (x >= 0)
27
28
29
30 formal_p find_formal(p,type,off)
31         proc_p  p;
32         int     type;
33         offset  off;
34 {
35         /* Find a formal parameter of p
36          * If the formal overlaps with an existing formal
37          * or has an unknown type (i.e. its address is used)
38          * 0 is returned.
39          */
40
41         formal_p f,prev,nf;
42
43         if (type == UNKNOWN) return (formal_p) 0;
44         prev = (formal_p) 0;
45         for (f = p->P_FORMALS; f != (formal_p) 0; f = f->f_next) {
46                 if (f->f_offset >= off) break;
47                 prev = f;
48         }
49         if (f != (formal_p) 0 && f->f_offset == off) {
50                 return (same_size(f->f_type,type) ? f : (formal_p) 0);
51         }
52         if (f != (formal_p) 0 && par_overlap(off,type,f->f_offset,f->f_type)) {
53                 return (formal_p) 0;
54         }
55         if (prev != (formal_p) 0 && par_overlap(prev->f_offset,prev->f_type,
56                                         off,type)) {
57                 return (formal_p) 0;
58         }
59         nf = newformal();
60         nf->f_type = type;
61         nf->f_offset = off;
62         if (prev == (formal_p) 0) {
63                 p->P_FORMALS = nf;
64         } else {
65                 prev->f_next = nf;
66         }
67         nf->f_next = f;
68         return nf;
69 }
70
71
72
73 STATIC no_inl_pars(p)
74         proc_p p;
75 {
76         /* p may not have any in line parameters */
77
78         p->p_flags2 |= PF_NO_INLPARS;
79         remov_formals(p);
80 }
81
82
83
84 STATIC inc_use(f,b)
85         formal_p f;
86         bblock_p b;
87 {
88         /* Increment the use count of formal f.
89          * The counter has only three states: not used,
90          * used once, used more than once.
91          * We count the number of times the formal
92          * is used dynamically (rather than statically),
93          * so if it is used in a loop, the counter
94          * is always set to more than once.
95          */
96
97         if (NOT_USED(f) && OUTSIDE_LOOP(b)) {
98                 USED_ONCE(f);
99         } else {
100                 USED_OFTEN(f);
101         }
102 }
103
104
105
106 formal(p,b,off,type,usage)
107         proc_p    p;
108         bblock_p  b;
109         offset    off;
110         int       type,
111                   usage;
112 {
113         /* Analyze a reference to a parameter of p
114          * (occurring within basic block b).
115          * The parameter has offset off. If this
116          * offset is less than 0, it is not a
117          * parameter, but a local.
118          * The type can be SINGLE (1 word), DOUBLE
119          * (2 words), POINTER or UNKNOWN.
120          */
121
122         formal_p f;
123
124         if (!IS_FORMAL(off) || !SUITABLE(p) || !INLINE_PARS(p)) return;
125         /* We are not interested in formal parameters of
126          * proccedures that will never be expanded in line,
127          * or whose parameters will not be expanded in line.
128          */
129         f = find_formal(p,type,off);
130         /* Find the formal; if not found, create one;
131          * if inconsistent with previous formals (e.g.
132          * overlapping formals) then return 0;
133          * also fills in its type.
134          */
135         if (f == (formal_p) 0) {
136                 no_inl_pars(p);
137                 /* parameters of p may not be expanded in line */
138         } else {
139                 if (usage == CHANGE) {
140                         /* don't expand f in line */
141                         BADFORMAL(f);
142                 } else {
143                         inc_use(f,b); /* increment use count */
144                 }
145         }
146 }