bool registerSpace::allocateSpecificRegister(codeGen &gen, Register num, bool noCost) { regalloc_printf("Allocating specific register %d\n", num); debugPrint(); auto iter = registers_.find(num); if (iter == registers_.end()) { regalloc_printf("Error: register does not exist!\n"); return false; } registerSlot *reg = iter->second; if (reg->offLimits) { regalloc_printf("Error: register off limits!\n"); return false; } else if (reg->refCount > 0) { regalloc_printf("Error: register currently in use!\n"); return false; } else if (reg->liveState == registerSlot::live) { if (!spillRegister(num, gen, noCost)) { regalloc_printf("Error: specific register could not be spilled!\n"); return false; } } else if (reg->keptValue) { if (!stealRegister(num, gen, noCost)) { regalloc_printf("Error: register has cached value, unable to steal!\n"); return false; } } reg->markUsed(true); gen.markRegDefined(reg->number); regalloc_printf("Allocated register %d\n", num); return true; }
bool registerSpace::trySpecificRegister(codeGen &gen, Register num, bool noCost) { auto iter = registers_.find(num); if (iter == registers_.end()) return false; registerSlot *reg = iter->second; if (reg->offLimits) return false; else if (reg->refCount > 0) return false; else if (reg->liveState == registerSlot::live) { if (!spillRegister(num, gen, noCost)) { return false; } } else if (reg->keptValue) { return false; } reg->markUsed(true); regalloc_printf("Allocated register %d\n", num); return true; }
void VariableEvent::dumpSpillInfo(const char* name, PrintStream& out) const { out.print(name, "(", id(), ", ", spillRegister(), ", ", dataFormatToString(dataFormat()), ")"); }
Register registerSpace::getScratchRegister(codeGen &gen, pdvector<Register> &excluded, bool noCost, bool realReg) { static int num_allocs = 0; pdvector<registerSlot *> couldBeStolen; pdvector<registerSlot *> couldBeSpilled; debugPrint(); registerSlot *toUse = NULL; regalloc_printf("Allocating register: selection is %s\n", realReg ? (realRegisters_.empty() ? "GPRS" : "Real registers") : "GPRs"); pdvector<registerSlot *> ®s = (realReg ? (realRegisters_.empty() ? GPRs_ : realRegisters_ ) : GPRs_ ); regalloc_printf("%d options in registers\n", regs.size()); for (unsigned i = 0; i < regs.size(); i++) { registerSlot *reg = regs[i]; regalloc_printf("%s[%d]: getting scratch register, examining %d of %d: reg %d (%s), offLimits %d, refCount %d, liveState %s, keptValue %d\n", FILE__, __LINE__, i, regs.size(), reg->number, reg->name.c_str(), reg->offLimits, reg->refCount, (reg->liveState == registerSlot::live) ? "live" : ((reg->liveState == registerSlot::dead) ? "dead" : "spilled"), reg->keptValue); bool found = false; for (unsigned int i = 0; i < excluded.size(); ++i) { Register &ex_reg = excluded[i]; if (reg->number == ex_reg) { found = true; break; } } if (found) continue; if (reg->offLimits) continue; if (reg->refCount > 0) continue; if (reg->liveState == registerSlot::live) { // Don't do anything for now, but add to the "could be" list couldBeSpilled.push_back(reg); continue; } if (reg->keptValue) { // As above couldBeStolen.push_back(reg); continue; } // Hey, got one. toUse = reg; break; } if (toUse == NULL) { // Argh. Let's assume spilling is cheaper for (unsigned i = 0; i < couldBeSpilled.size(); i++) { if (spillRegister(couldBeSpilled[i]->number, gen, noCost)) { toUse = couldBeSpilled[i]; break; } } } // Still? if (toUse == NULL) { for (unsigned i = 0; i < couldBeStolen.size(); i++) { if (stealRegister(couldBeStolen[i]->number, gen, noCost)) { toUse = couldBeStolen[i]; break; } } } if (toUse == NULL) { // Crap. // debugPrint(); return REG_NULL; } toUse->alloc_num = num_allocs; num_allocs++; toUse->markUsed(false); gen.markRegDefined(toUse->number); return toUse->number; }