Pristine Ack-5.5
[Ack-5.5.git] / util / ego / il / il1_cal.c
1 /* $Id: il1_cal.c,v 1.5 1994/06/24 10:25:30 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 _ C A L . C
9  */
10
11 #include <stdio.h>
12 #include <em_spec.h>
13 #include <em_mnem.h>
14 #include "../share/types.h"
15 #include "il.h"
16 #include "il1_cal.h"
17 #include "../share/debug.h"
18 #include "../share/alloc.h"
19 #include "../share/global.h"
20 #include "../share/lset.h"
21 #include "il1_aux.h"
22 #include "../share/parser.h"
23
24 STATIC actual_p acts, *app;
25
26 #define INIT_ACTS()     {acts = (actual_p) 0; app = &acts;}
27 #define APPEND_ACTUAL(a) {*app = a; app = &a->ac_next;}
28
29 STATIC make_actual(l1,l2,size)
30         line_p l1,l2;
31         offset size;
32 {
33         /* Allocate a struct for a new actual parameter
34          * expression, the code of which extends from
35          * l1 to l2.
36          */
37
38         actual_p a;
39
40         a = newactual();
41         a->ac_exp = copy_code(l1,l2);
42         a->ac_size = size;
43         APPEND_ACTUAL(a); /* append it to actual-list */
44 }
45
46
47
48 STATIC bool chck_asp(p,l)
49         proc_p p;
50         line_p l;
51 {
52         /* We require a call to a procedure p that has n formal
53          * parameters to be followed by an 'asp n' instruction
54          * (i.e. the caller should remove the actual parameters).
55          */
56
57         return (p->p_nrformals == 0 || (l != (line_p) 0 &&INSTR(l) == op_asp &&
58                    TYPE(l) == OPSHORT && SHORT(l) == p->p_nrformals));
59 }
60
61
62
63 STATIC inc_count(caller,callee)
64         proc_p caller, callee;
65 {
66         /* Update the call-count information.
67          * Record the fact that there is one more call
68          * to 'callee', appearing in 'caller'.
69          */
70
71         calcnt_p cc;
72
73         if (!SUITABLE(caller)) return;
74         /* if the calling routine is never expanded in line
75          * we do not need call-count information.
76          */
77         for (cc = cchead; cc != (calcnt_p) 0; cc = cc->cc_next) {
78                 if (cc->cc_proc == callee) {
79                         cc->cc_count++;
80                         /* #calls to callee from caller */
81                         return;
82                 }
83         }
84         /* This is the first call from caller to callee.
85          * Allocate a new calcnt struct.
86          */
87         cc = newcalcnt();
88         cc->cc_proc = callee;
89         cc->cc_count = 1;
90         cc->cc_next = cchead; /* insert it at front of list */
91         cchead = cc;
92 }
93
94
95
96 anal_cal(p,call,b,cf)
97         proc_p p;
98         line_p call;
99         bblock_p b;
100         FILE   *cf;
101 {
102         /* Analyze a call instruction. If the called
103          * routine may be expanded in line, try to
104          * recognize the actual parameter expressions of
105          * the call and extend the call list.
106          */
107
108         call_p c;
109         line_p lnp;
110         proc_p callee;
111
112 #ifdef VERBOSE
113         Scals++;
114 #endif
115         calnr++;
116         callee = PROC(call);
117         if (SUITABLE(callee)) {
118                 /* The called procedure may be expanded */
119                 callee->P_NRCALLED++;   /* #calls to callee from anywhere */
120                 INIT_ACTS();
121                 if (parse(PREV(call),callee->p_nrformals,&lnp,0,make_actual) &&
122                       chck_asp(callee,call->l_next)) {
123                         /* succeeded in recognizing the actuals */
124                         c = newcall();
125                         c->cl_caller = p;
126                         c->cl_id = calnr;
127                         c->cl_proc = callee;
128                         c->cl_looplevel = (byte) looplevel(b);
129                         if (c->cl_looplevel > 0 && IS_FIRM(b)) {
130                                 c->cl_flags |= CLF_FIRM;
131                         }
132                         c->cl_actuals = acts;
133                         inc_count(p,callee);
134                         /* update call-count info */
135                         putcall(c,cf,(short) 0);  /* write the call to the calfile */
136                 } else {
137 #ifdef VERBOSE
138                         Sparsefails++;
139 #endif
140                         rem_actuals(acts);
141                 }
142         }
143 }