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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [BasicBlock.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
#include "stdafx.h"
2
 
3
extern bool HasTargetReg(OCODE *);
4
int nBasicBlocks;
5
BasicBlock *basicBlocks[10000];
6
BasicBlock *sortedBlocks[10000];
7
 
8
BasicBlock *BasicBlock::MakeNew()
9
{
10
        BasicBlock *bb;
11
 
12
        bb = (BasicBlock *)allocx(sizeof(BasicBlock));
13
        bb->live = CSet::MakeNew();
14
        bb->gen = CSet::MakeNew();
15
        bb->kill = CSet::MakeNew();
16
        bb->LiveIn = CSet::MakeNew();
17
        bb->LiveOut = CSet::MakeNew();
18
        bb->MustSpill = CSet::MakeNew();
19
        bb->NeedLoad = CSet::MakeNew();
20
        bb->ihead = nullptr;
21
        bb->ohead = nullptr;
22
        bb->itail = nullptr;
23
        bb->otail = nullptr;
24
        return (bb);
25
}
26
 
27
// Detect basic block separater instruction
28
 
29
bool IsBasicBlockSeparater(OCODE *ip)
30
{
31
        if (ip->opcode==op_label)
32
                return (false);
33
        switch(ip->opcode) {
34
        case op_rte:    return (true);
35
        case op_ret:    return true;
36
        case op_jal:    return true;
37
        case op_jmp:    return true;
38
        case op_bra:    return true;
39
        case op_beq:    return true;
40
        case op_bne:    return true;
41
        case op_blt:    return true;
42
        case op_bge:    return true;
43
        case op_ble:    return true;
44
        case op_bgt:    return true;
45
        case op_bltu:   return true;
46
        case op_bgeu:   return true;
47
        case op_bleu:   return true;
48
        case op_bgtu:   return true;
49
        case op_bbs:    return (true);
50
        case op_bbc:    return (true);
51
        case op_beqi:   return (true);
52
        case op_bchk:   return (true);
53
        case op_ibne:   return (true);
54
        case op_dbnz:   return (true);
55
        default:        return (false);
56
        }
57
        return (false);
58
}
59
 
60
// Break the program down into basic blocks
61
 
62
BasicBlock *BasicBlock::Blockize(OCODE *start)
63
{
64
        OCODE *ip, *ip2;
65
        BasicBlock *bbs, *pb;
66
        int num;
67
 
68
        num = 0;
69
        currentFn->RootBlock = bbs = BasicBlock::MakeNew();
70
        bbs->code = start;
71
        bbs->num = num;
72
        bbs->length = 0;
73
        pb = bbs;
74
        basicBlocks[0] = currentFn->RootBlock;
75
        start->leader = true;
76
        for (ip = start; ip; ip = ip2) {
77
                ip->bb = pb;
78
                if (pb == nullptr)
79
                        printf("hi");
80
                pb->depth = ip->loop_depth + 1;
81
                ip2 = ip->fwd;
82
                if (ip->opcode != op_label && ip->opcode != op_rem && ip->opcode != op_rem2 && ip->opcode != op_hint && ip->opcode != op_hint2)
83
                        pb->length++;
84
                if (ip->opcode == op_ret || ip->opcode==op_rti)
85
                        currentFn->ReturnBlock = pb;
86
                if (IsBasicBlockSeparater(ip)) {
87
                        pb->lcode = ip;
88
                        if (ip->fwd)
89
                                ip->fwd->leader = true;
90
                        num++;
91
                        pb->next = BasicBlock::MakeNew();
92
                        pb->next->prev = pb;
93
                        pb->next->code = ip2;
94
                        pb = pb->next;
95
                        pb->num = num;
96
                        pb->length = 0;
97
                        basicBlocks[num] = pb;
98
                }
99
        }
100
        nBasicBlocks = num;
101
        currentFn->LastBlock = pb->prev;
102
        if (currentFn->LastBlock==nullptr)
103
                currentFn->LastBlock = currentFn->RootBlock;
104
        // ASSERT(LastBlock!=nullptr);
105
        pb->next = nullptr;
106
        dfs.printf("%s: ", (char *)currentFn->sym->name->c_str());
107
        dfs.printf("%d basic blocks\n", num);
108
        return (bbs);
109
}
110
 
111
Edge *BasicBlock::MakeOutputEdge(BasicBlock *dst)
112
{
113
        Edge *edge;
114
        Edge *p;
115
 
116
        // Prevent the same edge from being added multiple times.
117
        for (p = ohead; p; p = p->next) {
118
                if (p->dst==dst)
119
                        return (nullptr);
120
        }
121
        edge = (Edge *)allocx(sizeof(Edge));
122
        edge->src = this;
123
        edge->dst = dst;
124
        edge->backedge = dst->num < num;
125
        if (otail) {
126
                otail->next = edge;
127
                edge->prev = otail;
128
                otail = edge;
129
        }
130
        else {
131
                ohead = otail = edge;
132
        }
133
        return (edge);
134
}
135
 
136
Edge *BasicBlock::MakeInputEdge(BasicBlock *src)
137
{
138
        Edge *edge;
139
        Edge *p;
140
 
141
        // Prevent the same edge from being added multiple times.
142
        for (p = ihead; p; p = p->next)
143
                if (p->src==src)
144
                        return (nullptr);
145
        edge = (Edge *)allocx(sizeof(Edge));
146
        edge->src = src;
147
        edge->dst = this;
148
        edge->backedge = src->num > num;
149
        if (itail) {
150
                itail->next = edge;
151
                edge->prev = itail;
152
                itail = edge;
153
        }
154
        else {
155
                ihead = itail = edge;
156
        }
157
        return (edge);
158
}
159
 
160
Edge *BasicBlock::MakeDomEdge(BasicBlock *dst)
161
{
162
        Edge *edge;
163
        Edge *p;
164
 
165
        // Prevent the same edge from being added multiple times.
166
        for (p = dhead; p; p = p->next)
167
                if (p->dst==dst)
168
                        return (nullptr);
169
        edge = (Edge *)allocx(sizeof(Edge));
170
        edge->src = this;
171
        edge->dst = dst;
172
        if (dtail) {
173
                dtail->next = edge;
174
                edge->prev = dtail;
175
                dtail = edge;
176
        }
177
        else {
178
                dhead = dtail = edge;
179
        }
180
        return (edge);
181
}
182
 
183
int bbdcmp(const void *a, const void *b)
184
{
185
        BasicBlock *aa, *bb;
186
 
187
        aa = (BasicBlock *)a;
188
        bb = (BasicBlock *)b;
189
        return (aa->depth < bb->depth ? 1 : aa->depth == bb->depth ? 0 : -1);
190
}
191
 
192
void BasicBlock::DepthSort()
193
{
194
        memcpy(sortedBlocks, basicBlocks, (currentFn->LastBlock->num+1)*sizeof(BasicBlock *));
195
        qsort(sortedBlocks, (size_t)currentFn->LastBlock->num+1, sizeof(BasicBlock *), bbdcmp);
196
}
197
 
198
CSet *BasicBlock::livo;
199
 
200
void BasicBlock::ComputeLiveVars()
201
{
202
        OCODE *ip;
203
        int tr;
204
        static CSet OldLiveIn, OldLiveOut;
205
        int rg1, rg2;
206
//      char buf [4000];
207
 
208
        if (livo==nullptr)
209
                livo = CSet::MakeNew();
210
        livo->clear();
211
        changed = false;
212
        gen->clear();
213
        kill->clear();
214
        for (ip = code; ip && (!ip->leader || ip == code); ip = ip->fwd) {
215
                if (ip->remove || ip->remove2)
216
                        continue;
217
                if (ip->opcode == op_label)
218
                        continue;
219
                if (ip->HasTargetReg()) {
220
                        ip->GetTargetReg(&rg1, &rg2);
221
                        tr = rg1;
222
                        if ((tr & 0xFFF) >= 0x800) {
223
                                kill->add((tr & 0xfff)-0x780);
224
                        }
225
                        else {
226
                                kill->add(tr);
227
                        }
228
                        if (tr >= regFirstArg && tr <= regLastArg)
229
                                gen->add(tr);
230
                        // There could be a second target
231
                        tr = rg2;
232
                        if (tr) {
233
                                if ((tr & 0xFFF) >= 0x800) {
234
                                        kill->add((tr & 0xfff)-0x780);
235
                                }
236
                                else {
237
                                        kill->add(tr);
238
                                }
239
                                if (tr >= regFirstArg && tr <= regLastArg)
240
                                        gen->add(tr);
241
                        }
242
                }
243
                // If there was an explicit target it would have been oper1
244
                // there was an else here
245
                else
246
                //if (ip->oper1 && ip->oper1->mode == am_reg) {
247
                if (ip->oper1) {
248
                        if ((ip->oper1->preg & 0xfff) >= 0x800) {
249
                                gen->add((ip->oper1->preg & 0xfff)-0x780);
250
                        }
251
                        else {
252
                                gen->add(ip->oper1->preg);
253
                        }
254
                }
255
                // Stack operations implicitly read SP. It doesn't appear in the operx operands.
256
                if (ip->opcode==op_push || ip->opcode==op_pop || ip->opcode==op_link || ip->opcode==op_unlk) {
257
                        gen->add(regSP);
258
                }
259
                if (ip->oper2) {
260
//                              if (ip->oper2->mode == am_reg) {
261
                        if ((ip->oper2->preg & 0xfff) >= 0x800) {
262
                                gen->add((ip->oper2->preg & 0xfff)-0x780);
263
                        }
264
                        else {
265
                                gen->add(ip->oper2->preg);
266
                        }
267
                        if (ip->oper2->mode == am_indx2) {
268
                                gen->add(ip->oper2->sreg);
269
                        }
270
//                              }
271
                }
272
                if (ip->oper3) {
273
//                              if (ip->oper3->mode == am_reg) {
274
                        if ((ip->oper3->preg & 0xfff) >= 0x800) {
275
                                gen->add((ip->oper3->preg & 0xfff)-0x780);
276
                        }
277
                        else {
278
                                gen->add(ip->oper3->preg);
279
                        }
280
//                              }
281
                }
282
                if (ip->oper4) {
283
//                              if (ip->oper4->mode == am_reg) {
284
                        if ((ip->oper4->preg & 0xfff) >= 0x800) {
285
                                gen->add((ip->oper4->preg & 0xfff)-0x780);
286
                        }
287
                        else {
288
                                gen->add(ip->oper4->preg);
289
                        }
290
//                              }
291
                }
292
        }
293
        OldLiveIn.clear();
294
        OldLiveOut.clear();
295
        OldLiveIn.copy(*LiveIn);
296
        OldLiveOut.copy(*LiveOut);
297
        LiveIn->copy(*LiveOut);
298
        LiveIn->remove(*kill);
299
        LiveIn->add(gen);
300
        //gen->resetPtr();
301
        //kill->resetPtr();
302
        //dfs.printf("%d: ", num);
303
        //for (nn = 0; nn < gen->NumMember(); nn++)
304
        //      dfs.printf("g%d ", gen->nextMember());
305
        //dfs.printf(" || ");
306
        //for (nn = 0; nn < kill->NumMember(); nn++)
307
        //      dfs.printf("k%d ", kill->nextMember());
308
        //dfs.printf("\n");
309
        //dfs.printf("Edges to: ");
310
        if (ohead==nullptr)
311
                LiveOut->copy(*LiveIn);
312
        else
313
                AddLiveOut(this);
314
        /*
315
        for (ep = ohead; ep; ep = ep->next) {
316
                if (ep->dst) {
317
                        //dfs.printf("%d ", ep->dst->num);
318
                        LiveOut->add(ep->dst->LiveIn);
319
                        //LiveOut->sprint(buf,sizeof(buf));
320
                        //dfs.printf("LiveOut: %s", buf);
321
                }
322
        }
323
        */
324
//      dfs.printf("\n");
325
        if (OldLiveIn != *LiveIn)
326
                changed = true;
327
        if (OldLiveOut != *LiveOut)
328
                changed = true;
329
}
330
 
331
void BasicBlock::AddLiveOut(BasicBlock *ip)
332
{
333
        Edge *ep;
334
 
335
        for (ep = ohead; ep; ep = ep->next) {
336
                if (!livo->isMember(ep->dst->num)) {
337
                        livo->add(ep->dst->num);
338
                        if (ep->dst) {
339
                                AddLiveOut(ep->dst);
340
                        //dfs.printf("%d ", ep->dst->num);
341
                                LiveOut->add(ep->dst->LiveIn);
342
                        //LiveOut->sprint(buf,sizeof(buf));
343
                        //dfs.printf("LiveOut: %s", buf);
344
                        }
345
                }
346
        }
347
}
348
 
349
bool BasicBlock::IsIdom(BasicBlock *b)
350
{
351
        Edge *e;
352
 
353
        for (e = dhead; e; e = e->next) {
354
                if (e->dst==b)
355
                        return (true);
356
        }
357
        return (false);
358
}
359
 
360
void BasicBlock::ExpandReturnBlocks()
361
{
362
        BasicBlock *bb;
363
        Edge *p;
364
        OCODE *ip, *nc, *oc, *bk;
365
 
366
        if (currentFn->ReturnBlock == nullptr)
367
                return;
368
        for (bb = currentFn->RootBlock; bb; bb = bb->next) {
369
 
370
                // Prevent the same edge from being added multiple times.
371
                for (p = bb->ohead; p; p = p->next) {
372
                        if (p->dst == currentFn->ReturnBlock && currentFn->ReturnBlock->length < 32) {
373
                                oc = bb->lcode;
374
                                bk = bb->lcode->back;
375
                                oc = bb->lcode = OCODE::Clone(currentFn->ReturnBlock->code);
376
                                for (ip = ip->fwd; ip != currentFn->ReturnBlock->lcode; ip = ip->fwd) {
377
                                        oc->back = bk;
378
                                        oc->fwd = OCODE::Clone(ip);
379
                                        bk = oc;
380
                                        oc = oc->fwd;
381
                                }
382
                                oc->fwd = bb->next->code;
383
                                bb->lcode = nc;
384
                                break;
385
                        }
386
                }
387
 
388
        }
389
 
390
}
391
 
392
 
393
void BasicBlock::UpdateLive(int r)
394
{
395
        if (NeedLoad->isMember(r)) {
396
                NeedLoad->remove(r);
397
                if (!MustSpill->isMember(r)) {
398
                        forest.trees[r]->infinite = true;
399
                }
400
        }
401
        forest.trees[r]->stores += depth * 4;
402
        live->remove(r);
403
}
404
 
405
 
406
void BasicBlock::CheckForDeaths(int r)
407
{
408
        int m;
409
 
410
        if (!live->isMember(r)) {
411
                NeedLoad->resetPtr();
412
                for (m = NeedLoad->nextMember(); m >= 0; m = NeedLoad->nextMember()) {
413
                        forest.trees[m]->loads += depth * 4;
414
                        MustSpill->add(m);
415
                }
416
                NeedLoad->clear();
417
        }
418
}
419
 
420
 
421
void BasicBlock::ComputeSpillCosts()
422
{
423
        BasicBlock *b;
424
        OCODE *ip;
425
        Instruction *i;
426
        Operand *pam;
427
        int r;
428
        bool endLoop;
429
 
430
        forest.ClearCosts();
431
 
432
        for (b = currentFn->RootBlock; b; b = b->next) {
433
                b->NeedLoad->clear();
434
                // build the set live from b->liveout
435
                b->BuildLivesetFromLiveout();
436
                //*b->live = *b->LiveOut;
437
                *b->MustSpill = *b->live;
438
                endLoop = false;
439
                for (ip = b->lcode; ip && !endLoop; ip = ip->back) {
440
                        if (ip->opcode == op_label)
441
                                continue;
442
                        if (ip->opcode == op_mov) {
443
                                r = ip->oper1->preg;
444
                                r = forest.map[r];
445
                                forest.trees[r]->copies++;
446
                        }
447
                        else {
448
                                if (ip->oper1 && ip->insn->HasTarget()) {
449
                                        r = ip->oper1->preg;
450
                                        r = forest.map[r];
451
                                        forest.trees[r]->others += ip->insn->extime;
452
                                }
453
                        }
454
                        i = ip->insn;
455
                        // examine instruction i updating sets and accumulating costs
456
                        if (i->HasTarget()) {
457
                                r = ip->oper1->preg;
458
                                r = forest.map[r];
459
                                b->UpdateLive(r);
460
                        }
461
                        // This is a loop in the Briggs thesis, but we only allow 4 operands
462
                        // so the loop is unrolled.
463
                        if (ip->oper1) {
464
                                if (!i->HasTarget()) {
465
                                        r = ip->oper1->preg;
466
                                        r = forest.map[r];
467
                                        b->CheckForDeaths(r);
468
                                        if (r = ip->oper1->sreg) {      // '=' is correct
469
                                                r = forest.map[r];
470
                                                b->CheckForDeaths(r);
471
                                        }
472
                                }
473
                        }
474
                        if (ip->oper2) {
475
                                r = ip->oper1->preg;
476
                                r = forest.map[r];
477
                                b->CheckForDeaths(r);
478
                                if (r = ip->oper1->sreg) {
479
                                        r = forest.map[r];
480
                                        b->CheckForDeaths(r);
481
                                }
482
                        }
483
                        if (ip->oper3) {
484
                                r = ip->oper1->preg;
485
                                r = forest.map[r];
486
                                b->CheckForDeaths(r);
487
                                if (r = ip->oper1->sreg) {
488
                                        r = forest.map[r];
489
                                        b->CheckForDeaths(r);
490
                                }
491
                        }
492
                        if (ip->oper4) {
493
                                r = ip->oper1->preg;
494
                                r = forest.map[r];
495
                                b->CheckForDeaths(r);
496
                                if (r = ip->oper1->sreg) {
497
                                        r = forest.map[r];
498
                                        b->CheckForDeaths(r);
499
                                }
500
                        }
501
                        // Re-examine uses to update live and needload
502
                        pam = ip->oper1;
503
                        if (pam && !i->HasTarget()) {
504
                                r = pam->preg;
505
                                r = forest.map[r];
506
                                //r = Var::Find2(pam->lrpreg)->cnum;
507
                                b->live->add(r);
508
                                b->NeedLoad->add(r);
509
                                if (pam->sreg) {
510
                                        //r = Var::Find2(pam->lrsreg)->cnum;
511
                                        r = pam->sreg;
512
                                        r = forest.map[r];
513
                                        b->live->add(r);
514
                                        b->NeedLoad->add(r);
515
                                }
516
                        }
517
                        pam = ip->oper2;
518
                        if (ip->oper2) {
519
                                r = ip->oper2->preg;
520
                                r = forest.map[r];
521
//                              r = Var::Find2(pam->lrpreg)->cnum;
522
                                b->live->add(r);
523
                                b->NeedLoad->add(r);
524
                                if (ip->oper2->sreg) {
525
                                        r = ip->oper2->sreg;
526
                                        r = forest.map[r];
527
//                                      r = Var::Find2(pam->lrsreg)->cnum;
528
                                        b->live->add(r);
529
                                        b->NeedLoad->add(r);
530
                                }
531
                        }
532
                        pam = ip->oper3;
533
                        if (ip->oper3) {
534
                                r = ip->oper3->preg;
535
                                r = forest.map[r];
536
//                              r = Var::Find2(pam->lrpreg)->cnum;
537
                                b->live->add(r);
538
                                b->NeedLoad->add(r);
539
                                if (ip->oper3->sreg) {
540
//                                      r = Var::Find2(pam->lrsreg)->cnum;
541
                                        r = ip->oper3->sreg;
542
                                        r = forest.map[r];
543
                                        b->live->add(r);
544
                                        b->NeedLoad->add(r);
545
                                }
546
                        }
547
                        pam = ip->oper4;
548
                        if (ip->oper4) {
549
//                              r = Var::Find2(pam->lrpreg)->cnum;
550
                                r = ip->oper4->preg;
551
                                r = forest.map[r];
552
                                b->live->add(r);
553
                                b->NeedLoad->add(r);
554
                                if (ip->oper4->sreg) {
555
                                        r = ip->oper4->sreg;
556
                                        r = forest.map[r];
557
//                                      r = Var::Find2(pam->lrsreg)->cnum;
558
                                        b->live->add(r);
559
                                        b->NeedLoad->add(r);
560
                                }
561
                        }
562
                        if (ip == b->code)
563
                                endLoop = true;
564
                }
565
                b->NeedLoad->resetPtr();
566
                for (r = b->NeedLoad->nextMember(); r >= 0; r = b->NeedLoad->nextMember()) {
567
                        //Var::FindByCnum(r)->trees.loads += b->depth * 4;
568
                        //forest.loads += b->depth * 4;
569
                        if (forest.trees[r])
570
                                forest.trees[r]->loads += b->depth * 4;
571
                }
572
        }
573
 
574
        forest.SummarizeCost();
575
}
576
 
577
 
578
// We don't actually want entire ranges. Only the part of the
579
// range that the basic block is sitting on. There could be
580
// multiple pieces to the range associated with a var.
581
 
582
void BasicBlock::BuildLivesetFromLiveout()
583
{
584
        int m;
585
        int v;
586
        Var *vr;
587
        int K = 17;
588
 
589
        live->clear();
590
        LiveOut->resetPtr();
591
        //for (m = LiveOut->nextMember(); m >= 0; m = LiveOut->nextMember()) {
592
        //      vr = Var::Find2(m);
593
        //      v = vr->cnum;
594
        //      if (v >= 0) live->add(v);
595
        //}
596
 
597
        for (m = LiveOut->nextMember(); m >= 0; m = LiveOut->nextMember()) {
598
                // Find the live range associated with value m
599
                v = Var::FindTreeno(map.newnums[m],num);
600
                if (v >= 0 && ::forest.trees[v]->color==K) {
601
                        live->add(v);
602
                }
603
                // else compiler error
604
        }
605
 
606
}
607
 
608
 
609
// Update the CFG by uniting the son's edges with the father's.
610
 
611
void BasicBlock::Unite(int father, int son)
612
{
613
        Edge *ep;
614
 
615
        for (ep = basicBlocks[son]->ohead; ep; ep = ep->next) {
616
                basicBlocks[father]->MakeOutputEdge(ep->dst);
617
        }
618
        for (ep = basicBlocks[son]->ihead; ep; ep = ep->next) {
619
                basicBlocks[father]->MakeInputEdge(ep->src);
620
        }
621
        for (ep = basicBlocks[son]->dhead; ep; ep = ep->next) {
622
                basicBlocks[father]->MakeDomEdge(ep->dst);
623
        }
624
}
625
 
626
// Insert a register move operation before block.
627
 
628
void BasicBlock::InsertMove(int reg, int rreg, int blk)
629
{
630
        OCODE *cd, *ip;
631
 
632
        cd = (OCODE *)allocx(sizeof(OCODE));
633
        cd->opcode = op_mov;
634
        cd->insn = GetInsn(op_mov);
635
        cd->oper1 = allocOperand();
636
        cd->oper1->mode = am_reg;
637
        cd->oper1->preg = rreg;
638
        cd->oper2 = allocOperand();
639
        cd->oper2->mode = am_reg;
640
        cd->oper2->preg = reg;
641
        ip = basicBlocks[blk]->code;
642
 
643
        basicBlocks[blk]->code = cd;
644
        cd->back = ip->back;
645
        cd->fwd = ip;
646
        cd->bb = ip->bb;
647
        if (ip->bb == nullptr)
648
                printf("hi");
649
        if (ip->back)
650
                ip->back->fwd = cd;
651
        ip->back = cd;
652
        cd->leader = true;
653
        ip->leader = false;
654
}
655
 
656
// The interference graph works based on tree numbers
657
// Basic blocks work based on basic block numbers.
658
// There is some conversion required.
659
 
660
bool BasicBlock::Coalesce()
661
{
662
        OCODE *ip;
663
        int dst, src, dtree, stree;
664
        int father, son, ft, st;
665
        bool improved;
666
        int nn;
667
 
668
        improved = false;
669
 
670
        for (nn = 0; nn <= currentFn->LastBlock->num; nn++) {
671
                for (ip = sortedBlocks[nn]->code; ip && ip != sortedBlocks[nn]->lcode; ip = ip->fwd) {
672
                        if (ip->remove)
673
                                continue;
674
                        if (ip->insn == nullptr)
675
                                continue;
676
                        if (ip->insn->opcode == op_mov) {
677
                                dst = Var::PathCompress(ip->oper1->preg, ip->bb->num, &dtree);
678
                                src = Var::PathCompress(ip->oper2->preg, ip->bb->num, &stree);
679
                                if (dst < 0 || src < 0)
680
                                        continue;
681
                                if (stree != dtree) {
682
                                        // For iGraph we just want the tree number not the bb number.
683
                                        ft = min(stree, dtree);
684
                                        st = max(stree, dtree);
685
                                        if (stree < dtree) {
686
                                                father = src;
687
                                                son = dst;
688
                                        }
689
                                        else {
690
                                                father = dst;
691
                                                son = src;
692
                                        }
693
                                        if (!iGraph.DoesInterfere(ft, st)) {
694
                                                iGraph.Unite(ft, st);
695
                                                // update graph so father contains all edges from son
696
                                                if (father != son)
697
                                                        Unite(father, son);
698
                                                improved = true;
699
                                                MarkRemove(ip);
700
                                        }
701
                                }
702
                        }
703
                }
704
        }
705
        return (improved);
706
}
707
 
708
 
709
void DumpLiveRegs()
710
{
711
        int regno;
712
        BasicBlock *b;
713
 
714
        dfs.printf("<LiveRegisters>\n");
715
        for (regno = 1; regno < 32; regno++) {
716
                dfs.printf("Reg:%d ", regno);
717
                for (b = currentFn->RootBlock; b; b = b->next) {
718
                        if (/*b->LiveOut->isMember(regno) || */b->LiveIn->isMember(regno))
719
                                dfs.printf("%d ", b->num);
720
                }
721
                dfs.printf("\n");
722
        }
723
        dfs.printf("</LiveRegisters>\n");
724
}
725
 
726
void BasicBlock::InsertSpillCode(int reg, int64_t offs)
727
{
728
        OCODE *cd;
729
 
730
        if (this == nullptr)
731
                return;
732
        cd = (OCODE *)xalloc(sizeof(OCODE));
733
        cd->insn = GetInsn(op_sw);
734
        cd->opcode = op_sw;
735
        cd->oper1 = allocOperand();
736
        cd->oper2 = allocOperand();
737
        cd->oper1->mode = am_reg;
738
        cd->oper1->preg = reg;
739
        cd->oper2->mode = am_indx;
740
        cd->oper2->preg = regFP;
741
        cd->oper2->offset = allocEnode();
742
        cd->oper2->offset->nodetype = en_icon;
743
        cd->oper2->offset->i = offs;
744
        cd->bb = this;
745
        if (num==0)
746
                PeepList::InsertBefore(lcode, cd);
747
        else
748
                PeepList::InsertBefore(code, cd);
749
}
750
 
751
void BasicBlock::InsertFillCode(int reg, int64_t offs)
752
{
753
        OCODE *cd;
754
 
755
        if (this == nullptr)
756
                return;
757
        cd = (OCODE *)xalloc(sizeof(OCODE));
758
        cd->insn = GetInsn(op_lw);
759
        cd->opcode = op_lw;
760
        cd->oper1 = allocOperand();
761
        cd->oper2 = allocOperand();
762
        cd->oper1->mode = am_reg;
763
        cd->oper1->preg = reg;
764
        cd->oper2->mode = am_indx;
765
        cd->oper2->preg = regFP;
766
        cd->oper2->offset = allocEnode();
767
        cd->oper2->offset->nodetype = en_icon;
768
        cd->oper2->offset->i = offs;
769
        cd->bb = this;
770
        if (currentFn->rcode->bb==this)
771
                PeepList::InsertAfter(currentFn->rcode, cd);
772
        else
773
                PeepList::InsertBefore(lcode, cd);
774
}
775
 
776
void BasicBlock::Color()
777
{
778
        int r;
779
        OCODE *ip;
780
 
781
        for (ip = code; ip && ip != lcode; ip = ip->fwd) {
782
                if (ip->remove)
783
                        continue;
784
                if (ip->insn == nullptr)
785
                        continue;
786
                if (ip->oper1) {
787
                        r = ip->oper1->preg;
788
                        r = forest.map[r];
789
                        ip->oper1->preg = forest.trees[r]->color;
790
                        r = ip->oper1->sreg;
791
                        r = forest.map[r];
792
                        ip->oper1->sreg = forest.trees[r]->color;
793
                }
794
                if (ip->oper2) {
795
                        r = ip->oper2->preg;
796
                        r = forest.map[r];
797
                        ip->oper2->preg = forest.trees[r]->color;
798
                        r = ip->oper2->sreg;
799
                        r = forest.map[r];
800
                        ip->oper2->sreg = forest.trees[r]->color;
801
                }
802
                if (ip->oper3) {
803
                        r = ip->oper3->preg;
804
                        r = forest.map[r];
805
                        ip->oper3->preg = forest.trees[r]->color;
806
                        r = ip->oper3->sreg;
807
                        r = forest.map[r];
808
                        ip->oper3->sreg = forest.trees[r]->color;
809
                }
810
                if (ip->oper4) {
811
                        r = ip->oper4->preg;
812
                        r = forest.map[r];
813
                        ip->oper4->preg = forest.trees[r]->color;
814
                        r = ip->oper4->sreg;
815
                        r = forest.map[r];
816
                        ip->oper4->sreg = forest.trees[r]->color;
817
                }
818
        }
819
}
820
 
821
void BasicBlock::ColorAll()
822
{
823
        int nn;
824
 
825
        for (nn = 0; nn <= currentFn->LastBlock->num; nn++) {
826
                basicBlocks[nn]->Color();
827
        }
828
}

powered by: WebSVN 2.1.0

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