瀏覽代碼

added stackheight computation

eck 34 年之前
父節點
當前提交
c08f3b3c80
共有 18 個文件被更改,包括 358 次插入13 次删除
  1. 43 13
      util/opt/Makefile
  2. 11 0
      util/opt/alloc.c
  3. 1 0
      util/opt/alloc.h
  4. 1 0
      util/opt/backward.c
  5. 1 0
      util/opt/flow.c
  6. 7 0
      util/opt/getline.c
  7. 1 0
      util/opt/line.h
  8. 1 0
      util/opt/lookup.c
  9. 1 0
      util/opt/main.c
  10. 1 0
      util/opt/peephole.c
  11. 18 0
      util/opt/process.c
  12. 3 0
      util/opt/proinf.h
  13. 1 0
      util/opt/putline.c
  14. 20 0
      util/opt/reg.c
  15. 226 0
      util/opt/shc.c
  16. 20 0
      util/opt/shc.h
  17. 1 0
      util/opt/util.c
  18. 1 0
      util/opt/var.c

+ 43 - 13
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

+ 11 - 0
util/opt/alloc.c

@@ -5,6 +5,7 @@ static char rcsid[] = "$Header$";
 #include <stdio.h>
 #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)));

+ 1 - 0
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();

+ 1 - 0
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"

+ 1 - 0
util/opt/flow.c

@@ -4,6 +4,7 @@ static char rcsid[] = "$Header$";
 
 #include "param.h"
 #include "types.h"
+#include "shc.h"
 #include <em_flag.h>
 #include <em_spec.h>
 #include <em_mnem.h>

+ 7 - 0
util/opt/getline.c

@@ -5,6 +5,7 @@ static char rcsid[] = "$Header$";
 #include <stdio.h>
 #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:

+ 1 - 0
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;

+ 1 - 0
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"

+ 1 - 0
util/opt/main.c

@@ -5,6 +5,7 @@ static char rcsid[] = "$Header$";
 #include <stdio.h>
 #include "param.h"
 #include "types.h"
+#include "shc.h"
 #include "alloc.h"
 #include <em_spec.h>
 #include "ext.h"

+ 1 - 0
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"

+ 18 - 0
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 <em_spec.h>
 #include <em_pseu.h>
@@ -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;
+	}
+}

+ 3 - 0
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();

+ 1 - 0
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 <em_spec.h>
 #include <em_pseu.h>

+ 20 - 0
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 <em_spec.h>
@@ -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;
 

+ 226 - 0
util/opt/shc.c

@@ -0,0 +1,226 @@
+/*
+ * This file contains the main part of the stackheight computation phase. 
+ *
+ * Author: Hans van Eck. 
+ */
+
+#include <stdio.h>
+#include <em_spec.h>
+#include <em_mnem.h>
+#include <em_pseu.h>
+#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;
+	}
+}

+ 20 - 0
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

+ 1 - 0
util/opt/util.c

@@ -5,6 +5,7 @@ static char rcsid[] = "$Header$";
 #include <stdio.h>
 #include "param.h"
 #include "types.h"
+#include "shc.h"
 #include "assert.h"
 #include "lookup.h"
 #include "proinf.h"

+ 1 - 0
util/opt/var.c

@@ -5,6 +5,7 @@ static char rcsid[] = "$Header$";
 #include <stdio.h>
 #include "param.h"
 #include "types.h"
+#include "shc.h"
 #include "lookup.h"
 #include "proinf.h"