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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_36/] [or1ksim/] [cuc/] [memory.c] - Blame information for rev 953

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

powered by: WebSVN 2.1.0

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