version 1.155, 2005/11/09 15:46:28
|
version 1.156, 2005/11/09 18:04:44
|
Line 1325 struct waypoint {
|
Line 1325 struct waypoint {
|
* or this transition (does not change state) */ |
* or this transition (does not change state) */ |
}; |
}; |
|
|
struct tpastate { /* tree parsing automaton (like) state */ |
struct tpa_state { /* tree parsing automaton (like) state */ |
/* labeling is back-to-front */ |
/* labeling is back-to-front */ |
struct waypoint *inst; /* in front of instruction */ |
struct waypoint *inst; /* in front of instruction */ |
struct waypoint *trans; /* in front of instruction and transition */ |
struct waypoint *trans; /* in front of instruction and transition */ |
}; |
}; |
|
|
struct tpastate *termstate = NULL; /* initialized in loader() */ |
struct tpa_state *termstate = NULL; /* initialized in loader() */ |
|
|
void init_waypoints(struct waypoint ws[]) |
void init_waypoints(struct waypoint ws[]) |
{ |
{ |
Line 1341 void init_waypoints(struct waypoint ws[]
|
Line 1341 void init_waypoints(struct waypoint ws[]
|
ws[k].cost=INF_COST; |
ws[k].cost=INF_COST; |
} |
} |
|
|
struct tpastate *empty_tpastate() |
struct tpa_state *empty_tpa_state() |
{ |
{ |
struct tpastate *s = malloc(sizeof(struct tpastate)); |
struct tpa_state *s = malloc(sizeof(struct tpa_state)); |
|
|
s->inst = malloc(maxstates*sizeof(struct waypoint)); |
s->inst = malloc(maxstates*sizeof(struct waypoint)); |
init_waypoints(s->inst); |
init_waypoints(s->inst); |
Line 1352 struct tpastate *empty_tpastate()
|
Line 1352 struct tpastate *empty_tpastate()
|
return s; |
return s; |
} |
} |
|
|
void transitions(struct tpastate *t) |
void transitions(struct tpa_state *t) |
{ |
{ |
int k; |
int k; |
struct super_state *l; |
struct super_state *l; |
Line 1380 void transitions(struct tpastate *t)
|
Line 1380 void transitions(struct tpastate *t)
|
} |
} |
} |
} |
|
|
struct tpastate *make_termstate() |
struct tpa_state *make_termstate() |
{ |
{ |
struct tpastate *s=empty_tpastate(); |
struct tpa_state *s=empty_tpa_state(); |
|
|
s->inst[CANONICAL_STATE].cost = 0; |
s->inst[CANONICAL_STATE].cost = 0; |
transitions(s); |
transitions(s); |
return s; |
return s; |
} |
} |
|
|
|
#define TPA_SIZE 16384 |
|
|
|
struct tpa_entry { |
|
struct tpa_entry *next; |
|
PrimNum inst; |
|
struct tpa_state *state_behind; /* note: brack-to-front labeling */ |
|
struct tpa_state *state_infront; /* note: brack-to-front labeling */ |
|
} *tpa_table[TPA_SIZE]; |
|
|
|
int hash_tpa(PrimNum p, struct tpa_state *t) |
|
{ |
|
UCell it = (UCell )t; |
|
return (p+it+(it>>14))&(TPA_SIZE-1); |
|
} |
|
|
|
struct tpa_state **lookup_tpa(PrimNum p, struct tpa_state *t2) |
|
{ |
|
int hash=hash_tpa(p, t2); |
|
struct tpa_entry *te = tpa_table[hash]; |
|
|
|
for (; te!=NULL; te = te->next) { |
|
if (p == te->inst && t2 == te->state_behind) |
|
return &(te->state_infront); |
|
} |
|
te = (struct tpa_entry *)malloc(sizeof(struct tpa_entry)); |
|
te->next = tpa_table[hash]; |
|
te->inst = p; |
|
te->state_behind = t2; |
|
te->state_infront = NULL; |
|
tpa_table[hash] = te; |
|
return &(te->state_infront); |
|
} |
|
|
/* use dynamic programming to find the shortest paths within the basic |
/* use dynamic programming to find the shortest paths within the basic |
block origs[0..ninsts-1] and rewrite the instructions pointed to by |
block origs[0..ninsts-1] and rewrite the instructions pointed to by |
instps to use it */ |
instps to use it */ |
void optimize_rewrite(Cell *instps[], PrimNum origs[], int ninsts) |
void optimize_rewrite(Cell *instps[], PrimNum origs[], int ninsts) |
{ |
{ |
int i,j; |
int i,j; |
struct tpastate *ts[ninsts+1]; |
struct tpa_state *ts[ninsts+1]; |
int nextdyn, nextstate, no_transition; |
int nextdyn, nextstate, no_transition; |
|
|
ts[ninsts] = termstate; |
ts[ninsts] = termstate; |
for (i=ninsts-1; i>=0; i--) { |
for (i=ninsts-1; i>=0; i--) { |
ts[i] = empty_tpastate(); |
struct tpa_state **tp = lookup_tpa(origs[i],ts[i+1]); |
for (j=1; j<=max_super && i+j<=ninsts; j++) { |
struct tpa_state *t = *tp; |
struct super_state **superp = lookup_super(origs+i, j); |
if (t) |
if (superp!=NULL) { |
ts[i] = t; |
struct super_state *supers = *superp; |
else { |
for (; supers!=NULL; supers = supers->next) { |
ts[i] = empty_tpa_state(); |
PrimNum s = supers->super; |
for (j=1; j<=max_super && i+j<=ninsts; j++) { |
int jcost; |
struct super_state **superp = lookup_super(origs+i, j); |
struct cost *c=super_costs+s; |
if (superp!=NULL) { |
struct waypoint *wi=&(ts[i]->inst[c->state_in]); |
struct super_state *supers = *superp; |
struct waypoint *wo=&(ts[i+j]->trans[c->state_out]); |
for (; supers!=NULL; supers = supers->next) { |
int no_transition = wo->no_transition; |
PrimNum s = supers->super; |
if (!(is_relocatable(s)) && !wo->relocatable) { |
int jcost; |
wo=&(ts[i+j]->inst[c->state_out]); |
struct cost *c=super_costs+s; |
no_transition=1; |
struct waypoint *wi=&(ts[i]->inst[c->state_in]); |
} |
struct waypoint *wo=&(ts[i+j]->trans[c->state_out]); |
if (wo->cost == INF_COST) |
int no_transition = wo->no_transition; |
continue; |
if (!(is_relocatable(s)) && !wo->relocatable) { |
jcost = wo->cost + ss_cost(s); |
wo=&(ts[i+j]->inst[c->state_out]); |
if (jcost <= wi->cost) { |
no_transition=1; |
wi->cost = jcost; |
} |
wi->inst = s; |
if (wo->cost == INF_COST) |
wi->relocatable = is_relocatable(s); |
continue; |
wi->no_transition = no_transition; |
jcost = wo->cost + ss_cost(s); |
/* if (ss_greedy) wi->cost = wo->cost ? */ |
if (jcost <= wi->cost) { |
|
wi->cost = jcost; |
|
wi->inst = s; |
|
wi->relocatable = is_relocatable(s); |
|
wi->no_transition = no_transition; |
|
/* if (ss_greedy) wi->cost = wo->cost ? */ |
|
} |
} |
} |
} |
} |
} |
} |
|
transitions(ts[i]); |
|
*tp = ts[i]; |
} |
} |
transitions(ts[i]); |
|
} |
} |
/* now rewrite the instructions */ |
/* now rewrite the instructions */ |
nextdyn=0; |
nextdyn=0; |