From: eck Date: Wed, 18 Jul 1990 14:33:07 +0000 (+0000) Subject: added stackheight computation X-Git-Tag: release-5-5~1647 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=379511e23288a6d6c55e67c7ad506434410ad903;p=ack.git added stackheight computation --- diff --git a/util/opt/Makefile b/util/opt/Makefile index 1ee65c995..c41509896 100644 --- a/util/opt/Makefile +++ b/util/opt/Makefile @@ -1,10 +1,12 @@ # $Header$ EMHOME=../.. -CFILES=main.c getline.c lookup.c var.c process.c backward.c util.c\ - alloc.c putline.c cleanup.c peephole.c flow.c reg.c +CFILES=main.c getline.c lookup.c var.c process.c backward.c util.c \ + alloc.c putline.c cleanup.c peephole.c flow.c reg.c shc.c \ + pop_push.c + OFILES=main.o getline.o lookup.o var.o process.o backward.o util.o\ - alloc.o putline.o cleanup.o peephole.o flow.o + alloc.o putline.o cleanup.o peephole.o flow.o shc.o pop_push.o ONOGLOB=regnoglob.o OGLOB=regglob.o LIBS=$(EMHOME)/lib/em_data.a @@ -19,16 +21,16 @@ LEXLIB=-ll all: opt opt2 -opt: $(OFILES) $(ONOGLOB) pattern.o $(LIBS) +opt: $(OFILES) $(ONOGLOB) pattern.o $(LIBS) $(CC) $(LDFLAGS) $(CFLAGS) $(OFILES) $(ONOGLOB) pattern.o $(LIBS) -o opt -opt2: $(OFILES) $(OGLOB) pattern.o $(LIBS) +opt2: $(OFILES) $(OGLOB) pattern.o $(LIBS) $(CC) $(LDFLAGS) $(CFLAGS) $(OFILES) $(OGLOB) pattern.o $(LIBS) -o opt2 -test: opt testopt +test: opt testopt testopt -cmp : all +cmp: all -cmp opt $(EMHOME)/lib/em_opt -cmp opt2 $(EMHOME)/lib/em_opt2 -cmp em_opt.6 $(EMHOME)/man/em_opt.6 @@ -43,14 +45,17 @@ install:all rm -f $(EMHOME)/man/em_opt.6 cp em_opt.6 $(EMHOME)/man/em_opt.6 -pattern.c: patterns mktab +pattern.c: patterns mktab $(CPP) patterns | mktab > pattern.c -mktab: mktab.o $(LIBS) +mktab: mktab.o $(LIBS) $(CC) $(CFLAGS) mktab.o $(LIBS) $(LEXLIB) -o mktab mktab.o: scan.c optim.h param.h pattern.h types.h +pop_push.c ./pop_push.h: $(EMHOME)/etc/em_table pop_push.awk + awk -f pop_push.awk < $(EMHOME)/etc/em_table > pop_push.c + depend: pattern.c sed '/^#AUTOAUTO/,$$d' Makefile >Makefile.new echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new @@ -61,14 +66,14 @@ depend: pattern.c mv Makefile Makefile.old mv Makefile.new Makefile -lint: $(CFILES) pattern.c - $(LINT) $(CFILES) pattern.c>lint 2>&1 +lint: $(CFILES) pattern.c + $(LINT) $(CFLAGS) $(CFILES) pattern.c>lint 2>&1 printall: -pr $(PROPTS) Makefile -n *.h `ls $(CFILES)` mktab.y scan.l patterns|$(OPR) touch print -print: Makefile *.h $(CFILES) mktab.y scan.l patterns +print: Makefile *.h $(CFILES) mktab.y scan.l patterns -pr $(PROPTS) -n $? | $(OPR) touch print @@ -79,7 +84,8 @@ pr: @pr $(PROPTS) -n Makefile *.h $(CFILES) mktab.y scan.l patterns clean: - rm -f *.o opt mktab mktab.c scan.c pattern.c opt2 Out + rm -f *.o opt mktab mktab.c scan.c pattern.c opt2 Out \ + pop_push.c pop_push.h regnoglob.o: reg.c $(CC) $(CFLAGS) -c -o regnoglob.o reg.c @@ -92,6 +98,7 @@ regglob.o: reg.c main.o: alloc.h main.o: ext.h main.o: param.h +main.o: shc.h main.o: types.h getline.o: alloc.h getline.o: ext.h @@ -99,15 +106,18 @@ getline.o: line.h getline.o: lookup.h getline.o: param.h getline.o: proinf.h +getline.o: shc.h getline.o: types.h lookup.o: alloc.h lookup.o: lookup.h lookup.o: param.h lookup.o: proinf.h +lookup.o: shc.h lookup.o: types.h var.o: lookup.h var.o: param.h var.o: proinf.h +var.o: shc.h var.o: types.h process.o: alloc.h process.o: assert.h @@ -116,6 +126,7 @@ process.o: line.h process.o: lookup.h process.o: param.h process.o: proinf.h +process.o: shc.h process.o: types.h backward.o: alloc.h backward.o: assert.h @@ -124,6 +135,7 @@ backward.o: line.h backward.o: lookup.h backward.o: param.h backward.o: proinf.h +backward.o: shc.h backward.o: types.h util.o: assert.h util.o: ext.h @@ -131,6 +143,7 @@ util.o: lookup.h util.o: optim.h util.o: param.h util.o: proinf.h +util.o: shc.h util.o: types.h alloc.o: alloc.h alloc.o: assert.h @@ -138,6 +151,7 @@ alloc.o: line.h alloc.o: lookup.h alloc.o: param.h alloc.o: proinf.h +alloc.o: shc.h alloc.o: types.h putline.o: alloc.h putline.o: assert.h @@ -147,6 +161,7 @@ putline.o: lookup.h putline.o: optim.h putline.o: param.h putline.o: proinf.h +putline.o: shc.h putline.o: types.h cleanup.o: assert.h cleanup.o: ext.h @@ -162,6 +177,7 @@ peephole.o: optim.h peephole.o: param.h peephole.o: pattern.h peephole.o: proinf.h +peephole.o: shc.h peephole.o: types.h flow.o: alloc.h flow.o: ext.h @@ -169,6 +185,7 @@ flow.o: line.h flow.o: optim.h flow.o: param.h flow.o: proinf.h +flow.o: shc.h flow.o: types.h reg.o: alloc.h reg.o: assert.h @@ -176,7 +193,18 @@ reg.o: ext.h reg.o: line.h reg.o: param.h reg.o: proinf.h +reg.o: shc.h reg.o: types.h +shc.o: alloc.h +shc.o: assert.h +shc.o: ext.h +shc.o: line.h +shc.o: param.h +shc.o: pop_push.h +shc.o: proinf.h +shc.o: shc.h +shc.o: types.h +pop_push.o: pop_push.h pattern.o: param.h pattern.o: pattern.h pattern.o: types.h @@ -186,6 +214,7 @@ regglob.o: ext.h regglob.o: line.h regglob.o: param.h regglob.o: proinf.h +regglob.o: shc.h regglob.o: types.h regnoglob.o: alloc.h regnoglob.o: assert.h @@ -193,4 +222,5 @@ regnoglob.o: ext.h regnoglob.o: line.h regnoglob.o: param.h regnoglob.o: proinf.h +regnoglob.o: shc.h regnoglob.o: types.h diff --git a/util/opt/alloc.c b/util/opt/alloc.c index dc5be6826..edc4937a8 100644 --- a/util/opt/alloc.c +++ b/util/opt/alloc.c @@ -5,6 +5,7 @@ static char rcsid[] = "$Header$"; #include #include "param.h" #include "types.h" +#include "shc.h" #include "assert.h" #include "alloc.h" #include "line.h" @@ -171,6 +172,16 @@ oldnum(lp) num_p lp; { oldcore((short *) lp,sizeof(num_t)); } +lblst_p newlblst() { + + return((lblst_p) newcore(sizeof(lblst_t))); +} + +oldlblst(lbp) lblst_p lbp; { + + oldcore((short *) lbp, sizeof(lblst_t)); +} + offset *newrom() { return((offset *) newcore(MAXROM*sizeof(offset))); diff --git a/util/opt/alloc.h b/util/opt/alloc.h index 788fd9c8f..547771167 100644 --- a/util/opt/alloc.h +++ b/util/opt/alloc.h @@ -8,6 +8,7 @@ extern line_p newline(); extern offset *newrom(); extern sym_p newsym(); extern num_p newnum(); +extern lblst_p newlblst(); extern arg_p newarg(); extern argb_p newargb(); extern reg_p newreg(); diff --git a/util/opt/backward.c b/util/opt/backward.c index aa21b075a..00c5ee0ec 100644 --- a/util/opt/backward.c +++ b/util/opt/backward.c @@ -4,6 +4,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" +#include "shc.h" #include "assert.h" #include "line.h" #include "lookup.h" diff --git a/util/opt/flow.c b/util/opt/flow.c index 4821dff8d..afe1091aa 100644 --- a/util/opt/flow.c +++ b/util/opt/flow.c @@ -4,6 +4,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" +#include "shc.h" #include #include #include diff --git a/util/opt/getline.c b/util/opt/getline.c index 2af7b2df8..c0f9afd8b 100644 --- a/util/opt/getline.c +++ b/util/opt/getline.c @@ -5,6 +5,7 @@ static char rcsid[] = "$Header$"; #include #include "param.h" #include "types.h" +#include "shc.h" #include "line.h" #include "lookup.h" #include "alloc.h" @@ -467,6 +468,12 @@ int inpseudo(n) short n; { lnp=newline(OPNO); n=ps_exc; /* kludge to force out this line */ break; + case ms_sth: + tstinpro(); + oldline(lnp); + lnp=newline(OPNO); + n=ps_exc; /* kludge to force out this line */ + break; } break; case ps_pro: diff --git a/util/opt/line.h b/util/opt/line.h index 502467b25..f282e9e4b 100644 --- a/util/opt/line.h +++ b/util/opt/line.h @@ -70,6 +70,7 @@ typedef union { struct line { line_p l_next; /* maintains linked list */ + line_p l_prev; /* for back referencing loc's */ byte l_instr; /* instruction number */ byte l_optyp; /* specifies what follows */ un_l_a l_a; diff --git a/util/opt/lookup.c b/util/opt/lookup.c index 3eb51b049..45e5a18ed 100644 --- a/util/opt/lookup.c +++ b/util/opt/lookup.c @@ -4,6 +4,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" +#include "shc.h" #include "lookup.h" #include "alloc.h" #include "proinf.h" diff --git a/util/opt/main.c b/util/opt/main.c index ae94f296f..09edae44e 100644 --- a/util/opt/main.c +++ b/util/opt/main.c @@ -5,6 +5,7 @@ static char rcsid[] = "$Header$"; #include #include "param.h" #include "types.h" +#include "shc.h" #include "alloc.h" #include #include "ext.h" diff --git a/util/opt/peephole.c b/util/opt/peephole.c index 56862983c..138dbfeb5 100644 --- a/util/opt/peephole.c +++ b/util/opt/peephole.c @@ -4,6 +4,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" +#include "shc.h" #include "assert.h" #include "line.h" #include "lookup.h" diff --git a/util/opt/process.c b/util/opt/process.c index 724b24b57..7282b8348 100644 --- a/util/opt/process.c +++ b/util/opt/process.c @@ -4,6 +4,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" +#include "shc.h" #include "assert.h" #include #include @@ -41,8 +42,10 @@ process() { } while (madeopt && ++npasses < 5000); assert(!madeopt); } + do_shc(); /* stackheight computation phase */ outpro(); /* generate PRO pseudo */ outregs(); /* generate MES ms_reg pseudos */ + outsth(); /* generate MES ms_sth pseudos */ } putlines(pseudos); /* pseudos first */ if (prodepth != 0) { @@ -101,6 +104,7 @@ symknown() { cleanlocals() { register num_p *npp,np,tp; + delete_labels(); for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) { np = *npp; while (np != (num_p) 0) { @@ -185,3 +189,17 @@ symvalue() { } } } + +do_shc() +{ + register line_p insptr = instrs, oldlin = NULL; + + init_state(); + shc_pseudos(); + while (insptr != NULL) { + insptr->l_prev = oldlin; + oldlin = insptr; + shc_instr(insptr); + insptr = insptr->l_next; + } +} diff --git a/util/opt/proinf.h b/util/opt/proinf.h index 193e8a35f..8638e9013 100644 --- a/util/opt/proinf.h +++ b/util/opt/proinf.h @@ -10,6 +10,7 @@ struct num { unsigned n_jumps; num_p n_repl; short n_flags; + lblst_p n_lst_elt; line_p n_line; }; @@ -19,6 +20,8 @@ struct num { #define NUMKNOWN 000004 #define NUMMARK 000010 #define NUMSCAN 000020 +#define NUMSET 000040 +#define NUMCOND 000100 #define NNUMHASH 37 extern num_p numlookup(); diff --git a/util/opt/putline.c b/util/opt/putline.c index 0fd7f03e9..b6184bac0 100644 --- a/util/opt/putline.c +++ b/util/opt/putline.c @@ -4,6 +4,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" +#include "shc.h" #include "assert.h" #include #include diff --git a/util/opt/reg.c b/util/opt/reg.c index 3bf31f98a..e17ab4ceb 100644 --- a/util/opt/reg.c +++ b/util/opt/reg.c @@ -6,6 +6,7 @@ static char rcsid[] = "$Header$"; #include "param.h" #include "types.h" #include "line.h" +#include "shc.h" #include "proinf.h" #include "alloc.h" #include @@ -77,6 +78,25 @@ outregs() { curpro.freg = (reg_p) 0; } +/* outsth() handles the output of the stackheight messages */ +outsth() { + register lblst_p lp = est_list; + + if (state == NO_STACK_MES) return; + + while(lp != NULL) { + if ((lp->ll_height != 0) && !(lp->ll_num->n_flags & NUMCOND)) { + outinst(ps_mes); + outoff((offset)ms_sth); + outoff((offset)lp->ll_num->n_number); + outoff((offset)lp->ll_height); + outoff((offset)lp->ll_fallthrough); + outinst(sp_cend); + } + lp = lp->ll_next; + } +} + incregusage(off) offset off; { register reg_p rp; diff --git a/util/opt/shc.c b/util/opt/shc.c new file mode 100644 index 000000000..7856e321a --- /dev/null +++ b/util/opt/shc.c @@ -0,0 +1,226 @@ +/* + * This file contains the main part of the stackheight computation phase. + * + * Author: Hans van Eck. + */ + +#include +#include +#include +#include +#include "param.h" +#include "assert.h" +#include "types.h" +#include "shc.h" +#include "alloc.h" +#include "proinf.h" +#include "line.h" +#include "ext.h" +#include "pop_push.h" + +extern char *pop_push[]; +extern char flow_tab[]; + +#define NON_CONTINUABLE(i) (flow_tab[i]&JUMP) +#define ISABRANCH(i) (flow_tab[i]&HASLABEL) +#define ISCONDBRANCH(i) (flow_tab[i]&CONDBRA) + +lblst_p est_list = NULL; + +#define INSTR(lnp) (lnp->l_instr & BMASK) +#define TYPE(lnp) lnp->l_optyp +#define PREV(lnp) lnp->l_prev +#define SHORT(lnp) lnp->l_a.la_short +#define MINI(lnp) ((lnp->l_optyp & BMASK) - Z_OPMINI) + +#define IS_MINI(lnp) (lnp->l_optyp >= OPMINI) +#define IS_LOC(l) (l!=(line_p) 0 && INSTR(l)==op_loc && IS_MINI(l)) + +int state; +static int stack_height = 0; + +init_state() +{ + stack_height = 0; + change_state(KNOWN); + est_list = NULL; +} + +shc_pseudos() +{ + register line_p lp; + + for (lp = pseudos; lp != (line_p)0; lp = lp->l_next) { + switch(INSTR(lp)) { + case ps_con: + case ps_rom: + if (lp->l_optyp == OPLIST) { + register arg_p ap = lp->l_a.la_arg; + + while (ap != (arg_p) 0) { + if (ap->a_typ == ARGNUM) { + assign_label(ap->a_a.a_np->n_repl); + } + ap = ap->a_next; + } + } else if (lp->l_optyp == OPNUMLAB) + assign_label(lp->l_a.la_np->n_repl); + } + } +} + +shc_instr(lnp) +line_p lnp; +{ + char *s; + register instr = INSTR(lnp); + register int mult, arg, argdef; + line_p x = PREV(lnp); + line_p y = (x == (line_p) 0 ? (line_p) 0 : PREV(x)); + + if (state == NO_STACK_MES) return; + + if ( instr == op_lab) { + do_inst_label(lnp); + return; + } + if (instr < sp_fmnem || instr > sp_lmnem) { + return; + } + + if(state == NOTREACHED) return; /* What else ? */ + s = pop_push[instr]; + + if (*s != '0') + while (*s != '\0') { + if (*s++ == '-') mult = -1; + else mult = 1; + if (TYPE(lnp) == OPSHORT) { + arg = SHORT(lnp); + if (arg < wordsize) arg = wordsize; + argdef = TRUE; + } else if (IS_MINI(lnp)) { + arg = MINI(lnp); + if (arg > 0 && arg < wordsize) arg = wordsize; + if (arg < 0 && -arg < wordsize) arg = -wordsize; + argdef = TRUE; + } else argdef = FALSE; + switch (*s++) { + case 'w': stack_height += mult * wordsize; break; + case 'd': stack_height += mult * wordsize * 2; break; + case 'p': stack_height += mult * pointersize; break; + case 'a': + if (argdef == FALSE || instr == op_ass) { + change_state(NO_STACK_MES); + return; + } + stack_height += mult * arg; + break; + case 'x': + if (IS_LOC(x)) { + arg = MINI(x); + if (arg < wordsize) arg = wordsize; + stack_height += mult * arg; + break; + } + change_state(NO_STACK_MES); + return; + case 'y': + if (IS_LOC(y)) { + arg = MINI(y); + if (arg < wordsize) arg = wordsize; + stack_height += mult * arg; + break; + } + change_state(NO_STACK_MES); + return; + case '?': + /* Actually, the effect of a ret on the stack is + * known, but it has a '?' anyway. I think this + * should be changed in ~etc/em_table + */ + if (instr == op_ret) + break; + change_state(NO_STACK_MES); + return; + default: + assert(FALSE); + } + } + + if (ISABRANCH(instr)) do_inst_label(lnp); + if (NON_CONTINUABLE(instr)) change_state(NOTREACHED); +} + +change_state(mode) +int mode; +{ + state = mode; + if (mode != KNOWN) stack_height = 0; +} + +delete_labels() +{ + register lblst_p tmp; + + while ((tmp = est_list) != NULL) { + est_list = est_list->ll_next; + oldlblst(tmp); + } +} + +inst_old_label(lst_elt) +register lblst_p lst_elt; +{ + if (state != NOTREACHED) { + if (stack_height < 0 || lst_elt->ll_height != stack_height) { + change_state(NO_STACK_MES); + } + } else { /* after a label */ + stack_height = lst_elt->ll_height; + change_state(KNOWN); + } +} + +inst_new_label(label) +register num_p label; +{ + register lblst_p lst_elt; + + lst_elt = newlblst(); + lst_elt->ll_next = est_list; + lst_elt->ll_num = label; + lst_elt->ll_height = stack_height; + + est_list = lst_elt; + + label->n_lst_elt = lst_elt; + label->n_flags |= NUMSET; +} + +assign_label(label) +num_p label; +{ + if (label->n_flags & NUMSET) + inst_old_label(label->n_lst_elt); + else inst_new_label(label); +} + +do_inst_label(lnp) /* (re-)install a label */ +line_p lnp; +{ + num_p label = lnp->l_a.la_np->n_repl; + int instr = INSTR(lnp); + + assign_label(label); + + if (instr == op_lab) { + if (state == NOTREACHED) { + label->n_lst_elt->ll_fallthrough = FALSE; + } else { + label->n_lst_elt->ll_fallthrough = TRUE; + } + } else if (ISCONDBRANCH(instr)) { /* conditional branch */ + label->n_flags |= NUMCOND; + } +} diff --git a/util/opt/shc.h b/util/opt/shc.h new file mode 100644 index 000000000..5f76e65a8 --- /dev/null +++ b/util/opt/shc.h @@ -0,0 +1,20 @@ +/* + * Author: Hans van Eck. + */ + +typedef struct label_list *lblst_p; + +struct label_list { + lblst_p ll_next; /* pointer to next label in the list */ + num_p ll_num; /* pointer to label definition */ + short ll_height; /* the height of the stack at this label */ + char ll_fallthrough; /* is the label reached by fallthrough ? */ +}; + +typedef struct label_list lblst_t; + +extern lblst_p est_list; +extern int state; +#define KNOWN 1 +#define NOTREACHED 2 +#define NO_STACK_MES 3 diff --git a/util/opt/util.c b/util/opt/util.c index da9e3b8ac..8c6326ebd 100644 --- a/util/opt/util.c +++ b/util/opt/util.c @@ -5,6 +5,7 @@ static char rcsid[] = "$Header$"; #include #include "param.h" #include "types.h" +#include "shc.h" #include "assert.h" #include "lookup.h" #include "proinf.h" diff --git a/util/opt/var.c b/util/opt/var.c index 3eea009c2..5a39aca50 100644 --- a/util/opt/var.c +++ b/util/opt/var.c @@ -5,6 +5,7 @@ static char rcsid[] = "$Header$"; #include #include "param.h" #include "types.h" +#include "shc.h" #include "lookup.h" #include "proinf.h"