blob: 0b30e5c1af6e988fbace4e19f741c1557238df61 [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