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

Subversion Repositories thor

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// CC64 - 'C' derived language compiler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
 
28
Forest forest;
29
 
30
Tree *Forest::PlantTree(Tree *t)
31
{
32
        trees[treecount] = t;
33
        treecount++;
34
        return (t);
35
}
36
 
37
Tree *Forest::MakeNewTree() {
38
        Tree *t;
39
        t = (Tree*)allocx(sizeof(Tree));
40
        t->blocks = CSet::MakeNew();
41
        trees[treecount] = t;
42
        treecount++;
43
        return (t);
44
}
45
 
46
void Forest::CalcRegclass()
47
{
48
        int n;
49
        Tree *t;
50
        int j;
51
        BasicBlock *b;
52
        OCODE *ip;
53
 
54
        for (n = 0; n < treecount; n++) {
55
                t = trees[n];
56
                t->regclass = 0;
57
                t->blocks->resetPtr();
58
                for (j = t->blocks->nextMember(); j >= 0; j = t->blocks->nextMember()) {
59
                        b = basicBlocks[j];
60
                        for (ip = b->code; !ip->leader && ip; ip = ip->fwd) {
61
                                t->regclass |= ip->insn->regclass1;
62
                                t->regclass |= ip->insn->regclass2;
63
                                t->regclass |= ip->insn->regclass3;
64
                                t->regclass |= ip->insn->regclass4;
65
                        }
66
                }
67
        }
68
}
69
 
70
 
71
// Summarize costs
72
void Forest::SummarizeCost()
73
{
74
        int r;
75
 
76
        dfs.printf("<TreeCosts>\n");
77
        for (r = 0; r < treecount; r++) {
78
                if (trees[r]->lattice < 2)
79
                        trees[r]->cost = 2.0f * (trees[r]->loads + trees[r]->stores);
80
                else
81
                        trees[r]->cost = trees[r]->loads - trees[r]->stores;
82
                trees[r]->cost += trees[r]->others;
83
                trees[r]->cost -= trees[r]->copies;
84
                dfs.printf("Tree(%d):%d ", trees[r]->lattice,r);
85
                dfs.printf("cost = %d\n", (int)trees[r]->cost);
86
        }
87
        dfs.printf("</TreeCosts>\n");
88
}
89
 
90
bool IsRenumberable(int reg)
91
{
92
        if (reg > regLastRegvar)
93
                return (false);
94
        if (reg < 3)
95
                return (false);
96
        return (true);
97
}
98
 
99
// Renumber the registers according to the tree (live range) numbers.
100
void Forest::Renumber()
101
{
102
        OCODE *ip;
103
        Tree *t;
104
        int tt;
105
        BasicBlock *b;
106
        int bb;
107
        bool eol;
108
 
109
        memset(::map.newnums, -1, sizeof(::map.newnums));
110
        for (bb = 0; bb < 512; bb++)
111
                ::map.newnums[bb] = bb;
112
 
113
        return;
114
 
115
        for (tt = 0; tt < treecount; tt++) {
116
                t = trees[tt];
117
                ::map.newnums[t->var] = t->num;
118
                t->blocks->resetPtr();
119
                for (bb = t->blocks->nextMember(); bb >= 0; bb = t->blocks->nextMember()) {
120
                        b = basicBlocks[bb];
121
                        eol = false;
122
                        for (ip = b->code; ip && !eol; ip = ip->fwd) {
123
                                if (ip->opcode == op_label)
124
                                        continue;
125
                                if (ip->oper1 && ip->oper1->preg == t->var) {// && IsRenumberable(t->var))
126
                                        Var::Renumber(ip->oper1->preg, t->num);
127
                                        ip->oper1->preg = t->num;
128
                                }
129
                                if (ip->oper1 && ip->oper1->sreg == t->var) {// && IsRenumberable(t->var))
130
                                        Var::Renumber(ip->oper1->sreg, t->num);
131
                                        ip->oper1->sreg = t->num;
132
                                }
133
 
134
                                if (ip->oper2 && ip->oper2->preg == t->var) {// && IsRenumberable(t->var))
135
                                        Var::Renumber(ip->oper2->preg, t->num);
136
                                        ip->oper2->preg = t->num;
137
                                }
138
                                if (ip->oper2 && ip->oper2->sreg == t->var) {// && IsRenumberable(t->var))
139
                                        Var::Renumber(ip->oper2->sreg, t->num);
140
                                        ip->oper2->sreg = t->num;
141
                                }
142
 
143
                                if (ip->oper3 && ip->oper3->preg == t->var) {// && IsRenumberable(t->var))
144
                                        Var::Renumber(ip->oper3->preg, t->num);
145
                                        ip->oper3->preg = t->num;
146
                                }
147
                                if (ip->oper3 && ip->oper3->sreg == t->var) {// && IsRenumberable(t->var))
148
                                        ip->oper3->sreg = t->num;
149
                                        Var::Renumber(ip->oper3->sreg, t->num);
150
                                }
151
 
152
                                if (ip->oper4 && ip->oper4->preg == t->var) {// && IsRenumberable(t->var))
153
                                        Var::Renumber(ip->oper4->preg, t->num);
154
                                        ip->oper4->preg = t->num;
155
                                }
156
                                if (ip->oper4 && ip->oper4->sreg == t->var) {// && IsRenumberable(t->var))
157
                                        Var::Renumber(ip->oper4->sreg, t->num);
158
                                        ip->oper4->sreg = t->num;
159
                                }
160
 
161
                                if (ip == b->lcode)
162
                                        eol = true;
163
                        }
164
                }
165
        }
166
        for (tt = 0; tt < treecount; tt++) {
167
                t = trees[tt];
168
                t->var = ::map.newnums[t->var];
169
        }
170
        for (ip = peep_head; ip; ip = ip->fwd) {
171
                if (ip->opcode == op_label)
172
                        continue;
173
                if (ip->oper1) {
174
                        ip->oper1->preg = ::map.newnums[ip->oper1->preg];
175
                        ip->oper1->sreg = ::map.newnums[ip->oper1->sreg];
176
                }
177
                if (ip->oper2) {
178
                        ip->oper2->preg = ::map.newnums[ip->oper2->preg];
179
                        ip->oper2->sreg = ::map.newnums[ip->oper2->sreg];
180
                }
181
                if (ip->oper3) {
182
                        ip->oper3->preg = ::map.newnums[ip->oper3->preg];
183
                        ip->oper3->sreg = ::map.newnums[ip->oper3->sreg];
184
                }
185
                if (ip->oper4) {
186
                        ip->oper4->preg = ::map.newnums[ip->oper4->preg];
187
                        ip->oper4->sreg = ::map.newnums[ip->oper4->sreg];
188
                }
189
        }
190
        Var::RenumberNeg();
191
}
192
 
193
 
194
// Consider all nodes in the high set as candidates for a spill.
195
// Based on the lowest cost to degree ratio.
196
 
197
int Forest::SelectSpillCandidate()
198
{
199
        int n;
200
        float ratio, rt;
201
        bool ratioSet = false;
202
        int s = -1;
203
 
204
        high.resetPtr();
205
        for (n = high.nextMember(); n >= 0; n = high.nextMember()) {
206
                rt = trees[n]->SelectRatio();
207
                if (!ratioSet) {
208
                        s = n;
209
                        ratio = rt;
210
                        ratioSet = true;
211
                }
212
                else {
213
                        if (rt < ratio) {
214
                                ratio = rt;
215
                                s = n;
216
                        }
217
                }
218
        }
219
        return (s);
220
}
221
 
222
void Forest::Simplify()
223
{
224
        int m;
225
        int K = 17;
226
 
227
        iGraph.frst = this;
228
        low.clear();
229
        high.clear();
230
        for (m = 0; m < treecount; m++) {
231
                if (trees[m]->color == K) {
232
                        if (iGraph.degrees[m] < K)
233
                                low.add(m);
234
                        else if (!trees[m]->infinite)
235
                                high.add(m);
236
                }
237
        }
238
 
239
        while (true) {
240
                low.resetPtr();
241
                while ((m = low.nextMember()) >= 0) {
242
                        low.remove(m);
243
                        high.remove(m);
244
                        // remove m from the graph updating low and high
245
                        iGraph.Remove(m);
246
                        push(m);
247
                }
248
                if (high.NumMember() == 0)
249
                        break;
250
                // select a spill candidate m from high
251
                m = SelectSpillCandidate();     // there should always be an m >= 0
252
                if (m >= 0) {
253
                        high.remove(m);
254
                        low.add(m);
255
                }
256
        }
257
}
258
 
259
 
260
void Forest::Color()
261
{
262
        int nn, m;
263
        int c;
264
        int j, k = 17;
265
        int *p;
266
        CSet used;
267
        Tree *t;
268
 
269
        if (pass == 1) {
270
                for (c = 0; c < treecount; c++) {
271
                        trees[c]->spill = false;
272
                        trees[c]->color = k;
273
                        if (trees[c]->var < 3)
274
                                trees[c]->color = trees[c]->var;
275
                        if (trees[c]->var >= regFirstArg && trees[c]->var <= regLastArg) {
276
                                trees[c]->color = trees[c]->var - regFirstArg + 18;
277
                        }
278
                        if (trees[c]->var == regFP
279
                                || trees[c]->var == regLR
280
                                || trees[c]->var == regXLR
281
                                || trees[c]->var == regSP) {
282
                                trees[c]->color = trees[c]->var - regXLR + 28;
283
                        }
284
                }
285
        }
286
        used.clear();
287
        used.add(0);     // reg0 is a constant 0
288
        used.add(1);    // these two are return value
289
        used.add(2);
290
        while (!stk->IsEmpty()) {
291
                t = trees[m=pop()];
292
                if (pass == 1 && !t->infinite && t->cost < 0.0f) {      // was <= 0.0f
293
                        t->spill = true;
294
                }
295
                else {
296
                        p = iGraph.GetNeighbours(m, &nn);
297
                        for (j = 0; j < nn; j++)
298
                                used.add(trees[p[j]]->color);
299
                        for (c = 0; used.isMember(c) && c < k; c++);
300
                        if (c < k && t->color == k) {   // The tree may have been colored already
301
                                t->color = c;
302
                                used.add(c);
303
                        }
304
                        else if (t->color <= k)         // Don't need to spill args
305
                                t->spill = true;
306
                }
307
        }
308
}
309
 
310
 
311
// Count the number of trees requiring spills.
312
 
313
int Forest::GetSpillCount()
314
{
315
        int c;
316
        int spillCount;
317
        CSet ts;
318
        char buf[2000];
319
 
320
        ts.clear();
321
        for (spillCount = c = 0; c < treecount; c++) {
322
                if (trees[c]->spill) {
323
                        spillCount++;
324
                        ts.add(c);
325
                }
326
        }
327
        dfs.printf("<SpillCount>%d</SpillCount>\n", spillCount);
328
        ts.sprint(buf, sizeof(buf));
329
        dfs.printf("<TreesSpilled>%s</TreesSpilled>\n", buf);
330
        return (spillCount);
331
}
332
 
333
bool Forest::SpillCode()
334
{
335
        int c, m, n;
336
        Var *v;
337
        Tree *t;
338
        BasicBlock *bb;
339
        int64_t spillOffset;
340
        OCODE *cd;
341
        CSet spilled;
342
        bool ret;
343
 
344
        ret = false;
345
        cd = currentFn->spAdjust;
346
        if (cd == nullptr)
347
                return (ret);
348
        spillOffset = cd->oper3->offset->i;
349
        spilled.clear();
350
        for (c = 0; c < treecount; c++) {
351
                t = trees[c];   // convenience
352
                // Tree couldn't be colored that means there are no available registers.
353
                // So, spill one of the registers. The register to spill should be one
354
                // that isn't live at the same time as this tree.
355
                if (t->spill) {
356
                        ret = true;
357
                        v = Var::Find(t->var);
358
                        v = v->GetVarToSpill(&spilled);
359
                        if (v == nullptr)
360
                                continue;
361
                        // The var is spilled at the head of the tree, and restored later
362
                        t->blocks->resetPtr();
363
                        m = t->blocks->nextMember();
364
                        if (m >= 0) {    // should always be true, otherwise no code
365
                                bb = basicBlocks[m];
366
                                if (!spilled.isMember(v->num)) {
367
                                        v->spillOffset = spillOffset;
368
                                        spillOffset += sizeOfWord;
369
                                        spilled.add(v->num);
370
                                }
371
                                bb->InsertSpillCode(v->num, -v->spillOffset);
372
                                while(1) {
373
                                        n = m;
374
                                        m = t->blocks->nextMember();
375
                                        if (m < 0)
376
                                                break;
377
                                        // Detect when a different branch is present. The node
378
                                        // number will jump by more than 1 between branches.
379
                                        // *** suspect this won't work, should just pick last block in tree
380
                                        if (m - n > 1) {
381
                                                bb = basicBlocks[n];
382
                                                bb->InsertFillCode(v->num, -v->spillOffset);
383
                                        }
384
                                }
385
                                bb = basicBlocks[n];
386
                                bb->InsertFillCode(v->num, -v->spillOffset);
387
                        }
388
                        t->spill = false;
389
                }
390
        }
391
        cd->oper3->offset->i = spillOffset;
392
        return (ret);
393
}
394
 
395
 
396
bool Forest::IsAllTreesColored()
397
{
398
        int c;
399
        Tree *t;
400
        int K = 17;
401
 
402
        for (c = 0; c < treecount; c++) {
403
                t = trees[c];   // convenience
404
                if (t->color == K)
405
                        return (false);
406
        }
407
        return (true);
408
}

powered by: WebSVN 2.1.0

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