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