00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025 # ifdef DELTA_COMPILER
00026 # include "incls/_locations.cpp.incl"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 Locations::Locations(int nofArgs, int nofRegs, int nofInitialStackTmps) {
00042 assert(0 <= nofArgs, "illegal number of arguments");
00043 assert(0 <= nofRegs && nofRegs <= maxNofUsableRegisters, "too many registers required");
00044 _nofArguments = nofArgs;
00045 _nofRegisters = nofRegs;
00046 _freeList = new GrowableArray<int>(nofArgs + nofRegs + nofInitialStackTmps);
00047 int i = 0;
00048
00049 while (i < nofArgs) {
00050 _freeList->at_put_grow(i, 0);
00051 i++;
00052 }
00053
00054 while (i < nofArgs + nofRegs) {
00055 _freeList->at_put_grow(i, i-1);
00056 i++;
00057 }
00058 _freeList->at_put(nofArgs, sentinel);
00059 _firstFreeRegister = i-1;
00060
00061 while (i < nofArgs + nofRegs + nofInitialStackTmps) {
00062 _freeList->at_put_grow(i, i-1);
00063 i++;
00064 }
00065 _freeList->at_put(nofArgs + nofRegs, sentinel);
00066 _firstFreeStackTmp = i-1;
00067 verify();
00068 }
00069
00070
00071 Locations::Locations(Locations* l) {
00072 l->verify();
00073 _nofArguments = l->_nofArguments;
00074 _nofRegisters = l->_nofRegisters;
00075 _freeList = l->_freeList->copy();
00076 _firstFreeRegister = l->_firstFreeRegister;
00077 _firstFreeStackTmp = l->_firstFreeStackTmp;
00078 verify();
00079 }
00080
00081
00082 void Locations::extendTo(int nofStackTmps) {
00083 while (this->nofStackTmps() < nofStackTmps) {
00084
00085 _freeList->append(_firstFreeStackTmp);
00086 _firstFreeStackTmp = _freeList->length() - 1;
00087 }
00088 verify();
00089 }
00090
00091
00092 int Locations::allocateRegister() {
00093 int i = _firstFreeRegister;
00094 if (!isRegister(i)) fatal("out of registers");
00095 _firstFreeRegister = _freeList->at(i);
00096 _freeList->at_put(i, -1);
00097 verify();
00098 return i;
00099 }
00100
00101
00102 int Locations::allocateStackTmp() {
00103 int i = _firstFreeStackTmp;
00104 if (!isStackTmp(i)) {
00105
00106 _freeList->append(sentinel);
00107 assert(_freeList->length() <= sentinel, "sentinel too small");
00108 i = _freeList->length() - 1;
00109 }
00110 _firstFreeStackTmp = _freeList->at(i);
00111 _freeList->at_put(i, -1);
00112 verify();
00113 return i;
00114 }
00115
00116
00117 void Locations::allocate(int i) {
00118 assert(isLocation(i), "illegal location");
00119 assert(nofUses(i) == 0, "already allocated");
00120 if (isRegister(i)) {
00121 int j = _firstFreeRegister;
00122 if (j == i) {
00123
00124 _firstFreeRegister = _freeList->at(i);
00125 } else {
00126
00127 while (_freeList->at(j) != i) j = _freeList->at(j);
00128 _freeList->at_put(j, _freeList->at(i));
00129 }
00130 _freeList->at_put(i, -1);
00131 } else if (isStackTmp(i)) {
00132 int j = _firstFreeStackTmp;
00133 if (j == i) {
00134
00135 _firstFreeStackTmp = _freeList->at(i);
00136 } else {
00137
00138 while (_freeList->at(j) != i) j = _freeList->at(j);
00139 _freeList->at_put(j, _freeList->at(i));
00140 }
00141 _freeList->at_put(i, -1);
00142 } else {
00143 ShouldNotReachHere();
00144 }
00145 verify();
00146 }
00147
00148
00149 void Locations::use(int i) {
00150 assert(isLocation(i), "illegal location");
00151 assert(isArgument(i) || nofUses(i) > 0, "not yet allocated");
00152 _freeList->at_put(i, _freeList->at(i) - 1);
00153 verify();
00154 }
00155
00156
00157 void Locations::release(int i) {
00158 assert(isLocation(i), "illegal location");
00159 assert(nofUses(i) > 0, "not yet allocated");
00160 _freeList->at_put(i, _freeList->at(i) + 1);
00161 if (_freeList->at(i) == 0) {
00162
00163 if (isRegister(i)) {
00164
00165 _freeList->at_put(i, _firstFreeRegister);
00166 _firstFreeRegister = i;
00167 } else if (isStackTmp(i)) {
00168
00169 _freeList->at_put(i, _firstFreeStackTmp);
00170 _firstFreeStackTmp = i;
00171 }
00172 }
00173 verify();
00174 }
00175
00176
00177 int Locations::nofUses(int i) const {
00178 assert(isLocation(i), "illegal location");
00179 int n = _freeList->at(i);
00180 return n < 0 ? -n : 0;
00181 }
00182
00183
00184 int Locations::nofTotalUses() const {
00185 int totalUses = 0;
00186 for (int i = locationsBeg(); i < locationsEnd(); i++) totalUses += nofUses(i);
00187 return totalUses;
00188 }
00189
00190
00191 int Locations::nofFreeRegisters() const {
00192 int i = _firstFreeRegister;
00193 int n = 0;
00194 while (isRegister(i)) {
00195 i = _freeList->at(i);
00196 n++;
00197 }
00198 return n;
00199 }
00200
00201
00202 int Locations::freeRegisterMask() const {
00203 int mask = 0;
00204 for (int i = registersBeg(); i < registersEnd(); i++) {
00205 if (nofUses(i) == 0) mask |= 1 << locationAsRegister(i).number();
00206 }
00207 return mask;
00208 }
00209
00210
00211 int Locations::usedRegisterMask() const {
00212 int mask = 0;
00213 for (int i = registersBeg(); i < registersEnd(); i++) {
00214 if (nofUses(i) > 0) mask |= 1 << locationAsRegister(i).number();
00215 }
00216 return mask;
00217 }
00218
00219
00220 int Locations::argumentAsLocation(int argNo) const {
00221 assert(0 <= argNo && argNo < nofArguments(), "illegal argument no.");
00222 return argumentsBeg() + argNo;
00223 }
00224
00225
00226 int Locations::registerAsLocation(Register reg) const {
00227 assert(maxNofUsableRegisters == 6, "inconsistency - adjust this code");
00228 if (reg == eax) return registersBeg() + 0;
00229 if (reg == ebx) return registersBeg() + 1;
00230 if (reg == ecx) return registersBeg() + 2;
00231 if (reg == edx) return registersBeg() + 3;
00232 if (reg == edi) return registersBeg() + 4;
00233 if (reg == esi) return registersBeg() + 5;
00234 ShouldNotReachHere();
00235 return 0;
00236 }
00237
00238
00239 int Locations::temporaryAsLocation(int tempNo) const {
00240 assert(0 <= tempNo, "illegal temporary no.");
00241 return stackTmpsBeg() + tempNo;
00242 }
00243
00244
00245 Register Locations::locationAsRegister(int loc) const {
00246 assert(isRegister(loc), "location is not a register");
00247 switch (loc - registersBeg()) {
00248 case 0: return eax;
00249 case 1: return ebx;
00250 case 2: return ecx;
00251 case 3: return edx;
00252 case 4: return edi;
00253 case 5: return esi;
00254 default: fatal("inconsistency - adjust this code");
00255 }
00256 ShouldNotReachHere();
00257 return eax;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 int Locations::locationAsWordOffset(int loc) const {
00271 assert(isLocation(loc), "illegal location");
00272 if (isArgument(loc)) {
00273 int lastParameterOffset = 2;
00274 return lastParameterOffset + (nofArguments() - 1 - (loc - argumentsBeg()));
00275 } else if (isStackTmp(loc)) {
00276 const int firstTemporaryOffset = -1;
00277 return firstTemporaryOffset - (loc - stackTmpsBeg());
00278 }
00279 ShouldNotReachHere();
00280 return 0;
00281 }
00282
00283
00284 void Locations::print() {
00285 int len = _freeList->length();
00286 int i;
00287
00288 std->print("Locations:\n");
00289 for (i = 0; i < len; i++) {
00290 if (nofUses(i) > 0) {
00291 std->print("%d: %d uses\n", i, nofUses(i));
00292 }
00293 }
00294 std->cr();
00295
00296 std->print("Free List:\n");
00297 std->print("no. of arguments : %d\n", _nofArguments);
00298 std->print("no. of registers : %d\n", _nofRegisters);
00299 std->print("first free register : %d\n", _firstFreeRegister);
00300 std->print("first free stack loc: %d\n", _firstFreeStackTmp);
00301 for (i = 0; i < len; i++) {
00302 std->print("%d: %d\n", i, _freeList->at(i));
00303 }
00304 std->cr();
00305 }
00306
00307
00308 void Locations::verify() {
00309 if (!CompilerDebug) return;
00310 int nofFreeRegisters = 0;
00311 int nofFreeStackTmps = 0;
00312 int nofUsedLocations = 0;
00313 int i;
00314
00315 i = 0;
00316 while (i < _nofArguments) {
00317 if (_freeList->at(i) > 0) fatal("bug in argument reference counts");
00318 i++;
00319 }
00320
00321 i = _firstFreeRegister;
00322 while (i != sentinel) {
00323 if (!isRegister(i)) fatal("bug in registers free list");
00324 nofFreeRegisters++;
00325 i = _freeList->at(i);
00326 }
00327 if (nofFreeRegisters > _nofRegisters) fatal("too many free registers");
00328
00329 i = _firstFreeStackTmp;
00330 while (i != sentinel) {
00331 if (!isStackTmp(i)) fatal("bug in stack locs free list");
00332 nofFreeStackTmps++;
00333 i = _freeList->at(i);
00334 }
00335 if (nofFreeStackTmps > _freeList->length() - _nofRegisters - _nofArguments) fatal("too many free stack locs");
00336
00337 i = _freeList->length();
00338 while (i-- > _nofArguments) {
00339 if (_freeList->at(i) < 0) nofUsedLocations++;
00340 }
00341
00342 if (_nofArguments + nofFreeRegisters + nofFreeStackTmps + nofUsedLocations != _freeList->length()) fatal("locations data structure is leaking");
00343 }
00344
00345
00346 # endif