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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_73/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 997

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 879 markom
  func = preunroll_loop (f, b, i, j, bb_filename);
143 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_PREUNROLL");
144 931 markom
  cuc_optimize (func);
145 879 markom
 
146 883 markom
  cucdebug (2, "new_time = %i, old_time = %i, size = %f\n",
147 879 markom
           timings->new_time, func->orig_time, timings->size);
148
  log ("new time = %icyc, old_time = %icyc, size = %.0f gates\n",
149
         timings->new_time, func->orig_time, timings->size);
150
  //output_verilog (func, argv[1]);
151
  free_func (func);
152
  timings->b = b;
153
  timings->unroll = j;
154
  timings->preroll = i;
155 883 markom
  timings->nshared = 0;
156 879 markom
  return timings;
157
}
158
 
159 931 markom
/* Simple comparison function */
160 879 markom
int tim_comp (cuc_timings *a, cuc_timings *b)
161
{
162
  if (a->new_time < b->new_time) return -1;
163
  else if (a->new_time > b->new_time) return 1;
164
  else return 0;
165
}
166
 
167 931 markom
/* Analyses function; done when cuc command is entered in (sim) prompt */
168 879 markom
cuc_func *analyse_function (char *module_name, long orig_time,
169 897 markom
                unsigned long start_addr, unsigned long end_addr,
170
                int memory_order)
171 879 markom
{
172
  cuc_timings timings;
173
  cuc_func *func = (cuc_func *) malloc (sizeof (cuc_func));
174
  cuc_func *saved;
175
  int b, i, j;
176
  char tmp1[256];
177
  char tmp2[256];
178
 
179
  func->orig_time = orig_time;
180
  func->start_addr = start_addr;
181
  func->end_addr = end_addr;
182 897 markom
  func->memory_order = memory_order;
183 906 markom
  func->nfdeps = 0;
184
  func->fdeps = NULL;
185 879 markom
 
186
  sprintf (tmp1, "%s.bin", module_name);
187 883 markom
  cucdebug (2, "Loading %s.bin\n", module_name);
188 897 markom
  if (cuc_load (tmp1)) {
189
    free (func);
190
    return NULL;
191
  }
192 879 markom
 
193
  log ("Detecting basic blocks\n");
194
  detect_bb (func);
195 883 markom
  if (cuc_debug >= 2) print_cuc_insns ("WITH_BB_LIMITS", 0);
196 879 markom
 
197
  //sprintf (tmp1, "%s.bin.mp", module_name);
198
  sprintf (tmp2, "%s.bin.bb", module_name);
199
  generate_bb_seq (func, config.sim.mprof_fn, tmp2);
200 897 markom
  log ("Assuming %i clk cycle load (%i cyc burst)\n", runtime.cuc.mdelay[0], runtime.cuc.mdelay[2]);
201
  log ("Assuming %i clk cycle store (%i cyc burst)\n", runtime.cuc.mdelay[1], runtime.cuc.mdelay[3]);
202 879 markom
 
203
  build_bb (func);
204 883 markom
  if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_BUILD_BB");
205 879 markom
  reg_dep (func);
206
 
207
  log ("Detecting dependencies\n");
208 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_REG_DEP");
209 931 markom
  cuc_optimize (func);
210 879 markom
 
211 897 markom
#if 0
212 883 markom
  csm (func);
213 897 markom
#endif
214 879 markom
  assert (saved = dup_func (func));
215 883 markom
 
216
  timings.preroll = timings.unroll = 1;
217
  timings.nshared = 0;
218 931 markom
 
219 883 markom
  add_latches (func);
220
  if (cuc_debug >= 1) print_cuc_bb (func, "AFTER_LATCHES");
221
  analyse_timings (func, &timings);
222 879 markom
 
223
  free_func (func);
224 883 markom
  log ("Base option: pre%i,un%i,sha%i: %icyc %.1f\n",
225
        timings.preroll, timings.unroll, timings.nshared, timings.new_time, timings.size);
226
  saved->timings = timings;
227 879 markom
 
228
#if 1
229
  /* detect and unroll simple loops */
230
  for (b = 0; b < saved->num_bb; b++) {
231
    cuc_timings t[MAX_UNROLL * MAX_PREROLL];
232
    cuc_timings *ut;
233
    cuc_timings *cut = &t[0];
234
    int nt = 1;
235
    double csize;
236 897 markom
    saved->bb[b].selected_tim = -1;
237 879 markom
 
238
    /* Is it a loop? */
239
    if (saved->bb[b].next[0] != b && saved->bb[b].next[1] != b) continue;
240
    t[0] = timings;
241
    t[0].b = b;
242
    t[0].preroll = 1;
243
    t[0].unroll = 1;
244 883 markom
    t[0].nshared = 0;
245 879 markom
 
246
    sprintf (tmp1, "%s.bin.bb", module_name);
247
    i = 1;
248
    do {
249
      cuc_timings *pt;
250
      cuc_timings *cpt = cut;
251
      j = 1;
252
 
253
      do {
254
        pt = cpt;
255
        cpt = preunroll_bb (tmp1, saved, &t[nt++], b, ++j, i);
256 915 markom
      } while (j <= MAX_PREROLL && pt->new_time > cpt->new_time);
257 879 markom
      i++;
258
      ut = cut;
259
      cut = preunroll_bb (tmp1, saved, &t[nt++], b, 1, i);
260 915 markom
    } while (i <= MAX_UNROLL && ut->new_time > cut->new_time);
261 879 markom
 
262
    /* Sort the timings */
263 883 markom
#if 0
264
    if (cuc_debug >= 3)
265 997 markom
    for (i = 0; i < nt; i++) PRINTF ("%i:%i,%i: %icyc\n",
266 879 markom
                    t[i].b, t[i].preroll, t[i].unroll, t[i].new_time);
267 883 markom
#endif
268 879 markom
 
269
    qsort (t, nt, sizeof (cuc_timings), (int (*)(const void *, const void *))tim_comp);
270
 
271
    /* Delete timings, that have worst time and bigger size than other */
272
    j = 1;
273
    csize = t[0].size;
274
    for (i = 1; i < nt; i++)
275
      if (t[i].size < csize) t[j++] = t[i];
276
    nt = j;
277 883 markom
 
278
    cucdebug (1, "Available options\n");
279
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
280
        t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
281
    /* Add results from CSM */
282
    j = nt;
283
    for (i = 0; i < saved->bb[b].ntim; i++) {
284
      int i1;
285
      for (i1 = 0; i1 < nt; i1++) {
286
        t[j] = t[i1];
287
        t[j].size += saved->bb[b].tim[i].size - timings.size;
288
        t[j].new_time += saved->bb[b].tim[i].new_time - timings.new_time;
289
        t[j].nshared = saved->bb[b].tim[i].nshared;
290
        t[j].shared = saved->bb[b].tim[i].shared;
291
        if (++j >= MAX_UNROLL * MAX_PREROLL) goto full;
292
      }
293
    }
294
 
295
full:
296
    nt = j;
297 879 markom
 
298 883 markom
    cucdebug (1, "Available options:\n");
299
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
300
        t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
301 879 markom
 
302 883 markom
    /* Sort again with new timings added */
303
    qsort (t, nt, sizeof (cuc_timings), (int (*)(const void *, const void *))tim_comp);
304
 
305
    /* Delete timings, that have worst time and bigger size than other */
306
    j = 1;
307
    csize = t[0].size;
308
    for (i = 1; i < nt; i++)
309
      if (t[i].size < csize) t[j++] = t[i];
310
    nt = j;
311
 
312
    cucdebug (1, "Available options:\n");
313
    for (i = 0; i < nt; i++) cucdebug (1, "%i:%i,%i: %icyc %.1f\n",
314
                               t[i].b, t[i].preroll, t[i].unroll, t[i].new_time, t[i].size);
315
 
316
    if (saved->bb[b].ntim) free (saved->bb[b].tim);
317 879 markom
    saved->bb[b].ntim = nt;
318
    assert (saved->bb[b].tim = (cuc_timings *) malloc (sizeof (cuc_timings) * nt));
319
 
320
    /* Copy options in reverse order -- smallest first */
321
    for (i = 0; i < nt; i++) saved->bb[b].tim[i] = t[nt - 1 - i];
322 883 markom
 
323
    log ("Available options:\n");
324
    for (i = 0; i < saved->bb[b].ntim; i++) {
325
      log ("%i:pre%i,un%i,sha%i: %icyc %.1f\n",
326
        saved->bb[b].tim[i].b, saved->bb[b].tim[i].preroll, saved->bb[b].tim[i].unroll,
327
        saved->bb[b].tim[i].nshared, saved->bb[b].tim[i].new_time, saved->bb[b].tim[i].size);
328
    }
329 879 markom
  }
330
#endif
331
  return saved;
332
}
333
 
334 897 markom
/* Utility option formatting functions */
335
static const char *option_char = "?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
336
 
337
/*static */char *gen_option (char *s, int bb_no, int f_opt)
338 883 markom
{
339 897 markom
  if (bb_no >= 0) sprintf (s, "%i", bb_no);
340
  assert (f_opt <= strlen (option_char));
341
  sprintf (s, "%s%c", s, option_char[f_opt]);
342
  return s;
343
}
344
 
345
/*static */void print_option (int bb_no, int f_opt)
346
{
347
  char tmp1[10];
348
  char tmp2[10];
349
  sprintf (tmp2, "%s", gen_option (tmp1, bb_no, f_opt));
350 997 markom
  PRINTF ("%3s", tmp2);
351 897 markom
}
352
 
353
static char *format_func_options (char *s, cuc_func *f)
354
{
355
  int b, first = 1;
356
  *s = '\0';
357
  for (b = 0; b < f->num_bb; b++)
358
    if (f->bb[b].selected_tim >= 0) {
359
      char tmp[10];
360
      sprintf (s, "%s%s%s", s, first ? "" : ",", gen_option (tmp, b, f->bb[b].selected_tim));
361
      first = 0;
362
    }
363
  return s;
364
}
365
 
366
static void options_cmd (int func_no, cuc_func *f)
367
{
368 883 markom
  int b, i;
369 903 markom
  char tmp[30];
370 897 markom
  char *name = prof_func[func_no].name;
371 997 markom
  PRINTF ("-----------------------------------------------------------------------------\n");
372
  PRINTF ("|%-28s|pre/unrolled|shared|  time  |  gates |old_time|\n",
373 904 markom
            strstrip (tmp, name, 28));
374 997 markom
  PRINTF ("|                    BASE    |%4i / %4i | %4i |%8i|%8.f|%8i|\n", 1, 1, 0,
375 903 markom
          f->timings.new_time, f->timings.size, f->orig_time);
376 883 markom
  for (b = 0; b < f->num_bb; b++) {
377
    /* Print out results */
378 897 markom
    for (i = 1; i < f->bb[b].ntim; i++) { /* First one is base option */
379
      int time = f->bb[b].tim[i].new_time - f->timings.new_time;
380
      double size = f->bb[b].tim[i].size - f->timings.size;
381 997 markom
      PRINTF ("|                   ");
382 897 markom
      print_option (b, i);
383 997 markom
      PRINTF ("      |%4i / %4i | %4i |%+8i|%+8.f|        |\n",
384 897 markom
        f->bb[b].tim[i].preroll, f->bb[b].tim[i].unroll, f->bb[b].tim[i].nshared,
385
        time, size);
386 883 markom
    }
387
  }
388
}
389
 
390 897 markom
/* Generates a function, based on specified parameters */
391 915 markom
cuc_func *generate_function (cuc_func *rf, char *name, char *cut_filename)
392 897 markom
{
393
  int b, i, j;
394
  char tmp[256];
395
  cuc_timings tt;
396
  cuc_func *f;
397
  assert (f = dup_func (rf));
398
 
399 915 markom
  if (cuc_debug >= 2) print_cuc_bb (f, "BEFORE_GENERATE");
400 897 markom
  log ("Generating function %s.\n", name);
401 997 markom
  PRINTF ("Generating function %s.\n", name);
402 897 markom
 
403
  format_func_options (tmp, rf);
404 997 markom
  if (strlen (tmp)) PRINTF ("Applying options: %s\n", tmp);
405
  else PRINTF ("Using basic options.\n");
406 897 markom
 
407
  /* Generate function as specified by options */
408
  for (b = 0; b < f->num_bb; b++) {
409
    cuc_timings *st;
410
    if (rf->bb[b].selected_tim < 0) continue;
411
    st = &rf->bb[b].tim[rf->bb[b].selected_tim];
412
    sprintf (tmp, "%s.bin.bb", name);
413
    preunroll_bb (&tmp[0], f, &tt, b, st->preroll, st->unroll);
414
    if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_PREUNROLL");
415
  }
416
  for (b = 0; b < f->num_bb; b++) {
417
    cuc_timings *st;
418
    if (rf->bb[b].selected_tim < 0) continue;
419
    st = &rf->bb[b].tim[rf->bb[b].selected_tim];
420
    if (!st->nshared) continue;
421
    assert (0);
422
    //csm_gen (f, rf, st->nshared, st->shared);
423
  }
424 915 markom
  add_latches (f);
425
  if (cuc_debug >= 1) print_cuc_bb (f, "AFTER_LATCHES");
426 897 markom
  analyse_timings (f, &tt);
427 915 markom
 
428
  sprintf (tmp, "%s%s", cut_filename, name);
429 941 markom
  output_verilog (f, tmp, name);
430 897 markom
  return f;
431
}
432
 
433
/* Calculates required time, based on selected options */
434
int calc_cycles (cuc_func *f)
435
{
436
  int b, i, ntime = f->timings.new_time;
437
  for (b = 0; b < f->num_bb; b++)
438
    if (f->bb[b].selected_tim >= 0) {
439
      assert (f->bb[b].selected_tim < f->bb[b].ntim);
440
      ntime += f->bb[b].tim[f->bb[b].selected_tim].new_time - f->timings.new_time;
441
    }
442
  return ntime;
443
}
444
 
445
/* Calculates required size, based on selected options */
446
double calc_size (cuc_func *f)
447
{
448
  int b, i;
449
  double size = f->timings.size;
450
  for (b = 0; b < f->num_bb; b++)
451
    if (f->bb[b].selected_tim >= 0) {
452
      assert (f->bb[b].selected_tim < f->bb[b].ntim);
453
      size += f->bb[b].tim[f->bb[b].selected_tim].size - f->timings.size;
454
    }
455
  return size;
456
}
457
 
458 879 markom
/* Dumps specified function to file (hex) */
459
unsigned long extract_function (char *out_fn, unsigned long start_addr)
460
{
461
  FILE *fo;
462
  unsigned long a = start_addr;
463
  int x = 0;
464
  assert (fo = fopen (out_fn, "wt+"));
465
 
466
  do {
467
    unsigned long d = evalsim_mem32 (a);
468
    int index = insn_decode (d);
469
    assert (index >= 0);
470
    if (x) x++;
471
    if (strcmp (insn_name (index), "l.jr") == 0) x = 1;
472
    a += 4;
473
    fprintf (fo, "%08x\n", d);
474
  } while (x < 2);
475
 
476
  fclose (fo);
477
  return a - 4;
478
}
479
 
480
static cuc_func *func[MAX_FUNCS];
481 897 markom
static int func_v[MAX_FUNCS];
482 879 markom
 
483 906 markom
/* Detects function dependencies and removes  */
484
static void set_func_deps ()
485
{
486
  int f, b, i, j;
487
restart:
488
  for (f = 0; f < prof_nfuncs - 1; f++) if (func[f]) {
489
    int fused[MAX_FUNCS] = {0};
490
    int c;
491
    for (b = 0; b < func[f]->num_bb; b++)
492
      for (i = 0; i < func[f]->bb[b].ninsn; i++) {
493
        cuc_insn *ii = &func[f]->bb[b].insn[i];
494
        if (ii->index == II_CALL) {
495
          assert (ii->opt[0] == OPT_CONST);
496
          for (j = 0; j < prof_nfuncs - 1; j++)
497
            if (func[j] && func[j]->start_addr == ii->op[0]) break;
498
          if (j >= prof_nfuncs - 1) {
499
            log ("%s is calling unknown function, address %08x\n",
500
                            prof_func[f].name, ii->op[0]);
501
            debug (1, "%s is calling unknown function, address %08x\n",
502
                            prof_func[f].name, ii->op[0]);
503
            free_func (func[f]);
504
            func[f] = NULL;
505
            goto restart;
506
          } else if (f == j) {
507
            log ("%s is recursive, ignoring\n", prof_func[f].name);
508
            debug (1, "%s is recursive, ignoring\n", prof_func[f].name);
509
            free_func (func[f]);
510
            func[f] = NULL;
511
            goto restart;
512
          } else fused[j]++;
513
        }
514
      }
515
    for (i = 0; i < MAX_FUNCS; i++) if (fused[i]) c++;
516
    if (func[f]->nfdeps) free (func[f]->fdeps);
517
    func[f]->nfdeps = c;
518
    func[f]->fdeps = (cuc_func **) malloc (sizeof (cuc_func *) * c);
519
    for (i = 0, j = 0; i < MAX_FUNCS; i++)
520
      if (fused[i]) func[f]->fdeps[j++] = func[i];
521
  }
522
 
523
  /* Detect loops */
524
  {
525
    int change;
526
    for (f = 0; f < MAX_FUNCS; f++) if (func[f]) func[f]->tmp = 0;
527
    do {
528
      change = 0;
529
      for (f = 0; f < MAX_FUNCS; f++) if (func[f] && !func[f]->tmp) {
530
        int o = 1;
531
        for (i = 0; i < func[f]->nfdeps; i++)
532
          if (!func[f]->fdeps[i]->tmp) {o = 0; break;}
533
        if (o) {
534
          func[f]->tmp = 1;
535
          change = 1;
536
        }
537
      }
538
    } while (change);
539
 
540
    change = 0;
541
    for (f = 0; f < MAX_FUNCS; f++) if (func[f] && !func[f]->tmp) {
542
      free_func (func[f]);
543
      func[f] = NULL;
544
      change = 1;
545
    }
546
    if (change) goto restart;
547
  }
548
}
549
 
550 879 markom
void main_cuc (char *filename)
551
{
552 883 markom
  int i, j;
553 879 markom
  char tmp1[256];
554 915 markom
  char filename_cut[256];
555 940 markom
  for (i = 0; i < sizeof (filename_cut); i++) {
556 915 markom
    if (isalpha(filename[i])) filename_cut[i] = filename[i];
557
    else {
558
      filename_cut[i] = '\0';
559
      break;
560
    }
561
  }
562 879 markom
 
563 997 markom
  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
564
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n", config.sim.prof_fn, config.sim.mprof_fn);
565 915 markom
  sprintf (tmp1, "%s.log", filename_cut);
566 997 markom
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
567 879 markom
  assert (flog = fopen (tmp1, "wt+"));
568
 
569
  /* Loads in the specified timings table */
570 997 markom
  PRINTF ("Using timings from \"%s\" at %s\n",config.cuc.timings_fn,
571 897 markom
                 generate_time_pretty (tmp1, config.sim.clkcycle_ps));
572
  load_timing_table (config.cuc.timings_fn);
573
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
574 997 markom
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
575 897 markom
    config.cuc.no_multicycle ? "OFF" : "ON", config.cuc.enable_bursts ? "ON" : "OFF",
576
    config.cuc.memory_order == MO_NONE ? "no" : config.cuc.memory_order == MO_WEAK ? "weak" :
577
    config.cuc.memory_order == MO_STRONG ? "strong" : "exact");
578 879 markom
 
579
  prof_set (1, 0);
580
  assert (prof_acquire (config.sim.prof_fn) == 0);
581 973 markom
  cuc_debug = 0;
582 897 markom
 
583
  if (config.cuc.calling_convention)
584 997 markom
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
585 879 markom
 
586
  /* Try all functions except "total" */
587
  for (i = 0; i < prof_nfuncs - 1; i++) {
588
    long orig_time;
589
    unsigned long start_addr, end_addr;
590
    orig_time = prof_func[i].cum_cycles;
591
    start_addr = prof_func[i].addr;
592
 
593
    /* Extract the function from the binary */
594
    sprintf (tmp1, "%s.bin", prof_func[i].name);
595
    end_addr = extract_function (tmp1, start_addr);
596
 
597
    log ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
598 997 markom
    PRINTF ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
599 897 markom
    func[i] = analyse_function (prof_func[i].name, orig_time, start_addr,
600
                   end_addr, config.cuc.memory_order);
601
    func_v[i] = 0;
602 879 markom
  }
603 906 markom
  set_func_deps ();
604
 
605 883 markom
  while (1) {
606
    char *s;
607 906 markom
wait_command:
608 997 markom
    PRINTF ("(cuc) ");
609 883 markom
    fflush (stdout);
610
    fgets(tmp1, sizeof tmp1, stdin);
611
    for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
612
    *s = '\0';
613
 
614 906 markom
      /* quit command */
615 883 markom
    if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0) {
616
      break;
617 906 markom
 
618
      /* profile command */
619 883 markom
    } else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0) {
620 897 markom
      int ntime = 0;
621
      int size = 0;
622 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
623
      PRINTF ("|function name       |calls|avg cycles  |old%| max. f.  | impr. f.| options |\n");
624
      PRINTF ("|--------------------+-----+------------+----+----------|---------+---------|\n");
625 883 markom
      for (j = 0; j < prof_nfuncs; j++) {
626
        int bestcyc = 0, besti = 0;
627 897 markom
        char tmp[100];
628 883 markom
        for (i = 0; i < prof_nfuncs; i++)
629
          if (prof_func[i].cum_cycles > bestcyc) {
630
            bestcyc = prof_func[i].cum_cycles;
631
            besti = i;
632
          }
633
        i = besti;
634 997 markom
        PRINTF ("|%-20s|%5i|%12.1f|%3.0f%%| ",
635 897 markom
                strstrip (tmp, prof_func[i].name, 20),  prof_func[i].calls,
636 883 markom
                ((double)prof_func[i].cum_cycles / prof_func[i].calls),
637
                (100. * prof_func[i].cum_cycles / prof_cycles));
638
        if (func[i]) {
639 897 markom
          double f = 1.0;
640
          if (func_v[i]) {
641
            int nt = calc_cycles (func[i]);
642
            int s = calc_size (func[i]);
643 996 markom
            f = 1. * func[i]->orig_time / nt;
644 897 markom
            ntime += nt * func[i]->num_runs;
645
            size += s;
646
          } else ntime += prof_func[i].cum_cycles;
647 997 markom
          PRINTF ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles
648 905 markom
                          / func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
649 897 markom
        } else {
650 997 markom
          PRINTF ("     N/A |     N/A |     N/A |\n");
651 897 markom
          ntime += prof_func[i].cum_cycles;
652
        }
653
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
654 883 markom
      }
655 897 markom
      for (i = 0; i < prof_nfuncs; i++)
656
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
657 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
658
      PRINTF ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
659 905 markom
                      ntime, prof_cycles, size, 1. * prof_cycles / ntime);
660 906 markom
 
661
      /* debug command */
662 883 markom
    } else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) {
663
      sscanf (tmp1, "%*s %i", &cuc_debug);
664
      if (cuc_debug < 0) cuc_debug = 0;
665
      if (cuc_debug > 9) cuc_debug = 9;
666 906 markom
 
667
      /* generate command */
668 883 markom
    } else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0) {
669 906 markom
      /* check for function dependencies */
670 897 markom
      for (i = 0; i < prof_nfuncs; i++)
671 906 markom
        if (func[i]) func[i]->tmp = func_v[i];
672 915 markom
      for (i = 0; i < prof_nfuncs; i++) if (func[i])
673 906 markom
        for (j = 0; j < func[i]->nfdeps; j++)
674
          if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp) {
675 997 markom
            PRINTF ("Function %s must be selected for translation (required by %s)\n",
676 906 markom
                    prof_func[j].name, prof_func[i].name);
677
            goto wait_command;
678
          }
679
      for (i = 0; i < prof_nfuncs; i++)
680 915 markom
        if (func[i] && func_v[i]) generate_function (func[i], prof_func[i].name, filename_cut);
681
      generate_main (prof_nfuncs, func, filename_cut);
682
 
683 918 markom
      /* selectall command */
684
    } else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0) {
685
      char tmp[50], ch;
686
      int p, o, b, f;
687
      for (f = 0; f < prof_nfuncs; f++) if (func[f]) {
688
        func_v[f] = 1;
689 997 markom
        PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
690 918 markom
      }
691
 
692 906 markom
      /* select command */
693 897 markom
    } else if (strncmp (tmp1, "s", 1) == 0 || strncmp (tmp1, "select", 6) == 0) {
694
      char tmp[50], ch;
695
      int p, o, b, f;
696
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
697 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
698 897 markom
      else {
699
        /* Check if we have valid option */
700
        for (f = 0; f < prof_nfuncs; f++)
701
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
702
        if (f < prof_nfuncs) {
703
          if (p == 1) {
704
            if (func[f]) {
705
              func_v[f] = 1;
706 997 markom
              PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
707
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
708 897 markom
          } else {
709
            if (!func_v[f])
710 997 markom
              PRINTF ("Function %s not yet selected for translation.\n", prof_func[f].name);
711 897 markom
            if (p < 3) goto invalid_option;
712
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
713
            if (!option_char[o]) goto invalid_option;
714
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
715
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
716
 
717
            /* select an option */
718
            func[f]->bb[b].selected_tim = o;
719
            if (func[f]->bb[b].tim[o].nshared) {
720 997 markom
              PRINTF ("Option has shared instructions: ");
721 897 markom
              print_shared (func[f], func[f]->bb[b].tim[o].shared, func[f]->bb[b].tim[o].nshared);
722 997 markom
              PRINTF ("\n");
723 897 markom
            }
724 906 markom
            goto wait_command;
725 897 markom
invalid_option:
726 997 markom
            PRINTF ("Invalid option.\n");
727 897 markom
          }
728 997 markom
        } else PRINTF ("Invalid function.\n");
729 897 markom
      }
730 906 markom
 
731
      /* unselect command */
732 897 markom
    } else if (strncmp (tmp1, "u", 1) == 0 || strncmp (tmp1, "unselect", 8) == 0) {
733
      char tmp[50], ch;
734
      int p, o, b, f;
735
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
736 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
737 897 markom
      else {
738
        /* Check if we have valid option */
739
        for (f = 0; f < prof_nfuncs; f++)
740
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
741
        if (f < prof_nfuncs) {
742
          if (p == 1) {
743
            if (func[f]) {
744
              func_v[f] = 0;
745 997 markom
              PRINTF ("Function %s unselected for translation.\n", prof_func[f].name);
746
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
747 897 markom
          } else {
748
            if (p < 3) goto invalid_option;
749
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
750
            if (!option_char[o]) goto invalid_option;
751
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
752
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
753
 
754
            /* select an option */
755
            func[f]->bb[b].selected_tim = -1;
756
          }
757 997 markom
        } else PRINTF ("Invalid function.\n");
758 897 markom
      }
759 906 markom
 
760
      /* options command */
761 883 markom
    } else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0) {
762 897 markom
      int any = 0;
763 997 markom
      PRINTF ("Available options:\n");
764 883 markom
      for (i = 0; i < prof_nfuncs; i++)
765 897 markom
        if (func[i]) {
766
          options_cmd (i, func[i]);
767
          any = 1;
768
        }
769 997 markom
      if (any) PRINTF ("-----------------------------------------------------------------------------\n");
770
      else PRINTF ("Sorry. No available options.\n");
771 906 markom
 
772
      /* Ignore empty string */
773 902 markom
    } else if (strcmp (tmp1, "") == 0) {
774 906 markom
 
775
      /* help command */
776 883 markom
    } else {
777
      if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
778 997 markom
        PRINTF ("Unknown command.\n");
779
      PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
780
      PRINTF ("Available commands:\n");
781
      PRINTF ("  h | help                   displays this help\n");
782
      PRINTF ("  q | quit                   returns to or1ksim prompt\n");
783
      PRINTF ("  p | profile                displays function profiling\n");
784
      PRINTF ("  d | debug #                sets debug level (0-9)\n");
785
      PRINTF ("  o | options                displays available options\n");
786
      PRINTF ("  s | select func [option]   selects an option/function\n");
787
      PRINTF ("  u | unselect func [option] unselects an option/function\n");
788
      PRINTF ("  g | generate               generates verilog file\n");
789 883 markom
    }
790
  }
791
 
792 879 markom
  /* Dispose memory */
793
  for (i = 0; i < prof_nfuncs -1; i++)
794
    if (func[i]) free_func (func[i]);
795
 
796
  fclose (flog);
797
}
798
 

powered by: WebSVN 2.1.0

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