Converted dfa to use row displacement compaction

This commit is contained in:
bruce 1987-07-28 09:37:09 +00:00
parent ead2873ab5
commit 545bed355d
6 changed files with 182 additions and 85 deletions

View file

@ -1,5 +1,5 @@
# $Header$
EMHOME = /proj/em/Work
EMHOME = ../../..
INSTALL = $(EMHOME)/modules/install
COMPARE = $(EMHOME)/modules/compare
LINT = lint

View 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)

View 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>

View 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;

View file

@ -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;

View 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;
}
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