blob: 3d43fa3d2a164e92d561fe608c13f965690349c1 [file] [log] [blame]
Chris Lattner20b1ea02001-09-14 03:47:57 +00001#include "llvm/CodeGen/IGNode.h"
Ruchira Sasanka94d86e92001-09-14 20:31:39 +00002#include "SparcRegInfo.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +00003
Ruchira Sasanka94d86e92001-09-14 20:31:39 +00004#include "llvm/Target/Sparc.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +00005
6//-----------------------------------------------------------------------------
7// Int Register Class
8//-----------------------------------------------------------------------------
9
10void SparcIntRegClass::colorIGNode(IGNode * Node, bool IsColorUsedArr[]) const
11{
12
13 /* Algorithm:
14 Record the color of all neighbors.
15
16 If there is no call interf, try to allocate volatile, then non volatile
17 If there is call interf, try to allocate non-volatile. If that fails
18 try to allocate a volatile and insert save across calls
19 If both above fail, spill.
20
21 */
22
23 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
24
25 for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
26 IGNode *NeighIGNode = Node->getAdjIGNode(n);
27 if( NeighIGNode->hasColor() ) { // if neigh has a color
28 IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
29 }
30 }
31
32
33
34 unsigned SearchStart; // start pos of color in pref-order
35 bool ColorFound= false; // have we found a color yet?
36
37 //if this Node is between calls
38 if( Node->getNumOfCallInterferences() == 0) {
39
40 // start with volatiles (we can allocate volatiles safely)
41 SearchStart = SparcIntRegOrder::StartOfAllRegs;
42 }
43 else {
44 // start with non volatiles (no non-volatiles)
45 SearchStart = SparcIntRegOrder::StartOfNonVolatileRegs;
46 }
47
48 unsigned c=0; // color
49
50 // find first unused color
51 for( c=SearchStart; c < SparcIntRegOrder::NumOfAvailRegs; c++) {
52 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
53 }
54
55 if( ColorFound)
56 Node->setColor(c); // first color found in preffered order
57
58 // if color is not found because of call interference
59 // try even finding a volatile color and insert save across calls
60 else if( Node->getNumOfCallInterferences() )
61 {
62 // start from 0 - try to find even a volatile this time
63 SearchStart = SparcIntRegOrder::StartOfAllRegs;
64
65 // find first unused volatile color
66 for(c=SearchStart; c < SparcIntRegOrder::StartOfNonVolatileRegs; c++) {
67 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
68 }
69
70 if( ColorFound) {
71 Node->setColor(c);
72 // since LR span across calls, must save across calls
73 Node->markForSaveAcrossCalls();
74 }
75
76 }
77
78 // If we couldn't find a color regardless of call interference - i.e., we
79 // don't have either a volatile or non-volatile color left
80 if( !ColorFound )
81 Node->markForSpill(); // no color found - must spill
82
83
84 if( DEBUG_RA)
85 UltraSparcRegInfo::printReg( Node->getParentLR() );
86
87}
88
89
90
91
92
93
94//-----------------------------------------------------------------------------
95// Float Register Class
96//-----------------------------------------------------------------------------
97
98// find the first available color in the range [Start,End] depending on the
99// type of the Node (i.e., float/double)
100
101int SparcFloatRegClass::findFloatColor(const IGNode *const Node, unsigned Start,
102 unsigned End,
103 bool IsColorUsedArr[] ) const
104{
105
106 bool ColorFound = false;
107 unsigned c;
108
109 if( Node->getTypeID() == Type::DoubleTyID ) {
110
111 // find first unused color for a double
112 for( c=Start; c < End ;c+= 2){
113 if( ! IsColorUsedArr[ c ] && ! IsColorUsedArr[ c+1 ])
114 { ColorFound=true; break; }
115 }
116
117 } else {
118
119 // find first unused color for a single
120 for( c=Start; c < End; c++) {
121 if( ! IsColorUsedArr[ c ] ) { ColorFound=true; break; }
122 }
123 }
124
125 if( ColorFound ) return c;
126 else return -1;
127}
128
129
130
131
132
133void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
134{
135
136 /* Algorithm:
137
138 If the LR is a double try to allocate f32 - f63
139 If the above fails or LR is single precision
140 If the LR does not interfere with a call
141 start allocating from f0
142 Else start allocating from f6
143 If a color is still not found because LR interferes with a call
144 Search in f0 - f6. If found mark for spill across calls.
145 If a color is still not fond, mark for spilling
146 */
147
148
149 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
150
151 for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
152 IGNode *NeighIGNode = Node->getAdjIGNode(n);
153 if( NeighIGNode->hasColor() ) { // if neigh has a color
154 IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
155 if( NeighIGNode->getTypeID() == Type::DoubleTyID )
156 IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;
157 }
158 }
159
160 int ColorFound = -1; // have we found a color yet?
161 unsigned NumOfCallInterf = Node->getNumOfCallInterferences();
162
163 // if value is a double - search the double only reigon (f32 - f63)
164 if( Node->getTypeID() == Type::DoubleTyID )
165 ColorFound = findFloatColor( Node, 32, 64, IsColorUsedArr );
166
167
168 if( ColorFound >= 0 ) {
169 Node->setColor(ColorFound);
170 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
171 return;
172 }
173
174 else { // the above fails or LR is single precision
175
176 unsigned SearchStart; // start pos of color in pref-order
177
178 //if this Node is between calls (i.e., no call interferences )
179 if( ! NumOfCallInterf ) {
180 // start with volatiles (we can allocate volatiles safely)
181 SearchStart = SparcFloatRegOrder::StartOfAllRegs;
182 }
183 else {
184 // start with non volatiles (no non-volatiles)
185 SearchStart = SparcFloatRegOrder::StartOfNonVolatileRegs;
186 }
187
188 ColorFound = findFloatColor( Node, SearchStart, 32, IsColorUsedArr );
189
190 }
191
192 if( ColorFound >= 0 ) {
193 Node->setColor(ColorFound);
194 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
195 return;
196 }
197
198 else if( NumOfCallInterf ) {
199
200 // We are here because there is a call interference and no non-volatile
201 // color could be found.
202 // Now try to allocate even a volatile color
203
204 ColorFound = findFloatColor( Node, SparcFloatRegOrder::StartOfAllRegs,
205 SparcFloatRegOrder::StartOfNonVolatileRegs,
206 IsColorUsedArr);
207 }
208
209 if( ColorFound >= 0 ) {
210 Node->setColor(ColorFound); // first color found in preffered order
211 Node->markForSaveAcrossCalls();
212 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
213 return;
214 }
215
216 else {
217 Node->markForSpill(); // no color found - must spill
218 if( DEBUG_RA) UltraSparcRegInfo::printReg( Node->getParentLR() );
219 }
220
221
222}
223
224
225
226
227
228
Ruchira Sasanka94d86e92001-09-14 20:31:39 +0000229
230
231
232
233
234
235
236
237
238
239
240
241
242
Chris Lattner20b1ea02001-09-14 03:47:57 +0000243#if 0
244
245//-----------------------------------------------------------------------------
246// Float Register Class
247//-----------------------------------------------------------------------------
248
249void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
250{
251
252 /* Algorithm:
253 Record the color of all neighbors.
254
255 Single precision can use f0 - f31
256 Double precision can use f0 - f63
257
258 if LR is a double, try to allocate f32 - f63.
259 if the above attempt fails, or Value is single presion, try to allcoate
260 f0 - f31.
261
262 */
263
264 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
265
266 for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
267 IGNode *NeighIGNode = Node->getAdjIGNode(n);
268 if( NeighIGNode->hasColor() ) { // if neigh has a color
269 IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
270 if( NeighIGNode->getTypeID() == Type::DoubleTyID )
271 IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;
272 }
273 }
274
275
276 unsigned SearchStart; // start pos of color in pref-order
277 bool ColorFound= false; // have we found a color yet?
278 unsigned c;
279
280
281 if( Node->getTypeID() == Type::DoubleTyID ) { // if value is a double
282
283 // search the double only reigon (f32 - f63)
284 for( c=32; c < 64; c+= 2) {
285 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
286 }
287
288 // search f0 - f31 region
289 if( ! ColorFound ) { // if color not found
290 for( c=0; c < 32; c+= 2) {
291 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
292 }
293 }
294
295 }
296
297 else { // value is Single
298
299 for( c=0; c < 32; c++) {
300 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
301 }
302 }
303
304
305 if( ColorFound)
306 Node->setColor(c); // first color found in preferred order
307 else
308 Node->markForSpill(); // no color found - must spill
309
310
311 if( DEBUG_RA)
312 UltraSparcRegInfo::printReg( Node->getParentLR() );
313
314}
315
316#endif