1 /* $Id: sp.c,v 1.6 1994/06/24 10:31:19 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 /* S T A C K P O L L U T I O N
15 #include "../share/types.h"
16 #include "../share/debug.h"
17 #include "../share/global.h"
18 #include "../share/files.h"
19 #include "../share/get.h"
20 #include "../share/put.h"
21 #include "../share/lset.h"
22 #include "../share/map.h"
23 #include "../share/alloc.h"
24 #include "../share/aux.h"
25 #include "../share/go.h"
26 #include "../share/stack_chg.h"
29 /* Stack pollution throws away the ASP instructions after a procedure call.
30 * This saves a lot of code, at the cost of some extra stack space.
31 * ASPs that are part of a loop are not removed.
35 #define MARK(b) b->b_flags |= BF_MARK
36 #define NOT_MARKED(b) (!(b->b_flags&BF_MARK))
37 #define IN_LOOP(b) (Lnrelems(b->b_loops) > 0)
39 STATIC int Ssp; /* number of optimizations */
41 /* According to the EM definition, the stack must be cleaned up
42 * before any return. However, for some backends it causes no harm
43 * if the stack is not cleaned up. If so, we can do Stack Pollution
47 STATIC int globl_sp_allowed;
50 #define IS_ASP(l) (INSTR(l) == op_asp && TYPE(l) == OPSHORT && SHORT(l) > 0)
56 /* Read target machine dependent information for this phase */
60 while(getc(f) != '\n');
62 if (strcmp(s,"%%SP") == 0)break;
64 fscanf(f,"%d",&globl_sp_allowed);
70 assert(INSTR(l1) == op_asp);
71 assert(INSTR(l2) == op_asp);
72 assert(TYPE(l1) == OPSHORT);
73 assert(TYPE(l2) == OPSHORT);
75 SHORT(l2) += SHORT(l1);
85 /* For every pair of successive ASP instructions in basic
86 * block b, try to combine the two into one ASP.
90 line_p asp,next = b->b_start;
91 bool asp_seen = FALSE;
92 int stack_diff,pop,push;
97 for (l = next; l != (line_p) 0; l = next) {
101 if (INSTR(l) == op_ret) {
102 stack_diff -= SHORT(l);
104 line_change(l,&ok,&pop,&push);
105 if (!ok || (stack_diff -= pop) < 0) {
106 /* can't eliminate last ASP */
115 if (l == (line_p) 0) {
116 /* last asp of basic block */
117 if (globl_sp_allowed &&
118 NOT_MARKED(b) && !IN_LOOP(b)) {
123 /* try to combine with previous asp */
124 if (SHORT(l) == stack_diff) {
131 asp_seen = TRUE; /* use new ASP for next try! */
132 } while (asp != (line_p) 0);
135 STATIC bool block_save(b)
140 int stack_diff,pop,push;
144 for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
145 if (INSTR(l) == op_ret) {
146 stack_diff -= SHORT(l);
149 line_change(l,&ok,&pop,&push);
150 /* printf("instr %d, pop %d,push %d,ok %d\n",INSTR(l),pop,push,ok); */
151 if (!ok || (stack_diff -= pop) < 0) {
157 return stack_diff >= 0;
168 for (i = Lfirst(b->b_pred); i != (Lindex) 0; i = Lnext(i,b->b_pred)) {
169 x = (bblock_p) Lelem(i);
181 STATIC mark_unsave_blocks(p)
186 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
187 if (NOT_MARKED(b) && !block_save(b)) {
200 if (IS_ENTERED_WITH_GTO(p)) return;
201 mark_unsave_blocks(p);
202 for (b = p->p_start; b != 0; b = b->b_next) {
214 go(argc,argv,no_action,sp_optimize,sp_machinit,no_action);
215 report("stack adjustments deleted",Ssp);
224 debug_stack_pollution(p)
229 int lcnt,aspcnt,instr;
231 for (b = p->p_start; b != 0; b = b->b_next) {
232 lcnt = 0; aspcnt = 0;
233 for (l = b->b_start; l != 0; l= l->l_next) {
235 if (instr >= sp_fmnem && instr <= sp_lmnem) {
237 if (instr == op_asp && off_set(l) > 0) {
242 printf("%d\t%d\n",aspcnt,lcnt);