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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 1059

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

Line No. Rev Author Line
1 879 markom
/* cuc.c -- OpenRISC Custom Unit Compiler
2
 *    Copyright (C) 2002 Marko Mlinar, markom@opencores.org
3
 *
4
 *    This file is part of OpenRISC 1000 Architectural Simulator.
5
 *
6
 *    This program is free software; you can redistribute it and/or modify
7
 *    it under the terms of the GNU General Public License as published by
8
 *    the Free Software Foundation; either version 2 of the License, or
9
 *    (at your option) any later version.
10
 *
11
 *    This program is distributed in the hope that it will be useful,
12
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *    GNU General Public License for more details.
15
 *
16
 *    You should have received a copy of the GNU General Public License
17
 *    along with this program; if not, write to the Free Software
18
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Main file, including code optimization and command prompt */
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <stdarg.h>
25
#include <assert.h>
26 915 markom
#include <ctype.h>
27 879 markom
#include "sim-config.h"
28
#include "cuc.h"
29
#include "insn.h"
30
#include "profiler.h"
31 883 markom
#include "opcode/or32.h"
32 897 markom
#include "parse.h"
33 879 markom
 
34
FILE *flog;
35 883 markom
int cuc_debug = 0;
36 879 markom
 
37
/* Last used registers by software convention */
38 939 markom
/* Note that r11 is caller saved register, and we can destroy it.
39
   Due to CUC architecture we must always return something, even garbage (so that
40
   caller knows, we are finished, when we send acknowledge).
41
   In case r11 was not used (trivial register assignment) we will remove it later,
42
   but if we assigned a value to it, it must not be removed, so caller_saved[11] = 0 */
43
const int caller_saved[MAX_REGS] = {
44 879 markom
  0, 0, 0, 1, 1, 1, 1, 1,
45 939 markom
  1, 1, 0, 0, 0, 1, 0, 1,
46 879 markom
  0, 1, 0, 1, 0, 1, 0, 1,
47
  0, 1, 0, 1, 0, 1, 0, 1,
48
  1, 1};
49
 
50 933 markom
/* returns log2(x) */
51
int log2 (unsigned long x)
52
{
53
  int c = 0;
54
  assert (x >= 0);
55
  if (!x) return 0; /* not by the book, but practical */
56
  while (x != 1) x >>= 1, c++;
57
  return c;
58
}
59
 
60 931 markom
/* Does all known instruction optimizations */
61
void cuc_optimize (cuc_func *func)
62
{
63
  int modified = 0;
64 936 markom
  int first = 1;
65 931 markom
  log ("Optimizing.\n");
66
  do {
67
    modified = 0;
68 941 markom
    clean_deps (func);
69
    if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_CLEAN_DEPS");
70 931 markom
    if (optimize_cmovs (func)) {
71
      if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_CMOVS");
72
      modified = 1;
73
    }
74 934 markom
    if (cuc_debug) cuc_check (func);
75 931 markom
    if (optimize_tree (func)) {
76
      if (cuc_debug >= 6) print_cuc_bb (func, "AFTER_OPT_TREE1");
77
      modified = 1;
78
    }
79
    if (remove_nops (func)) {
80
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
81
      modified = 1;
82
    }
83 934 markom
    if (cuc_debug) cuc_check (func);
84 931 markom
    if (remove_dead (func)) {
85
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD");
86
      modified = 1;
87
    }
88 934 markom
    if (cuc_debug) cuc_check (func);
89 931 markom
    if (cse (func)) {
90
      log ("Common subexpression elimination.\n");
91
      if (cuc_debug >= 3) print_cuc_bb (func, "AFTER_CSE");
92
      modified = 1;
93
    }
94 936 markom
    if (first) {
95
      insert_conditional_facts (func);
96
      if (cuc_debug >= 3) print_cuc_bb (func, "AFTER_COND_FACT");
97
      if (cuc_debug) cuc_check (func);
98
      first = 0;
99
    }
100 931 markom
    if (optimize_bb (func)) {
101
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_OPT_BB");
102
      modified = 1;
103
    }
104 934 markom
    if (cuc_debug) cuc_check (func);
105 931 markom
    if (remove_nops (func)) {
106
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
107
      modified = 1;
108
    }
109
    if (remove_dead_bb (func)) {
110
      if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_DEAD_BB");
111
      modified = 1;
112
    }
113
    if (remove_trivial_regs (func)) {
114
      if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_TRIVIAL");
115
      modified = 1;
116
    }
117
    if (remove_nops (func)) {
118
      if (cuc_debug >= 6) print_cuc_bb (func, "NO_NOPS");
119
      modified = 1;
120
    }
121 941 markom
    add_memory_dep (func, func->memory_order);
122
    if (cuc_debug >= 7) print_cuc_bb (func, "AFTER_MEMORY_DEP");
123
    add_data_dep (func);
124
    if (cuc_debug >= 8) print_cuc_bb (func, "AFTER_DATA_DEP");
125 953 markom
    if (schedule_memory (func, func->memory_order)) {
126
      if (cuc_debug >= 7) print_cuc_bb (func, "AFTER_SCHEDULE_MEM");
127
      modified = 1;
128
    }
129 931 markom
  } while (modified);
130 953 markom
  set_io (func);
131 937 markom
#if 0
132 936 markom
  detect_max_values (func);
133
  if (cuc_debug >= 5) print_cuc_bb (func, "AFTER_MAX_VALUES");
134 937 markom
#endif
135 931 markom
}
136
 
137
/* Pre/unrolls basic block and optimizes it */
138 879 markom
cuc_timings *preunroll_bb (char *bb_filename, cuc_func *f, cuc_timings *timings, int b, int i, int j)
139
{
140
  cuc_func *func;
141 883 markom
  cucdebug (2, "BB%i unroll %i times preroll %i times\n", b, j, i);
142 1041 markom
  log ("BB%i unroll %i times preroll %i times\n", b, j, i);
143 879 markom
  func = preunroll_loop (f, b, i, j, bb_filename);
144 883 markom
  if (cuc_debug >= 2) print_cuc_bb (func, "AFTER_PREUNROLL");
145 931 markom
  cuc_optimize (func);
146 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 1059 markom
  cuc_debug = 0;
590 897 markom
 
591
  if (config.cuc.calling_convention)
592 997 markom
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
593 879 markom
 
594
  /* Try all functions except "total" */
595
  for (i = 0; i < prof_nfuncs - 1; i++) {
596
    long orig_time;
597
    unsigned long start_addr, end_addr;
598
    orig_time = prof_func[i].cum_cycles;
599
    start_addr = prof_func[i].addr;
600
 
601
    /* Extract the function from the binary */
602
    sprintf (tmp1, "%s.bin", prof_func[i].name);
603
    end_addr = extract_function (tmp1, start_addr);
604
 
605
    log ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
606 997 markom
    PRINTF ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
607 897 markom
    func[i] = analyse_function (prof_func[i].name, orig_time, start_addr,
608 1041 markom
                   end_addr, config.cuc.memory_order, prof_func[i].calls);
609 897 markom
    func_v[i] = 0;
610 879 markom
  }
611 906 markom
  set_func_deps ();
612
 
613 883 markom
  while (1) {
614
    char *s;
615 906 markom
wait_command:
616 997 markom
    PRINTF ("(cuc) ");
617 883 markom
    fflush (stdout);
618
    fgets(tmp1, sizeof tmp1, stdin);
619
    for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
620
    *s = '\0';
621
 
622 906 markom
      /* quit command */
623 883 markom
    if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0) {
624 1003 markom
      /* Delete temporary files */
625
      for (i = 0; i < prof_nfuncs - 1; i++) {
626
        sprintf (tmp1, "%s.bin", prof_func[i].name);
627 1041 markom
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK");
628 1003 markom
        sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
629 1041 markom
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK");
630 1003 markom
      }
631 883 markom
      break;
632 1003 markom
 
633 906 markom
      /* profile command */
634 883 markom
    } else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0) {
635 897 markom
      int ntime = 0;
636
      int size = 0;
637 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
638
      PRINTF ("|function name       |calls|avg cycles  |old%| max. f.  | impr. f.| options |\n");
639
      PRINTF ("|--------------------+-----+------------+----+----------|---------+---------|\n");
640 883 markom
      for (j = 0; j < prof_nfuncs; j++) {
641
        int bestcyc = 0, besti = 0;
642 897 markom
        char tmp[100];
643 883 markom
        for (i = 0; i < prof_nfuncs; i++)
644
          if (prof_func[i].cum_cycles > bestcyc) {
645
            bestcyc = prof_func[i].cum_cycles;
646
            besti = i;
647
          }
648
        i = besti;
649 997 markom
        PRINTF ("|%-20s|%5i|%12.1f|%3.0f%%| ",
650 897 markom
                strstrip (tmp, prof_func[i].name, 20),  prof_func[i].calls,
651 883 markom
                ((double)prof_func[i].cum_cycles / prof_func[i].calls),
652
                (100. * prof_func[i].cum_cycles / prof_cycles));
653
        if (func[i]) {
654 897 markom
          double f = 1.0;
655
          if (func_v[i]) {
656
            int nt = calc_cycles (func[i]);
657
            int s = calc_size (func[i]);
658 996 markom
            f = 1. * func[i]->orig_time / nt;
659 1041 markom
            ntime += nt;
660 897 markom
            size += s;
661
          } else ntime += prof_func[i].cum_cycles;
662 997 markom
          PRINTF ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles
663 905 markom
                          / func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
664 897 markom
        } else {
665 997 markom
          PRINTF ("     N/A |     N/A |     N/A |\n");
666 897 markom
          ntime += prof_func[i].cum_cycles;
667
        }
668
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
669 883 markom
      }
670 897 markom
      for (i = 0; i < prof_nfuncs; i++)
671
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
672 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
673
      PRINTF ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
674 905 markom
                      ntime, prof_cycles, size, 1. * prof_cycles / ntime);
675 906 markom
 
676
      /* debug command */
677 883 markom
    } else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) {
678
      sscanf (tmp1, "%*s %i", &cuc_debug);
679
      if (cuc_debug < 0) cuc_debug = 0;
680
      if (cuc_debug > 9) cuc_debug = 9;
681 906 markom
 
682
      /* generate command */
683 883 markom
    } else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0) {
684 906 markom
      /* check for function dependencies */
685 897 markom
      for (i = 0; i < prof_nfuncs; i++)
686 906 markom
        if (func[i]) func[i]->tmp = func_v[i];
687 915 markom
      for (i = 0; i < prof_nfuncs; i++) if (func[i])
688 906 markom
        for (j = 0; j < func[i]->nfdeps; j++)
689
          if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp) {
690 997 markom
            PRINTF ("Function %s must be selected for translation (required by %s)\n",
691 906 markom
                    prof_func[j].name, prof_func[i].name);
692
            goto wait_command;
693
          }
694
      for (i = 0; i < prof_nfuncs; i++)
695 915 markom
        if (func[i] && func_v[i]) generate_function (func[i], prof_func[i].name, filename_cut);
696
      generate_main (prof_nfuncs, func, filename_cut);
697
 
698 918 markom
      /* selectall command */
699
    } else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0) {
700
      char tmp[50], ch;
701
      int p, o, b, f;
702
      for (f = 0; f < prof_nfuncs; f++) if (func[f]) {
703
        func_v[f] = 1;
704 997 markom
        PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
705 918 markom
      }
706
 
707 906 markom
      /* select command */
708 897 markom
    } else if (strncmp (tmp1, "s", 1) == 0 || strncmp (tmp1, "select", 6) == 0) {
709
      char tmp[50], ch;
710
      int p, o, b, f;
711
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
712 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
713 897 markom
      else {
714
        /* Check if we have valid option */
715
        for (f = 0; f < prof_nfuncs; f++)
716
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
717
        if (f < prof_nfuncs) {
718
          if (p == 1) {
719
            if (func[f]) {
720
              func_v[f] = 1;
721 997 markom
              PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
722
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
723 897 markom
          } else {
724
            if (!func_v[f])
725 997 markom
              PRINTF ("Function %s not yet selected for translation.\n", prof_func[f].name);
726 897 markom
            if (p < 3) goto invalid_option;
727
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
728
            if (!option_char[o]) goto invalid_option;
729
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
730
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
731
 
732
            /* select an option */
733
            func[f]->bb[b].selected_tim = o;
734
            if (func[f]->bb[b].tim[o].nshared) {
735 997 markom
              PRINTF ("Option has shared instructions: ");
736 897 markom
              print_shared (func[f], func[f]->bb[b].tim[o].shared, func[f]->bb[b].tim[o].nshared);
737 997 markom
              PRINTF ("\n");
738 897 markom
            }
739 906 markom
            goto wait_command;
740 897 markom
invalid_option:
741 997 markom
            PRINTF ("Invalid option.\n");
742 897 markom
          }
743 997 markom
        } else PRINTF ("Invalid function.\n");
744 897 markom
      }
745 906 markom
 
746
      /* unselect command */
747 897 markom
    } else if (strncmp (tmp1, "u", 1) == 0 || strncmp (tmp1, "unselect", 8) == 0) {
748
      char tmp[50], ch;
749
      int p, o, b, f;
750
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
751 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
752 897 markom
      else {
753
        /* Check if we have valid option */
754
        for (f = 0; f < prof_nfuncs; f++)
755
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
756
        if (f < prof_nfuncs) {
757
          if (p == 1) {
758
            if (func[f]) {
759
              func_v[f] = 0;
760 997 markom
              PRINTF ("Function %s unselected for translation.\n", prof_func[f].name);
761
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
762 897 markom
          } else {
763
            if (p < 3) goto invalid_option;
764
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
765
            if (!option_char[o]) goto invalid_option;
766
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
767
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
768
 
769
            /* select an option */
770
            func[f]->bb[b].selected_tim = -1;
771
          }
772 997 markom
        } else PRINTF ("Invalid function.\n");
773 897 markom
      }
774 906 markom
 
775
      /* options command */
776 883 markom
    } else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0) {
777 897 markom
      int any = 0;
778 997 markom
      PRINTF ("Available options:\n");
779 883 markom
      for (i = 0; i < prof_nfuncs; i++)
780 897 markom
        if (func[i]) {
781
          options_cmd (i, func[i]);
782
          any = 1;
783
        }
784 997 markom
      if (any) PRINTF ("-----------------------------------------------------------------------------\n");
785
      else PRINTF ("Sorry. No available options.\n");
786 906 markom
 
787
      /* Ignore empty string */
788 902 markom
    } else if (strcmp (tmp1, "") == 0) {
789 906 markom
 
790
      /* help command */
791 883 markom
    } else {
792
      if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
793 997 markom
        PRINTF ("Unknown command.\n");
794
      PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
795
      PRINTF ("Available commands:\n");
796
      PRINTF ("  h | help                   displays this help\n");
797
      PRINTF ("  q | quit                   returns to or1ksim prompt\n");
798
      PRINTF ("  p | profile                displays function profiling\n");
799
      PRINTF ("  d | debug #                sets debug level (0-9)\n");
800
      PRINTF ("  o | options                displays available options\n");
801
      PRINTF ("  s | select func [option]   selects an option/function\n");
802
      PRINTF ("  u | unselect func [option] unselects an option/function\n");
803
      PRINTF ("  g | generate               generates verilog file\n");
804 883 markom
    }
805
  }
806
 
807 879 markom
  /* Dispose memory */
808
  for (i = 0; i < prof_nfuncs -1; i++)
809
    if (func[i]) free_func (func[i]);
810
 
811
  fclose (flog);
812
}
813
 

powered by: WebSVN 2.1.0

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