blob: 2cda2d7f39d9c3524ea7f619fc1473845bd295c5 [file] [log] [blame]
Ruchira Sasankaf2a64772001-08-31 20:59:58 +00001#include "llvm/CodeGen/IGNode.h"
2#include "llvm/CodeGen/SparcRegInfo.h"
3
4#include "llvm/CodeGen/Sparc.h"
5
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
229#if 0
230
231//-----------------------------------------------------------------------------
232// Float Register Class
233//-----------------------------------------------------------------------------
234
235void SparcFloatRegClass::colorIGNode(IGNode * Node,bool IsColorUsedArr[]) const
236{
237
238 /* Algorithm:
239 Record the color of all neighbors.
240
241 Single precision can use f0 - f31
242 Double precision can use f0 - f63
243
244 if LR is a double, try to allocate f32 - f63.
245 if the above attempt fails, or Value is single presion, try to allcoate
246 f0 - f31.
247
248 */
249
250 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
251
252 for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
253 IGNode *NeighIGNode = Node->getAdjIGNode(n);
254 if( NeighIGNode->hasColor() ) { // if neigh has a color
255 IsColorUsedArr[ NeighIGNode->getColor() ] = true; // record that color
256 if( NeighIGNode->getTypeID() == Type::DoubleTyID )
257 IsColorUsedArr[ (NeighIGNode->getColor()) + 1 ] = true;
258 }
259 }
260
261
262 unsigned SearchStart; // start pos of color in pref-order
263 bool ColorFound= false; // have we found a color yet?
264 unsigned c;
265
266
267 if( Node->getTypeID() == Type::DoubleTyID ) { // if value is a double
268
269 // search the double only reigon (f32 - f63)
270 for( c=32; c < 64; c+= 2) {
271 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
272 }
273
274 // search f0 - f31 region
275 if( ! ColorFound ) { // if color not found
276 for( c=0; c < 32; c+= 2) {
277 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
278 }
279 }
280
281 }
282
283 else { // value is Single
284
285 for( c=0; c < 32; c++) {
286 if( ! IsColorUsedArr[ c ] ) { ColorFound = true; break; }
287 }
288 }
289
290
291 if( ColorFound)
292 Node->setColor(c); // first color found in preferred order
293 else
294 Node->markForSpill(); // no color found - must spill
295
296
297 if( DEBUG_RA)
298 UltraSparcRegInfo::printReg( Node->getParentLR() );
299
300}
301
302#endif