URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 931 to Rev 932
- ↔ Reverse comparison
Rev 931 → Rev 932
/trunk/or1ksim/cuc/cuc.h
76,7 → 76,8
#define BB_END 0x04 /* Whether this block is last */ |
#define BB_DEAD 0x08 /* This block is unaccessible -> to be removed */ |
|
#define BBID_END MAX_BB /* End pointer */ |
#define BBID_START MAX_BB /* Start BB pointer */ |
#define BBID_END (MAX_BB + 1) /* End BB pointer */ |
|
/* Various macros to minimize code size */ |
#define REF(bb,i) (((bb) * MAX_INSNS) + (i)) |
/trunk/or1ksim/cuc/bb.c
32,6 → 32,7
{ |
if (num < 0) printf ("*"); |
else if (num == BBID_END) printf ("END"); |
else if (num == BBID_START) printf ("START"); |
else printf ("%2x", num); |
} |
|
307,6 → 308,10
} |
} |
} |
/* Add START marker */ |
assert (f->bb[0].prev[0] < 0); |
f->bb[0].prev[0]= BBID_START; |
|
/* Add END marker */ |
for (i = 0; i < f->num_bb; i++) |
if (f->bb[i].type & BB_END) { |
645,19 → 650,21
/* Change to add LRBB, 0, 0 */ |
change_insn_type (&f->bb[i].insn[j], II_ADD); |
f->bb[i].insn[j].type &= ~IT_VOLATILE; |
t = &f->bb[f->bb[i].prev[0]].insn[f->bb[f->bb[i].prev[0]].ninsn - 1]; |
f->bb[i].insn[j].opt[1] = f->bb[i].insn[j].opt[2] = OPT_CONST; |
f->bb[i].insn[j].op[1] = f->bb[i].insn[j].op[2] = 0; /* always use left block */ |
f->bb[i].insn[j].opt[3] = OPT_NONE; |
modified = 1; |
if (f->bb[i].prev[0] != BBID_START) { |
t = &f->bb[f->bb[i].prev[0]].insn[f->bb[f->bb[i].prev[0]].ninsn - 1]; |
|
/* If the predecessor still has a conditional jump instruction, we must be careful. |
If next[0] == next[1] join them. Now we will link lrbb and correct the situation */ |
if (t->type & IT_BRANCH) { /* We must set a reference to branch result */ |
f->bb[i].insn[j].opt[1] = t->opt[1]; |
f->bb[i].insn[j].op[1] = t->op[1]; |
/* sometimes branch is not needed anymore */ |
if (f->bb[f->bb[i].prev[0]].next[1] < 0) change_insn_type (t, II_NOP); |
/* If the predecessor still has a conditional jump instruction, we must be careful. |
If next[0] == next[1] join them. Now we will link lrbb and correct the situation */ |
if (t->type & IT_BRANCH) { /* We must set a reference to branch result */ |
f->bb[i].insn[j].opt[1] = t->opt[1]; |
f->bb[i].insn[j].op[1] = t->op[1]; |
/* sometimes branch is not needed anymore */ |
if (f->bb[f->bb[i].prev[0]].next[1] < 0) change_insn_type (t, II_NOP); |
} |
} |
} |
} |
671,31 → 678,33
1. link between pred & succ |
2. no other pred's successors |
3. no other succ's predecessors, except if pred has max one */ |
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD)) |
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD)) { |
int p = f->bb[i].prev[0]; |
if (p < 0 || p == BBID_START) continue; |
/* one successor and max sum of 3 predecessors */ |
if (f->bb[f->bb[i].prev[0]].next[0] >= 0 && f->bb[f->bb[i].prev[0]].next[1] < 0 |
&& (f->bb[f->bb[i].prev[0]].prev[1] < 0 || f->bb[i].prev[1] < 0)) { |
if (f->bb[p].next[0] >= 0 && f->bb[p].next[1] < 0 |
&& (f->bb[p].prev[1] < 0 || f->bb[i].prev[1] < 0)) { |
/* First we will move all predecessors from succ to pred, and then we will do |
real type 1 joining */ |
if (f->bb[i].prev[1] >= 0) { |
if (f->bb[i].prev[1] >= 0 && f->bb[i].prev[1] != BBID_START) { |
int p1 = f->bb[i].prev[1]; |
/* joining is surely not worth another extra memory access */ |
if (f->bb[f->bb[i].prev[0]].nmemory) continue; |
if (f->bb[f->bb[i].prev[0]].prev[0] >= 0) { |
assert (f->bb[f->bb[i].prev[0]].prev[1] < 0); |
f->bb[f->bb[i].prev[0]].prev[1] = f->bb[i].prev[1]; |
} else f->bb[f->bb[i].prev[0]].prev[0] = f->bb[i].prev[1]; |
if (f->bb[f->bb[i].prev[1]].next[0] == i) |
f->bb[f->bb[i].prev[1]].next[0] = f->bb[i].prev[0]; |
else if (f->bb[f->bb[i].prev[1]].next[1] == i) |
f->bb[f->bb[i].prev[1]].next[1] = f->bb[i].prev[0]; |
if (f->bb[p].nmemory) continue; |
if (f->bb[p].prev[0] >= 0) { |
assert (f->bb[p].prev[1] < 0); |
f->bb[p].prev[1] = p1; |
} else f->bb[p].prev[0] = p1; |
if (f->bb[p1].next[0] == i) f->bb[p1].next[0] = p; |
else if (f->bb[p1].next[1] == i) f->bb[p1].next[1] = p; |
else assert (0); |
f->bb[i].prev[1] = -1; |
} |
assert (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0); /* one predecessor */ |
join_bb (f, f->bb[i].prev[0], i, 1); |
assert (p >= 0 && f->bb[i].prev[1] < 0); /* one predecessor */ |
join_bb (f, p, i, 1); |
modified = 1; |
goto remove_lrbb; |
} |
} |
|
/* Type 0 joining |
1. link between pred & succ |
703,7 → 712,8
3. optional pred's second successors |
4. max. one succ's successors */ |
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD)) |
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0 /* one predecessor */ |
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[0] != BBID_START |
&& f->bb[i].prev[1] < 0 /* one predecessor */ |
&& f->bb[i].next[1] < 0 /* max. one successor */ |
&& f->bb[i].nmemory == 0) { /* and no memory acceses */ |
join_bb (f, f->bb[i].prev[0], i, 0); |
719,6 → 729,7
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD)) |
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0) { /* one predecessor */ |
int p = f->bb[i].prev[0]; |
if (p == BBID_START) continue; |
#if 0 /* not yet supported */ |
if (f->bb[p].next[0] == i |
&& (f->bb[i].next[1] == f->bb[p].next[1] |
762,8 → 773,10
for (i = 0; i < f->num_bb; i++) if (!(f->bb[i].type & BB_DEAD)) { |
printf ("%x %x %x %x %x\n", i, f->bb[i].prev[0], f->bb[i].prev[1], f->bb[i].next[0], f->bb[i].next[1]); |
fflush (stdout); |
if (f->bb[i].prev[0] >= 0) assert ((f->bb[i].prev[0] = reloc[f->bb[i].prev[0]]) >= 0); |
if (f->bb[i].prev[1] >= 0) assert ((f->bb[i].prev[1] = reloc[f->bb[i].prev[1]]) >= 0); |
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[0] != BBID_START) |
assert ((f->bb[i].prev[0] = reloc[f->bb[i].prev[0]]) >= 0); |
if (f->bb[i].prev[1] >= 0 && f->bb[i].prev[1] != BBID_START) |
assert ((f->bb[i].prev[1] = reloc[f->bb[i].prev[1]]) >= 0); |
if (f->bb[i].next[0] >= 0 && f->bb[i].next[0] != BBID_END) |
assert ((f->bb[i].next[0] = reloc[f->bb[i].next[0]]) >= 0); |
if (f->bb[i].next[1] >= 0 && f->bb[i].next[1] != BBID_END) |
839,8 → 852,10
/* search though all non-visited for minimum number of unvisited predecessors */ |
for (b = 0; b < f->num_bb; b++) if (!f->bb[b].tmp) { |
int tmp = 0; |
if (f->bb[b].prev[0] >= 0 && !f->bb[f->bb[b].prev[0]].tmp) tmp++; |
if (f->bb[b].prev[1] >= 0 && !f->bb[f->bb[b].prev[1]].tmp) tmp++; |
if (f->bb[b].prev[0] >= 0 && f->bb[b].prev[0] != BBID_START |
&& !f->bb[f->bb[b].prev[0]].tmp) tmp++; |
if (f->bb[b].prev[1] >= 0 && f->bb[b].prev[1] != BBID_START |
&& !f->bb[f->bb[b].prev[1]].tmp) tmp++; |
if (tmp < min) { |
minb = b; |
min = tmp; |
862,9 → 877,9
assert (f->bb[b].insn[i].index == II_CMOV); |
assert (f->bb[b].insn[i].opt[0] == OPT_REGISTER | OPT_DEST); |
assert (f->bb[b].insn[i].op[0] == i); |
if (f->bb[b].prev[0] < 0) pa = -1; |
if (f->bb[b].prev[0] < 0 || f->bb[b].prev[0] == BBID_START) pa = -1; |
else pa = f->bb[f->bb[b].prev[0]].last_used_reg[i]; |
if (f->bb[b].prev[1] < 0) pb = -1; |
if (f->bb[b].prev[1] < 0 || f->bb[b].prev[1] == BBID_START) pb = -1; |
else pb = f->bb[f->bb[b].prev[1]].last_used_reg[i]; |
|
/* We do some very simple optimizations right away to make things more readable */ |
/trunk/or1ksim/cuc/insn.c
177,13 → 177,22
ii->op[1] = 0; ii->opt[1] = OPT_CONST; |
ii->op[2] = 0; ii->opt[2] = OPT_CONST; |
return 1; |
} else if (ii->opt[2] & OPT_CONST && c == 0xffffffff) { |
change_insn_type (ii, II_ADD); |
ii->op[2] = 0; ii->opt[2] = OPT_CONST; |
return 1; |
} else break; |
case II_OR: |
if (ii->opt[2] & OPT_CONST && c == 0xffffffff) { |
if (ii->opt[2] & OPT_CONST && c == 0x0) { |
change_insn_type (ii, II_ADD); |
ii->op[1] = c; ii->opt[1] = OPT_CONST; |
ii->op[2] = 0; ii->opt[2] = OPT_CONST; |
return 1; |
} else if (ii->opt[2] & OPT_CONST && c == 0xffffffff) { |
change_insn_type (ii, II_ADD); |
ii->op[1] = 0xffffffff; ii->opt[1] = OPT_CONST; |
ii->op[2] = 0; ii->opt[2] = OPT_CONST; |
return 1; |
} else break; |
case II_SUB: |
if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) { |
732,6 → 741,18
return modified; |
} |
|
static void unmark_tree (cuc_func *f, int ref) |
{ |
cuc_insn *ii = &f->INSN(ref); |
printf ("%x ", ref); |
if (ii->type & IT_UNUSED) { |
int j; |
ii->type &= ~IT_UNUSED; |
for (j = 0; j < MAX_OPERANDS; j++) |
if (ii->opt[j] & OPT_REF) unmark_tree (f, ii->op[j]); |
} |
} |
|
/* Remove unused assignments */ |
int remove_dead (cuc_func *f) |
{ |
738,16 → 759,18
int b, i, j; |
for (b = 0; b < f->num_bb; b++) |
for (i = 0; i < f->bb[b].ninsn; i++) |
if (!(f->bb[b].insn[i].type & (IT_VOLATILE | IT_OUTPUT))) |
f->bb[b].insn[i].type |= IT_UNUSED; |
f->bb[b].insn[i].type |= IT_UNUSED; |
|
for (b = 0; b < f->num_bb; b++) { |
for (i = 0; i < f->bb[b].ninsn; i++) |
for (j = 0; j < MAX_OPERANDS; j++) |
if (f->bb[b].insn[i].opt[j] & OPT_REF) { |
f->INSN(f->bb[b].insn[i].op[j]).type &= ~IT_UNUSED; |
} |
} |
for (b = 0; b < f->num_bb; b++) |
for (i = 0; i < f->bb[b].ninsn; i++) { |
cuc_insn *ii = &f->bb[b].insn[i]; |
if (ii->type & IT_VOLATILE || ii->type & IT_OUTPUT |
|| II_IS_LOAD (ii->index) && (f->memory_order == MO_NONE || f->memory_order == MO_WEAK) |
|| II_IS_STORE (ii->index)) { |
unmark_tree (f, REF (b, i)); |
printf ("\n"); |
} |
} |
|
for (b = 0; b < f->num_bb; b++) |
for (i = 0; i < f->bb[b].ninsn; i++) |
/trunk/or1ksim/cuc/verilog.c
155,8 → 155,11
} |
} else if (ii->index == II_LRBB) { |
GEN (" if (rst) t%x_%x <= #Tp 1'b0;\n", b, i); |
assert (f->bb[b].prev[0] >= 0 && f->bb[b].prev[0] != BBID_END); |
GEN (" else if (bb_start[%i]) t%x_%x <= #Tp bb_stb[%i];\n", b, b, i, f->bb[b].prev[0]); |
assert (f->bb[b].prev[0] >= 0); |
if (f->bb[b].prev[0] == BBID_START) |
GEN (" else if (bb_start[%i]) t%x_%x <= #Tp start_i;\n", b, b, i); |
else |
GEN (" else if (bb_start[%i]) t%x_%x <= #Tp bb_stb[%i];\n", b, b, i, f->bb[b].prev[0]); |
} else if (ii->index == II_REG) { |
assert (ii->opt[1] == OPT_REF); |
GEN (" if ("); |
472,7 → 475,7
GEN ("wire [%2i:0] bb_start = {\n", f->num_bb - 1); |
for (b = f->num_bb - 1; b >= 0; b--) { |
GEN (" /* bb_start[%2i] */ ", b); |
for (i = 0; i < 2; i++) if (f->bb[b].prev[i] >= 0) { |
for (i = 0; i < 2; i++) if (f->bb[b].prev[i] >= 0 && f->bb[b].prev[i] != BBID_START) { |
cuc_bb *prev = &f->bb[f->bb[b].prev[i]]; |
int t; |
if (i) GEN ("\n || "); |
/trunk/or1ksim/cuc/cuc.c
47,6 → 47,7
{ |
int modified = 0; |
log ("Optimizing.\n"); |
insert_conditional_facts (func); |
do { |
modified = 0; |
if (optimize_cmovs (func)) { |
/trunk/or1ksim/cuc/timings.c
206,7 → 206,8
prevcnt++; |
} else { |
/* End the block */ |
if (prevbb >= 0) f->bb[prevbb].cnt += prevcnt / f->bb[prevbb].unrolled + 1; |
if (prevbb >= 0 && prevbb != BBID_START) |
f->bb[prevbb].cnt += prevcnt / f->bb[prevbb].unrolled + 1; |
prevcnt = 0; |
prevbb = b; |
} |
/trunk/or1ksim/cuc/insn.h
58,6 → 58,7
#define II_SIGNED 0x2000 |
|
#define II_IS_LOAD(x) ((x) == II_LB || (x) == II_LH || (x) == II_LW) |
#define II_IS_STORE(x) ((x) == II_SB || (x) == II_SH || (x) == II_SW) |
#define II_MEM_WIDTH(x) (((x) == II_LB || (x) == II_SB) ? 1 :\ |
((x) == II_LH || (x) == II_SH) ? 2 :\ |
((x) == II_LW || (x) == II_SW) ? 4 : -1) |