Line 627... |
Line 627... |
if (cuc_debug) cuc_check (f);
|
if (cuc_debug) cuc_check (f);
|
if (cuc_debug >= 3) print_cuc_bb (f, "join");
|
if (cuc_debug >= 3) print_cuc_bb (f, "join");
|
}
|
}
|
|
|
/* Optimize basic blocks */
|
/* Optimize basic blocks */
|
void optimize_bb (cuc_func *f)
|
int optimize_bb (cuc_func *f)
|
{
|
{
|
|
int modified = 0;
|
int i, j;
|
int i, j;
|
remove_lrbb:
|
remove_lrbb:
|
/* we can remove lrbb instructions from blocks with just one predecessor */
|
/* we can remove lrbb instructions from blocks with just one predecessor */
|
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)) {
|
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0) { /* exactly one predecessor */
|
if (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0) { /* exactly one predecessor */
|
Line 646... |
Line 647... |
f->bb[i].insn[j].type &= ~IT_VOLATILE;
|
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];
|
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].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].op[1] = f->bb[i].insn[j].op[2] = 0; /* always use left block */
|
f->bb[i].insn[j].opt[3] = OPT_NONE;
|
f->bb[i].insn[j].opt[3] = OPT_NONE;
|
|
modified = 1;
|
|
|
/* If the predecessor still has a conditional jump instruction, we must be careful.
|
/* 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 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 */
|
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].opt[1] = t->opt[1];
|
Line 689... |
Line 691... |
else assert (0);
|
else assert (0);
|
f->bb[i].prev[1] = -1;
|
f->bb[i].prev[1] = -1;
|
}
|
}
|
assert (f->bb[i].prev[0] >= 0 && f->bb[i].prev[1] < 0); /* one predecessor */
|
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);
|
join_bb (f, f->bb[i].prev[0], i, 1);
|
|
modified = 1;
|
goto remove_lrbb;
|
goto remove_lrbb;
|
}
|
}
|
|
|
/* Type 0 joining
|
/* Type 0 joining
|
1. link between pred & succ
|
1. link between pred & succ
|
Line 702... |
Line 705... |
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))
|
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[1] < 0 /* one predecessor */
|
&& f->bb[i].next[1] < 0 /* max. one successor */
|
&& f->bb[i].next[1] < 0 /* max. one successor */
|
&& f->bb[i].nmemory == 0) { /* and no memory acceses */
|
&& f->bb[i].nmemory == 0) { /* and no memory acceses */
|
join_bb (f, f->bb[i].prev[0], i, 0);
|
join_bb (f, f->bb[i].prev[0], i, 0);
|
|
modified = 1;
|
goto remove_lrbb;
|
goto remove_lrbb;
|
}
|
}
|
|
|
#if 1
|
|
/* Type 2 joining
|
/* Type 2 joining
|
1. link between pred & succ
|
1. link between pred & succ
|
2. succ has exactly one predeccessor
|
2. succ has exactly one predeccessor
|
3. pred & succ share common successor
|
3. pred & succ share common successor
|
4. optional succ's second successor */
|
4. optional succ's second successor */
|
Line 726... |
Line 729... |
#endif
|
#endif
|
if (f->bb[p].next[1] == i
|
if (f->bb[p].next[1] == i
|
&& (f->bb[i].next[0] == f->bb[p].next[1]
|
&& (f->bb[i].next[0] == f->bb[p].next[1]
|
|| f->bb[i].next[0] == f->bb[p].next[0])) {
|
|| f->bb[i].next[0] == f->bb[p].next[0])) {
|
join_bb (f, p, i, 2);
|
join_bb (f, p, i, 2);
|
|
modified = 1;
|
goto remove_lrbb;
|
goto remove_lrbb;
|
}
|
}
|
}
|
}
|
#endif
|
return modified;
|
}
|
}
|
|
|
/* Removes BBs marked as dead */
|
/* Removes BBs marked as dead */
|
void remove_dead_bb (cuc_func *f)
|
int remove_dead_bb (cuc_func *f)
|
{
|
{
|
int i, j, k, d = 0;
|
int i, j, k, d = 0;
|
|
|
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) {
|
if (f->bb[i].insn) free (f->bb[i].insn);
|
if (f->bb[i].insn) free (f->bb[i].insn);
|
Line 745... |
Line 749... |
reloc[i] = -1;
|
reloc[i] = -1;
|
} else {
|
} else {
|
reloc[i] = d;
|
reloc[i] = d;
|
f->bb[d++] = f->bb[i];
|
f->bb[d++] = f->bb[i];
|
}
|
}
|
|
if (f->num_bb == d) return 0;
|
f->num_bb = d;
|
f->num_bb = d;
|
|
|
/* relocate initial blocks */
|
/* relocate initial blocks */
|
for (i = 0; i < f->num_init_bb; i++)
|
for (i = 0; i < f->num_init_bb; i++)
|
f->init_bb_reloc[i] = reloc[f->init_bb_reloc[i]];
|
f->init_bb_reloc[i] = reloc[f->init_bb_reloc[i]];
|
Line 775... |
Line 780... |
int t = f->bb[i].insn[j].op[k];
|
int t = f->bb[i].insn[j].op[k];
|
assert (reloc[REF_BB(t)] >= 0);
|
assert (reloc[REF_BB(t)] >= 0);
|
f->bb[i].insn[j].op[k] = REF (reloc[REF_BB(t)], REF_I (t));
|
f->bb[i].insn[j].op[k] = REF (reloc[REF_BB(t)], REF_I (t));
|
}
|
}
|
}
|
}
|
|
return 1;
|
}
|
}
|
|
|
/* Recursive calculation of dependencies */
|
/* Recursive calculation of dependencies */
|
static int reg_dep_rec (cuc_func *f, int cur)
|
static int reg_dep_rec (cuc_func *f, int cur)
|
{
|
{
|