Converted dfa to use row displacement compaction
authorbruce <none@none>
Tue, 28 Jul 1987 09:37:09 +0000 (09:37 +0000)
committerbruce <none@none>
Tue, 28 Jul 1987 09:37:09 +0000 (09:37 +0000)
modules/src/em_opt/Makefile
modules/src/em_opt/findworst.c
modules/src/em_opt/initlex.c
modules/src/em_opt/nopt.c
modules/src/em_opt/nopt.h
modules/src/em_opt/outputdfa.c

index 58a9059..246829b 100644 (file)
@@ -1,5 +1,5 @@
 # $Header$
-EMHOME =       /proj/em/Work
+EMHOME =       ../../..
 INSTALL =      $(EMHOME)/modules/install
 COMPARE =      $(EMHOME)/modules/compare
 LINT   =       lint
index 420285a..88814d5 100644 (file)
@@ -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)
index 9337626..fc3675a 100644 (file)
@@ -6,7 +6,7 @@ static char rcsidp2[] = "$Header$";
 #include <em_flag.h>
 #include <em_spec.h>
 #include "parser.h"
-#define op_lab 255
+#define op_lab sp_fpseu        /* if you change this change nopt.h also */
 
 #include <idf_pkg.body>
 
index a50d8e4..90b5d0e 100644 (file)
@@ -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;
index 1bb873b..afb9ba6 100644 (file)
 
 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;
index fd22c51..d87af09 100644 (file)
@@ -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 (newsize<size);
+       printf("Extending next/check arrays from %d to %d\n",currsize,newsize);
+       next = (int *)Realloc(next,newsize);
+       check = (int *)Realloc(check,newsize);
+       /* clear ends of new arrays */
+       for(i=currsize;i<newsize;i++)
+               next[i] = check[i] = EMPTY;
+       currsize = newsize;
+}
+
+PRIVATE
+store_row(state,row)
+       int state;
+       register int *row;
+{
+       /* find a place to store row in arrays */
+       register b,i,o;
+       register int *n = next;
+       b=0;
+       for(;;) {
+               /* look for first possible place to store it */
+               for(i=0;i<MAXOPCODE;i++) {
+                       if(row[i]) {
+                               if((o = b+i)>currsize) increase_next(o);
+                               if(n[o]!=EMPTY) goto nextpos;
+                       }
+               }
+               /* found a place */
+               base[state]=b;
+               for(i=0;i<MAXOPCODE;i++)
+                       if(row[i]) {
+                               if((o=b+i) >maxpos) 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;i<currsize;i++) check[i]=next[i]=EMPTY;
        for(s=0;s<=higheststate;s++) {
-               fprintf(ofile,"static dfa%d();\n",s);
+               /* empty row */
+               for(i=0;i<MAXOPCODE;i++) row[i]=0;
+               numinrow = 0;
+               /* fill in non zero entries */
+               for(p=states[s];p!=(struct state *)NULL;p=p->next) {
+                       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;
+       }
+
+       /* 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,"\nint (*OO_fstate[])()=\n{\n");
+       fprintf(ofile,"};\n\n");
+       fprintf(ofile,"struct dfa *OO_base[] = {\n");
        for(s=0;s<=higheststate;s++) {
-               fprintf(ofile,"\tdfa%d,\n",s);
+               fprintf(ofile,"\t/* %4d: ",s);
+               outmnems(patterns[s]);
+               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,"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");
+               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