Pristine Ack-5.5
[Ack-5.5.git] / util / opt / flow.c
1 #ifndef NORCSID
2 static char rcsid[] = "$Id: flow.c,v 2.10 1994/06/24 10:40:00 ceriel Exp $";
3 #endif
4
5 #include "param.h"
6 #include "types.h"
7 #include "tes.h"
8 #include <em_flag.h>
9 #include <em_spec.h>
10 #include <em_mnem.h>
11 #include "alloc.h"
12 #include "line.h"
13 #include "proinf.h"
14 #include "optim.h"
15 #include "ext.h"
16
17 /*
18  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
19  * See the copyright notice in the ACK home directory, in the file "Copyright".
20  *
21  * Author: Hans van Staveren
22  */
23
24 flow() {
25
26         findreach();    /* determine reachable labels */
27         cleaninstrs();  /* throw away unreachable code */
28 }
29
30 findreach() {
31         register num_p  *npp,np;
32
33         reach(instrs);
34         for(npp=curpro.numhash;npp< &curpro.numhash[NNUMHASH]; npp++)
35                 for(np= *npp; np != (num_p) 0 ; np = np->n_next)
36                         if (np->n_flags&NUMDATA) {
37                                 np->n_repl->n_flags |= NUMREACH;
38                                 np->n_repl->n_jumps++;
39                                 if (!(np->n_flags&NUMSCAN)) {
40                                         np->n_flags |= NUMSCAN;
41                                         if (np->n_line) {
42                                                 reach(np->n_line->l_next);
43                                                 continue;
44                                         }
45                                         if (!(np->n_repl->n_flags&NUMSCAN)) {
46                                                 np->n_repl->n_flags |= NUMSCAN;
47                                                 if (np->n_repl->n_line)
48                                                     reach(np->n_repl->n_line->l_next);
49                                         }
50                                 }
51                         }
52 }
53
54 reach(lnp) register line_p lnp; {
55         register num_p np;
56
57         for (;lnp != (line_p) 0; lnp = lnp->l_next) {
58                 if(lnp->l_optyp == OPNUMLAB) {
59                         /*
60                          * Branch instruction or label
61                          */
62                         np = lnp->l_a.la_np;
63                         if ((lnp->l_instr&BMASK) != op_lab)
64                                 lnp->l_a.la_np = np = np->n_repl;
65                         np->n_flags |= NUMREACH;
66                         if (!(np->n_flags&NUMSCAN)) {
67                                 np->n_flags |= NUMSCAN;
68                                 if (np->n_line)
69                                         reach(np->n_line->l_next);
70                                 else {
71                                         np = np->n_repl;
72                                         np->n_flags |= NUMREACH;
73                                         if (!(np->n_flags & NUMSCAN)) {
74                                                 np->n_flags |= NUMSCAN;
75                                                 if (np->n_line)
76                                                         reach(np->n_line->l_next);
77                                         }
78                                 }
79                         }
80                         if ((lnp->l_instr&BMASK) == op_lab)
81                                 return;
82                         else
83                                 np->n_jumps++;
84                 }
85                 if ((lnp->l_instr & BMASK) > sp_lmnem) continue;
86                 if ((em_flag[(lnp->l_instr&BMASK)-sp_fmnem]&EM_FLO)==FLO_T)
87                         return;
88         }
89 }
90
91 cleaninstrs() {
92         register line_p *lpp,lp,*lastbra;
93         bool reachable,superfluous;
94         int instr;
95
96         lpp = &instrs; lastbra = (line_p *) 0; reachable = TRUE;
97         while ((lp = *lpp) != (line_p) 0) {
98                 instr = lp->l_instr&BMASK;
99                 if (instr == op_lab) {
100                         if ((lp->l_a.la_np->n_flags&NUMREACH) != 0) {
101                                 reachable = TRUE;
102                                 if (lastbra != (line_p *) 0
103                                     && (*lastbra)->l_next == lp
104                                     && (*lastbra)->l_a.la_np->n_repl==lp->l_a.la_np) {
105                                         oldline(*lastbra);
106                                         OPTIM(O_BRALAB);
107                                         lpp = lastbra;
108                                         *lpp = lp;
109                                         lastbra = (line_p *) 0;
110                                         lp->l_a.la_np->n_jumps--;
111                                 }
112                         }
113                         if ( lp->l_a.la_np->n_repl != lp->l_a.la_np ||
114                              ((lp->l_a.la_np->n_flags&NUMDATA)==0 &&
115                               lp->l_a.la_np->n_jumps == 0))
116                                 superfluous = TRUE;
117                         else
118                                 superfluous = FALSE;
119                 } else
120                         superfluous = FALSE;
121                 if ( (!reachable) || superfluous) {
122                         if (instr == op_lab) {
123                                 lp->l_a.la_np->n_line = 0;
124                         }
125                         else if (instr > sp_lmnem) {
126                                 /* leave pseudo's */
127                                 lpp = &lp->l_next;
128                                 continue;
129                         }
130                         lp = lp->l_next;
131                         oldline(*lpp);
132                         OPTIM(O_UNREACH);
133                         *lpp = lp;
134                 } else {
135                         if ( instr <= sp_lmnem &&
136                             (em_flag[instr-sp_fmnem]&EM_FLO)==FLO_T) {
137                                 reachable = FALSE;
138                                 if ((lp->l_instr&BMASK) == op_bra)
139                                         lastbra = lpp;
140                         }
141                         lpp = &lp->l_next;
142                 }
143         }
144 }