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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_68/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 1061

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

powered by: WebSVN 2.1.0

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