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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [cuc/] [bb.c] - Diff between revs 883 and 897

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

Rev 883 Rev 897
Line 19... Line 19...
 
 
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdarg.h>
#include <assert.h>
#include <assert.h>
 
#include "sim-config.h"
 
#include "abstract.h"
#include "cuc.h"
#include "cuc.h"
#include "insn.h"
#include "insn.h"
#include "support/profile.h"
#include "support/profile.h"
 
 
/* Print out basic blocks */
/* Print out basic blocks */
Line 44... Line 46...
    else printf ("*\n");
    else printf ("*\n");
 
 
    if (f->bb[i].insn) print_insns (f->bb[i].insn, f->bb[i].ninsn, 0);
    if (f->bb[i].insn) print_insns (f->bb[i].insn, f->bb[i].ninsn, 0);
  }
  }
  printf ("\n");
  printf ("\n");
 
  fflush (stdout);
}
}
 
 
/* Copies src basic block into destination */
/* Copies src basic block into destination */
cuc_bb *cpy_bb (cuc_bb *dest, cuc_bb *src)
cuc_bb *cpy_bb (cuc_bb *dest, cuc_bb *src)
{
{
  int i;
  int i, j;
 
  assert (dest != src);
  *dest = *src;
  *dest = *src;
  assert (dest->insn = malloc (sizeof (cuc_insn) * src->ninsn));
  assert (dest->insn = malloc (sizeof (cuc_insn) * src->ninsn));
  for (i = 0; i < src->ninsn; i++)
  for (i = 0; i < src->ninsn; i++)
    dest->insn[i] = src->insn[i];
    dest->insn[i] = src->insn[i];
  if (src->ntim) {
  if (src->ntim) {
    assert (dest->tim = malloc (sizeof (cuc_timings) * src->ntim));
    assert (dest->tim = malloc (sizeof (cuc_timings) * src->ntim));
    for (i = 0; i < src->ntim; i++) dest->tim[i] = src->tim[i];
    for (i = 0; i < src->ntim; i++) {
 
      dest->tim[i] = src->tim[i];
 
      if (src->tim[i].nshared) {
 
        assert (dest->tim[i].shared = malloc (sizeof (int) * src->tim[i].nshared));
 
        for (j = 0; j < src->tim[i].nshared; j++)
 
          dest->tim[i].shared[j] = src->tim[i].shared[j];
 
      }
 
    }
  }
  }
}
}
 
 
/* Duplicates function */
/* Duplicates function */
cuc_func *dup_func (cuc_func *f)
cuc_func *dup_func (cuc_func *f)
Line 90... Line 101...
  int b, i;
  int b, i;
  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++)
      dispose_list (&f->bb[b].insn[i].dep);
      dispose_list (&f->bb[b].insn[i].dep);
    if (f->bb[b].insn) free (f->bb[b].insn);
    if (f->bb[b].insn) free (f->bb[b].insn);
 
    for (i = 0; i < f->bb[b].ntim; i++)
 
      if (f->bb[b].tim[i].nshared && f->bb[b].tim[i].shared)
 
        free (f->bb[b].tim[i].shared);
    if (f->bb[b].tim && f->bb[b].ntim) free (f->bb[b].tim);
    if (f->bb[b].tim && f->bb[b].ntim) free (f->bb[b].tim);
  }
  }
  free (f);
  free (f);
}
}
 
 
Line 310... Line 324...
      f->bb[i].insn[j].opt[0] = f->bb[i].insn[j].opt[1] = f->bb[i].insn[j].opt[2] = OPT_REGISTER;
      f->bb[i].insn[j].opt[0] = f->bb[i].insn[j].opt[1] = f->bb[i].insn[j].opt[2] = OPT_REGISTER;
      f->bb[i].insn[j].opt[0] |= OPT_DEST;
      f->bb[i].insn[j].opt[0] |= OPT_DEST;
      f->bb[i].insn[j].op[0] = f->bb[i].insn[j].op[1] = f->bb[i].insn[j].op[2] = j;
      f->bb[i].insn[j].op[0] = f->bb[i].insn[j].op[1] = f->bb[i].insn[j].op[2] = j;
      f->bb[i].insn[j].op[3] = LRBB_REG; f->bb[i].insn[j].opt[3] = OPT_REGISTER;
      f->bb[i].insn[j].op[3] = LRBB_REG; f->bb[i].insn[j].opt[3] = OPT_REGISTER;
    }
    }
 
 
 
    /* Relocate instructions */
    for (j = MAX_REGS - 1; j < f->bb[i].ninsn; j++) {
    for (j = MAX_REGS - 1; j < f->bb[i].ninsn; j++) {
      f->bb[i].insn[j] = insn[f->bb[i].first + j - (MAX_REGS - 1)];
      f->bb[i].insn[j] = insn[f->bb[i].first + j - (MAX_REGS - 1)];
      for (k = 0; k < MAX_OPERANDS; k++)
      for (k = 0; k < MAX_OPERANDS; k++)
        if (f->bb[i].insn[j].opt[k] & OPT_REF) {
        if (f->bb[i].insn[j].opt[k] & OPT_REF) {
          int b1;
          int b1;
Line 324... Line 340...
          f->bb[i].insn[j].op[k] = REF (b1, f->bb[i].insn[j].op[k] - f->bb[b1].first + MAX_REGS - 1);
          f->bb[i].insn[j].op[k] = REF (b1, f->bb[i].insn[j].op[k] - f->bb[b1].first + MAX_REGS - 1);
        }
        }
      if (f->bb[i].insn[j].type & IT_MEMORY) f->bb[i].nmemory++;
      if (f->bb[i].insn[j].type & IT_MEMORY) f->bb[i].nmemory++;
    }
    }
  }
  }
 
 
 
  /* We do a quick check if there are some anomalies */
 
  for (i = 0; i < f->num_bb; i++)
 
    for (j = 0; j < f->bb[i].ninsn; j++)
 
      for (k = 0; k < MAX_OPERANDS; k++)
 
        if (f->bb[i].insn[j].opt[k] & OPT_REF) {
 
          int t = f->bb[i].insn[j].op[k];
 
          assert (REF_I (t) < f->bb[REF_BB(t)].ninsn);
 
        }
}
}
 
 
/* type == 0; keep predecessor condition
/* type == 0; keep predecessor condition
 * type == 1; keep successor condition
 * type == 1; keep successor condition
 * type == 2; join loop unrolled blocks */
 * type == 2; join loop unrolled blocks */
Line 335... Line 360...
{
{
  int i, j, k, add, ninsn, add_cond = 0;
  int i, j, k, add, ninsn, add_cond = 0;
  unsigned long cond_op, cond_opt;
  unsigned long cond_op, cond_opt;
  cuc_insn *insn;
  cuc_insn *insn;
 
 
  //printf ("%i <= %i+%i (%i)\n", pred, pred, succ, type);
  cucdebug (3, "%x <= %x+%x (%i)\n", pred, pred, succ, type);
  //printf ("%i %i\n", f->bb[pred].ninsn, f->bb[succ].ninsn);
  cucdebug (3, "%x %x\n", f->bb[pred].ninsn, f->bb[succ].ninsn);
 
  if (cuc_debug >= 3) fflush (stdout);
 
 
  add = f->bb[pred].ninsn;
  add = f->bb[pred].ninsn;
  if (f->bb[pred].ninsn <= 0
  if (f->bb[pred].ninsn <= 0
   || !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1;
   || !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1;
  if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1;
  if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1;
Line 526... Line 552...
     3. pred & succ share common successor
     3. pred & succ share common successor
     4. optional succ's second successor */
     4. optional succ's second successor */
  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 */
      int p = f->bb[i].prev[0];
      int p = f->bb[i].prev[0];
      if (f->bb[p].next[0] == i && f->bb[p].next[1] == f->bb[p].next[1])
      if (f->bb[p].next[0] == i && f->bb[p].next[1] == f->bb[p].next[1]) {
      join_bb (f, f->bb[i].prev[0], i, 2);
      join_bb (f, f->bb[i].prev[0], i, 2);
      goto remove_lrbb;
      goto remove_lrbb;
    }
    }
 
    }
#endif
#endif
}
}
 
 
/* Removes BBs marked as dead */
/* Removes BBs marked as dead */
void remove_dead_bb (cuc_func *f)
void remove_dead_bb (cuc_func *f)
Line 750... Line 777...
    /* Mark them volatile, so optimizer does not remove them */
    /* Mark them volatile, so optimizer does not remove them */
    if (t >= 0) f->bb[REF_BB(t)].insn[REF_I(t)].type |= IT_OUTPUT;
    if (t >= 0) f->bb[REF_BB(t)].insn[REF_I(t)].type |= IT_OUTPUT;
  }
  }
}
}
 
 
 
/* split the BB, based on the group numbers in .tmp */
 
void expand_bb (cuc_func *f, int b)
 
{
 
  int n = f->num_bb;
 
  int mg = 0;
 
  int b1, i, j;
 
 
 
  for (i = 0; i < f->bb[b].ninsn; i++)
 
    if (f->bb[b].insn[i].tmp > mg) mg = f->bb[b].insn[i].tmp;
 
 
 
  /* Create copies */
 
  for (b1 = 1; b1 <= mg; b1++) {
 
    assert (f->num_bb < MAX_BB);
 
    cpy_bb (&f->bb[f->num_bb], &f->bb[b]);
 
    f->num_bb++;
 
  }
 
 
 
  /* Relocate */
 
  for (b1 = 0; b1 < f->num_bb; b1++)
 
    for (i = 0; i < f->bb[b1].ninsn; i++) {
 
      dep_list *d = f->bb[b1].insn[i].dep;
 
      for (j = 0; j < MAX_OPERANDS; j++)
 
        if (f->bb[b1].insn[i].opt[j] & OPT_REF) {
 
          int t = f->bb[b1].insn[i].op[j];
 
          if (REF_BB(t) == b && f->INSN(t).tmp != 0)
 
            f->bb[b1].insn[i].op[j] = REF (n + f->INSN(t).tmp - 1, REF_I(t));
 
        }
 
      while (d) {
 
        if (REF_BB (d->ref) == b && f->INSN(d->ref).tmp != 0)
 
          d->ref = REF (n + f->INSN(d->ref).tmp - 1, REF_I(d->ref));
 
        d = d->next;
 
      }
 
    }
 
 
 
  /* Delete unused instructions */
 
  for (j = 0; j <= mg; j++) {
 
    if (j == 0) b1 = b;
 
    else b1 = n + j - 1;
 
    for (i = 0; i < f->bb[b1].ninsn; i++) {
 
      if (f->bb[b1].insn[i].tmp != j)
 
        change_insn_type (&f->bb[b1].insn[i], II_NOP);
 
      f->bb[b1].insn[i].tmp = 0;
 
    }
 
    if (j < mg) {
 
      f->bb[b1].next[0] = n + j;
 
      f->bb[b1].next[1] = -1;
 
      f->bb[n + j].prev[0] = b1;
 
      f->bb[n + j].prev[1] = -1;
 
    } else {
 
      i = f->bb[b1].next[0];
 
      f->bb[n + j].prev[0] = j == 1 ? b : b1 - 1;
 
      f->bb[n + j].prev[1] = -1;
 
      if (i >= 0) {
 
        if (f->bb[i].prev[0] == b) f->bb[i].prev[0] = b1;
 
        if (f->bb[i].prev[1] == b) f->bb[i].prev[1] = b1;
 
      }
 
      i = f->bb[b1].next[1];
 
      if (i >= 0) {
 
        if (f->bb[i].prev[0] == b) f->bb[i].prev[0] = b1;
 
        if (f->bb[i].prev[1] == b) f->bb[i].prev[1] = b1;
 
      }
 
    }
 
  }
 
}
 
 
/* Scans sequence of BBs and set bb[].cnt */
/* Scans sequence of BBs and set bb[].cnt */
void generate_bb_seq (cuc_func *f, char *mp_filename, char *bb_filename)
void generate_bb_seq (cuc_func *f, char *mp_filename, char *bb_filename)
{
{
  FILE *fi, *fo;
  FILE *fi, *fo;
  struct mprofentry_struct *buf;
  struct mprofentry_struct *buf;
Line 762... Line 854...
  unsigned long *bb_end;
  unsigned long *bb_end;
  int b, i, r;
  int b, i, r;
  int curbb, prevbb = -1;
  int curbb, prevbb = -1;
  unsigned long addr = -1;
  unsigned long addr = -1;
  unsigned long prevaddr = -1;
  unsigned long prevaddr = -1;
 
  int mssum = 0;
 
  int mlsum = 0;
 
  int mscnt = 0;
 
  int mlcnt = 0;
 
 
  assert (fi = fopen (mp_filename, "rb"));
  assert (fi = fopen (mp_filename, "rb"));
  assert (fo = fopen (bb_filename, "wb+"));
  assert (fo = fopen (bb_filename, "wb+"));
 
 
  assert (bb_start = (unsigned long *) malloc (sizeof (unsigned long) * f->num_bb));
  assert (bb_start = (unsigned long *) malloc (sizeof (unsigned long) * f->num_bb));
Line 803... Line 899...
          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;
        }
        }
 
      } else {
 
        if (verify_memoryarea(buf[i].addr))
 
          if (buf[i].type & MPROF_WRITE) mscnt++, mssum += cur_area->delayw;
 
          else mlcnt++, mlsum += cur_area->delayw;
      }
      }
    }
    }
    //printf ("\n");
    //printf ("\n");
  } while (r == bufsize);
  } while (r == bufsize);
  //printf ("\n");
  //printf ("\n");
 
 
 
  runtime.cuc.mdelay[0] = (1. * mlsum) / mlcnt;
 
  runtime.cuc.mdelay[1] = (1. * mlsum) / mlcnt;
 
  runtime.cuc.mdelay[2] = runtime.cuc.mdelay[3] = 1;
  f->num_runs = f->bb[0].cnt;
  f->num_runs = f->bb[0].cnt;
  fclose (fi);
  fclose (fi);
  fclose (fo);
  fclose (fo);
  free (buf);
  free (buf);
  free (bb_end);
  free (bb_end);
Line 983... Line 1086...
 
 
  //print_cuc_bb (n, "unroll1");
  //print_cuc_bb (n, "unroll1");
  /* repair BB after loop, to point back to latest artificial BB */
  /* repair BB after loop, to point back to latest artificial BB */
  b1 = n->bb[prevart_b].next[0];
  b1 = n->bb[prevart_b].next[0];
  if (b1 >= 0) {
  if (b1 >= 0) {
    if (n->bb[b1].prev[0] == b) n->bb[b1].prev[0] = b1;
    if (n->bb[b1].prev[0] == b) n->bb[b1].prev[0] = prevart_b;
    else if (n->bb[b1].prev[1] == b) n->bb[b1].prev[1] = b1;
    else if (n->bb[b1].prev[1] == b) n->bb[b1].prev[1] = prevart_b;
    else assert (0);
    else assert (0);
  }
  }
 
 
  /* Relink back to start of the loop */
  /* Relink back to start of the loop */
  /* Set predecessor's successor */
  /* Set predecessor's successor */
Line 1125... Line 1228...
 
 
  //print_cuc_bb (n, "preroll1");
  //print_cuc_bb (n, "preroll1");
  /* repair BB after loop, to point back to latest artificial BB */
  /* repair BB after loop, to point back to latest artificial BB */
  b1 = n->bb[prevart_b].next[0];
  b1 = n->bb[prevart_b].next[0];
  if (b1 >= 0) {
  if (b1 >= 0) {
    if (n->bb[b1].prev[0] == b) n->bb[b1].prev[0] = b1;
    if (n->bb[b1].prev[0] == b) n->bb[b1].prev[0] = prevart_b;
    else if (n->bb[b1].prev[1] == b) n->bb[b1].prev[1] = b1;
    else if (n->bb[b1].prev[1] == b) n->bb[b1].prev[1] = prevart_b;
    else assert (0);
    else assert (0);
  }
  }
 
 
  /* Relink to itself */
  /* Relink to itself */
  /* Set predecessor's successor */
  /* Set predecessor's successor */
Line 1176... Line 1279...
      n = unroll_loop (t, b1, unroll);
      n = unroll_loop (t, b1, unroll);
      free_func (t);
      free_func (t);
    } else n = t;
    } else n = t;
  } else {
  } else {
    b1 = b;
    b1 = b;
    if (unroll > 1)
    if (unroll > 1) n = unroll_loop (f, b1, unroll);
      n = unroll_loop (f, b1, unroll);
    else return dup_func (f);
    else n = dup_func (n);
 
  }
  }
 
 
  /* Assign new count to functions */
  /* Assign new counts to functions */
  assert (counts = (int *)malloc (sizeof (int) * (preroll - 1 + unroll)));
  assert (counts = (int *)malloc (sizeof (int) * (preroll - 1 + unroll)));
  count_bb_seq (n, b, bb_filename, counts, preroll, unroll);
  count_bb_seq (n, b, bb_filename, counts, preroll, unroll);
  for (i = 0; i < preroll - 1 + unroll; i++) {
  for (i = 0; i < preroll - 1 + unroll; i++) {
    if (i == 0) b1 = b;
    if (i == 0) b1 = b;
    else b1 = f->num_bb + (i - 1) * 2;
    else b1 = f->num_bb + (i - 1) * 2;

powered by: WebSVN 2.1.0

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