Move spillslot field from SSATmp to linearscan pass

Spillslot is an internal field for the linear scan pass,
we don't want it in SSATmp.
Esse commit está contido em:
Edwin Smith
2013-05-04 09:23:16 -07:00
commit de Sara Golemon
commit 8985169828
2 arquivos alterados com 35 adições e 44 exclusões
+5 -20
Ver Arquivo
@@ -2072,19 +2072,6 @@ public:
SpillInfo getSpillInfo(int idx) const { assert(m_isSpilled);
return m_spillInfo[idx]; }
/*
* During register allocation, this is used to track spill locations
* that are assigned to specific SSATmps. A value of -1 is used to
* indicate no spill slot has been assigned.
*
* After register allocation, use getSpillInfo to access information
* about where we've decided to spill/fill a given SSATmp from.
* This value doesn't have any meaning outside of the linearscan
* pass.
*/
int32_t getSpillSlot() const { return m_spillSlot; }
void setSpillSlot(int32_t val) { m_spillSlot = val; }
private:
friend class IRFactory;
friend class TraceBuilder;
@@ -2093,12 +2080,11 @@ private:
// destructed, so don't add complex members.
SSATmp(uint32_t opndId, IRInstruction* i, int dstId = 0)
: m_inst(i)
, m_id(opndId)
, m_type(outputType(i, dstId))
, m_id(opndId)
, m_lastUseId(0)
, m_useCount(0)
, m_isSpilled(false)
, m_spillSlot(-1)
{
m_regs[0] = m_regs[1] = Transl::InvalidReg;
}
@@ -2106,12 +2092,11 @@ private:
SSATmp& operator=(const SSATmp&);
IRInstruction* m_inst;
const uint32_t m_id;
Type m_type; // type when defined
uint32_t m_lastUseId;
uint16_t m_useCount;
bool m_isSpilled : 1;
int32_t m_spillSlot : 31;
const uint32_t m_id;
uint32_t m_lastUseId;
uint16_t m_useCount;
bool m_isSpilled;
/*
* m_regs[0] is always the value of this SSATmp.
+30 -24
Ver Arquivo
@@ -79,10 +79,10 @@ private:
struct SlotInfo {
// the SSATmp that represents this spill location
SSATmp* m_spillTmp;
SSATmp* spillTmp;
// The latest SSATmp that has the most recent reloaded spilled value
// If it's NULL, we have to reload this slot before using it.
SSATmp* m_latestReload;
SSATmp* latestReload;
};
class PreColoringHint {
@@ -113,6 +113,7 @@ private:
void allocRegToTmp(SSATmp* ssaTmp, uint32_t index);
void freeRegsAtId(uint32_t id);
void spill(SSATmp* tmp);
void numberInstructions(const BlockList& blocks);
template<typename T> SSATmp* cns(T val) {
return m_irFactory->cns(val);
@@ -158,6 +159,11 @@ private:
BlockList m_blocks; // all basic blocks in reverse postorder
IdomVector m_idoms; // immediate dominator vector
// any tmp that has been spilled has an entry in this array with
// the spill-slot number, which is an index into m_slots[]. tmps that
// have not spilled have -1.
StateVector<SSATmp, int32_t> m_spillSlots;
// the list of native instructions in the trace sorted by instruction ID;
// i.e. a filtered list in the same order as visited by m_blocks.
smart::list<IRInstruction*> m_natives;
@@ -226,6 +232,7 @@ void LinearScan::StateSave::restore(LinearScan* ls) {
LinearScan::LinearScan(IRFactory* irFactory)
: m_irFactory(irFactory)
, m_spillSlots(irFactory, -1)
, m_jmps(irFactory, JmpList())
{
for (int i = 0; i < kNumX64Regs; i++) {
@@ -276,10 +283,10 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
smart::vector<bool> needsReloading(inst->getNumSrcs(), true);
for (uint32_t i = 0; i < inst->getNumSrcs(); ++i) {
SSATmp* tmp = inst->getSrc(i);
int32_t slotId = tmp->getSpillSlot();
int32_t slotId = m_spillSlots[tmp];
if (slotId == -1) {
needsReloading[i] = false;
} else if ((tmp = m_slots[slotId].m_latestReload)) {
} else if ((tmp = m_slots[slotId].latestReload)) {
needsReloading[i] = false;
inst->setSrc(i, tmp);
}
@@ -292,12 +299,12 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
for (uint32_t i = 0; i < inst->getNumSrcs(); ++i) {
if (needsReloading[i]) {
SSATmp* tmp = inst->getSrc(i);
int32_t slotId = tmp->getSpillSlot();
int32_t slotId = m_spillSlots[tmp];
// <tmp> is spilled, and not reloaded.
// Therefore, We need to reload the value into a new SSATmp.
// Insert the Reload instruction.
SSATmp* spillTmp = m_slots[slotId].m_spillTmp;
SSATmp* spillTmp = m_slots[slotId].spillTmp;
IRInstruction* reload = m_irFactory->gen(Reload, spillTmp);
inst->getBlock()->insert(it, reload);
@@ -306,7 +313,7 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
// Replace <tmp> with <reloadTmp> in <inst>.
SSATmp* reloadTmp = reload->getDst();
reloadTmp->setLastUseId(spillTmp->getLastUseId());
reloadTmp->setSpillSlot(slotId);
m_spillSlots[reloadTmp] = slotId;
inst->setSrc(i, reloadTmp);
// reloadTmp and tmp share the same type. Since it was spilled, it
// must be using its entire needed-count of registers.
@@ -316,7 +323,7 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
allocRegToTmp(reloadTmp, locIndex);
}
// Remember this reload tmp in case we can reuse it in later blocks.
m_slots[slotId].m_latestReload = reloadTmp;
m_slots[slotId].latestReload = reloadTmp;
dumpIR<IRInstruction, 5>(reload, "created reload");
}
}
@@ -457,7 +464,7 @@ void LinearScan::allocRegToTmp(SSATmp* ssaTmp, uint32_t index) {
// Setting the last use ID to the next native is conservative.
// Setting it to the last use before the next native would be more precise,
// but that would be more expensive to compute.
if (ssaTmp->getSpillSlot() == -1) {
if (m_spillSlots[ssaTmp] == -1) {
createSpillSlot(ssaTmp);
}
ssaTmp->setLastUseId(getNextNativeId());
@@ -879,14 +886,14 @@ void LinearScan::preAllocSpillLoc(uint32_t numSpillLocs) {
}
// Assign ids to each instruction in linear order.
void numberInstructions(const BlockList& blocks) {
void LinearScan::numberInstructions(const BlockList& blocks) {
m_spillSlots.reset();
forEachInst(
blocks,
[](IRInstruction* inst) {
for (SSATmp& dst : inst->getDsts()) {
dst.setLastUseId(0);
dst.setUseCount(0);
dst.setSpillSlot(-1);
}
}
);
@@ -1035,9 +1042,9 @@ void LinearScan::allocRegsOneTrace(BlockList::iterator& blockIt,
// clear remembered reloads that don't dominate this block
for (SlotInfo& slot : m_slots) {
if (SSATmp* reload = slot.m_latestReload) {
if (SSATmp* reload = slot.latestReload) {
if (!dominates(reload->inst()->getBlock(), block, m_idoms)) {
slot.m_latestReload = nullptr;
slot.latestReload = nullptr;
}
}
}
@@ -1068,7 +1075,7 @@ void LinearScan::allocRegsOneTrace(BlockList::iterator& blockIt,
while (begin < end) {
SlotInfo& slot = m_slots[begin++];
IRInstruction* spill = slot.m_spillTmp->inst();
IRInstruction* spill = slot.spillTmp->inst();
IRInstruction* inst = spill->getSrc(0)->inst();
Block* block = inst->getBlock();
if (!isMain && block->getTrace()->isMain()) {
@@ -1269,8 +1276,7 @@ void LinearScan::rematerializeAux() {
void LinearScan::removeUnusedSpills() {
for (SlotInfo& slot : m_slots) {
SSATmp* spillTmp = slot.m_spillTmp;
IRInstruction* spill = spillTmp->inst();
IRInstruction* spill = slot.spillTmp->inst();
if (spill->getDst()->getUseCount() == 0) {
Block* block = spill->getBlock();
block->erase(block->iteratorTo(spill));
@@ -1366,9 +1372,9 @@ void LinearScan::freeReg(RegState* reg) {
pushFreeReg(reg);
// The <tmp> shouldn't be reused any more.
SSATmp* tmp = reg->m_ssaTmp;
int32_t slotId = tmp->getSpillSlot();
int32_t slotId = m_spillSlots[tmp];
if (slotId != -1) {
m_slots[slotId].m_latestReload = nullptr;
m_slots[slotId].latestReload = nullptr;
}
reg->m_ssaTmp = nullptr;
}
@@ -1415,29 +1421,29 @@ void LinearScan::spill(SSATmp* tmp) {
it = next;
}
if (tmp->getSpillSlot() == -1) {
if (m_spillSlots[tmp] == -1) {
// <tmp> hasn't been spilled before.
// We need to create a new spill slot for it.
uint32_t slotId = createSpillSlot(tmp);
// createSpillSlot sets the latest reloaded value of slotId to tmp.
// Here, we need reset this value because tmp is spilled and no longer
// synced with memory.
m_slots[slotId].m_latestReload = nullptr;
m_slots[slotId].latestReload = nullptr;
}
}
// Create a spill slot for <tmp>.
uint32_t LinearScan::createSpillSlot(SSATmp* tmp) {
uint32_t slotId = m_slots.size();
tmp->setSpillSlot(slotId);
m_spillSlots[tmp] = slotId;
IRInstruction* spillInst = m_irFactory->gen(Spill, tmp);
SSATmp* spillTmp = spillInst->getDst();
SlotInfo si;
si.m_spillTmp = spillTmp;
si.m_latestReload = tmp;
si.spillTmp = spillTmp;
si.latestReload = tmp;
m_slots.push_back(si);
// The spill slot inherits the last use ID of the spilled tmp.
si.m_spillTmp->setLastUseId(tmp->getLastUseId());
si.spillTmp->setLastUseId(tmp->getLastUseId());
return slotId;
}