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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 939

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

powered by: WebSVN 2.1.0

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