Converted dfa to use row displacement compaction
This commit is contained in:
parent
ead2873ab5
commit
545bed355d
|
@ -1,5 +1,5 @@
|
|||
# $Header$
|
||||
EMHOME = /proj/em/Work
|
||||
EMHOME = ../../..
|
||||
INSTALL = $(EMHOME)/modules/install
|
||||
COMPARE = $(EMHOME)/modules/compare
|
||||
LINT = lint
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
fprintf(ofile,"\nint (*OO_fstate[])()=\n{\n");
|
||||
for(s=0;s<=higheststate;s++) {
|
||||
fprintf(ofile,"\tdfa%d,\n",s);
|
||||
/* 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,"};\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,"*/\t");
|
||||
if(base[s]==EMPTY)
|
||||
fprintf(ofile,"0,\n");
|
||||
else
|
||||
fprintf(ofile,"&OO_checknext[%4d],\n", base[s]);
|
||||
}
|
||||
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");
|
||||
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,"\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,"{%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
|
||||
|
|
Loading…
Reference in a new issue