OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [or1ksim/] [cuc/] [memory.c] - Blame information for rev 647

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

Line No. Rev Author Line
1 19 jeremybenn
/* memory.c -- OpenRISC Custom Unit Compiler, memory optimization and scheduling
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
#include <stdio.h>
21
#include <stdlib.h>
22
#include <stdarg.h>
23
#include <assert.h>
24
 
25
#include "config.h"
26
 
27
#include "port.h"
28
#include "arch.h"
29
#include "abstract.h"
30
#include "sim-config.h"
31
#include "cuc.h"
32
#include "insn.h"
33
 
34
 
35
/* Cleans memory & data dependencies */
36
void clean_deps (cuc_func *f)
37
{
38
  int b, i;
39
  dep_list *t;
40
  for (b = 0; b < f->num_bb; b++) {
41
    for (i = 0; i < f->bb[b].ninsn; i++) {
42
      t = f->bb[b].insn[i].dep;
43
      while (t) {
44
        dep_list *tmp = t;
45
        t = t->next;
46
        free (tmp);
47
      }
48
      f->bb[b].insn[i].dep = NULL;
49
    }
50
 
51
    t = f->bb[b].mdep;
52
    while (t) {
53
      dep_list *tmp = t;
54
      t = t->next;
55
      free (tmp);
56
    }
57
    f->bb[b].mdep = NULL;
58
  }
59
 
60
  f->nmsched = 0;
61
}
62
 
63
/* Checks for memory conflicts between two instructions; returns 1 if detected
64
 
65
static int check_memory_conflict (cuc_func *f, cuc_insn *a, cuc_insn *b, int otype)
66
{
67
  switch (otype) {
68
    case MO_EXACT: /* exact */
69
    case MO_STRONG: /* strong */
70
      return 1;
71
    case MO_WEAK: /* weak */
72
      assert (a->type & IT_MEMORY);
73
      assert (b->type & IT_MEMORY);
74
      if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
75
        &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
76
        int aw, bw;
77
        assert ((aw = II_MEM_WIDTH (a->index)) >= 0);
78
        assert ((bw = II_MEM_WIDTH (b->index)) >= 0);
79
 
80
        a = &f->INSN(a->op[1]);
81
        b = &f->INSN(b->op[1]);
82
        if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
83
         || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) return 1;
84
 
85
        /* Check if they overlap */
86
        if (a->op[2] >= b->op[2] && a->op[2] < b->op[2] + bw) return 1;
87
        if (b->op[2] >= a->op[2] && b->op[2] < a->op[2] + aw) return 1;
88
        return 0;
89
      } else return 1;
90
    case MO_NONE: /* none */
91
      return 0;
92
    default:
93
      assert (0);
94
  }
95
  return 1;
96
}
97
 
98
/* Adds memory dependencies based on ordering type:
99
 
100
void add_memory_dep (cuc_func *f, int otype)
101
{
102
  int b, i;
103
  dep_list *all_mem = NULL;
104
 
105
  for (b = 0; b < f->num_bb; b++) {
106
    cuc_insn *insn = f->bb[b].insn;
107
    for (i = 0; i < f->bb[b].ninsn; i++)
108
      if (insn[i].type & IT_MEMORY) {
109
        dep_list *tmp = all_mem;
110
        while (tmp) {
111
          //PRINTF ("%x %x\n", REF (b,i), tmp->ref);
112
          if (check_memory_conflict (f, &insn[i], &f->INSN(tmp->ref), otype))
113
            add_dep (&insn[i].dep, tmp->ref);
114
          tmp = tmp->next;
115
        }
116
        add_dep (&all_mem, REF (b, i));
117
      }
118
  }
119
  dispose_list (&all_mem);
120
}
121
 
122
/* Check if they address the same location, so we can join them */
123
static int same_transfers (cuc_func *f, int otype)
124
{
125
  int i, j;
126
  int modified = 0;
127
  if (otype == MO_WEAK || otype == MO_NONE) {
128
    for (i = 1, j = 1; i < f->nmsched; i++)
129
      /* Exclude memory stores and different memory types */
130
      if (f->mtype[i - 1] == f->mtype[i] && f->mtype[i] & MT_LOAD) {
131
        cuc_insn *a = &f->INSN(f->msched[i - 1]);
132
        cuc_insn *b = &f->INSN(f->msched[i]);
133
        if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
134
          &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
135
          a = &f->INSN(a->op[1]);
136
          b = &f->INSN(b->op[1]);
137
          /* Not in usual form? */
138
          if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
139
           || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) goto keep;
140
 
141
          //PRINTF ("%i %i, ", a->op[2], b->op[2]);
142
 
143
          /* Check if they are the same => do not copy */
144
          if (a->op[2] == b->op[2]
145
            && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
146
            /* yes => remove actual instruction */
147
            int t1 = MIN (f->msched[i - 1], f->msched[i]);
148
            int t2 = MAX (f->msched[i - 1], f->msched[i]);
149
            int b, i, j;
150
            cucdebug (2, "Removing %x_%x and using %x_%x instead.\n",
151
              REF_BB(t2), REF_I(t2), REF_BB(t1), REF_I(t1));
152
            change_insn_type (&f->INSN(t2), II_NOP);
153
            modified = 1;
154
            /* Update references */
155
            for (b = 0; b < f->num_bb; b++)
156
              for (i = 0; i < f->bb[b].ninsn; i++)
157
                for (j = 0; j < MAX_OPERANDS; j++)
158
                  if (f->bb[b].insn[i].opt[j] & OPT_REF && f->bb[b].insn[i].op[j] == t2)
159
                    f->bb[b].insn[i].op[j] = t1;
160
 
161
          } else goto keep;
162
        } else goto keep;
163
      } else {
164
keep:
165
        f->msched[j] = f->msched[i];
166
        f->mtype[j++] = f->mtype[i];
167
      }
168
    f->nmsched = j;
169
  }
170
  return modified;
171
}
172
 
173
/* Check if two consecutive lb[zs] can be joined into lhz and if
174
   two consecutive lh[zs] can be joined into lwz */
175
static int join_transfers (cuc_func *f, int otype)
176
{
177
  int i, j;
178
  int modified = 0;
179
 
180
  /* We can change width even with strong memory ordering */
181
  if (otype == MO_WEAK || otype == MO_NONE || otype == MO_STRONG) {
182
    for (i = 1, j = 1; i < f->nmsched; i++)
183
      /* Exclude memory stores and different memory types */
184
      if (f->mtype[i - 1] == f->mtype[i] && f->mtype[i] & MT_LOAD) {
185
        cuc_insn *a = &f->INSN(f->msched[i - 1]);
186
        cuc_insn *b = &f->INSN(f->msched[i]);
187
        int aw = f->mtype[i - 1] & MT_WIDTH;
188
        if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
189
          &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
190
          a = &f->INSN(a->op[1]);
191
          b = &f->INSN(b->op[1]);
192
 
193
          /* Not in usual form? */
194
          if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
195
           || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) goto keep;
196
 
197
          /* Check if they touch together */
198
          if (a->op[2] + aw == b->op[2]
199
            && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
200
            /* yes => remove second instruction */
201
            int t1 = MIN (f->msched[i - 1], f->msched[i]);
202
            int t2 = MAX (f->msched[i - 1], f->msched[i]);
203
            dep_list *t1dep = f->INSN(t1).dep;
204
            int x, p;
205
            cuc_insn *ii;
206
 
207
            cucdebug (2, "Joining %x and %x.\n", t1, t2);
208
            if (cuc_debug >= 8) print_cuc_bb (f, "PREJT");
209
            change_insn_type (&f->INSN(t1), II_NOP);
210
            change_insn_type (&f->INSN(t2), II_NOP);
211
            /* We will reuse the memadd before the first load, and add some
212
               custom code at the end */
213
            insert_insns (f, t1, 10);
214
            if (cuc_debug > 8) print_cuc_bb (f, "PREJT2");
215
 
216
            /* Remove all dependencies to second access */
217
            for (x = 0; x < f->num_bb; x++) {
218
              int i;
219
              for (i = 0; i < f->bb[x].ninsn; i++) {
220
                dep_list *d = f->bb[x].insn[i].dep;
221
                dep_list **old = &f->bb[x].insn[i].dep;
222
                while (d) {
223
                  if (d->ref == t2) {
224
                    d = d->next;
225
                    *old = d;
226
                  } else {
227
                    d = d->next;
228
                    old = &((*old)->next);
229
                  }
230
                }
231
              }
232
            }
233
 
234
            /* Build the folowing code:
235
               l[hw]z p-1
236
               and p-1, 0xff
237
               sfle p-1, 0x7f
238
               or p-2, 0xffffff00
239
               cmov p-3, p-1, p-2
240
               shr p-5, 8
241
               and p-1, 0xff
242
               sfle p-1 0x7f
243
               or p-2 0xffffff00
244
               cmov p-3, p-1, p-2*/
245
            p = REF_I(t1);
246
            cucdebug (8, "%x %x\n", f->mtype[i - 1], f->mtype[i]);
247
            for (x = 0; x < 2; x++) {
248
              int t = f->mtype[i - 1 + x];
249
              ii = &f->bb[REF_BB(t1)].insn[p];
250
              if (!x) {
251
                change_insn_type (ii, aw == 1 ? II_LH : II_LW);
252
                ii->type = IT_MEMORY | IT_VOLATILE;
253
                ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
254
                ii->op[1] = t1 - 1; ii->opt[1] = OPT_REF;
255
                ii->opt[2] = ii->opt[3] = OPT_NONE;
256
                ii->dep = t1dep;
257
                f->mtype[i - 1] = MT_LOAD | (aw == 1 ? 2 : 4);
258
                f->msched[i - 1] = REF (REF_BB(t1), p);
259
              } else {
260
                change_insn_type (ii, II_SRL);
261
                ii->type = 0;
262
                ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
263
                ii->op[1] = t1; ii->opt[1] = OPT_REF;
264
                ii->op[2] = 8; ii->opt[2] = OPT_CONST;
265
                ii->opt[3] = OPT_NONE;
266
              }
267
 
268
              ii = &f->bb[REF_BB(t1)].insn[++p];
269
              change_insn_type (ii, II_AND);
270
              ii->type = 0;
271
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
272
              ii->op[1] = REF (REF_BB(t1), p - 1); ii->opt[1] = OPT_REF;
273
              ii->op[2] = 0xff; ii->opt[2] = OPT_CONST;
274
              ii->opt[3] = OPT_NONE;
275
 
276
              ii = &f->bb[REF_BB(t1)].insn[++p];
277
              change_insn_type (ii, II_SFLE);
278
              ii->type = IT_COND;
279
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
280
              ii->op[1] = REF (REF_BB(t1), p - 1); ii->opt[1] = OPT_REF;
281
              ii->op[2] = 0x7f; ii->opt[2] = OPT_CONST;
282
              ii->opt[3] = OPT_NONE;
283
 
284
              ii = &f->bb[REF_BB(t1)].insn[++p];
285
              change_insn_type (ii, II_OR);
286
              ii->type = 0;
287
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
288
              ii->op[1] = REF (REF_BB(t1), p - 2); ii->opt[1] = OPT_REF;
289
              if (t & MT_SIGNED) ii->op[2] = 0xffffff00;
290
              else ii->op[2] = 0;
291
              ii->opt[2] = OPT_CONST;
292
              ii->opt[3] = OPT_NONE;
293
 
294
              ii = &f->bb[REF_BB(t1)].insn[++p];
295
              change_insn_type (ii, II_CMOV);
296
              ii->type = 0;
297
              ii->op[0] = -1; ii->opt[0] = OPT_REGISTER | OPT_DEST;
298
              ii->op[1] = REF (REF_BB(t1), p - 1); ii->opt[1] = OPT_REF;
299
              ii->op[2] = REF (REF_BB(t1), p - 3); ii->opt[2] = OPT_REF;
300
              ii->op[3] = REF (REF_BB(t1), p - 2); ii->opt[3] = OPT_REF;
301
              p++;
302
            }
303
 
304
            modified = 1;
305
 
306
            {
307
              int b, i, j;
308
              /* Update references */
309
              for (b = 0; b < f->num_bb; b++)
310
                for (i = 0; i < f->bb[b].ninsn; i++)
311
                  for (j = 0; j < MAX_OPERANDS; j++)
312
                    if (REF_I (f->bb[b].insn[i].op[j]) < REF_I (t1)
313
                     || REF_I(f->bb[b].insn[i].op[j]) >= REF_I (t1) + 10) {
314
                      if (f->bb[b].insn[i].opt[j] & OPT_REF && f->bb[b].insn[i].op[j] == t1)
315
                        f->bb[b].insn[i].op[j] = t1 + 4;
316
                      else if (f->bb[b].insn[i].opt[j] & OPT_REF && f->bb[b].insn[i].op[j] == t2)
317
                        f->bb[b].insn[i].op[j] = t1 + 9;
318
                    }
319
            }
320
            if (cuc_debug >= 8) print_cuc_bb (f, "POSTJT");
321
          } else goto keep;
322
        } else goto keep;
323
      } else {
324
keep:
325
        f->msched[j] = f->msched[i];
326
        f->mtype[j++] = f->mtype[i];
327
      }
328
    f->nmsched = j;
329
  }
330
  return modified;
331
}
332
 
333
/* returns nonzero if a < b */
334
int mem_ordering_cmp (cuc_func *f, cuc_insn *a, cuc_insn *b)
335
{
336
  assert (a->type & IT_MEMORY);
337
  assert (b->type & IT_MEMORY);
338
  if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
339
    &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
340
    a = &f->INSN(a->op[1]);
341
    b = &f->INSN(b->op[1]);
342
    if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
343
     || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) return 0;
344
 
345
    /* Order linearly, we can then join them to bursts */
346
    return a->op[2] < b->op[2];
347
  } else return 0;
348
}
349
 
350
/* Schedule memory accesses
351
 
352
int schedule_memory (cuc_func *f, int otype)
353
{
354
  int b, i, j;
355
  int modified = 0;
356
  f->nmsched = 0;
357
 
358
  for (b = 0; b < f->num_bb; b++) {
359
    cuc_insn *insn = f->bb[b].insn;
360
    for (i = 0; i < f->bb[b].ninsn; i++)
361
      if (insn[i].type & IT_MEMORY) {
362
        f->msched[f->nmsched++] = REF (b, i);
363
        if (otype == MO_NONE || otype == MO_WEAK) insn[i].type |= IT_FLAG1; /* mark unscheduled */
364
      }
365
  }
366
 
367
  for (i = 0; i < f->nmsched; i++)
368
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
369
  cucdebug (2, "\n");
370
 
371
  /* We can reorder just more loose types
372
     We assume, that memory accesses are currently in valid (but not neccesserly)
373
     optimal order */
374
  if (otype == MO_WEAK || otype == MO_NONE) {
375
    for (i = 0; i < f->nmsched; i++) {
376
      int best = i;
377
      int tmp;
378
      for (j = i + 1; j < f->nmsched; j++) if (REF_BB(f->msched[j]) == REF_BB(f->msched[best])) {
379
        if (mem_ordering_cmp (f, &f->INSN (f->msched[j]), &f->INSN(f->msched[best]))) {
380
          /* Check dependencies */
381
          dep_list *t = f->INSN(f->msched[j]).dep;
382
          while (t) {
383
            if (f->INSN(t->ref).type & IT_FLAG1) break;
384
            t = t->next;
385
          }
386
          if (!t) best = j; /* no conflicts -> ok */
387
        }
388
      }
389
 
390
      /* we have to shift instructions up, to maintain valid dependencies
391
         and make space for best candidate */
392
 
393
      /* make local copy */
394
      tmp = f->msched[best];
395
      for (j = best; j > i; j--) f->msched[j] = f->msched[j - 1];
396
      f->msched[i] = tmp;
397
      f->INSN(f->msched[i]).type &= ~IT_FLAG1; /* mark scheduled */
398
    }
399
  }
400
 
401
  for (i = 0; i < f->nmsched; i++)
402
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
403
  cucdebug (2, "\n");
404
 
405
  /* Assign memory types */
406
  for (i = 0; i < f->nmsched; i++) {
407
    cuc_insn *a = &f->INSN(f->msched[i]);
408
    f->mtype[i] = !II_IS_LOAD(a->index) ? MT_STORE : MT_LOAD;
409
    f->mtype[i] |= II_MEM_WIDTH (a->index);
410
    if (a->type & IT_SIGNED) f->mtype[i] |= MT_SIGNED;
411
  }
412
 
413
  if (same_transfers (f, otype)) modified = 1;
414
  if (join_transfers (f, otype)) modified = 1;
415
 
416
  for (i = 0; i < f->nmsched; i++)
417
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
418
  cucdebug (2, "\n");
419
  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL");
420
 
421
  if (config.cuc.enable_bursts) {
422
    //PRINTF ("\n");
423
    for (i = 1; i < f->nmsched; i++) {
424
      cuc_insn *a = &f->INSN(f->msched[i - 1]);
425
      cuc_insn *b = &f->INSN(f->msched[i]);
426
      int aw = f->mtype[i - 1] & MT_WIDTH;
427
 
428
      /* Burst can only be out of words */
429
      if (aw != 4) continue;
430
 
431
      if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
432
        &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
433
        a = &f->INSN(a->op[1]);
434
        b = &f->INSN(b->op[1]);
435
        /* Not in usual form? */
436
        if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
437
         || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) continue;
438
 
439
        //PRINTF ("%i %i, ", a->op[2], b->op[2]);
440
 
441
        /* Check if they touch together */
442
        if (a->op[2] + aw == b->op[2]
443
          && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
444
          /* yes => do burst */
445
          f->mtype[i - 1] &= ~MT_BURSTE;
446
          f->mtype[i - 1] |= MT_BURST;
447
          f->mtype[i] |= MT_BURST | MT_BURSTE;
448
        }
449
      }
450
    }
451
  }
452
 
453
  for (i = 0; i < f->nmsched; i++)
454
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
455
  cucdebug (2, "\n");
456
 
457
  /* We don't need dependencies in non-memory instructions */
458
  for (b = 0; b < f->num_bb; b++) {
459
    cuc_insn *insn = f->bb[b].insn;
460
    for (i = 0; i < f->bb[b].ninsn; i++) if (!(insn[i].type & IT_MEMORY))
461
      dispose_list (&insn[i].dep);
462
  }
463
 
464
  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL2");
465
  /* Reduce number of dependecies, keeping just direct dependencies, based on memory schedule */
466
  {
467
    int lastl[3] = {-1, -1, -1};
468
    int lasts[3] = {-1, -1, -1};
469
    int lastc[3] = {-1, -1, -1};
470
    int last_load = -1, last_store = -1, last_call = -1;
471
    for (i = 0; i < f->nmsched; i++) {
472
      int t = f->mtype[i] & MT_LOAD ? 0 : f->mtype[i] & MT_STORE ? 1 : 2;
473
      int maxl = lastl[t];
474
      int maxs = lasts[t];
475
      int maxc = lastc[t];
476
      dep_list *tmp = f->INSN(f->msched[i]).dep;
477
      cucdebug (7, "!%i %x %p\n", i, f->msched[i], tmp);
478
      while (tmp) {
479
        if (f->INSN(tmp->ref).type & IT_MEMORY && REF_BB(tmp->ref) == REF_BB(f->msched[i])) {
480
          cucdebug (7, "%i %x %lx\n", i, f->msched[i], tmp->ref);
481
          /* Search for the reference */
482
          for (j = 0; j < f->nmsched; j++) if (f->msched[j] == tmp->ref) break;
483
          assert (j < f->nmsched);
484
          if (f->mtype[j] & MT_STORE) {
485
            if (maxs < j) maxs = j;
486
          } else if (f->mtype[j] & MT_LOAD) {
487
            if (maxl < j) maxl = j;
488
          } else if (f->mtype[j] & MT_CALL) {
489
            if (maxc < j) maxc = j;
490
          }
491
        }
492
        tmp = tmp->next;
493
      }
494
      dispose_list (&f->INSN(f->msched[i]).dep);
495
      if (f->mtype[i] & MT_STORE) {
496
        maxs = last_store;
497
        last_store = i;
498
      } else if (f->mtype[i] & MT_LOAD) {
499
        maxl = last_load;
500
        last_load = i;
501
      } else if (f->mtype[i] & MT_CALL) {
502
        maxc = last_call;
503
        last_call = i;
504
      }
505
 
506
      if (maxl > lastl[t]) {
507
        add_dep (&f->INSN(f->msched[i]).dep, f->msched[maxl]);
508
        lastl[t] = maxl;
509
      }
510
      if (maxs > lasts[t]) {
511
        add_dep (&f->INSN(f->msched[i]).dep, f->msched[maxs]);
512
        lasts[t] = maxs;
513
      }
514
      if (maxc > lastc[t]) {
515
        add_dep (&f->INSN(f->msched[i]).dep, f->msched[maxc]);
516
        lastc[t] = maxc;
517
      }
518
      //PRINTF ("%i(%i)> ml %i(%i) ms %i(%i) lastl %i %i lasts %i %i last_load %i last_store %i\n", i, f->msched[i], maxl, f->msched[maxl], maxs, f->msched[maxs], lastl[0], lastl[1], lasts[0], lasts[1], last_load, last_store);
519
 
520
      /* What we have to wait to finish this BB? */
521
      if (i + 1 >= f->nmsched || REF_BB(f->msched[i + 1]) != REF_BB(f->msched[i])) {
522
        if (last_load > lastl[t]) {
523
          add_dep (&f->bb[REF_BB(f->msched[i])].mdep, f->msched[last_load]);
524
          lastl[t] = last_load;
525
        }
526
        if (last_store > lasts[t]) {
527
          add_dep (&f->bb[REF_BB(f->msched[i])].mdep, f->msched[last_store]);
528
          lasts[t] = last_store;
529
        }
530
        if (last_call > lastc[t]) {
531
          add_dep (&f->bb[REF_BB(f->msched[i])].mdep, f->msched[last_call]);
532
          lastc[t] = last_call;
533
        }
534
      }
535
    }
536
  }
537
  return modified;
538
}

powered by: WebSVN 2.1.0

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