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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [dag.c] - Blame information for rev 190

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

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
 
3
static char rcsid[] = "$Id: dag.c,v 1.1 2002/08/28 23:12:42 drh Exp $";
4
 
5
#define iscall(op) (generic(op) == CALL \
6
        || IR->mulops_calls \
7
        && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \
8
        && ( optype(op)==U  || optype(op)==I))
9
static Node forest;
10
static struct dag {
11
        struct node node;
12
        struct dag *hlink;
13
} *buckets[16];
14
int nodecount;
15
static Tree firstarg;
16
int assignargs = 1;
17
int prunetemps = -1;
18
static Node *tail;
19
 
20
static int depth = 0;
21
static Node replace(Node);
22
static Node prune(Node);
23
static Node asgnnode(Symbol, Node);
24
static struct dag *dagnode(int, Node, Node, Symbol);
25
static Symbol equated(Symbol);
26
static void fixup(Node);
27
static void labelnode(int);
28
static void list(Node);
29
static void killnodes(Symbol);
30
static Node node(int, Node, Node, Symbol);
31
static void printdag1(Node, int, int);
32
static void printnode(Node, int, int);
33
static void reset(void);
34
static Node tmpnode(Node);
35
static void typestab(Symbol, void *);
36
static Node undag(Node);
37
static Node visit(Node, int);
38
static void unlist(void);
39
void walk(Tree tp, int tlab, int flab) {
40
        listnodes(tp, tlab, flab);
41
        if (forest) {
42
                Node list = forest->link;
43
                forest->link = NULL;
44
                if (!IR->wants_dag && errcnt == 0)
45
                        list = undag(list);
46
                code(Gen)->u.forest = list;
47
                forest = NULL;
48
        }
49
        reset();
50
        deallocate(STMT);
51
}
52
 
53
static Node node(int op, Node l, Node r, Symbol sym) {
54
        int i;
55
        struct dag *p;
56
 
57
        i = (opindex(op)^((unsigned long)sym>>2))&(NELEMS(buckets)-1);
58
        for (p = buckets[i]; p; p = p->hlink)
59
                if (p->node.op      == op && p->node.syms[0] == sym
60
                &&  p->node.kids[0] == l  && p->node.kids[1] == r)
61
                        return &p->node;
62
        p = dagnode(op, l, r, sym);
63
        p->hlink = buckets[i];
64
        buckets[i] = p;
65
        ++nodecount;
66
        return &p->node;
67
}
68
static struct dag *dagnode(int op, Node l, Node r, Symbol sym) {
69
        struct dag *p;
70
 
71
        NEW0(p, FUNC);
72
        p->node.op = op;
73
        if ((p->node.kids[0] = l) != NULL)
74
                ++l->count;
75
        if ((p->node.kids[1] = r) != NULL)
76
                ++r->count;
77
        p->node.syms[0] = sym;
78
        return p;
79
}
80
Node newnode(int op, Node l, Node r, Symbol sym) {
81
        return &dagnode(op, l, r, sym)->node;
82
}
83
static void killnodes(Symbol p) {
84
        int i;
85
        struct dag **q;
86
 
87
        for (i = 0; i < NELEMS(buckets); i++)
88
                for (q = &buckets[i]; *q; )
89
                        if (generic((*q)->node.op) == INDIR &&
90
                            (!isaddrop((*q)->node.kids[0]->op)
91
                             || (*q)->node.kids[0]->syms[0] == p)) {
92
                                *q = (*q)->hlink;
93
                                --nodecount;
94
                        } else
95
                                q = &(*q)->hlink;
96
}
97
static void reset(void) {
98
        if (nodecount > 0)
99
                memset(buckets, 0, sizeof buckets);
100
        nodecount = 0;
101
}
102
Node listnodes(Tree tp, int tlab, int flab) {
103
        Node p = NULL, l, r;
104
        int op;
105
 
106
        assert(tlab || flab || tlab == 0 && flab == 0);
107
        if (tp == NULL)
108
                return NULL;
109
        if (tp->node)
110
                return tp->node;
111
        if (isarray(tp->type))
112
                op = tp->op + sizeop(voidptype->size);
113
        else
114
                op = tp->op + sizeop(tp->type->size);
115
        switch (generic(tp->op)) {
116
        case AND:   { if (depth++ == 0) reset();
117
                      if (flab) {
118
                        listnodes(tp->kids[0], 0, flab);
119
                        listnodes(tp->kids[1], 0, flab);
120
                      } else {
121
                        listnodes(tp->kids[0], 0, flab = genlabel(1));
122
                        listnodes(tp->kids[1], tlab, 0);
123
                        labelnode(flab);
124
                      }
125
                      depth--; } break;
126
        case OR:    { if (depth++ == 0)
127
                        reset();
128
                      if (tlab) {
129
                        listnodes(tp->kids[0], tlab, 0);
130
                        listnodes(tp->kids[1], tlab, 0);
131
                      } else {
132
                        tlab = genlabel(1);
133
                        listnodes(tp->kids[0], tlab, 0);
134
                        listnodes(tp->kids[1], 0, flab);
135
                        labelnode(tlab);
136
                      }
137
                      depth--;
138
 } break;
139
        case NOT:   { return listnodes(tp->kids[0], flab, tlab); }
140
        case COND:  { Tree q = tp->kids[1];
141
                      assert(tlab == 0 && flab == 0);
142
                      if (tp->u.sym)
143
                        addlocal(tp->u.sym);
144
                      flab = genlabel(2);
145
                      listnodes(tp->kids[0], 0, flab);
146
                      assert(q && q->op == RIGHT);
147
                      reset();
148
                      listnodes(q->kids[0], 0, 0);
149
                      if (forest->op == LABEL+V) {
150
                        equatelab(forest->syms[0], findlabel(flab + 1));
151
                        unlist();
152
                      }
153
                      list(jump(flab + 1));
154
                      labelnode(flab);
155
                      listnodes(q->kids[1], 0, 0);
156
                      if (forest->op == LABEL+V) {
157
                        equatelab(forest->syms[0], findlabel(flab + 1));
158
                        unlist();
159
                      }
160
                      labelnode(flab + 1);
161
 
162
                      if (tp->u.sym)
163
                        p = listnodes(idtree(tp->u.sym), 0, 0); } break;
164
        case CNST:  { Type ty = unqual(tp->type);
165
                      assert(ty->u.sym);
166
                      if (tlab || flab) {
167
                        assert(ty == inttype);
168
                        if (tlab && tp->u.v.i != 0)
169
                                list(jump(tlab));
170
                        else if (flab && tp->u.v.i == 0)
171
                                list(jump(flab));
172
                      }
173
                      else if (ty->u.sym->addressed)
174
                        p = listnodes(cvtconst(tp), 0, 0);
175
                      else
176
                        p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break;
177
        case RIGHT: { if (   tp->kids[0] && tp->kids[1]
178
                          &&  generic(tp->kids[1]->op) == ASGN
179
                          && (generic(tp->kids[0]->op) == INDIR
180
                          && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]
181
                          || (tp->kids[0]->op == FIELD
182
                          &&  tp->kids[0] == tp->kids[1]->kids[0]))) {
183
                        assert(tlab == 0 && flab == 0);
184
                        if (generic(tp->kids[0]->op) == INDIR) {
185
                                p = listnodes(tp->kids[0], 0, 0);
186
                                list(p);
187
                                listnodes(tp->kids[1], 0, 0);
188
                        }
189
                        else {
190
                                assert(generic(tp->kids[0]->kids[0]->op) == INDIR);
191
                                list(listnodes(tp->kids[0]->kids[0], 0, 0));
192
                                p = listnodes(tp->kids[0], 0, 0);
193
                                listnodes(tp->kids[1], 0, 0);
194
                        }
195
                      } else if (tp->kids[1]) {
196
                        listnodes(tp->kids[0], 0, 0);
197
                        p = listnodes(tp->kids[1], tlab, flab);
198
                      } else
199
                        p = listnodes(tp->kids[0], tlab, flab); } break;
200
        case JUMP:  { assert(tlab == 0 && flab == 0);
201
                      assert(tp->u.sym == 0);
202
                      assert(tp->kids[0]);
203
                      l = listnodes(tp->kids[0], 0, 0);
204
                      list(newnode(JUMP+V, l, NULL, NULL));
205
                      reset(); } break;
206
        case CALL:  { Tree save = firstarg;
207
                      firstarg = NULL;
208
                      assert(tlab == 0 && flab == 0);
209
                      if (tp->op == CALL+B && !IR->wants_callb) {
210
                        Tree arg0 = tree(ARG+P, tp->kids[1]->type,
211
                                tp->kids[1], NULL);
212
                        if (IR->left_to_right)
213
                                firstarg = arg0;
214
                        l = listnodes(tp->kids[0], 0, 0);
215
                        if (!IR->left_to_right || firstarg) {
216
                                firstarg = NULL;
217
                                listnodes(arg0, 0, 0);
218
                        }
219
                        p = newnode(CALL+V, l, NULL, NULL);
220
                      } else {
221
                        l = listnodes(tp->kids[0], 0, 0);
222
                        r = listnodes(tp->kids[1], 0, 0);
223
                        p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL);
224
                      }
225
                      NEW0(p->syms[0], FUNC);
226
                      assert(isptr(tp->kids[0]->type));
227
                      assert(isfunc(tp->kids[0]->type->type));
228
                      p->syms[0]->type = tp->kids[0]->type->type;
229
                      list(p);
230
                      reset();
231
                      cfunc->u.f.ncalls++;
232
                      firstarg = save;
233
 } break;
234
        case ARG:   { assert(tlab == 0 && flab == 0);
235
                      if (IR->left_to_right)
236
                        listnodes(tp->kids[1], 0, 0);
237
                      if (firstarg) {
238
                        Tree arg = firstarg;
239
                        firstarg = NULL;
240
                        listnodes(arg, 0, 0);
241
                      }
242
                      l = listnodes(tp->kids[0], 0, 0);
243
                      list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL));
244
                      forest->syms[0] = intconst(tp->type->size);
245
                      forest->syms[1] = intconst(tp->type->align);
246
                      if (!IR->left_to_right)
247
                        listnodes(tp->kids[1], 0, 0); } break;
248
        case EQ:  case NE: case GT: case GE: case LE:
249
        case LT:    { assert(tp->u.sym == 0);
250
                      assert(errcnt || tlab || flab);
251
                      l = listnodes(tp->kids[0], 0, 0);
252
                      r = listnodes(tp->kids[1], 0, 0);
253
                      assert(errcnt || opkind(l->op) == opkind(r->op));
254
                      assert(errcnt || optype(op) == optype(l->op));
255
                      if (tlab)
256
                        assert(flab == 0),
257
                        list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab)));
258
                      else if (flab) {
259
                        switch (generic(tp->op)) {
260
                        case EQ: op = NE; break;
261
                        case NE: op = EQ; break;
262
                        case GT: op = LE; break;
263
                        case LT: op = GE; break;
264
                        case GE: op = LT; break;
265
                        case LE: op = GT; break;
266
                        default: assert(0);
267
                        }
268
                        list(newnode(op + opkind(l->op), l, r, findlabel(flab)));
269
                      }
270
                      if (forest && forest->syms[0])
271
                        forest->syms[0]->ref++; } break;
272
        case ASGN:  { assert(tlab == 0 && flab == 0);
273
                      if (tp->kids[0]->op == FIELD) {
274
                        Tree  x = tp->kids[0]->kids[0];
275
                        Field f = tp->kids[0]->u.field;
276
                        assert(generic(x->op) == INDIR);
277
                        reset();
278
                        l = listnodes(lvalue(x), 0, 0);
279
                        if (fieldsize(f) < 8*f->type->size) {
280
                                unsigned int fmask = fieldmask(f);
281
                                unsigned int  mask = fmask<<fieldright(f);
282
                                Tree q = tp->kids[1];
283
                                if (q->op == CNST+I && q->u.v.i == 0
284
                                ||  q->op == CNST+U && q->u.v.u == 0)
285
                                        q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask));
286
                                else if (q->op == CNST+I && (q->u.v.i&fmask) == fmask
287
                                ||       q->op == CNST+U && (q->u.v.u&fmask) == fmask)
288
                                        q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask));
289
                                else {
290
                                        listnodes(q, 0, 0);
291
                                        q = bittree(BOR,
292
                                                bittree(BAND, rvalue(lvalue(x)),
293
                                                        cnsttree(unsignedtype, (unsigned long)~mask)),
294
                                                bittree(BAND, shtree(LSH, cast(q, unsignedtype),
295
                                                        cnsttree(unsignedtype, (unsigned long)fieldright(f))),
296
                                                        cnsttree(unsignedtype, (unsigned long)mask)));
297
                                }
298
                                r = listnodes(q, 0, 0);
299
                                op = ASGN + ttob(q->type);
300
                        } else {
301
                                r = listnodes(tp->kids[1], 0, 0);
302
                                op = ASGN + ttob(tp->kids[1]->type);
303
                        }
304
                      } else {
305
                        l = listnodes(tp->kids[0], 0, 0);
306
                        r = listnodes(tp->kids[1], 0, 0);
307
                      }
308
                      list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL));
309
                      forest->syms[0] = intconst(tp->kids[1]->type->size);
310
                      forest->syms[1] = intconst(tp->kids[1]->type->align);
311
                      if (isaddrop(tp->kids[0]->op)
312
                      && !tp->kids[0]->u.sym->computed)
313
                        killnodes(tp->kids[0]->u.sym);
314
                      else
315
                        reset();
316
                      p = listnodes(tp->kids[1], 0, 0); } break;
317
        case BOR: case BAND: case BXOR:
318
        case ADD: case SUB:  case RSH:
319
        case LSH:   { assert(tlab == 0 && flab == 0);
320
                      l = listnodes(tp->kids[0], 0, 0);
321
                      r = listnodes(tp->kids[1], 0, 0);
322
                      p = node(op, l, r, NULL); } break;
323
        case DIV: case MUL:
324
        case MOD:   { assert(tlab == 0 && flab == 0);
325
                      l = listnodes(tp->kids[0], 0, 0);
326
                      r = listnodes(tp->kids[1], 0, 0);
327
                      p = node(op, l, r, NULL);
328
                      if (IR->mulops_calls && isint(tp->type)) {
329
                        list(p);
330
                        cfunc->u.f.ncalls++;
331
                      } } break;
332
        case RET:   { assert(tlab == 0 && flab == 0);
333
                      l = listnodes(tp->kids[0], 0, 0);
334
                      list(newnode(op, l, NULL, NULL)); } break;
335
        case CVF: case CVI: case CVP:
336
        case CVU:   { assert(tlab == 0 && flab == 0);
337
                      assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size);
338
                      l = listnodes(tp->kids[0], 0, 0);
339
                      p = node(op, l, NULL, intconst(tp->kids[0]->type->size));
340
 } break;
341
        case BCOM:
342
        case NEG:   { assert(tlab == 0 && flab == 0);
343
                      l = listnodes(tp->kids[0], 0, 0);
344
                      p = node(op, l, NULL, NULL); } break;
345
        case INDIR: { Type ty = tp->kids[0]->type;
346
                      assert(tlab == 0 && flab == 0);
347
                      l = listnodes(tp->kids[0], 0, 0);
348
                      if (isptr(ty))
349
                        ty = unqual(ty)->type;
350
                      if (isvolatile(ty)
351
                      || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields))
352
                        p = newnode(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL);
353
                      else
354
                        p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break;
355
        case FIELD: { Tree q = tp->kids[0];
356
                      if (tp->type == inttype) {
357
                        long n = fieldleft(tp->u.field);
358
                        q = shtree(RSH,
359
                                shtree(LSH, q, cnsttree(inttype, n)),
360
                                cnsttree(inttype, n + fieldright(tp->u.field)));
361
                      } else if (fieldsize(tp->u.field) < 8*tp->u.field->type->size)
362
                        q = bittree(BAND,
363
                                shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))),
364
                                cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field)));
365
                      assert(tlab == 0 && flab == 0);
366
                      p = listnodes(q, 0, 0); } break;
367
        case ADDRG:
368
        case ADDRF: { assert(tlab == 0 && flab == 0);
369
                      p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym);
370
 } break;
371
        case ADDRL: { assert(tlab == 0 && flab == 0);
372
                      if (tp->u.sym->generated)
373
                        addlocal(tp->u.sym);
374
                      p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break;
375
        default:assert(0);
376
        }
377
        tp->node = p;
378
        return p;
379
}
380
static void list(Node p) {
381
        if (p && p->link == NULL) {
382
                if (forest) {
383
                        p->link = forest->link;
384
                        forest->link = p;
385
                } else
386
                        p->link = p;
387
                forest = p;
388
        }
389
}
390
static void labelnode(int lab) {
391
        assert(lab);
392
        if (forest && forest->op == LABEL+V)
393
                equatelab(findlabel(lab), forest->syms[0]);
394
        else
395
                list(newnode(LABEL+V, NULL, NULL, findlabel(lab)));
396
        reset();
397
}
398
static void unlist(void) {
399
        Node p;
400
 
401
        assert(forest);
402
        assert(forest != forest->link);
403
        p = forest->link;
404
        while (p->link != forest)
405
                p = p->link;
406
        p->link = forest->link;
407
        forest = p;
408
}
409
Tree cvtconst(Tree p) {
410
        Symbol q = constant(p->type, p->u.v);
411
        Tree e;
412
 
413
        if (q->u.c.loc == NULL)
414
                q->u.c.loc = genident(STATIC, p->type, GLOBAL);
415
        if (isarray(p->type)) {
416
                e = simplify(ADDRG, atop(p->type), NULL, NULL);
417
                e->u.sym = q->u.c.loc;
418
        } else
419
                e = idtree(q->u.c.loc);
420
        return e;
421
}
422
void gencode(Symbol caller[], Symbol callee[]) {
423
        Code cp;
424
        Coordinate save;
425
 
426
        if (prunetemps == -1)
427
                prunetemps = !IR->wants_dag;
428
        save = src;
429
        if (assignargs) {
430
                int i;
431
                Symbol p, q;
432
                cp = codehead.next->next;
433
                codelist = codehead.next;
434
                for (i = 0; (p = callee[i]) != NULL
435
                         && (q = caller[i]) != NULL; i++)
436
                        if (p->sclass != q->sclass || p->type != q->type)
437
                                walk(asgn(p, idtree(q)), 0, 0);
438
                codelist->next = cp;
439
                cp->prev = codelist;
440
        }
441
        if (glevel && IR->stabsym) {
442
                int i;
443
                Symbol p, q;
444
                for (i = 0; (p = callee[i]) != NULL
445
                         && (q = caller[i]) != NULL; i++) {
446
                        (*IR->stabsym)(p);
447
                        if (p->sclass != q->sclass || p->type != q->type)
448
                                (*IR->stabsym)(q);
449
                }
450
                swtoseg(CODE);
451
        }
452
        cp = codehead.next;
453
        for ( ; errcnt <= 0 && cp; cp = cp->next)
454
                switch (cp->kind) {
455
                case Address:  assert(IR->address);
456
                               (*IR->address)(cp->u.addr.sym, cp->u.addr.base,
457
                                cp->u.addr.offset); break;
458
                case Blockbeg: {
459
                                Symbol *p = cp->u.block.locals;
460
                                (*IR->blockbeg)(&cp->u.block.x);
461
                                for ( ; *p; p++)
462
                                        if ((*p)->ref != 0.0)
463
                                                (*IR->local)(*p);
464
                                        else if (glevel) (*IR->local)(*p);
465
                               }
466
 break;
467
                case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break;
468
                case Defpoint: src = cp->u.point.src; break;
469
                case Gen: case Jump:
470
                case Label:    if (prunetemps)
471
                                cp->u.forest = prune(cp->u.forest);
472
                               fixup(cp->u.forest);
473
                               cp->u.forest = (*IR->gen)(cp->u.forest); break;
474
                case Local:    (*IR->local)(cp->u.var); break;
475
                case Switch:   break;
476
                default: assert(0);
477
                }
478
        src = save;
479
}
480
static void fixup(Node p) {
481
        for ( ; p; p = p->link)
482
                switch (generic(p->op)) {
483
                case JUMP:
484
                        if (specific(p->kids[0]->op) == ADDRG+P)
485
                                p->kids[0]->syms[0] =
486
                                        equated(p->kids[0]->syms[0]);
487
                        break;
488
                case LABEL: assert(p->syms[0] == equated(p->syms[0])); break;
489
                case EQ: case GE: case GT: case LE: case LT: case NE:
490
                        assert(p->syms[0]);
491
                        p->syms[0] = equated(p->syms[0]);
492
                }
493
}
494
static Symbol equated(Symbol p) {
495
        { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); }
496
        while (p->u.l.equatedto)
497
                p = p->u.l.equatedto;
498
        return p;
499
}
500
void emitcode(void) {
501
        Code cp;
502
        Coordinate save;
503
 
504
        save = src;
505
        cp = codehead.next;
506
        for ( ; errcnt <= 0 && cp; cp = cp->next)
507
                switch (cp->kind) {
508
                case Address: break;
509
                case Blockbeg: if (glevel && IR->stabblock) {
510
                                (*IR->stabblock)('{',  cp->u.block.level - LOCAL, cp->u.block.locals);
511
                                swtoseg(CODE);
512
                               }
513
 break;
514
                case Blockend: if (glevel && IR->stabblock) {
515
                                Code bp = cp->u.begin;
516
                                foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL);
517
                                foreach(bp->u.block.types,       bp->u.block.level, typestab, NULL);
518
                                (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals);
519
                                swtoseg(CODE);
520
                               }
521
 break;
522
                case Defpoint: src = cp->u.point.src;
523
                               if (glevel > 0 && IR->stabline) {
524
                                (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break;
525
                case Gen: case Jump:
526
                case Label:    if (cp->u.forest)
527
                                (*IR->emit)(cp->u.forest); break;
528
                case Local:    if (glevel && IR->stabsym) {
529
                                (*IR->stabsym)(cp->u.var);
530
                                swtoseg(CODE);
531
                               } break;
532
                case Switch:   {        int i;
533
                                defglobal(cp->u.swtch.table, LIT);
534
                                (*IR->defaddress)(equated(cp->u.swtch.labels[0]));
535
                                for (i = 1; i < cp->u.swtch.size; i++) {
536
                                        long k = cp->u.swtch.values[i-1];
537
                                        while (++k < cp->u.swtch.values[i])
538
                                                assert(k < LONG_MAX),
539
                                                (*IR->defaddress)(equated(cp->u.swtch.deflab));
540
                                        (*IR->defaddress)(equated(cp->u.swtch.labels[i]));
541
                                }
542
                                swtoseg(CODE);
543
                               } break;
544
                default: assert(0);
545
                }
546
        src = save;
547
}
548
 
549
static Node undag(Node forest) {
550
        Node p;
551
 
552
        tail = &forest;
553
        for (p = forest; p; p = p->link)
554
                if (generic(p->op) == INDIR) {
555
                        assert(p->count >= 1);
556
                        visit(p, 1);
557
                        if (p->syms[2]) {
558
                                assert(p->syms[2]->u.t.cse);
559
                                p->syms[2]->u.t.cse = NULL;
560
                                addlocal(p->syms[2]);
561
                        }
562
                } else if (iscall(p->op) && p->count >= 1)
563
                        visit(p, 1);
564
                else {
565
                        assert(p->count == 0),
566
                        visit(p, 1);
567
                        *tail = p;
568
                        tail = &p->link;
569
                }
570
        *tail = NULL;
571
        return forest;
572
}
573
static Node replace(Node p) {
574
        if (p && (  generic(p->op) == INDIR
575
                 && generic(p->kids[0]->op) == ADDRL
576
                 && p->kids[0]->syms[0]->temporary
577
                 && p->kids[0]->syms[0]->u.t.replace)) {
578
                p = p->kids[0]->syms[0]->u.t.cse;
579
                if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op))
580
                        p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL,
581
                                p->kids[0]->syms[0]), NULL, NULL);
582
                else if (generic(p->op) == ADDRG)
583
                        p = newnode(p->op, NULL, NULL, p->syms[0]);
584
                else
585
                        assert(0);
586
                p->count = 1;
587
        } else if (p) {
588
                p->kids[0] = replace(p->kids[0]);
589
                p->kids[1] = replace(p->kids[1]);
590
        }
591
        return p;
592
}
593
static Node prune(Node forest) {
594
        Node p, *tail = &forest;
595
        int count = 0;
596
 
597
        for (p = forest; p; p = p->link) {
598
                if (count > 0) {
599
                        p->kids[0] = replace(p->kids[0]);
600
                        p->kids[1] = replace(p->kids[1]);
601
                }
602
                if ((  generic(p->op) == ASGN
603
                    && generic(p->kids[0]->op) == ADDRL
604
                    && p->kids[0]->syms[0]->temporary
605
                    && p->kids[0]->syms[0]->u.t.cse == p->kids[1])) {
606
                        Symbol tmp = p->kids[0]->syms[0];
607
                        if (!tmp->defined)
608
                                (*IR->local)(tmp);
609
                        tmp->defined = 1;
610
                        if ((  generic(p->kids[1]->op) == INDIR
611
                            && isaddrop(p->kids[1]->kids[0]->op)
612
                            && p->kids[1]->kids[0]->syms[0]->sclass == REGISTER)
613
                        || ((  generic(p->kids[1]->op) == INDIR
614
                            && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO)
615
                        || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) {
616
                                tmp->u.t.replace = 1;
617
                                count++;
618
                                continue;       /* and omit the assignment */
619
                        }
620
                }
621
                /* keep the assignment and other roots */
622
                *tail = p;
623
                tail = &(*tail)->link;
624
        }
625
        assert(*tail == NULL);
626
        return forest;
627
}
628
static Node visit(Node p, int listed) {
629
        if (p)
630
                if (p->syms[2])
631
                        p = tmpnode(p);
632
                else if (p->count <= 1 && !iscall(p->op)
633
                ||       p->count == 0 &&  iscall(p->op)) {
634
                        p->kids[0] = visit(p->kids[0], 0);
635
                        p->kids[1] = visit(p->kids[1], 0);
636
                }
637
 
638
                else if (specific(p->op) == ADDRL+P || specific(p->op) == ADDRF+P) {
639
                        assert(!listed);
640
                        p = newnode(p->op, NULL, NULL, p->syms[0]);
641
                        p->count = 1;
642
                }
643
                else if (p->op == INDIR+B) {
644
                        p = newnode(p->op, p->kids[0], NULL, NULL);
645
                        p->count = 1;
646
                        p->kids[0] = visit(p->kids[0], 0);
647
                        p->kids[1] = visit(p->kids[1], 0);
648
                }
649
                else {
650
                        p->kids[0] = visit(p->kids[0], 0);
651
                        p->kids[1] = visit(p->kids[1], 0);
652
                        p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op)));
653
                        assert(!p->syms[2]->defined);
654
                        p->syms[2]->ref = 1;
655
                        p->syms[2]->u.t.cse = p;
656
 
657
                        *tail = asgnnode(p->syms[2], p);
658
                        tail = &(*tail)->link;
659
                        if (!listed)
660
                                p = tmpnode(p);
661
                };
662
        return p;
663
}
664
static Node tmpnode(Node p) {
665
        Symbol tmp = p->syms[2];
666
 
667
        assert(tmp);
668
        if (--p->count == 0)
669
                p->syms[2] = NULL;
670
        p = newnode(INDIR + ttob(tmp->type),
671
                newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL);
672
        p->count = 1;
673
        return p;
674
}
675
static Node asgnnode(Symbol tmp, Node p) {
676
        p = newnode(ASGN + ttob(tmp->type),
677
                newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL);
678
        p->syms[0] = intconst(tmp->type->size);
679
        p->syms[1] = intconst(tmp->type->align);
680
        return p;
681
}
682
/* printdag - print dag p on fd, or the node list if p == 0 */
683
void printdag(Node p, int fd) {
684
        FILE *f = fd == 1 ? stdout : stderr;
685
 
686
        printed(0);
687
        if (p == 0) {
688
                if ((p = forest) != NULL)
689
                        do {
690
                                p = p->link;
691
                                printdag1(p, fd, 0);
692
                        } while (p != forest);
693
        } else if (*printed(nodeid((Tree)p)))
694
                fprint(f, "node'%d printed above\n", nodeid((Tree)p));
695
        else
696
                printdag1(p, fd, 0);
697
}
698
 
699
/* printdag1 - recursively print dag p */
700
static void printdag1(Node p, int fd, int lev) {
701
        int id, i;
702
 
703
        if (p == 0 || *printed(id = nodeid((Tree)p)))
704
                return;
705
        *printed(id) = 1;
706
        for (i = 0; i < NELEMS(p->kids); i++)
707
                printdag1(p->kids[i], fd, lev + 1);
708
        printnode(p, fd, lev);
709
}
710
 
711
/* printnode - print fields of dag p */
712
static void printnode(Node p, int fd, int lev) {
713
        if (p) {
714
                FILE *f = fd == 1 ? stdout : stderr;
715
                int i, id = nodeid((Tree)p);
716
                fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id,
717
                        &"   "[id < 10 ? 0 : id < 100 ? 1 : 2]);
718
                fprint(f, "%s count=%d", opname(p->op), p->count);
719
                for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
720
                        fprint(f, " #%d", nodeid((Tree)p->kids[i]));
721
                if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type)
722
                        fprint(f, " {%t}", p->syms[0]->type);
723
                else
724
                        for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++)
725
                                if (p->syms[i]->name)
726
                                        fprint(f, " %s", p->syms[i]->name);
727
                                else
728
                                        fprint(f, " %p", p->syms[i]);
729
                fprint(f, "\n");
730
        }
731
}
732
 
733
/* typestab - emit stab entries for p */
734
static void typestab(Symbol p, void *cl) {
735
        if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym)
736
                (*IR->stabsym)(p);
737
        else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
738
                (*IR->stabtype)(p);
739
}
740
 

powered by: WebSVN 2.1.0

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