1 //===-- SparcRegClassInfo.cpp - Register class def'ns for Sparc -----------===//
3 // This file defines the register classes used by the Sparc target description.
5 //===----------------------------------------------------------------------===//
7 #include "SparcRegClassInfo.h"
9 #include "../../CodeGen/RegAlloc/RegAllocCommon.h" // FIXME!
11 //-----------------------------------------------------------------------------
12 // Int Register Class - method for coloring a node in the interference graph.
15 // Record the colors/suggested colors of all neighbors.
17 // If there is a suggested color, try to allocate it
18 // If there is no call interf, try to allocate volatile, then non volatile
19 // If there is call interf, try to allocate non-volatile. If that fails
20 // try to allocate a volatile and insert save across calls
21 // If both above fail, spill.
23 //-----------------------------------------------------------------------------
24 void SparcIntRegClass::colorIGNode(IGNode * Node,
25 std::vector<bool> &IsColorUsedArr) const
27 LiveRange *LR = Node->getParentLR();
30 std::cerr << "\nColoring LR [CallInt=" << LR->isCallInterference() <<"]:";
34 if (LR->hasSuggestedColor()) {
35 unsigned SugCol = LR->getSuggestedColor();
36 if (!IsColorUsedArr[SugCol]) {
37 if (LR->isSuggestedColorUsable()) {
38 // if the suggested color is volatile, we should use it only if
39 // there are no call interferences. Otherwise, it will get spilled.
41 std::cerr << "\n -Coloring with sug color: " << SugCol;
43 LR->setColor(LR->getSuggestedColor());
46 std::cerr << "\n Couldn't alloc Sug col - LR volatile & calls interf";
48 } else if (DEBUG_RA) { // can't allocate the suggested col
49 std::cerr << "\n Could NOT allocate the suggested color (already used) ";
50 printSet(*LR); std::cerr << "\n";
54 unsigned SearchStart; // start pos of color in pref-order
55 bool ColorFound= false; // have we found a color yet?
57 //if this Node is between calls
58 if (! LR->isCallInterference()) {
59 // start with volatiles (we can allocate volatiles safely)
60 SearchStart = SparcIntRegClass::StartOfAllRegs;
62 // start with non volatiles (no non-volatiles)
63 SearchStart = SparcIntRegClass::StartOfNonVolatileRegs;
66 unsigned c=0; // color
68 // find first unused color
69 for (c=SearchStart; c < SparcIntRegClass::NumOfAvailRegs; c++) {
70 if (!IsColorUsedArr[c]) {
77 LR->setColor(c); // first color found in preffered order
78 if (DEBUG_RA) std::cerr << "\n Colored after first search with col " << c;
81 // if color is not found because of call interference
82 // try even finding a volatile color and insert save across calls
84 else if (LR->isCallInterference()) {
85 // start from 0 - try to find even a volatile this time
86 SearchStart = SparcIntRegClass::StartOfAllRegs;
88 // find first unused volatile color
89 for(c=SearchStart; c < SparcIntRegClass::StartOfNonVolatileRegs; c++) {
90 if (! IsColorUsedArr[c]) {
98 // get the live range corresponding to live var
99 // since LR span across calls, must save across calls
101 LR->markForSaveAcrossCalls();
103 std::cerr << "\n Colored after SECOND search with col " << c;
108 // If we couldn't find a color regardless of call interference - i.e., we
109 // don't have either a volatile or non-volatile color left
112 LR->markForSpill(); // no color found - must spill
116 //-----------------------------------------------------------------------------
117 // Float Register Class - method for coloring a node in the interference graph.
121 // If the LR is a double try to allocate f32 - f63
122 // If the above fails or LR is single precision
123 // If the LR does not interfere with a call
124 // start allocating from f0
125 // Else start allocating from f6
126 // If a color is still not found because LR interferes with a call
127 // Search in f0 - f6. If found mark for spill across calls.
128 // If a color is still not fond, mark for spilling
130 //----------------------------------------------------------------------------
131 void SparcFloatRegClass::colorIGNode(IGNode * Node,
132 std::vector<bool> &IsColorUsedArr) const
134 LiveRange *LR = Node->getParentLR();
136 // Mark the second color for double-precision registers:
137 // This is UGLY and should be merged into nearly identical code
138 // in RegClass::colorIGNode that handles the first color.
140 unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
141 for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
142 IGNode *NeighIGNode = Node->getAdjIGNode(n);
143 LiveRange *NeighLR = NeighIGNode->getParentLR();
145 if (NeighLR->hasColor() &&
146 NeighLR->getType() == Type::DoubleTy) {
147 IsColorUsedArr[ (NeighLR->getColor()) + 1 ] = true;
149 } else if (NeighLR->hasSuggestedColor() &&
150 NeighLR-> isSuggestedColorUsable() ) {
152 // if the neighbour can use the suggested color
153 IsColorUsedArr[ NeighLR->getSuggestedColor() ] = true;
154 if (NeighLR->getType() == Type::DoubleTy)
155 IsColorUsedArr[ (NeighLR->getSuggestedColor()) + 1 ] = true;
159 // **NOTE: We don't check for call interferences in allocating suggested
160 // color in this class since ALL registers are volatile. If this fact
161 // changes, we should change the following part
162 //- see SparcIntRegClass::colorIGNode()
164 if( LR->hasSuggestedColor() ) {
165 if( ! IsColorUsedArr[ LR->getSuggestedColor() ] ) {
166 LR->setColor( LR->getSuggestedColor() );
168 } else if (DEBUG_RA) { // can't allocate the suggested col
169 std::cerr << " Could NOT allocate the suggested color for LR ";
170 printSet(*LR); std::cerr << "\n";
175 int ColorFound = -1; // have we found a color yet?
176 bool isCallInterf = LR->isCallInterference();
178 // if value is a double - search the double only region (f32 - f63)
179 // i.e. we try to allocate f32 - f63 first for doubles since singles
180 // cannot go there. By doing that, we provide more space for singles
183 if (LR->getType() == Type::DoubleTy)
184 ColorFound = findFloatColor( LR, 32, 64, IsColorUsedArr );
186 if (ColorFound >= 0) { // if we could find a color
187 LR->setColor(ColorFound);
191 // if we didn't find a color becuase the LR was single precision or
192 // all f32-f63 range is filled, we try to allocate a register from
193 // the f0 - f31 region
195 unsigned SearchStart; // start pos of color in pref-order
197 //if this Node is between calls (i.e., no call interferences )
198 if (! isCallInterf) {
199 // start with volatiles (we can allocate volatiles safely)
200 SearchStart = SparcFloatRegClass::StartOfAllRegs;
202 // start with non volatiles (no non-volatiles)
203 SearchStart = SparcFloatRegClass::StartOfNonVolatileRegs;
206 ColorFound = findFloatColor(LR, SearchStart, 32, IsColorUsedArr);
209 if (ColorFound >= 0) { // if we could find a color
210 LR->setColor(ColorFound);
212 } else if (isCallInterf) {
213 // We are here because there is a call interference and no non-volatile
214 // color could be found.
215 // Now try to allocate even a volatile color
216 ColorFound = findFloatColor(LR, SparcFloatRegClass::StartOfAllRegs,
217 SparcFloatRegClass::StartOfNonVolatileRegs,
221 if (ColorFound >= 0) {
222 LR->setColor(ColorFound); // first color found in prefered order
223 LR->markForSaveAcrossCalls();
225 // we are here because no color could be found
226 LR->markForSpill(); // no color found - must spill
231 //-----------------------------------------------------------------------------
232 // Helper method for coloring a node of Float Reg class.
233 // Finds the first available color in the range [Start,End] depending on the
234 // type of the Node (i.e., float/double)
235 //-----------------------------------------------------------------------------
237 int SparcFloatRegClass::findFloatColor(const LiveRange *LR,
240 std::vector<bool> &IsColorUsedArr) const
242 bool ColorFound = false;
245 if (LR->getType() == Type::DoubleTy) {
246 // find first unused color for a double
247 for (c=Start; c < End ; c+= 2)
248 if (!IsColorUsedArr[c] && !IsColorUsedArr[c+1])
251 // find first unused color for a single
252 for (c = Start; c < End; c++)
253 if (!IsColorUsedArr[c])