Make class TargetMachine the common interface to all target-dependent
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9RegInfo.cpp
1 #include "llvm/CodeGen/IGNode.h"
2 #include "SparcRegInfo.h"
3 #include "SparcInternals.h"
4
5 #include "llvm/Target/Sparc.h"
6
7 //-----------------------------------------------------------------------------
8 // Int Register Class
9 //-----------------------------------------------------------------------------
10
11 void 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
102 int 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
134 void 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
230
231
232
233
234
235
236
237
238
239