Line 71... |
Line 71... |
} else PRINTF ("\n");
|
} else PRINTF ("\n");
|
fflush (stdout);
|
fflush (stdout);
|
}
|
}
|
|
|
/* Copies src basic block into destination */
|
/* Copies src basic block into destination */
|
cuc_bb *cpy_bb (cuc_bb *dest, cuc_bb *src)
|
void cpy_bb (cuc_bb *dest, cuc_bb *src)
|
{
|
{
|
int i, j;
|
int i, j;
|
dep_list *d;
|
dep_list *d;
|
assert (dest != src);
|
assert (dest != src);
|
*dest = *src;
|
*dest = *src;
|
Line 350... |
Line 350... |
}
|
}
|
|
|
/* We do a quick check if there are some anomalies with references */
|
/* We do a quick check if there are some anomalies with references */
|
void cuc_check (cuc_func *f)
|
void cuc_check (cuc_func *f)
|
{
|
{
|
int i, j, k;
|
int i, j = 0, k = 0;
|
cucdebug (1, "cuc_check\n");
|
cucdebug (1, "cuc_check\n");
|
for (i = 0; i < f->num_bb; i++) {
|
for (i = 0; i < f->num_bb; i++) {
|
if (!f->bb[i].insn && f->bb[i].ninsn) goto err;
|
if (!f->bb[i].insn && f->bb[i].ninsn) goto err;
|
for (j = 0; j < f->bb[i].ninsn; j++) {
|
for (j = 0; j < f->bb[i].ninsn; j++) {
|
cuc_insn *ii = &f->bb[i].insn[j];
|
cuc_insn *ii = &f->bb[i].insn[j];
|
Line 367... |
Line 367... |
}
|
}
|
}
|
}
|
for (k = 0; k < MAX_OPERANDS; k++) {
|
for (k = 0; k < MAX_OPERANDS; k++) {
|
if (ii->opt[k] & OPT_REF) {
|
if (ii->opt[k] & OPT_REF) {
|
int t = ii->op[k];
|
int t = ii->op[k];
|
if (REF_BB(t) >= f->num_bb || REF_I (t) >= f->bb[REF_BB(t)].ninsn
|
if (REF_BB(t) >= f->num_bb || REF_I (t) >= f->bb[REF_BB(t)].ninsn ||
|
|| (ii->index == II_CMOV || ii->index == II_ADD) && (
|
((ii->index == II_CMOV || ii->index == II_ADD) &&
|
(f->INSN(t).type & IT_COND) != (ii->type & IT_COND) && k < 3
|
(((f->INSN(t).type & IT_COND) != (ii->type & IT_COND) && k < 3) ||
|
|| !(f->INSN(t).type & IT_COND) && k == 3)) {
|
((!(f->INSN(t).type & IT_COND) && k == 3))))) {
|
cucdebug (1, "Conditional misused\n");
|
cucdebug (1, "Conditional misused\n");
|
goto err;
|
goto err;
|
}
|
}
|
}
|
}
|
if (k && ii->opt[k] & OPT_DEST) {
|
if (k && ii->opt[k] & OPT_DEST) {
|
Line 481... |
Line 481... |
* type == 1; keep successor condition
|
* type == 1; keep successor condition
|
* type == 2; join loop unrolled blocks */
|
* type == 2; join loop unrolled blocks */
|
static void join_bb (cuc_func *f, int pred, int succ, int type)
|
static void join_bb (cuc_func *f, int pred, int succ, int type)
|
{
|
{
|
int i, j, k, n1, n2, ninsn, add_cond = 0;
|
int i, j, k, n1, n2, ninsn, add_cond = 0;
|
unsigned long cond_op, cond_opt;
|
unsigned long cond_op = 0, cond_opt = 0;
|
cuc_insn *insn;
|
cuc_insn *insn;
|
|
|
if (cuc_debug) cuc_check (f);
|
if (cuc_debug) cuc_check (f);
|
cucdebug (3, "%x <= %x+%x (%i)\n", pred, pred, succ, type);
|
cucdebug (3, "%x <= %x+%x (%i)\n", pred, pred, succ, type);
|
cucdebug (3, "%x %x\n", f->bb[pred].ninsn, f->bb[succ].ninsn);
|
cucdebug (3, "%x %x\n", f->bb[pred].ninsn, f->bb[succ].ninsn);
|
Line 911... |
Line 911... |
}
|
}
|
return 1;
|
return 1;
|
}
|
}
|
|
|
/* Recursive calculation of dependencies */
|
/* Recursive calculation of dependencies */
|
static int reg_dep_rec (cuc_func *f, int cur)
|
static void reg_dep_rec (cuc_func *f, int cur)
|
{
|
{
|
int i, j;
|
int i, j;
|
cuc_insn *insn = f->bb[cur].insn;
|
cuc_insn *insn = f->bb[cur].insn;
|
|
|
//PRINTF ("\n %i", cur);
|
//PRINTF ("\n %i", cur);
|
Line 959... |
Line 959... |
if (f->bb[i].tmp) f->bb[i].tmp = 0;
|
if (f->bb[i].tmp) f->bb[i].tmp = 0;
|
else f->bb[i].type |= BB_DEAD;
|
else f->bb[i].type |= BB_DEAD;
|
|
|
/* Detect loops; mark BBs where loops must be broken */
|
/* Detect loops; mark BBs where loops must be broken */
|
for (c = 0; c < f->num_bb; c++) {
|
for (c = 0; c < f->num_bb; c++) {
|
int min = 3, minb;
|
int min = 3, minb = 0;
|
|
|
/* search though all non-visited for minimum number of unvisited predecessors */
|
/* search though all non-visited for minimum number of unvisited predecessors */
|
for (b = 0; b < f->num_bb; b++) if (!f->bb[b].tmp) {
|
for (b = 0; b < f->num_bb; b++) if (!f->bb[b].tmp) {
|
int tmp = 0;
|
int tmp = 0;
|
if (f->bb[b].prev[0] >= 0 && f->bb[b].prev[0] != BBID_START
|
if (f->bb[b].prev[0] >= 0 && f->bb[b].prev[0] != BBID_START
|
Line 987... |
Line 987... |
/* Set real predecessors in cmov instructions to previous blocks */
|
/* Set real predecessors in cmov instructions to previous blocks */
|
for (b = 0; b < f->num_bb; b++)
|
for (b = 0; b < f->num_bb; b++)
|
for (i = 1; i < MAX_REGS - 1; i++) {
|
for (i = 1; i < MAX_REGS - 1; i++) {
|
int pa, pb;
|
int pa, pb;
|
assert (f->bb[b].insn[i].index == II_CMOV);
|
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].opt[0] == (OPT_REGISTER | OPT_DEST));
|
assert (f->bb[b].insn[i].op[0] == i);
|
assert (f->bb[b].insn[i].op[0] == i);
|
if (f->bb[b].prev[0] < 0 || f->bb[b].prev[0] == BBID_START) 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];
|
else pa = f->bb[f->bb[b].prev[0]].last_used_reg[i];
|
if (f->bb[b].prev[1] < 0 || f->bb[b].prev[1] == BBID_START) 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];
|
else pb = f->bb[f->bb[b].prev[1]].last_used_reg[i];
|
Line 1217... |
Line 1217... |
assert (b < f->num_bb);
|
assert (b < f->num_bb);
|
curbb = b;
|
curbb = b;
|
if (prevaddr + 4 != addr) prevbb = -1;
|
if (prevaddr + 4 != addr) prevbb = -1;
|
} else curbb = -1;
|
} else curbb = -1;
|
|
|
#warning TODO: do not count interrupts
|
/* TODO: do not count interrupts */
|
if (curbb != prevbb && curbb >= 0) {
|
if (curbb != prevbb && curbb >= 0) {
|
fwrite (&curbb, sizeof (unsigned long), 1, fo);
|
fwrite (&curbb, sizeof (unsigned long), 1, fo);
|
//PRINTF (" [%i] ", curbb);
|
//PRINTF (" [%i] ", curbb);
|
f->bb[curbb].cnt++;
|
f->bb[curbb].cnt++;
|
prevbb = curbb;
|
prevbb = curbb;
|