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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [cuc/] [cuc.c] - Blame information for rev 1047

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 940 markom
  for (i = 0; i < sizeof (filename_cut); i++) {
560 915 markom
    if (isalpha(filename[i])) filename_cut[i] = filename[i];
561
    else {
562
      filename_cut[i] = '\0';
563
      break;
564
    }
565
  }
566 879 markom
 
567 997 markom
  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
568
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n", config.sim.prof_fn, config.sim.mprof_fn);
569 915 markom
  sprintf (tmp1, "%s.log", filename_cut);
570 997 markom
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
571 879 markom
  assert (flog = fopen (tmp1, "wt+"));
572
 
573
  /* Loads in the specified timings table */
574 997 markom
  PRINTF ("Using timings from \"%s\" at %s\n",config.cuc.timings_fn,
575 897 markom
                 generate_time_pretty (tmp1, config.sim.clkcycle_ps));
576
  load_timing_table (config.cuc.timings_fn);
577
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
578 997 markom
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
579 897 markom
    config.cuc.no_multicycle ? "OFF" : "ON", config.cuc.enable_bursts ? "ON" : "OFF",
580
    config.cuc.memory_order == MO_NONE ? "no" : config.cuc.memory_order == MO_WEAK ? "weak" :
581
    config.cuc.memory_order == MO_STRONG ? "strong" : "exact");
582 879 markom
 
583
  prof_set (1, 0);
584
  assert (prof_acquire (config.sim.prof_fn) == 0);
585 1041 markom
  cuc_debug = 9;
586 897 markom
 
587
  if (config.cuc.calling_convention)
588 997 markom
    PRINTF ("Assuming OpenRISC standard calling convention.\n");
589 879 markom
 
590
  /* Try all functions except "total" */
591
  for (i = 0; i < prof_nfuncs - 1; i++) {
592
    long orig_time;
593
    unsigned long start_addr, end_addr;
594
    orig_time = prof_func[i].cum_cycles;
595
    start_addr = prof_func[i].addr;
596
 
597
    /* Extract the function from the binary */
598
    sprintf (tmp1, "%s.bin", prof_func[i].name);
599
    end_addr = extract_function (tmp1, start_addr);
600
 
601
    log ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
602 997 markom
    PRINTF ("Testing function %s (%08x - %08x)\n", prof_func[i].name, start_addr, end_addr);
603 897 markom
    func[i] = analyse_function (prof_func[i].name, orig_time, start_addr,
604 1041 markom
                   end_addr, config.cuc.memory_order, prof_func[i].calls);
605 897 markom
    func_v[i] = 0;
606 879 markom
  }
607 906 markom
  set_func_deps ();
608
 
609 883 markom
  while (1) {
610
    char *s;
611 906 markom
wait_command:
612 997 markom
    PRINTF ("(cuc) ");
613 883 markom
    fflush (stdout);
614
    fgets(tmp1, sizeof tmp1, stdin);
615
    for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
616
    *s = '\0';
617
 
618 906 markom
      /* quit command */
619 883 markom
    if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0) {
620 1003 markom
      /* Delete temporary files */
621
      for (i = 0; i < prof_nfuncs - 1; i++) {
622
        sprintf (tmp1, "%s.bin", prof_func[i].name);
623 1041 markom
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK");
624 1003 markom
        sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
625 1041 markom
        log ("Deleting temporary file %s %s\n", tmp1, remove (tmp1) ? "FAILED" : "OK");
626 1003 markom
      }
627 883 markom
      break;
628 1003 markom
 
629 906 markom
      /* profile command */
630 883 markom
    } else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0) {
631 897 markom
      int ntime = 0;
632
      int size = 0;
633 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
634
      PRINTF ("|function name       |calls|avg cycles  |old%| max. f.  | impr. f.| options |\n");
635
      PRINTF ("|--------------------+-----+------------+----+----------|---------+---------|\n");
636 883 markom
      for (j = 0; j < prof_nfuncs; j++) {
637
        int bestcyc = 0, besti = 0;
638 897 markom
        char tmp[100];
639 883 markom
        for (i = 0; i < prof_nfuncs; i++)
640
          if (prof_func[i].cum_cycles > bestcyc) {
641
            bestcyc = prof_func[i].cum_cycles;
642
            besti = i;
643
          }
644
        i = besti;
645 997 markom
        PRINTF ("|%-20s|%5i|%12.1f|%3.0f%%| ",
646 897 markom
                strstrip (tmp, prof_func[i].name, 20),  prof_func[i].calls,
647 883 markom
                ((double)prof_func[i].cum_cycles / prof_func[i].calls),
648
                (100. * prof_func[i].cum_cycles / prof_cycles));
649
        if (func[i]) {
650 897 markom
          double f = 1.0;
651
          if (func_v[i]) {
652
            int nt = calc_cycles (func[i]);
653
            int s = calc_size (func[i]);
654 996 markom
            f = 1. * func[i]->orig_time / nt;
655 1041 markom
            ntime += nt;
656 897 markom
            size += s;
657
          } else ntime += prof_func[i].cum_cycles;
658 997 markom
          PRINTF ("%8.1f |%8.1f | %-8s|\n", 1.f * prof_func[i].cum_cycles
659 905 markom
                          / func[i]->timings.new_time, f, format_func_options (tmp, func[i]));
660 897 markom
        } else {
661 997 markom
          PRINTF ("     N/A |     N/A |     N/A |\n");
662 897 markom
          ntime += prof_func[i].cum_cycles;
663
        }
664
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
665 883 markom
      }
666 897 markom
      for (i = 0; i < prof_nfuncs; i++)
667
        prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
668 997 markom
      PRINTF ("-----------------------------------------------------------------------------\n");
669
      PRINTF ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
670 905 markom
                      ntime, prof_cycles, size, 1. * prof_cycles / ntime);
671 906 markom
 
672
      /* debug command */
673 883 markom
    } else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0) {
674
      sscanf (tmp1, "%*s %i", &cuc_debug);
675
      if (cuc_debug < 0) cuc_debug = 0;
676
      if (cuc_debug > 9) cuc_debug = 9;
677 906 markom
 
678
      /* generate command */
679 883 markom
    } else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0) {
680 906 markom
      /* check for function dependencies */
681 897 markom
      for (i = 0; i < prof_nfuncs; i++)
682 906 markom
        if (func[i]) func[i]->tmp = func_v[i];
683 915 markom
      for (i = 0; i < prof_nfuncs; i++) if (func[i])
684 906 markom
        for (j = 0; j < func[i]->nfdeps; j++)
685
          if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp) {
686 997 markom
            PRINTF ("Function %s must be selected for translation (required by %s)\n",
687 906 markom
                    prof_func[j].name, prof_func[i].name);
688
            goto wait_command;
689
          }
690
      for (i = 0; i < prof_nfuncs; i++)
691 915 markom
        if (func[i] && func_v[i]) generate_function (func[i], prof_func[i].name, filename_cut);
692
      generate_main (prof_nfuncs, func, filename_cut);
693
 
694 918 markom
      /* selectall command */
695
    } else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0) {
696
      char tmp[50], ch;
697
      int p, o, b, f;
698
      for (f = 0; f < prof_nfuncs; f++) if (func[f]) {
699
        func_v[f] = 1;
700 997 markom
        PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
701 918 markom
      }
702
 
703 906 markom
      /* select command */
704 897 markom
    } else if (strncmp (tmp1, "s", 1) == 0 || strncmp (tmp1, "select", 6) == 0) {
705
      char tmp[50], ch;
706
      int p, o, b, f;
707
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
708 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
709 897 markom
      else {
710
        /* Check if we have valid option */
711
        for (f = 0; f < prof_nfuncs; f++)
712
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
713
        if (f < prof_nfuncs) {
714
          if (p == 1) {
715
            if (func[f]) {
716
              func_v[f] = 1;
717 997 markom
              PRINTF ("Function %s selected for translation.\n", prof_func[f].name);
718
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
719 897 markom
          } else {
720
            if (!func_v[f])
721 997 markom
              PRINTF ("Function %s not yet selected for translation.\n", prof_func[f].name);
722 897 markom
            if (p < 3) goto invalid_option;
723
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
724
            if (!option_char[o]) goto invalid_option;
725
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
726
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
727
 
728
            /* select an option */
729
            func[f]->bb[b].selected_tim = o;
730
            if (func[f]->bb[b].tim[o].nshared) {
731 997 markom
              PRINTF ("Option has shared instructions: ");
732 897 markom
              print_shared (func[f], func[f]->bb[b].tim[o].shared, func[f]->bb[b].tim[o].nshared);
733 997 markom
              PRINTF ("\n");
734 897 markom
            }
735 906 markom
            goto wait_command;
736 897 markom
invalid_option:
737 997 markom
            PRINTF ("Invalid option.\n");
738 897 markom
          }
739 997 markom
        } else PRINTF ("Invalid function.\n");
740 897 markom
      }
741 906 markom
 
742
      /* unselect command */
743 897 markom
    } else if (strncmp (tmp1, "u", 1) == 0 || strncmp (tmp1, "unselect", 8) == 0) {
744
      char tmp[50], ch;
745
      int p, o, b, f;
746
      p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
747 997 markom
      if (p < 1) PRINTF ("Invalid parameters.\n");
748 897 markom
      else {
749
        /* Check if we have valid option */
750
        for (f = 0; f < prof_nfuncs; f++)
751
          if (strcmp (prof_func[f].name, tmp) == 0 && func[f]) break;
752
        if (f < prof_nfuncs) {
753
          if (p == 1) {
754
            if (func[f]) {
755
              func_v[f] = 0;
756 997 markom
              PRINTF ("Function %s unselected for translation.\n", prof_func[f].name);
757
            } else PRINTF ("Function %s not suitable for translation.\n", prof_func[f].name);
758 897 markom
          } else {
759
            if (p < 3) goto invalid_option;
760
            for (o = 0; option_char[o] != '\0' && option_char[o] != ch; o++);
761
            if (!option_char[o]) goto invalid_option;
762
            if (b < 0 || b >= func[f]->num_bb) goto invalid_option;
763
            if (o < 0 || o >= func[f]->bb[b].ntim) goto invalid_option;
764
 
765
            /* select an option */
766
            func[f]->bb[b].selected_tim = -1;
767
          }
768 997 markom
        } else PRINTF ("Invalid function.\n");
769 897 markom
      }
770 906 markom
 
771
      /* options command */
772 883 markom
    } else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0) {
773 897 markom
      int any = 0;
774 997 markom
      PRINTF ("Available options:\n");
775 883 markom
      for (i = 0; i < prof_nfuncs; i++)
776 897 markom
        if (func[i]) {
777
          options_cmd (i, func[i]);
778
          any = 1;
779
        }
780 997 markom
      if (any) PRINTF ("-----------------------------------------------------------------------------\n");
781
      else PRINTF ("Sorry. No available options.\n");
782 906 markom
 
783
      /* Ignore empty string */
784 902 markom
    } else if (strcmp (tmp1, "") == 0) {
785 906 markom
 
786
      /* help command */
787 883 markom
    } else {
788
      if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
789 997 markom
        PRINTF ("Unknown command.\n");
790
      PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
791
      PRINTF ("Available commands:\n");
792
      PRINTF ("  h | help                   displays this help\n");
793
      PRINTF ("  q | quit                   returns to or1ksim prompt\n");
794
      PRINTF ("  p | profile                displays function profiling\n");
795
      PRINTF ("  d | debug #                sets debug level (0-9)\n");
796
      PRINTF ("  o | options                displays available options\n");
797
      PRINTF ("  s | select func [option]   selects an option/function\n");
798
      PRINTF ("  u | unselect func [option] unselects an option/function\n");
799
      PRINTF ("  g | generate               generates verilog file\n");
800 883 markom
    }
801
  }
802
 
803 879 markom
  /* Dispose memory */
804
  for (i = 0; i < prof_nfuncs -1; i++)
805
    if (func[i]) free_func (func[i]);
806
 
807
  fclose (flog);
808
}
809
 

powered by: WebSVN 2.1.0

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