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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_58/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 1041

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 879 markom
/* cuc.c -- OpenRISC Custom Unit Compiler
2
 *    Copyright (C) 2002 Marko Mlinar, markom@opencores.org
3
 *
4
 *    This file is part of OpenRISC 1000 Architectural Simulator.
5
 *
6
 *    This program is free software; you can redistribute it and/or modify
7
 *    it under the terms of the GNU General Public License as published by
8
 *    the Free Software Foundation; either version 2 of the License, or
9
 *    (at your option) any later version.
10
 *
11
 *    This program is distributed in the hope that it will be useful,
12
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *    GNU General Public License for more details.
15
 *
16
 *    You should have received a copy of the GNU General Public License
17
 *    along with this program; if not, write to the Free Software
18
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Main file, including code optimization and command prompt */
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <stdarg.h>
25
#include <assert.h>
26 915 markom
#include <ctype.h>
27 879 markom
#include "sim-config.h"
28
#include "cuc.h"
29
#include "insn.h"
30
#include "profiler.h"
31 883 markom
#include "opcode/or32.h"
32 897 markom
#include "parse.h"
33 879 markom
 
34
FILE *flog;
35 883 markom
int cuc_debug = 0;
36 879 markom
 
37
/* Last used registers by software convention */
38 939 markom
/* Note that r11 is caller saved register, and we can destroy it.
39
   Due to CUC architecture we must always return something, even garbage (so that
40
   caller knows, we are finished, when we send acknowledge).
41
   In case r11 was not used (trivial register assignment) we will remove it later,
42
   but if we assigned a value to it, it must not be removed, so caller_saved[11] = 0 */
43
const int caller_saved[MAX_REGS] = {
44 879 markom
  0, 0, 0, 1, 1, 1, 1, 1,
45 939 markom
  1, 1, 0, 0, 0, 1, 0, 1,
46 879 markom
  0, 1, 0, 1, 0, 1, 0, 1,
47
  0, 1, 0, 1, 0, 1, 0, 1,
48
  1, 1};
49
 
50 933 markom
/* returns log2(x) */
51
int log2 (unsigned long x)
52
{
53
  int c = 0;
54
  assert (x >= 0);
55
  if (!x) return 0; /* not by the book, but practical */
56
  while (x != 1) x >>= 1, c++;
57
  return c;
58
}
59
 
60 931 markom
/* Does all known instruction optimizations */
61
void cuc_optimize (cuc_func *func)
62
{
63
  int modified = 0;
64 936 markom
  int first = 1;
65 931 markom
  log ("Optimizing.\n");
66
  do {
67
    modified = 0;
68 941 markom
    clean_deps (func);
69
    if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_CLEAN_DEPS");
70 931 markom
    if (optimize_cmovs (func)) {
71
      if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS");
72
      modified = 1;
73
    }
74 934 markom
    if (cuc_debug) cuc_check (func);
75 931 markom
    if (optimize_tree (func)) {
76
      if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_TREE1");
77
      modified = 1;
78
    }
79
    if (remove_nops (func)) {
80
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
81
      modified = 1;
82
    }
83 934 markom
    if (cuc_debug) cuc_check (func);
84 931 markom
    if (remove_dead (func)) {
85
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD");
86
      modified = 1;
87
    }
88 934 markom
    if (cuc_debug) cuc_check (func);
89 931 markom
    if (cse (func)) {
90
      log ("Common subexpression elimination.\n");
91
      if (cuc_debug >= 3) print_cuc_bb (func, "AFTER_CSE");
92
      modified = 1;
93
    }
94 936 markom
    if (first) {
95
      insert_conditional_facts (func);
96
      if (cuc_debug >= 3) print_cuc_bb (func, "AFTER_COND_FACT");
97
      if (cuc_debug) cuc_check (func);
98
      first = 0;
99
    }
100 931 markom
    if (optimize_bb (func)) {
101
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_OPT_BB");
102
      modified = 1;
103
    }
104 934 markom
    if (cuc_debug) cuc_check (func);
105 931 markom
    if (remove_nops (func)) {
106
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
107
      modified = 1;
108
    }
109
    if (remove_dead_bb (func)) {
110
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD_BB");
111
      modified = 1;
112
    }
113
    if (remove_trivial_regs (func)) {
114
      if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_TRIVIAL");
115
      modified = 1;
116
    }
117
    if (remove_nops (func)) {
118
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
119
      modified = 1;
120
    }
121 941 markom
    add_memory_dep (func, func->memory_order);
122
    if (cuc_debug >= 7) print_cuc_bb (func, "AFTER_MEMORY_DEP");
123
    add_data_dep (func);
124
    if (cuc_debug >= 8) print_cuc_bb (func, "AFTER_DATA_DEP");
125 953 markom
    if (schedule_memory (func, func->memory_order)) {
126
      if (cuc_debug >= 7) print_cuc_bb (func, "AFTER_SCHEDULE_MEM");
127
      modified = 1;
128
    }
129 931 markom
  } while (modified);
130 953 markom
  set_io (func);
131 937 markom
#if 0
132 936 markom
  detect_max_values (func);
133
  if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_MAX_VALUES");
134 937 markom
#endif
135 931 markom
}
136
 
137
/* Pre/unrolls basic block and optimizes it */
138 879 markom
cuc_timings *preunroll_bb (char *bb_filename, cuc_func *f, cuc_timings *timings, int b, int i, int j)
139
{
140
  cuc_func *func;
141 883 markom
  cucdebug (2, "BB%i unroll %i times preroll %i times\n", b, j, i);
142 1041 markom
  log ("BB%i unroll %i times preroll %i times\n", b, j, i);
143 879 markom
  func = preunroll_loop (f, b, i, j, bb_filename);
144 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_PREUNROLL");
145 931 markom
  cuc_optimize (func);
146 879 markom
 
147 883 markom
  cucdebug (2, "new_time = %i, old_time = %i, size = %f\n",
148 879 markom
           timings->new_time, func->orig_time, timings->size);
149
  log ("new time = %icyc, old_time = %icyc, size = %.0f gates\n",
150
         timings->new_time, func->orig_time, timings->size);
151
  //output_verilog (func, argv[1]);
152
  free_func (func);
153
  timings->b = b;
154
  timings->unroll = j;
155
  timings->preroll = i;
156 883 markom
  timings->nshared = 0;
157 879 markom
  return timings;
158
}
159
 
160 931 markom
/* Simple comparison function */
161 879 markom
int tim_comp (cuc_timings *a, cuc_timings *b)
162
{
163
  if (a->new_time < b->new_time) return -1;
164
  else if (a->new_time > b->new_time) return 1;
165
  else return 0;
166
}
167
 
168 931 markom
/* Analyses function; done when cuc command is entered in (sim) prompt */
169 879 markom
cuc_func *analyse_function (char *module_name, long orig_time,
170 897 markom
                unsigned long start_addr, unsigned long end_addr,
171 1041 markom
                int memory_order, int num_runs)
172 879 markom
{
173
  cuc_timings timings;
174
  cuc_func *func = (cuc_func *) malloc (sizeof (cuc_func));
175
  cuc_func *saved;
176
  int b, i, j;
177
  char tmp1[256];
178
  char tmp2[256];
179
 
180
  func->orig_time = orig_time;
181
  func->start_addr = start_addr;
182
  func->end_addr = end_addr;
183 897 markom
  func->memory_order = memory_order;
184 906 markom
  func->nfdeps = 0;
185
  func->fdeps = NULL;
186 1041 markom
  func->num_runs = num_runs;
187 879 markom
 
188
  sprintf (tmp1, "%s.bin", module_name);
189 883 markom
  cucdebug (2, "Loading %s.bin\n", module_name);
190 897 markom
  if (cuc_load (tmp1)) {
191
    free (func);
192
    return NULL;
193
  }
194 879 markom
 
195
  log ("Detecting basic blocks\n");
196
  detect_bb (func);
197 883 markom
  if (cuc_debug >= 2) print_cuc_insns ("WITH_BB_LIMITS", 0);
198 879 markom
 
199
  //sprintf (tmp1, "%s.bin.mp", module_name);
200
  sprintf (tmp2, "%s.bin.bb", module_name);
201
  generate_bb_seq (func, config.sim.mprof_fn, tmp2);
202 897 markom
  log ("Assuming %i clk cycle load (%i cyc burst)\n", runtime.cuc.mdelay[0], runtime.cuc.mdelay[2]);
203
  log ("Assuming %i clk cycle store (%i cyc burst)\n", runtime.cuc.mdelay[1], runtime.cuc.mdelay[3]);
204 879 markom
 
205
  build_bb (func);
206 883 markom
  if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_BUILD_BB");
207 879 markom
  reg_dep (func);
208
 
209
  log ("Detecting dependencies\n");
210 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_REG_DEP");
211 931 markom
  cuc_optimize (func);
212 879 markom
 
213 897 markom
#if 0
214 883 markom
  csm (func);
215 897 markom
#endif
216 879 markom
  assert (saved = dup_func (func));
217 883 markom
 
218
  timings.preroll = timings.unroll = 1;
219
  timings.nshared = 0;
220 931 markom
 
221 883 markom
  add_latches (func);
222
  if (cuc_debug >= 1) print_cuc_bb (func, "AFTER_LATCHES");
223
  analyse_timings (func, &timings);
224 879 markom
 
225
  free_func (func);
226 883 markom
  log ("Base option: pre%i,un%i,sha%i: %icyc %.1f\n",
227
        timings.preroll, timings.unroll, timings.nshared, timings.new_time, timings.size);
228
  saved->timings = timings;
229 879 markom
 
230
#if 1
231
  /* detect and unroll simple loops */
232
  for (b = 0; b < saved->num_bb; b++) {
233
    cuc_timings t[MAX_UNROLL * MAX_PREROLL];
234
    cuc_timings *ut;
235
    cuc_timings *cut = &t[0];
236
    int nt = 1;
237
    double csize;
238 897 markom
    saved->bb[b].selected_tim = -1;
239 879 markom
 
240
    /* Is it a loop? */
241
    if (saved->bb[b].next[0] != b && saved->bb[b].next[1] != b) continue;
242
    t[0] = timings;
243
    t[0].b = b;
244
    t[0].preroll = 1;
245
    t[0].unroll = 1;
246 883 markom
    t[0].nshared = 0;
247 879 markom
 
248
    sprintf (tmp1, "%s.bin.bb", module_name);
249
    i = 1;
250
    do {
251
      cuc_timings *pt;
252
      cuc_timings *cpt = cut;
253
      j = 1;
254
 
255
      do {
256
        pt = cpt;
257
        cpt = preunroll_bb (tmp1, saved, &t[nt++], b, ++j, i);
258 915 markom
      } while (j <= MAX_PREROLL && pt->new_time > cpt->new_time);
259 879 markom
      i++;
260
      ut = cut;
261
      cut = preunroll_bb (tmp1, saved, &t[nt++], b, 1, i);
262 915 markom
    } while (i <= MAX_UNROLL && ut->new_time > cut->new_time);
263 879 markom
 
264
    /* Sort the timings */
265 883 markom
#if 0
266
    if (cuc_debug >= 3)
267 997 markom
    for (i = 0; i < nt; i++) PRINTF ("%i:%i,%i: %icyc\n",
268 879 markom
                    t[i].b, t[i].preroll, t[i].unroll, t[i].new_time);
269 883 markom
#endif
270 879 markom
 
271
    qsort (t, nt, sizeof (cuc_timings), (int (*)(const void *, const void *))tim_comp);
272
 
273
    /* Delete timings, that have worst time and bigger size than other */
274
    j = 1;
275
    csize = t[0].size;
276
    for (i = 1; i < nt; i++)
277
      if (t[i].size < csize) t[j++] = t[i];
278
    nt = j;
279 883 markom
 
280
    cucdebug (1, "Available options\n");
281
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
282
        t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
283
    /* Add results from CSM */
284
    j = nt;
285
    for (i = 0; i < saved->bb[b].ntim; i++) {
286
      int i1;
287
      for (i1 = 0; i1 < nt; i1++) {
288
        t[j] = t[i1];
289
        t[j].size += saved->bb[b].tim[i].size - timings.size;
290
        t[j].new_time += saved->bb[b].tim[i].new_time - timings.new_time;
291
        t[j].nshared = saved->bb[b].tim[i].nshared;
292
        t[j].shared = saved->bb[b].tim[i].shared;
293
        if (++j >= MAX_UNROLL * MAX_PREROLL) goto full;
294
      }
295
    }
296
 
297
full:
298
    nt = j;
299 879 markom
 
300 883 markom
    cucdebug (1, "Available options:\n");
301
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
302
        t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
303 879 markom
 
304 883 markom
    /* Sort again with new timings added */
305
    qsort (t, nt, sizeof (cuc_timings), (int (*)(const void *, const void *))tim_comp);
306
 
307
    /* Delete timings, that have worst time and bigger size than other */
308
    j = 1;
309
    csize = t[0].size;
310
    for (i = 1; i < nt; i++)
311
      if (t[i].size < csize) t[j++] = t[i];
312
    nt = j;
313
 
314
    cucdebug (1, "Available options:\n");
315
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
316
                               t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
317
 
318
    if (saved->bb[b].ntim) free (saved->bb[b].tim);
319 879 markom
    saved->bb[b].ntim = nt;
320
    assert (saved->bb[b].tim = (cuc_timings *) malloc (sizeof (cuc_timings) * nt));
321
 
322
    /* Copy options in reverse order -- smallest first */
323
    for (i = 0; i < nt; i++) saved->bb[b].tim[i] = t[nt - 1 - i];
324 883 markom
 
325
    log ("Available options:\n");
326
    for (i = 0; i < saved->bb[b].ntim; i++) {
327
      log ("%i:pre%i,un%i,sha%i: %icyc %.1f\n",
328
        saved->bb[b].tim[i].b, saved->bb[b].tim[i].preroll, saved->bb[b].tim[i].unroll,
329
        saved->bb[b].tim[i].nshared, saved->bb[b].tim[i].new_time, saved->bb[b].tim[i].size);
330
    }
331 879 markom
  }
332
#endif
333
  return saved;
334
}
335
 
336 897 markom
/* Utility option formatting functions */
337
static const char *option_char = "?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
338
 
339
/*static */char *gen_option (char *s, int bb_no, int f_opt)
340 883 markom
{
341 897 markom
  if (bb_no >= 0) sprintf (s, "%i", bb_no);
342
  assert (f_opt <= strlen (option_char));
343
  sprintf (s, "%s%c", s, option_char[f_opt]);
344
  return s;
345
}
346
 
347
/*static */void print_option (int bb_no, int f_opt)
348
{
349
  char tmp1[10];
350
  char tmp2[10];
351
  sprintf (tmp2, "%s", gen_option (tmp1, bb_no, f_opt));
352 997 markom
  PRINTF ("%3s", tmp2);
353 897 markom
}
354
 
355
static char *format_func_options (char *s, cuc_func *f)
356
{
357
  int b, first = 1;
358
  *s = '\0';
359
  for (b = 0; b < f->num_bb; b++)
360
    if (f->bb[b].selected_tim >= 0) {
361
      char tmp[10];
362
      sprintf (s, "%s%s%s", s, first ? "" : ",", gen_option (tmp, b, f->bb[b].selected_tim));
363
      first = 0;
364
    }
365
  return s;
366
}
367
 
368
static void options_cmd (int func_no, cuc_func *f)
369
{
370 883 markom
  int b, i;
371 903 markom
  char tmp[30];
372 897 markom
  char *name = prof_func[func_no].name;
373 997 markom
  PRINTF ("-----------------------------------------------------------------------------\n");
374
  PRINTF ("|%-28s|pre/unrolled|shared|  time  |  gates |old_time|\n",
375 904 markom
            strstrip (tmp, name, 28));
376 997 markom
  PRINTF ("|                    BASE    |%4i / %4i | %4i |%8i|%8.f|%8i|\n", 1, 1, 0,
377 903 markom
          f->timings.new_time, f->timings.size, f->orig_time);
378 883 markom
  for (b = 0; b < f->num_bb; b++) {
379
    /* Print out results */
380 897 markom
    for (i = 1; i < f->bb[b].ntim; i++) { /* First one is base option */
381
      int time = f->bb[b].tim[i].new_time - f->timings.new_time;
382
      double size = f->bb[b].tim[i].size - f->timings.size;
383 997 markom
      PRINTF ("|                   ");
384 897 markom
      print_option (b, i);
385 997 markom
      PRINTF ("      |%4i / %4i | %4i |%+8i|%+8.f|        |\n",
386 897 markom
        f->bb[b].tim[i].preroll, f->bb[b].tim[i].unroll, f->bb[b].tim[i].nshared,
387
        time, size);
388 883 markom
    }
389
  }
390
}
391
 
392 897 markom
/* Generates a function, based on specified parameters */
393 915 markom
cuc_func *generate_function (cuc_func *rf, char *name, char *cut_filename)
394 897 markom
{
395
  int b, i, j;
396
  char tmp[256];
397
  cuc_timings tt;
398
  cuc_func *f;
399
  assert (f = dup_func (rf));
400
 
401 915 markom
  if (cuc_debug >= 2) print_cuc_bb (f, "BEFORE_GENERATE");
402 897 markom
  log ("Generating function %s.\n", name);
403 997 markom
  PRINTF ("Generating function %s.\n", name);
404 897 markom
 
405
  format_func_options (tmp, rf);
406 997 markom
  if (strlen (tmp)) PRINTF ("Applying options: %s\n", tmp);
407
  else PRINTF ("Using basic options.\n");
408 897 markom
 
409
  /* Generate function as specified by options */
410
  for (b = 0; b < f->num_bb; b++) {
411
    cuc_timings *st;
412
    if (rf->bb[b].selected_tim < 0) continue;
413
    st = &rf->bb[b].tim[rf->bb[b].selected_tim];
414
    sprintf (tmp, "%s.bin.bb", name);
415
    preunroll_bb (&tmp[0], f, &tt, b, st->preroll, st->unroll);
416
    if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_PREUNROLL");
417
  }
418
  for (b = 0; b < f->num_bb; b++) {
419
    cuc_timings *st;
420
    if (rf->bb[b].selected_tim < 0) continue;
421
    st = &rf->bb[b].tim[rf->bb[b].selected_tim];
422
    if (!st->nshared) continue;
423
    assert (0);
424
    //csm_gen (f, rf, st->nshared, st->shared);
425
  }
426 915 markom
  add_latches (f);
427
  if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_LATCHES");
428 897 markom
  analyse_timings (f, &tt);
429 915 markom
 
430
  sprintf (tmp, "%s%s", cut_filename, name);
431 941 markom
  output_verilog (f, tmp, name);
432 897 markom
  return f;
433
}
434
 
435
/* Calculates required time, based on selected options */
436
int calc_cycles (cuc_func *f)
437
{
438
  int b, i, ntime = f->timings.new_time;
439
  for (b = 0; b < f->num_bb; b++)
440
    if (f->bb[b].selected_tim >= 0) {
441
      assert (f->bb[b].selected_tim < f->bb[b].ntim);
442
      ntime += f->bb[b].tim[f->bb[b].selected_tim].new_time - f->timings.new_time;
443
    }
444
  return ntime;
445
}
446
 
447
/* Calculates required size, based on selected options */
448
double calc_size (cuc_func *f)
449
{
450
  int b, i;
451
  double size = f->timings.size;
452
  for (b = 0; b < f->num_bb; b++)
453
    if (f->bb[b].selected_tim >= 0) {
454
      assert (f->bb[b].selected_tim < f->bb[b].ntim);
455
      size += f->bb[b].tim[f->bb[b].selected_tim].size - f->timings.size;
456
    }
457
  return size;
458
}
459
 
460 879 markom
/* Dumps specified function to file (hex) */
461
unsigned long extract_function (char *out_fn, unsigned long start_addr)
462
{
463
  FILE *fo;
464
  unsigned long a = start_addr;
465
  int x = 0;
466
  assert (fo = fopen (out_fn, "wt+"));
467
 
468
  do {
469
    unsigned long d = evalsim_mem32 (a);
470
    int index = insn_decode (d);
471
    assert (index >= 0);
472
    if (x) x++;
473
    if (strcmp (insn_name (index), "l.jr") == 0) x = 1;
474
    a += 4;
475
    fprintf (fo, "%08x\n", d);
476
  } while (x < 2);
477
 
478
  fclose (fo);
479
  return a - 4;
480
}
481
 
482
static cuc_func *func[MAX_FUNCS];
483 897 markom
static int func_v[MAX_FUNCS];
484 879 markom
 
485 906 markom
/* Detects function dependencies and removes  */
486
static void set_func_deps ()
487
{
488
  int f, b, i, j;
489
restart:
490
  for (f = 0; f < prof_nfuncs - 1; f++) if (func[f]) {
491
    int fused[MAX_FUNCS] = {0};
492
    int c;
493
    for (b = 0; b < func[f]->num_bb; b++)
494
      for (i = 0; i < func[f]->bb[b].ninsn; i++) {
495
        cuc_insn *ii = &func[f]->bb[b].insn[i];
496
        if (ii->index == II_CALL) {
497
          assert (ii->opt[0] == OPT_CONST);
498
          for (j = 0; j < prof_nfuncs - 1; j++)
499
            if (func[j] && func[j]->start_addr == ii->op[0]) break;
500
          if (j >= prof_nfuncs - 1) {
501
            log ("%s is calling unknown function, address %08x\n",
502
                            prof_func[f].name, ii->op[0]);
503
            debug (1, "%s is calling unknown function, address %08x\n",
504
                            prof_func[f].name, ii->op[0]);
505
            free_func (func[f]);
506
            func[f] = NULL;
507
            goto restart;
508
          } else if (f == j) {
509
            log ("%s is recursive, ignoring\n", prof_func[f].name);
510
            debug (1, "%s is recursive, ignoring\n", prof_func[f].name);
511
            free_func (func[f]);
512
            func[f] = NULL;
513
            goto restart;
514
          } else fused[j]++;
515
        }
516
      }
517
    for (i = 0; i < MAX_FUNCS; i++) if (fused[i]) c++;
518
    if (func[f]->nfdeps) free (func[f]->fdeps);
519
    func[f]->nfdeps = c;
520
    func[f]->fdeps = (cuc_func **) malloc (sizeof (cuc_func *) * c);
521
    for (i = 0, j = 0; i < MAX_FUNCS; i++)
522
      if (fused[i]) func[f]->fdeps[j++] = func[i];
523
  }
524
 
525
  /* Detect loops */
526
  {
527
    int change;
528
    for (f = 0; f < MAX_FUNCS; f++) if (func[f]) func[f]->tmp = 0;
529
    do {
530
      change = 0;
531
      for (f = 0; f < MAX_FUNCS; f++) if (func[f] && !func[f]->tmp) {
532
        int o = 1;
533
        for (i = 0; i < func[f]->nfdeps; i++)
534
          if (!func[f]->fdeps[i]->tmp) {o = 0; break;}
535
        if (o) {
536
          func[f]->tmp = 1;
537
          change = 1;
538
        }
539
      }
540
    } while (change);
541
 
542
    change = 0;
543
    for (f = 0; f < MAX_FUNCS; f++) if (func[f] && !func[f]->tmp) {
544
      free_func (func[f]);
545
      func[f] = NULL;
546
      change = 1;
547
    }
548
    if (change) goto restart;
549
  }
550
}
551
 
552 879 markom
void main_cuc (char *filename)
553
{
554 883 markom
  int i, j;
555 879 markom
  char tmp1[256];
556 915 markom
  char filename_cut[256];
557 940 markom
  for (i = 0; i < sizeof (filename_cut); i++) {
558 915 markom
    if (isalpha(filename[i])) filename_cut[i] = filename[i];
559
    else {
560
      filename_cut[i] = '\0';
561
      break;
562
    }
563
  }
564 879 markom
 
565 997 markom
  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
566
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n", config.sim.prof_fn, config.sim.mprof_fn);
567 915 markom
  sprintf (tmp1, "%s.log", filename_cut);
568 997 markom
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
569 879 markom
  assert (flog = fopen (tmp1, "wt+"));
570
 
571
  /* Loads in the specified timings table */
572 997 markom
  PRINTF ("Using timings from \"%s\" at %s\n",config.cuc.timings_fn,
573 897 markom
                 generate_time_pretty (tmp1, config.sim.clkcycle_ps));
574
  load_timing_table (config.cuc.timings_fn);
575
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
576 997 markom
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
577 897 markom
    config.cuc.no_multicycle ? "OFF" : "ON", config.cuc.enable_bursts ? "ON" : "OFF",
578
    config.cuc.memory_order == MO_NONE ? "no" : config.cuc.memory_order == MO_WEAK ? "weak" :
579
    config.cuc.memory_order == MO_STRONG ? "strong" : "exact");
580 879 markom
 
581
  prof_set (1, 0);
582
  assert (prof_acquire (config.sim.prof_fn) == 0);
583 1041 markom
  cuc_debug = 9;
584 897 markom
 
585
  if (config.cuc.calling_convention)
586 997 markom
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
587 879 markom
 
588
  /* Try all functions except "total" */
589
  for (i = 0; i < prof_nfuncs - 1; i++) {
590
    long orig_time;
591
    unsigned long start_addr, end_addr;
592
    orig_time = prof_func[i].cum_cycles;
593
    start_addr = prof_func[i].addr;
594
 
595
    /* Extract the function from the binary */
596
    sprintf (tmp1, "%s.bin", prof_func[i].name);
597
    end_addr = extract_function (tmp1, start_addr);
598
 
599
    log ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
600 997 markom
    PRINTF ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
601 897 markom
    func[i] = analyse_function (prof_func[i].name, orig_time, start_addr,
602 1041 markom
                   end_addr, config.cuc.memory_order, prof_func[i].calls);
603 897 markom
    func_v[i] = 0;
604 879 markom
  }
605 906 markom
  set_func_deps ();
606
 
607 883 markom
  while (1) {
608
    char *s;
609 906 markom
wait_command:
610 997 markom
    PRINTF ("(cuc) ");
611 883 markom
    fflush (stdout);
612
    fgets(tmp1, sizeof tmp1, stdin);
613
    for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
614
    *s = '\0';
615
 
616 906 markom
      /* quit command */
617 883 markom
    if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0) {
618 1003 markom
      /* Delete temporary files */
619
      for (i = 0; i < prof_nfuncs - 1; i++) {
620
        sprintf (tmp1, "%s.bin", prof_func[i].name);
621 1041 markom
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK");
622 1003 markom
        sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
623 1041 markom
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK");
624 1003 markom
      }
625 883 markom
      break;
626 1003 markom
 
627 906 markom
      /* profile command */
628 883 markom
    } else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0) {
629 897 markom
      int ntime = 0;
630
      int size = 0;
631 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
632
      PRINTF ("|function name       |calls|avg cycles  |old%| max. f.  | impr. f.| options |\n");
633
      PRINTF ("|--------------------+-----+------------+----+----------|---------+---------|\n");
634 883 markom
      for (j = 0; j < prof_nfuncs; j++) {
635
        int bestcyc = 0, besti = 0;
636 897 markom
        char tmp[100];
637 883 markom
        for (i = 0; i < prof_nfuncs; i++)
638
          if (prof_func[i].cum_cycles > bestcyc) {
639
            bestcyc = prof_func[i].cum_cycles;
640
            besti = i;
641
          }
642
        i = besti;
643 997 markom
        PRINTF ("|%-20s|%5i|%12.1f|%3.0f%%| ",
644 897 markom
                strstrip (tmp, prof_func[i].name, 20),  prof_func[i].calls,
645 883 markom
                ((double)prof_func[i].cum_cycles / prof_func[i].calls),
646
                (100. * prof_func[i].cum_cycles / prof_cycles));
647
        if (func[i]) {
648 897 markom
          double f = 1.0;
649
          if (func_v[i]) {
650
            int nt = calc_cycles (func[i]);
651
            int s = calc_size (func[i]);
652 996 markom
            f = 1. * func[i]->orig_time / nt;
653 1041 markom
            ntime += nt;
654 897 markom
            size += s;
655
          } else ntime += prof_func[i].cum_cycles;
656 997 markom
          PRINTF ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles
657 905 markom
                          / func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
658 897 markom
        } else {
659 997 markom
          PRINTF ("     N/A |     N/A |     N/A |\n");
660 897 markom
          ntime += prof_func[i].cum_cycles;
661
        }
662
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
663 883 markom
      }
664 897 markom
      for (i = 0; i < prof_nfuncs; i++)
665
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
666 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
667
      PRINTF ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
668 905 markom
                      ntime, prof_cycles, size, 1. * prof_cycles / ntime);
669 906 markom
 
670
      /* debug command */
671 883 markom
    } else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) {
672
      sscanf (tmp1, "%*s %i", &cuc_debug);
673
      if (cuc_debug < 0) cuc_debug = 0;
674
      if (cuc_debug > 9) cuc_debug = 9;
675 906 markom
 
676
      /* generate command */
677 883 markom
    } else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0) {
678 906 markom
      /* check for function dependencies */
679 897 markom
      for (i = 0; i < prof_nfuncs; i++)
680 906 markom
        if (func[i]) func[i]->tmp = func_v[i];
681 915 markom
      for (i = 0; i < prof_nfuncs; i++) if (func[i])
682 906 markom
        for (j = 0; j < func[i]->nfdeps; j++)
683
          if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp) {
684 997 markom
            PRINTF ("Function %s must be selected for translation (required by %s)\n",
685 906 markom
                    prof_func[j].name, prof_func[i].name);
686
            goto wait_command;
687
          }
688
      for (i = 0; i < prof_nfuncs; i++)
689 915 markom
        if (func[i] && func_v[i]) generate_function (func[i], prof_func[i].name, filename_cut);
690
      generate_main (prof_nfuncs, func, filename_cut);
691
 
692 918 markom
      /* selectall command */
693
    } else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0) {
694
      char tmp[50], ch;
695
      int p, o, b, f;
696
      for (f = 0; f < prof_nfuncs; f++) if (func[f]) {
697
        func_v[f] = 1;
698 997 markom
        PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
699 918 markom
      }
700
 
701 906 markom
      /* select command */
702 897 markom
    } else if (strncmp (tmp1, "s", 1) == 0 || strncmp (tmp1, "select", 6) == 0) {
703
      char tmp[50], ch;
704
      int p, o, b, f;
705
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
706 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
707 897 markom
      else {
708
        /* Check if we have valid option */
709
        for (f = 0; f < prof_nfuncs; f++)
710
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
711
        if (f < prof_nfuncs) {
712
          if (p == 1) {
713
            if (func[f]) {
714
              func_v[f] = 1;
715 997 markom
              PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
716
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
717 897 markom
          } else {
718
            if (!func_v[f])
719 997 markom
              PRINTF ("Function %s not yet selected for translation.\n", prof_func[f].name);
720 897 markom
            if (p < 3) goto invalid_option;
721
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
722
            if (!option_char[o]) goto invalid_option;
723
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
724
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
725
 
726
            /* select an option */
727
            func[f]->bb[b].selected_tim = o;
728
            if (func[f]->bb[b].tim[o].nshared) {
729 997 markom
              PRINTF ("Option has shared instructions: ");
730 897 markom
              print_shared (func[f], func[f]->bb[b].tim[o].shared, func[f]->bb[b].tim[o].nshared);
731 997 markom
              PRINTF ("\n");
732 897 markom
            }
733 906 markom
            goto wait_command;
734 897 markom
invalid_option:
735 997 markom
            PRINTF ("Invalid option.\n");
736 897 markom
          }
737 997 markom
        } else PRINTF ("Invalid function.\n");
738 897 markom
      }
739 906 markom
 
740
      /* unselect command */
741 897 markom
    } else if (strncmp (tmp1, "u", 1) == 0 || strncmp (tmp1, "unselect", 8) == 0) {
742
      char tmp[50], ch;
743
      int p, o, b, f;
744
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
745 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
746 897 markom
      else {
747
        /* Check if we have valid option */
748
        for (f = 0; f < prof_nfuncs; f++)
749
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
750
        if (f < prof_nfuncs) {
751
          if (p == 1) {
752
            if (func[f]) {
753
              func_v[f] = 0;
754 997 markom
              PRINTF ("Function %s unselected for translation.\n", prof_func[f].name);
755
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
756 897 markom
          } else {
757
            if (p < 3) goto invalid_option;
758
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
759
            if (!option_char[o]) goto invalid_option;
760
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
761
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
762
 
763
            /* select an option */
764
            func[f]->bb[b].selected_tim = -1;
765
          }
766 997 markom
        } else PRINTF ("Invalid function.\n");
767 897 markom
      }
768 906 markom
 
769
      /* options command */
770 883 markom
    } else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0) {
771 897 markom
      int any = 0;
772 997 markom
      PRINTF ("Available options:\n");
773 883 markom
      for (i = 0; i < prof_nfuncs; i++)
774 897 markom
        if (func[i]) {
775
          options_cmd (i, func[i]);
776
          any = 1;
777
        }
778 997 markom
      if (any) PRINTF ("-----------------------------------------------------------------------------\n");
779
      else PRINTF ("Sorry. No available options.\n");
780 906 markom
 
781
      /* Ignore empty string */
782 902 markom
    } else if (strcmp (tmp1, "") == 0) {
783 906 markom
 
784
      /* help command */
785 883 markom
    } else {
786
      if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
787 997 markom
        PRINTF ("Unknown command.\n");
788
      PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
789
      PRINTF ("Available commands:\n");
790
      PRINTF ("  h | help                   displays this help\n");
791
      PRINTF ("  q | quit                   returns to or1ksim prompt\n");
792
      PRINTF ("  p | profile                displays function profiling\n");
793
      PRINTF ("  d | debug #                sets debug level (0-9)\n");
794
      PRINTF ("  o | options                displays available options\n");
795
      PRINTF ("  s | select func [option]   selects an option/function\n");
796
      PRINTF ("  u | unselect func [option] unselects an option/function\n");
797
      PRINTF ("  g | generate               generates verilog file\n");
798 883 markom
    }
799
  }
800
 
801 879 markom
  /* Dispose memory */
802
  for (i = 0; i < prof_nfuncs -1; i++)
803
    if (func[i]) free_func (func[i]);
804
 
805
  fclose (flog);
806
}
807
 

powered by: WebSVN 2.1.0

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