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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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