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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [cuc/] [memory.c] - Diff between revs 941 and 953

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

Rev 941 Rev 953
Line 111... Line 111...
      }
      }
  }
  }
  dispose_list (&all_mem);
  dispose_list (&all_mem);
}
}
 
 
 
/* Check if they address the same location, so we can join them */
 
static int same_transfers (cuc_func *f, int otype)
 
{
 
  int i, j;
 
  int modified = 0;
 
  if (otype == MO_WEAK || otype == MO_NONE) {
 
    for (i = 1, j = 1; i < f->nmsched; i++)
 
      /* Exclude memory stores and different memory types */
 
      if (f->mtype[i - 1] == f->mtype[i] && f->mtype[i] & MT_LOAD) {
 
        cuc_insn *a = &f->INSN(f->msched[i - 1]);
 
        cuc_insn *b = &f->INSN(f->msched[i]);
 
        if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
 
          &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
 
          a = &f->INSN(a->op[1]);
 
          b = &f->INSN(b->op[1]);
 
          /* Not in usual form? */
 
          if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
 
           || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) goto keep;
 
 
 
          //printf ("%i %i, ", a->op[2], b->op[2]);
 
 
 
          /* Check if they are the same => do not copy */
 
          if (a->op[2] == b->op[2]
 
            && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
 
            /* yes => remove actual instruction */
 
            int t1 = MIN (f->msched[i - 1], f->msched[i]);
 
            int t2 = MAX (f->msched[i - 1], f->msched[i]);
 
            int b, i, j;
 
            cucdebug (2, "Removing %x_%x and using %x_%x instead.\n",
 
              REF_BB(t2), REF_I(t2), REF_BB(t1), REF_I(t1));
 
            change_insn_type (&f->INSN(t2), II_NOP);
 
            modified = 1;
 
            /* Update references */
 
            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] == t2)
 
                    f->bb[b].insn[i].op[j] = t1;
 
 
 
          } else goto keep;
 
        } else goto keep;
 
      } else {
 
keep:
 
        f->msched[j] = f->msched[i];
 
        f->mtype[j++] = f->mtype[i];
 
      }
 
    f->nmsched = j;
 
  }
 
  return modified;
 
}
 
 
 
/* Check if two consecutive lb[zs] can be joined into lhz and if
 
   two consecutive lh[zs] can be joined into lwz */
 
static int join_transfers (cuc_func *f, int otype)
 
{
 
  int i, j;
 
  int modified = 0;
 
 
 
  /* We can change width even with strong memory ordering */
 
  if (otype == MO_WEAK || otype == MO_NONE || otype == MO_STRONG) {
 
    for (i = 1, j = 1; i < f->nmsched; i++)
 
      /* Exclude memory stores and different memory types */
 
      if (f->mtype[i - 1] == f->mtype[i] && f->mtype[i] & MT_LOAD) {
 
        cuc_insn *a = &f->INSN(f->msched[i - 1]);
 
        cuc_insn *b = &f->INSN(f->msched[i]);
 
        int aw = f->mtype[i - 1] & MT_WIDTH;
 
        if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
 
          &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
 
          a = &f->INSN(a->op[1]);
 
          b = &f->INSN(b->op[1]);
 
 
 
          /* Not in usual form? */
 
          if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
 
           || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) goto keep;
 
 
 
          /* Check if they touch together */
 
          if (a->op[2] + aw == b->op[2]
 
            && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
 
            /* yes => remove second instruction */
 
            int t1 = MIN (f->msched[i - 1], f->msched[i]);
 
            int t2 = MAX (f->msched[i - 1], f->msched[i]);
 
            dep_list *t1dep = f->INSN(t1).dep;
 
            int x, p;
 
            cuc_insn *ii;
 
 
 
            cucdebug (2, "Joining %x and %x.\n", t1, t2);
 
            print_cuc_bb (f, "PREJT");
 
            change_insn_type (&f->INSN(t1), II_NOP);
 
            change_insn_type (&f->INSN(t2), II_NOP);
 
            /* We will reuse the memadd before the first load, and add some
 
               custom code at the end */
 
            insert_insns (f, t1, 10);
 
            print_cuc_bb (f, "PREJT2");
 
 
 
            /* Remove all dependencies to second access */
 
            for (x = 0; x < f->num_bb; x++) {
 
              int i;
 
              for (i = 0; i < f->bb[x].ninsn; i++) {
 
                dep_list *d = f->bb[x].insn[i].dep;
 
                dep_list **old = &f->bb[x].insn[i].dep;
 
                while (d) {
 
                  if (d->ref == t2) {
 
                    d = d->next;
 
                    *old = d;
 
                  } else {
 
                    d = d->next;
 
                    old = &((*old)->next);
 
                  }
 
                }
 
              }
 
            }
 
 
 
            /* Build the folowing code:
 
               l[hw]z p-1
 
               and p-1, 0xff
 
               sfle p-1, 0x7f
 
               or p-2, 0xffffff00
 
               cmov p-3, p-1, p-2
 
               shr p-5, 8
 
               and p-1, 0xff
 
               sfle p-1 0x7f
 
               or p-2 0xffffff00
 
               cmov p-3, p-1, p-2*/
 
            p = REF_I(t1);
 
            printf ("%x %x\n", f->mtype[i - 1], f->mtype[i]);
 
            for (x = 0; x < 2; x++) {
 
              int t = f->mtype[i - 1 + x];
 
              ii = &f->bb[REF_BB(t1)].insn[p];
 
              if (!x) {
 
                change_insn_type (ii, aw == 1 ? II_LH : II_LW);
 
                ii->type = IT_MEMORY | IT_VOLATILE;
 
                ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
 
                ii->op[1] = t1 - 1; ii->opt[1] = OPT_REF;
 
                ii->opt[2] = ii->opt[3] = OPT_NONE;
 
                ii->dep = t1dep;
 
                f->mtype[i - 1] = MT_LOAD | (aw == 1 ? 2 : 4);
 
                f->msched[i - 1] = REF (REF_BB(t1), p);
 
              } else {
 
                change_insn_type (ii, II_SRL);
 
                ii->type = 0;
 
                ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
 
                ii->op[1] = t1; ii->opt[1] = OPT_REF;
 
                ii->op[2] = 8; ii->opt[2] = OPT_CONST;
 
                ii->opt[3] = OPT_NONE;
 
              }
 
 
 
              printf ("1. %x %x\n", p, t);
 
              ii = &f->bb[REF_BB(t1)].insn[++p];
 
              change_insn_type (ii, II_AND);
 
              ii->type = 0;
 
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
 
              ii->op[1] = REF (REF_BB(t1), p - 1); ii->opt[1] = OPT_REF;
 
              ii->op[2] = 0xff; ii->opt[2] = OPT_CONST;
 
              ii->opt[3] = OPT_NONE;
 
 
 
              printf ("2. %x\n", p);
 
              ii = &f->bb[REF_BB(t1)].insn[++p];
 
              change_insn_type (ii, II_SFLE);
 
              ii->type = IT_COND;
 
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
 
              ii->op[1] = REF (REF_BB(t1), p - 1); ii->opt[1] = OPT_REF;
 
              ii->op[2] = 0x7f; ii->opt[2] = OPT_CONST;
 
              ii->opt[3] = OPT_NONE;
 
 
 
              printf ("3. %x\n", p);
 
              ii = &f->bb[REF_BB(t1)].insn[++p];
 
              change_insn_type (ii, II_OR);
 
              ii->type = 0;
 
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
 
              ii->op[1] = REF (REF_BB(t1), p - 2); ii->opt[1] = OPT_REF;
 
              if (t & MT_SIGNED) ii->op[2] = 0xffffff00;
 
              else ii->op[2] = 0;
 
              ii->opt[2] = OPT_CONST;
 
              ii->opt[3] = OPT_NONE;
 
 
 
              printf ("4. %x\n", p);
 
              ii = &f->bb[REF_BB(t1)].insn[++p];
 
              change_insn_type (ii, II_CMOV);
 
              ii->type = 0;
 
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
 
              ii->op[1] = REF (REF_BB(t1), p - 1); ii->opt[1] = OPT_REF;
 
              ii->op[2] = REF (REF_BB(t1), p - 3); ii->opt[2] = OPT_REF;
 
              ii->op[3] = REF (REF_BB(t1), p - 2); ii->opt[3] = OPT_REF;
 
              p++;
 
            }
 
 
 
            modified = 1;
 
 
 
            {
 
              int b, i, j;
 
              /* Update references */
 
              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 (REF_I (f->bb[b].insn[i].op[j]) < REF_I (t1)
 
                     || REF_I(f->bb[b].insn[i].op[j]) >= REF_I (t1) + 10) {
 
                      if (f->bb[b].insn[i].opt[j] & OPT_REF && f->bb[b].insn[i].op[j] == t1)
 
                        f->bb[b].insn[i].op[j] = t1 + 4;
 
                      else if (f->bb[b].insn[i].opt[j] & OPT_REF && f->bb[b].insn[i].op[j] == t2)
 
                        f->bb[b].insn[i].op[j] = t1 + 9;
 
                    }
 
            }
 
            print_cuc_bb (f, "POSTJT");
 
          } else goto keep;
 
        } else goto keep;
 
      } else {
 
keep:
 
        f->msched[j] = f->msched[i];
 
        f->mtype[j++] = f->mtype[i];
 
      }
 
    f->nmsched = j;
 
  }
 
  return modified;
 
}
 
 
/* returns nonzero if a < b */
/* returns nonzero if a < b */
int mem_ordering_cmp (cuc_func *f, cuc_insn *a, cuc_insn *b)
int mem_ordering_cmp (cuc_func *f, cuc_insn *a, cuc_insn *b)
{
{
  assert (a->type & IT_MEMORY);
  assert (a->type & IT_MEMORY);
  assert (b->type & IT_MEMORY);
  assert (b->type & IT_MEMORY);
Line 130... Line 345...
  } else return 0;
  } else return 0;
}
}
 
 
/* Schedule memory accesses
/* Schedule memory accesses
  0 - exact; 1 - strong; 2 - weak;  3 - none */
  0 - exact; 1 - strong; 2 - weak;  3 - none */
void schedule_memory (cuc_func *f, int otype)
int schedule_memory (cuc_func *f, int otype)
{
{
  int b, i, j;
  int b, i, j;
 
  int modified = 0;
  f->nmsched = 0;
  f->nmsched = 0;
 
 
  for (b = 0; b < f->num_bb; b++) {
  for (b = 0; b < f->num_bb; b++) {
    cuc_insn *insn = f->bb[b].insn;
    cuc_insn *insn = f->bb[b].insn;
    for (i = 0; i < f->bb[b].ninsn; i++)
    for (i = 0; i < f->bb[b].ninsn; i++)
Line 190... Line 406...
    f->mtype[i] = !II_IS_LOAD(a->index) ? MT_STORE : MT_LOAD;
    f->mtype[i] = !II_IS_LOAD(a->index) ? MT_STORE : MT_LOAD;
    f->mtype[i] |= II_MEM_WIDTH (a->index);
    f->mtype[i] |= II_MEM_WIDTH (a->index);
    if (a->type & IT_SIGNED) f->mtype[i] |= MT_SIGNED;
    if (a->type & IT_SIGNED) f->mtype[i] |= MT_SIGNED;
  }
  }
 
 
  /* Check if they address the same location, so we can join them */
  if (same_transfers (f, otype)) modified = 1;
  if (otype == MO_WEAK || otype == MO_NONE) {
  if (join_transfers (f, otype)) modified = 1;
    for (i = 1, j = 1; i < f->nmsched; i++)
 
      /* Exclude memory stores and different memory types */
 
      if (f->mtype[i - 1] == f->mtype[i] && f->mtype[i] & MT_LOAD) {
 
        cuc_insn *a = &f->INSN(f->msched[i - 1]);
 
        cuc_insn *b = &f->INSN(f->msched[i]);
 
        if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
 
          &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
 
          a = &f->INSN(a->op[1]);
 
          b = &f->INSN(b->op[1]);
 
          /* Not in usual form? */
 
          if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
 
           || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) goto keep;
 
 
 
          //printf ("%i %i, ", a->op[2], b->op[2]);
 
 
 
          /* Check if they are the same => do not copy */
 
          if (a->op[2] == b->op[2]
 
            && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
 
            /* yes => remove actual instruction */
 
            int t1 = MIN (f->msched[i - 1], f->msched[i]);
 
            int t2 = MAX (f->msched[i - 1], f->msched[i]);
 
            int b, i, j;
 
            cucdebug (2, "Removing %x_%x and using %x_%x instead.\n",
 
              REF_BB(t2), REF_I(t2), REF_BB(t1), REF_I(t1));
 
            change_insn_type (&f->INSN(t2), II_NOP);
 
            /* Update references */
 
            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] == t2)
 
                    f->bb[b].insn[i].op[j] = t1;
 
 
 
          } else goto keep;
 
        } else goto keep;
 
      } else {
 
keep:
 
        f->msched[j] = f->msched[i];
 
        f->mtype[j++] = f->mtype[i];
 
      }
 
    f->nmsched = j;
 
  }
 
 
 
  for (i = 0; i < f->nmsched; i++)
  for (i = 0; i < f->nmsched; i++)
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
  cucdebug (2, "\n");
  cucdebug (2, "\n");
  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL");
  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL");
Line 246... Line 421...
    for (i = 1; i < f->nmsched; i++) {
    for (i = 1; i < f->nmsched; i++) {
      cuc_insn *a = &f->INSN(f->msched[i - 1]);
      cuc_insn *a = &f->INSN(f->msched[i - 1]);
      cuc_insn *b = &f->INSN(f->msched[i]);
      cuc_insn *b = &f->INSN(f->msched[i]);
      int aw = f->mtype[i - 1] & MT_WIDTH;
      int aw = f->mtype[i - 1] & MT_WIDTH;
 
 
 
      /* Burst can only be out of words */
 
      if (aw != 4) continue;
 
 
      if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
      if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
        &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
        &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
        a = &f->INSN(a->op[1]);
        a = &f->INSN(a->op[1]);
        b = &f->INSN(b->op[1]);
        b = &f->INSN(b->op[1]);
        /* Not in usual form? */
        /* Not in usual form? */
Line 257... Line 435...
         || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) continue;
         || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) continue;
 
 
        //printf ("%i %i, ", a->op[2], b->op[2]);
        //printf ("%i %i, ", a->op[2], b->op[2]);
 
 
        /* Check if they touch together */
        /* Check if they touch together */
        if (a->op[2] + aw == b->op[2]) {
        if (a->op[2] + aw == b->op[2]
 
          && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
          /* yes => do burst */
          /* yes => do burst */
          f->mtype[i - 1] &= ~MT_BURSTE;
          f->mtype[i - 1] &= ~MT_BURSTE;
          f->mtype[i - 1] |= MT_BURST;
          f->mtype[i - 1] |= MT_BURST;
          f->mtype[i] |= MT_BURST | MT_BURSTE;
          f->mtype[i] |= MT_BURST | MT_BURSTE;
        }
        }
Line 278... Line 457...
    cuc_insn *insn = f->bb[b].insn;
    cuc_insn *insn = f->bb[b].insn;
    for (i = 0; i < f->bb[b].ninsn; i++) if (!(insn[i].type & IT_MEMORY))
    for (i = 0; i < f->bb[b].ninsn; i++) if (!(insn[i].type & IT_MEMORY))
      dispose_list (&insn[i].dep);
      dispose_list (&insn[i].dep);
  }
  }
 
 
 
  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL2");
  /* Reduce number of dependecies, keeping just direct dependencies, based on memory schedule */
  /* Reduce number of dependecies, keeping just direct dependencies, based on memory schedule */
  {
  {
    int lastl[3] = {-1, -1, -1};
    int lastl[3] = {-1, -1, -1};
    int lasts[3] = {-1, -1, -1};
    int lasts[3] = {-1, -1, -1};
    int lastc[3] = {-1, -1, -1};
    int lastc[3] = {-1, -1, -1};
Line 290... Line 470...
      int t = f->mtype[i] & MT_LOAD ? 0 : f->mtype[i] & MT_STORE ? 1 : 2;
      int t = f->mtype[i] & MT_LOAD ? 0 : f->mtype[i] & MT_STORE ? 1 : 2;
      int maxl = lastl[t];
      int maxl = lastl[t];
      int maxs = lasts[t];
      int maxs = lasts[t];
      int maxc = lastc[t];
      int maxc = lastc[t];
      dep_list *tmp = f->INSN(f->msched[i]).dep;
      dep_list *tmp = f->INSN(f->msched[i]).dep;
 
      printf ("!%i %x %x\n", i, f->msched[i], tmp);
 
      fflush (stdout);
      while (tmp) {
      while (tmp) {
        if (f->INSN(tmp->ref).type & IT_MEMORY && REF_BB(tmp->ref) == REF_BB(f->msched[i])) {
        if (f->INSN(tmp->ref).type & IT_MEMORY && REF_BB(tmp->ref) == REF_BB(f->msched[i])) {
          printf ("%i %x %x\n", i, f->msched[i], tmp->ref);
          printf ("%i %x %x\n", i, f->msched[i], tmp->ref);
 
          fflush (stdout);
          /* Search for the reference */
          /* Search for the reference */
          for (j = 0; j < f->nmsched; j++) if (f->msched[j] == tmp->ref) break;
          for (j = 0; j < f->nmsched; j++) if (f->msched[j] == tmp->ref) break;
          assert (j < f->nmsched);
          assert (j < f->nmsched);
          if (f->mtype[j] & MT_STORE) {
          if (f->mtype[j] & MT_STORE) {
            if (maxs < j) maxs = j;
            if (maxs < j) maxs = j;
Line 349... Line 532...
          lastc[t] = last_call;
          lastc[t] = last_call;
        }
        }
      }
      }
    }
    }
  }
  }
 
  return modified;
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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