OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_61/] [or1ksim/] [cuc/] [insn.c] - Diff between revs 929 and 930

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 929 Rev 930
Line 277... Line 277...
        if (!ii->op[1] && !ii->op[2]) {
        if (!ii->op[1] && !ii->op[2]) {
          change_insn_type (ii, II_ADD);
          change_insn_type (ii, II_ADD);
          ii->op[1] = 0; ii->opt[1] = OPT_CONST;
          ii->op[1] = 0; ii->opt[1] = OPT_CONST;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
          ii->opt[3] = OPT_NONE;
          ii->opt[3] = OPT_NONE;
          return 0;
          return 1;
 
        }
 
        if (ii->op[1] == ii->opt[3] && ii->opt[1] == ii->opt[3]) {
 
          ii->op[1] = 1; ii->opt[1] = OPT_CONST;
 
          return 1;
 
        }
 
        if (ii->op[2] == ii->opt[3] && ii->opt[2] == ii->opt[3]) {
 
          ii->op[2] = 0; ii->opt[2] = OPT_CONST;
 
          return 1;
        }
        }
      }
      }
    }
    }
  }
  }
  return 0;
  return 0;
Line 385... Line 393...
      }
      }
    }
    }
  }
  }
}
}
 
 
 
/* returns number of instructions, using instruction ref */
 
static int insn_uses (cuc_func *f, int ref)
 
{
 
  int b, i, j;
 
  int cnt = 0;
 
  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->bb[b].insn[i].op[j] == ref) cnt++;
 
  return cnt;
 
}
 
 
 
/* handles some common CMOV, CMOV-CMOV cases;
 
   returns nonzero if anything optimized */
 
static int optimize_cmov_more (cuc_func *f, int ref)
 
{
 
  int t = 0;
 
  cuc_insn *ii = &f->INSN(ref);
 
  assert (ii->index == II_CMOV);
 
 
 
  /* In case of x = cmov x, y; or x = cmov y, x; we have
 
     asynchroneous loop -> remove it */
 
  if ((ii->opt[1] & OPT_REF) && ii->op[1] == ref) t = 1;
 
  if ((ii->opt[2] & OPT_REF) && ii->op[2] == ref) t = 2;
 
  if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) t = 2;
 
  if (t) {
 
    change_insn_type (ii, II_ADD);
 
    cucdebug (2, "%8x:cmov     %i\n", ref, t);
 
    ii->opt[t] = OPT_CONST;
 
    ii->op[t] = 0;
 
    ii->opt[3] = OPT_NONE;
 
    return 1;
 
  }
 
  if (!(ii->type & IT_COND)) {
 
    for (t = 1; t <= 2; t++) {
 
      /*   cmov L, X, Y, C1
 
           cmov Z, L, Y, C2
 
         can be replaced with simpler:
 
           cmov L, C1, C2, C2
 
           cmov Z, X, Y, L */
 
      if (ii->opt[t] == OPT_REF && f->INSN(ii->op[t]).index == II_CMOV) {
 
        int r = ii->op[t];
 
        unsigned long x, xt, y, yt;
 
        cuc_insn *prev = &f->INSN(r);
 
        cuc_check (f);
 
        cucdebug (3, "%x-%x\n", ref, r);
 
        assert (!(prev->type & IT_COND));
 
        if (prev->op[3 - t] != ii->op[3 - t] || prev->opt[3 - t] != ii->opt[3 - t]
 
         || insn_uses (f, r) > 1) continue;
 
        cucdebug (3, "%x-%x cmov more\n", ref, r);
 
        prev->type |= IT_COND;
 
        x = prev->op[t]; xt = prev->opt[t];
 
        y = prev->op[3 - t]; yt = prev->opt[3 - t];
 
        prev->op[t] = ii->op[3]; prev->opt[t] = ii->opt[3];     /* C2 */
 
        ii->op[3] = r; ii->opt[3] = OPT_REF;                    /* L */
 
        prev->op[3 - t] = prev->op[3]; prev->opt[3 - t] = prev->opt[3]; /* C1 */
 
        prev->op[3] = prev->op[t]; prev->opt[3] = prev->opt[t]; /* C2 */
 
        ii->op[t] = x; ii->opt[t] = xt;                         /* X */
 
        ii->op[3 - t] = y; ii->opt[3 - t] = yt;                 /* Y */
 
        prev->op[0] = -1; prev->opt[0] = OPT_REGISTER | OPT_DEST;
 
        cuc_check (f);
 
        return 1;
 
      }
 
    }
 
  }
 
 
 
  if (ii->opt[3] == OPT_REF) {
 
    cuc_insn *prev = &f->INSN(ii->op[3]);
 
    assert (prev->type & IT_COND);
 
    if (prev->index == II_CMOV) {
 
    } else if (prev->index == II_ADD) {
 
      if (prev->opt[2] & OPT_CONST && prev->op[2] == 0) {
 
        ii->op[3] = prev->op[1]; ii->opt[3] = prev->opt[1];
 
        return 1;
 
      }
 
    }
 
  }
 
  return 0;
 
}
 
 
/* Optimizes dataflow tree */
/* Optimizes dataflow tree */
void optimize_tree (cuc_func *f)
void optimize_tree (cuc_func *f)
{
{
  int b, i, j;
  int b, i, j;
  int modified;
  int modified;
 
 
  do {
  do {
    modified = 0;
    modified = 0;
 
    if (cuc_debug) cuc_check (f);
    for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD)) {
    for (b = 0; b < f->num_bb; b++) if (!(f->bb[b].type & BB_DEAD)) {
      for (i = 0; i < f->bb[b].ninsn; i++) {
      for (i = 0; i < f->bb[b].ninsn; i++) {
        cuc_insn *ii = &f->bb[b].insn[i];
        cuc_insn *ii = &f->bb[b].insn[i];
        /* We tend to have the third parameter const if instruction is cumutative */
        /* We tend to have the third parameter const if instruction is cumutative */
        if ((ii->opt[1] & OPT_CONST) && !(ii->opt[2] & OPT_CONST)) {
        if ((ii->opt[1] & OPT_CONST) && !(ii->opt[2] & OPT_CONST)) {
Line 438... Line 527...
              modified = 1; cucdebug (2, "%8x:promote%i %8x %8x\n", REF (b, i), j, ii->op[j], t->op[1]);
              modified = 1; cucdebug (2, "%8x:promote%i %8x %8x\n", REF (b, i), j, ii->op[j], t->op[1]);
              ii->op[j] = t->op[1]; ii->opt[j] = t->opt[1];
              ii->op[j] = t->op[1]; ii->opt[j] = t->opt[1];
            }
            }
          }
          }
 
 
        /* In case of x = cmov x, y; or x = cmov y, x; we have
        /* handle some CMOV cases more deeply */
           asynchroneous loop -> remove it */
        if (ii->index == II_CMOV && optimize_cmov_more (f, REF (b, i))) {
        if (ii->index == II_CMOV) {
 
          int f = 0;
 
          if ((ii->opt[1] & OPT_REF) && ii->op[1] == REF (b, i)) f = 1;
 
          if ((ii->opt[2] & OPT_REF) && ii->op[2] == REF (b, i)) f = 2;
 
          if (ii->opt[1] == ii->opt[2] && ii->op[1] == ii->op[2]) f = 2;
 
          if (f) {
 
            change_insn_type (ii, II_ADD);
 
            cucdebug (2, "%8x:cmov     %i\n", REF(b, i), f);
 
            ii->opt[f] = OPT_CONST;
 
            ii->op[f] = 0;
 
            ii->opt[3] = OPT_NONE;
 
            modified = 1;
            modified = 1;
            continue;
            continue;
          }
          }
        }
 
 
 
        /* Do nothing to volatile instructions */
        /* Do nothing to volatile instructions */
        if (ii->type & IT_VOLATILE) continue;
        if (ii->type & IT_VOLATILE) continue;
 
 
        /* Check whether we can simplify the instruction */
        /* Check whether we can simplify the instruction */
Line 491... Line 568...
            ii->op[2] = 0; ii->opt[2] = OPT_CONST;
            ii->op[2] = 0; ii->opt[2] = OPT_CONST;
            modified = 1; cucdebug (2, "%8x:const\n", REF (b, i));
            modified = 1; cucdebug (2, "%8x:const\n", REF (b, i));
          }
          }
        } else if (ii->opt[1] & OPT_REF) {
        } else if (ii->opt[1] & OPT_REF) {
          cuc_insn *prev = &f->INSN(ii->op[1]);
          cuc_insn *prev = &f->INSN(ii->op[1]);
          /* Is this just a link? */
          /* Is this just a move? */
          if (ii->index == II_ADD
          if (ii->index == II_ADD
           && !(ii->type & IT_MEMADD) && ii->op[2] == 0) {
           && !(ii->type & IT_MEMADD) && ii->op[2] == 0) {
            int b1, i1, j1;
            int b1, i1, j1;
            cucdebug (2, "%8x:link      %8x: ", REF(b, i), ii->op[1]);
            cucdebug (2, "%8x:link      %8x: ", REF(b, i), ii->op[1]);
            for (b1 = 0; b1 < f->num_bb; b1++) if (!(f->bb[b1].type & BB_DEAD))
            for (b1 = 0; b1 < f->num_bb; b1++) if (!(f->bb[b1].type & BB_DEAD))
Line 757... Line 834...
/* CSE -- common subexpression elimination */
/* CSE -- common subexpression elimination */
void cse (cuc_func *f)
void cse (cuc_func *f)
{
{
  int b, i, j, b1, i1, b2, i2, j2;
  int b, i, j, b1, i1, b2, i2, j2;
  for (b1 = 0; b1 < f->num_bb; b1++)
  for (b1 = 0; b1 < f->num_bb; b1++)
    for (i1 = 0; i1 < f->bb[b1].ninsn; i1++)
    for (i1 = 0; i1 < f->bb[b1].ninsn; i1++) if (f->bb[b1].insn[i1].index != II_NOP
 
       && f->bb[b1].insn[i1].index != II_LRBB && !(f->bb[b1].insn[i1].type & IT_MEMORY)
 
       && !(f->bb[b1].insn[i1].type & IT_MEMADD))
      for (b2 = 0; b2 < f->num_bb; b2++)
      for (b2 = 0; b2 < f->num_bb; b2++)
        for (i2 = 0; i2 < f->bb[b2].ninsn; i2++) {
        for (i2 = 0; i2 < f->bb[b2].ninsn; i2++)
 
          if (f->bb[b2].insn[i2].index != II_NOP && f->bb[b2].insn[i2].index != II_LRBB
 
           && !(f->bb[b2].insn[i2].type & IT_MEMORY) && !(f->bb[b2].insn[i2].type & IT_MEMADD)
 
           && (b1 != b2 || i2 > i1)) {
          cuc_insn *ii1 = &f->bb[b1].insn[i1];
          cuc_insn *ii1 = &f->bb[b1].insn[i1];
          cuc_insn *ii2 = &f->bb[b2].insn[i2];
          cuc_insn *ii2 = &f->bb[b2].insn[i2];
 
            int ok = 1;
 
 
          /* Do we have an exact match? */
          /* Do we have an exact match? */
          if (ii1->index == ii2->index) continue;
            if (ii1->index != ii2->index) continue;
          if (ii1->type & IT_VOLATILE) continue;
            if (ii2->type & IT_VOLATILE) continue;
 
 
          if (ii1->op[1] != ii2->op[1] || ii1->opt[1] != ii2->opt[1]) continue;
            /* Check all operands also */
          if (ii1->op[2] != ii2->op[2] || ii1->opt[2] != ii2->opt[2]) continue;
            for (j = 0; j < MAX_OPERANDS; j++) {
          if (ii1->opt[3] != ii2->opt[3]) continue;
              if (ii1->opt[j] != ii2->opt[j]) {
          if (ii1->opt[3] != OPT_NONE && ii1->op[3] != ii2->op[3]) continue;
                ok = 0;
 
                break;
          /* Check if we drive outputs? */
              }
          if ((ii1->opt[0] & OPT_REGISTER) && ii1->op[0] >= 0)
              if (ii1->opt[j] & OPT_DEST) continue;
            if ((ii2->opt[0] & OPT_REGISTER) && ii2->op[0] >= 0) continue;
              if (ii1->opt[j] != OPT_NONE && ii1->op[j] != ii2->op[j]) {
            else ii2->op[0] = ii1->op[0];
                ok = 0;
 
                break;
 
              }
 
            }
 
 
 
            if (ok) {
          /* remove duplicated instruction and relink the references */
          /* remove duplicated instruction and relink the references */
 
              cucdebug (3, "%x - %x are same\n", REF(b1, i1), REF(b2, i2));
          change_insn_type (ii2, II_NOP);
          change_insn_type (ii2, II_NOP);
          for (b = 0; b < f->num_bb; b++)
          for (b = 0; b < f->num_bb; b++)
            for (i = 0; i < f->bb[b].ninsn; i++)
            for (i = 0; i < f->bb[b].ninsn; i++)
              for (j = 0; j < MAX_OPERANDS; j++)
              for (j = 0; j < MAX_OPERANDS; j++)
                if (f->bb[b].insn[i].opt[j] & OPT_REF && f->bb[b].insn[i].op[j] == REF (b2, i2))
                    if (f->bb[b].insn[i].opt[j] & OPT_REF
 
                     && f->bb[b].insn[i].op[j] == REF (b2, i2))
                  f->bb[b].insn[i].op[j] = REF (b1, i1);
                  f->bb[b].insn[i].op[j] = REF (b1, i1);
        }
        }
}
}
 
}
 
 
static int count_cmovs (cuc_insn *ii, int match)
static int count_cmovs (cuc_insn *ii, int match)
{
{
  int c = 0, j;
  int c = 0, j;
  if (match & 2) {
  if (match & 2) {

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.