a6d7f9e060c384c7fb1fb2d742d7761dc7cb82e3
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9RegClassInfo.cpp
1 #include "llvm/CodeGen/IGNode.h"
2 #include "SparcInternals.h"
3
4 #include "llvm/Target/Sparc.h"
5
6 //-----------------------------------------------------------------------------
7 // Int Register Class
8 //-----------------------------------------------------------------------------
9
10 void 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
101 int 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
133 void 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
230
231
232
233
234
235
236
237
238