From 545bed355d354e2f482fab6f5ca7ef9d212a1af1 Mon Sep 17 00:00:00 2001 From: bruce Date: Tue, 28 Jul 1987 09:37:09 +0000 Subject: [PATCH] Converted dfa to use row displacement compaction --- modules/src/em_opt/Makefile | 2 +- modules/src/em_opt/findworst.c | 9 +- modules/src/em_opt/initlex.c | 2 +- modules/src/em_opt/nopt.c | 60 ++++++----- modules/src/em_opt/nopt.h | 10 ++ modules/src/em_opt/outputdfa.c | 184 +++++++++++++++++++++++---------- 6 files changed, 182 insertions(+), 85 deletions(-) diff --git a/modules/src/em_opt/Makefile b/modules/src/em_opt/Makefile index 58a90593d..246829b94 100644 --- a/modules/src/em_opt/Makefile +++ b/modules/src/em_opt/Makefile @@ -1,5 +1,5 @@ # $Header$ -EMHOME = /proj/em/Work +EMHOME = ../../.. INSTALL = $(EMHOME)/modules/install COMPARE = $(EMHOME)/modules/compare LINT = lint diff --git a/modules/src/em_opt/findworst.c b/modules/src/em_opt/findworst.c index 420285a81..88814d5d8 100644 --- a/modules/src/em_opt/findworst.c +++ b/modules/src/em_opt/findworst.c @@ -6,8 +6,8 @@ static char rcsidp3[] = "$Header$"; #define UPDATEWORST(backups) if(backups>mostbackups) mostbackups = backups; -findworst(repl) - struct mnems repl; +findworst(patt,repl) + struct mnems patt,repl; { /* /* Find the pattern that requires the most backup of output queue. @@ -26,11 +26,12 @@ findworst(repl) /* requires a backup of n-i+1 instructions and a goto to state 0. */ int n = repl.m_len; + int diff = patt.m_len - repl.m_len; int first,i; int s; int mostbackups = 0; if(n==0) { - fprintf(ofile,"\t\tOO_backup(%d);\n", maxpattern-1); + fprintf(ofile,"\t\tOO_mkrepl(0,%d,%d);\n",diff,maxpattern-1); return; } for(s=1;s<=higheststate;s++) { @@ -56,7 +57,7 @@ findworst(repl) } } } - fprintf(ofile,"\t\tOO_backup(%d);\n",mostbackups); + fprintf(ofile,"\t\tOO_mkrepl(%d,%d,%d);\n",n,diff,mostbackups); } findfail(state,resout,rescpy,resgto) diff --git a/modules/src/em_opt/initlex.c b/modules/src/em_opt/initlex.c index 933762650..fc3675a39 100644 --- a/modules/src/em_opt/initlex.c +++ b/modules/src/em_opt/initlex.c @@ -6,7 +6,7 @@ static char rcsidp2[] = "$Header$"; #include #include #include "parser.h" -#define op_lab 255 +#define op_lab sp_fpseu /* if you change this change nopt.h also */ #include diff --git a/modules/src/em_opt/nopt.c b/modules/src/em_opt/nopt.c index a50d8e4f1..90b5d0e71 100644 --- a/modules/src/em_opt/nopt.c +++ b/modules/src/em_opt/nopt.c @@ -4,13 +4,18 @@ static char rcsid2[] = "$Header$"; #include "nopt.h" -extern int (*OO_fstate[])(); /* Initialized from patterns in dfa.c */ -extern int OO_maxpattern; /* Initialized from patterns in dfa.c */ -extern int OO_maxreplacement; /* Initialized from patterns in dfa.c */ +extern struct dfa OO_checknext[]; /* Initialized in dfa.c */ +extern struct dfa *OO_base[]; /* Initialized in dfa.c */ +extern struct dodefault OO_default[]; /* Initialized in dfa.c */ +extern int OO_maxpattern; /* Initialized in dfa.c */ +extern int OO_maxreplacement; /* Initialized in dfa.c */ +extern int (*OO_ftrans[])(); /* Initialized in trans.c */ extern char em_mnem[][4]; extern char em_pseu[][4]; +int OO_state = 0; + p_instr OO_buffer; p_instr OO_patternqueue; p_instr OO_nxtpatt; @@ -69,9 +74,23 @@ O_close() OO_dfa(last) register int last; { + register struct dfa *b; + register struct dodefault *d; + register int (*f)(); for(;;) { printstate("OO_dfa"); - (*OO_fstate[OO_state])(last); + if((b=OO_base[OO_state]) && ((b += last)->check==OO_state)) { + if(f=OO_ftrans[OO_state = b->next]) f(); + } + else if (OO_state) { + /* consult default entry */ + d = &OO_default[OO_state]; + if(!OO_endbackup) OO_endbackup = OO_nxtpatt; + OO_nxtpatt--; + OO_patternqueue += d->numout; + if(f=OO_ftrans[OO_state = d->next]) f(); + } + else OO_flush(); if (!OO_endbackup) return; last = (OO_nxtpatt++)->em_opcode; if (OO_nxtpatt >= OO_endbackup) @@ -197,18 +216,17 @@ OO_mkext(p,opcode,arg,off) } } -OO_backup(n) - int n; +OO_mkrepl(lrepl,diff,numbkup) + int lrepl,diff,numbkup; { /* copy the replacement queue into the buffer queue */ /* then move the pattern queue back n places */ register p_instr p,q; - register int i,lrepl, diff; + register int i; printstate("Before backup"); - lrepl = OO_nxtrepl-OO_replqueue; if(OO_endbackup) { /* move the region between OO_nxtpatt and OO_endbackup */ - if ((diff = (OO_nxtpatt-OO_patternqueue) - lrepl) > 0) { + if (diff > 0) { /* move left by diff */ BTSCPY(p,q,i,OO_nxtpatt-diff,OO_nxtpatt,OO_endbackup-OO_nxtpatt); OO_nxtpatt -= diff; @@ -233,28 +251,16 @@ OO_backup(n) OO_nxtrepl = OO_replqueue; OO_patternqueue += lrepl; } - /* now move the position of interest back n instructions */ - if ((OO_patternqueue-OO_buffer) < n) - n = (OO_patternqueue-OO_buffer); - OO_nxtpatt = OO_patternqueue -= n; - if(!OO_endbackup && n) - OO_endbackup = OO_patternqueue+n; + /* now move the position of interest back nunbkup instructions */ + if ((OO_patternqueue-OO_buffer) < numbkup) + numbkup = (OO_patternqueue-OO_buffer); + OO_nxtpatt = OO_patternqueue -= numbkup; + if(!OO_endbackup && numbkup) + OO_endbackup = OO_patternqueue+numbkup; OO_state = 0; printstate("After backup"); } -OO_dodefault(numout, newstate) - int numout; - int newstate; -{ - printstate("Before dodefault"); - if(!OO_endbackup) OO_endbackup = OO_nxtpatt; - OO_nxtpatt--; - OO_patternqueue += numout; - OO_state = newstate; - printstate("After dodefault"); -} - #ifdef DEBUG dumpstate(mess) char *mess; diff --git a/modules/src/em_opt/nopt.h b/modules/src/em_opt/nopt.h index 1bb873bf6..afb9ba60b 100644 --- a/modules/src/em_opt/nopt.h +++ b/modules/src/em_opt/nopt.h @@ -20,6 +20,16 @@ typedef struct e_instr *p_instr; +struct dfa { + short check; + short next; +}; + +struct dodefault { + short numout; + short next; +}; + extern p_instr OO_buffer; extern p_instr OO_patternqueue; extern p_instr OO_nxtpatt; diff --git a/modules/src/em_opt/outputdfa.c b/modules/src/em_opt/outputdfa.c index fd22c5110..d87af0985 100644 --- a/modules/src/em_opt/outputdfa.c +++ b/modules/src/em_opt/outputdfa.c @@ -90,66 +90,136 @@ RENAME(x,y) unlink(x); } +# define MAXOPCODE 255 +# define EMPTY -1 + +int *next, *check, *base; +unsigned currsize; /* current size of next and check arrays */ +int maxpos = 0; /* highest used position in these arrayes */ + +PRIVATE +increase_next(size) + int size; +{ + /* realloc arrays next and check so they are at least + * of size 'size' + */ + char *Realloc(); + unsigned newsize = currsize; + register int i; + do { + newsize *= 2; + } while (newsizecurrsize) increase_next(o); + if(n[o]!=EMPTY) goto nextpos; + } + } + /* found a place */ + base[state]=b; + for(i=0;imaxpos) maxpos = o; + next[o] = row[i]; + check[o] = state; + } + return; + nextpos: + ++b; + } +} + PRIVATE outdfa() { - int s; - struct state *p; + register int s,i; + register struct state *p; int nout, ncpy, ngto; - int seenswitch; + int row[MAXOPCODE]; + int numinrow; + int numentries = 0; + fprintf(ofile,"#include \"nopt.h\"\n"); fprintf(ofile,"\n"); fprintf(ofile,"int OO_maxreplacement = %d;\n", maxreplacement); - fprintf(ofile,"int OO_state = 0;\n"); fprintf(ofile,"\n"); + + /* find how many entries in dfa */ + for(s=0;s<=higheststate;s++) + for(p=states[s];p!=(struct state *)NULL;p=p->next) + numentries++; + /* start with next and check arrays twice this size */ + currsize = 2 * numentries; + next = (int *)Malloc(currsize*sizeof(int)); + check = (int *)Malloc(currsize*sizeof(int)); + base = (int *)Malloc(((unsigned)(higheststate+1))*sizeof(int)); + /* fill next array with EMPTY */ + for(i=0;inext) { + numinrow++; + row[p->op->id_opcode] = p->goto_state; + } + /* look for a place to store row */ + if(numinrow) + store_row(s,row); + else + base[s] = EMPTY; } - fprintf(ofile,"\nint (*OO_fstate[])()=\n{\n"); - for(s=0;s<=higheststate;s++) { - fprintf(ofile,"\tdfa%d,\n",s); + + /* output the arrays */ + printf("Compacted %d entries into %d positions\n",numentries,maxpos); + fprintf(ofile,"struct dfa OO_checknext[] = {\n"); + for(i=0;i<=maxpos;i++) { + fprintf(ofile,"\t/* %4d */\t",i); + fprintf(ofile,"{%4d,%4d},\n", check[i], next[i]); } fprintf(ofile,"};\n\n"); + fprintf(ofile,"struct dfa *OO_base[] = {\n"); for(s=0;s<=higheststate;s++) { - fprintf(ofile,"static dfa%d(opcode)\n",s); - fprintf(ofile,"\tint opcode;\n"); - fprintf(ofile,"{\n"); - fprintf(ofile,"\t/* "); + fprintf(ofile,"\t/* %4d: ",s); outmnems(patterns[s]); - fprintf(ofile," */\n"); - seenswitch = 0; - for(p=states[s];p!=(struct state *)NULL;p=p->next) { - if(!seenswitch) { - seenswitch++; - fprintf(ofile,"\tswitch(opcode) {\n"); - } - fprintf(ofile,"\tcase op_%s: ",p->op->id_text); - if(actions[p->goto_state]==(struct action *)NULL) - fprintf(ofile,"OO_state = %d; ",p->goto_state); - else fprintf(ofile,"OO_%ddotrans(); ",p->goto_state); - fprintf(ofile,"break;\n"); - } - if(s==0) { - if(!seenswitch) { - seenswitch++; - fprintf(ofile,"\tswitch(opcode) {\n"); - } - fprintf(ofile,"\tdefault:\n"); - fprintf(ofile,"\t\tOO_flush();\n"); - fprintf(ofile,"\t\tbreak;\n"); - } - else { - if(seenswitch) fprintf(ofile,"\tdefault:\n"); - findfail(s,&nout,&ncpy,&ngto); - fprintf(ofile,"\t\tOO_dodefault(%d,%d);\n",nout,ngto); - if(actions[ngto]!=NULL) - fprintf(ofile,"\t\tOO_%ddotrans();\n",ngto); - if(seenswitch) fprintf(ofile,"\t\tbreak;\n"); - } - if(seenswitch) fprintf(ofile,"\t}\n"); - fprintf(ofile,"}\n"); - fprintf(ofile,"\n"); + fprintf(ofile,"*/\t"); + if(base[s]==EMPTY) + fprintf(ofile,"0,\n"); + else + fprintf(ofile,"&OO_checknext[%4d],\n", base[s]); } + fprintf(ofile,"};\n\n"); + fprintf(ofile,"struct dodefault OO_default[] = {\n"); + for(s=0;s<=higheststate;s++) { + fprintf(ofile,"\t/* %4d: ",s); + outmnems(patterns[s]); + fprintf(ofile,"*/\t"); + findfail(s,&nout,&ncpy,&ngto); + fprintf(ofile,"{%4d,%4d},\n", nout,ngto); + } + fprintf(ofile,"};\n\n"); } PRIVATE @@ -168,9 +238,24 @@ outdotrans() struct action *a; int seennontested; fprintf(ofile,"#include \"nopt.h\"\n\n"); + /* declare all the trans functions */ + for(s=0;s<=higheststate;s++) { + if(actions[s]!=(struct action *)NULL) + fprintf(ofile,"static do%dtrans();\n",s); + } + /* output the array itself */ + fprintf(ofile,"\nint (*OO_ftrans[])()=\n{\n"); + for(s=0;s<=higheststate;s++) { + if(actions[s]!=(struct action *)NULL) + fprintf(ofile,"\tdo%dtrans,\n",s); + else + fprintf(ofile,"\t0,\n"); + } + fprintf(ofile,"};\n\n"); + /* now output the functions */ for(s=0;s<=higheststate;s++) { if(actions[s]!=(struct action *)NULL) { - fprintf(ofile,"\nOO_%ddotrans() {\n",s); + fprintf(ofile,"\nstatic do%dtrans() {\n",s); fprintf(ofile,"\tregister p_instr patt = OO_patternqueue;\n"); fprintf(ofile,"\t/* "); outmnems(patterns[s]); @@ -194,13 +279,8 @@ outdotrans() outoneaction(s,a); } } - if(!seennontested) - fprintf(ofile,"\tOO_state=%d;\n",s); fprintf(ofile,"}\n"); } - /* - * else fprintf(ofile,"\nOO_%ddotrans() {\n\tOO_state=%d;\n}\n",s,s); - */ } } @@ -216,7 +296,7 @@ outoneaction(s,a) fprintf(ofile,"\t\tif(OO_wrstats) fprintf(stderr,\"%d\\n\");\n",a->linenum); fprintf(ofile,"#endif\n"); outrepl(s,a->replacement); - findworst(a->replacement); + findworst(patterns[s],a->replacement); } PRIVATE