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