Bug 1058095 - IonMonkey: Move fields from InstructionData into LInstruction r=bhackett

This commit is contained in:
Dan Gohman 2014-10-10 21:21:35 -07:00
parent cf2b0c46a6
commit e29bfc0ecb
6 changed files with 84 additions and 98 deletions

View File

@ -249,7 +249,7 @@ BacktrackingAllocator::tryGroupReusedRegister(uint32_t def, uint32_t use)
return true;
}
LiveInterval *interval = usedReg.getInterval(0);
LBlock *block = insData[reg.ins()].block();
LBlock *block = reg.ins()->block();
// The input's lifetime must end within the same block as the definition,
// otherwise it could live on in phis elsewhere.
@ -263,7 +263,7 @@ BacktrackingAllocator::tryGroupReusedRegister(uint32_t def, uint32_t use)
continue;
LUse *use = iter->use;
if (FindReusingDefinition(insData[iter->pos].ins(), use)) {
if (FindReusingDefinition(insData[iter->pos], use)) {
reg.setMustCopyInput();
return true;
}
@ -958,16 +958,16 @@ BacktrackingAllocator::resolveControlFlow()
continue;
CodePosition start = interval->start();
InstructionData *data = &insData[start];
if (interval->start() > entryOf(data->block())) {
MOZ_ASSERT(start == inputOf(data->ins()) || start == outputOf(data->ins()));
LInstruction *ins = insData[start];
if (interval->start() > entryOf(ins->block())) {
MOZ_ASSERT(start == inputOf(ins) || start == outputOf(ins));
LiveInterval *prevInterval = reg->intervalFor(start.previous());
if (start.subpos() == CodePosition::INPUT) {
if (!moveInput(inputOf(data->ins()), prevInterval, interval, reg->type()))
if (!moveInput(inputOf(ins), prevInterval, interval, reg->type()))
return false;
} else {
if (!moveAfter(outputOf(data->ins()), prevInterval, interval, reg->type()))
if (!moveAfter(outputOf(ins), prevInterval, interval, reg->type()))
return false;
}
}
@ -1119,7 +1119,7 @@ BacktrackingAllocator::reifyAllocations()
// For any uses which feed into MUST_REUSE_INPUT definitions,
// add copies if the use and def have different allocations.
LInstruction *ins = insData[iter->pos].ins();
LInstruction *ins = insData[iter->pos];
if (LDefinition *def = FindReusingDefinition(ins, alloc)) {
LiveInterval *outputInterval =
vregs[def->virtualRegister()].intervalFor(outputOf(ins));
@ -1403,12 +1403,12 @@ BacktrackingAllocator::minimalInterval(const LiveInterval *interval, bool *pfixe
if (fixed)
return false;
fixed = true;
if (minimalUse(interval, insData[iter->pos].ins()))
if (minimalUse(interval, insData[iter->pos]))
minimal = true;
break;
case LUse::REGISTER:
if (minimalUse(interval, insData[iter->pos].ins()))
if (minimalUse(interval, insData[iter->pos]))
minimal = true;
break;
@ -1540,7 +1540,7 @@ BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, Live
// If the definition of the interval is in a register, consider that a
// register use too for our purposes here.
if (isRegisterDefinition(interval)) {
CodePosition spillStart = minimalDefEnd(insData[interval->start()].ins()).next();
CodePosition spillStart = minimalDefEnd(insData[interval->start()]).next();
if (!conflict || spillStart < conflict->start()) {
lastUse = lastRegisterFrom = interval->start();
lastRegisterTo = spillStart;
@ -1552,7 +1552,7 @@ BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, Live
iter++)
{
LUse *use = iter->use;
LInstruction *ins = insData[iter->pos].ins();
LInstruction *ins = insData[iter->pos];
// Uses in the interval should be sorted.
MOZ_ASSERT(iter->pos >= lastUse);
@ -1609,7 +1609,7 @@ BacktrackingAllocator::trySplitBeforeFirstRegisterUse(LiveInterval *interval, Li
iter++)
{
LUse *use = iter->use;
LInstruction *ins = insData[iter->pos].ins();
LInstruction *ins = insData[iter->pos];
if (!conflict || outputOf(ins) >= conflict->end()) {
if (isRegisterUse(use, ins, /* considerCopy = */ true)) {
@ -1661,7 +1661,7 @@ BacktrackingAllocator::splitAtAllRegisterUses(LiveInterval *interval)
// Treat the definition of the interval as a register use so that it
// can be split and spilled ASAP.
CodePosition from = interval->start();
CodePosition to = minimalDefEnd(insData[from].ins()).next();
CodePosition to = minimalDefEnd(insData[from]).next();
if (!addLiveInterval(newIntervals, vreg, spillInterval, from, to))
return false;
spillStart = to;
@ -1680,7 +1680,7 @@ BacktrackingAllocator::splitAtAllRegisterUses(LiveInterval *interval)
iter != interval->usesEnd();
iter++)
{
LInstruction *ins = insData[iter->pos].ins();
LInstruction *ins = insData[iter->pos];
if (iter->pos < spillStart) {
newIntervals.back()->addUseAtEnd(new(alloc()) UsePosition(iter->use, iter->pos));
} else if (isRegisterUse(iter->use, ins)) {
@ -1748,7 +1748,7 @@ BacktrackingAllocator::splitAt(LiveInterval *interval,
// Don't spill the interval until after the end of its definition.
CodePosition spillStart = interval->start();
if (isRegisterDefinition(interval))
spillStart = minimalDefEnd(insData[interval->start()].ins()).next();
spillStart = minimalDefEnd(insData[interval->start()]).next();
uint32_t vreg = interval->vreg();
@ -1782,7 +1782,7 @@ BacktrackingAllocator::splitAt(LiveInterval *interval,
size_t activeSplitPosition = NextSplitPosition(0, splitPositions, interval->start());
for (UsePositionIterator iter(interval->usesBegin()); iter != interval->usesEnd(); iter++) {
LInstruction *ins = insData[iter->pos].ins();
LInstruction *ins = insData[iter->pos];
if (iter->pos < spillStart) {
newIntervals.back()->addUseAtEnd(new(alloc()) UsePosition(iter->use, iter->pos));
activeSplitPosition = NextSplitPosition(activeSplitPosition, splitPositions, iter->pos);
@ -1820,7 +1820,7 @@ BacktrackingAllocator::splitAt(LiveInterval *interval,
else
end = newInterval->usesBack()->pos.next();
} else {
start = inputOf(insData[newInterval->usesBegin()->pos].ins());
start = inputOf(insData[newInterval->usesBegin()->pos]);
end = newInterval->usesBack()->pos.next();
}
for (; activeRange > 0; --activeRange) {

View File

@ -110,7 +110,8 @@ LBlock::init(TempAllocator &alloc)
if (!inputs)
return false;
new (&phis_[phiIndex++]) LPhi(phi, inputs);
LPhi *lphi = new (&phis_[phiIndex++]) LPhi(phi, inputs);
lphi->setBlock(this);
}
}
return true;

View File

@ -611,6 +611,10 @@ class LInstruction
// to hold either gcthings or Values.
LSafepoint *safepoint_;
LBlock *block_;
LMoveGroup *inputMoves_;
LMoveGroup *movesAfter_;
protected:
MDefinition *mir_;
@ -618,6 +622,9 @@ class LInstruction
: id_(0),
snapshot_(nullptr),
safepoint_(nullptr),
block_(nullptr),
inputMoves_(nullptr),
movesAfter_(nullptr),
mir_(nullptr)
{ }
@ -697,6 +704,24 @@ class LInstruction
/* Untyped MIR for this op. Prefer mir() methods in subclasses. */
return mir_;
}
LBlock *block() const {
return block_;
}
void setBlock(LBlock *block) {
block_ = block;
}
LMoveGroup *inputMoves() const {
return inputMoves_;
}
void setInputMoves(LMoveGroup *moves) {
inputMoves_ = moves;
}
LMoveGroup *movesAfter() const {
return movesAfter_;
}
void setMovesAfter(LMoveGroup *moves) {
movesAfter_ = moves;
}
void assignSnapshot(LSnapshot *snapshot);
void initSafepoint(TempAllocator &alloc);
@ -778,6 +803,7 @@ class LBlock
bool init(TempAllocator &alloc);
void add(LInstruction *ins) {
ins->setBlock(this);
instructions_.pushBack(ins);
}
size_t numPhis() const {

View File

@ -420,7 +420,7 @@ LinearScanAllocator::reifyAllocations()
return false;
}
}
else if (interval->start() > entryOf(insData[interval->start()].block()) &&
else if (interval->start() > entryOf(insData[interval->start()]->block()) &&
(!reg->canonicalSpill() ||
(reg->canonicalSpill() == interval->getAllocation() &&
!reg->mustSpillAtDefinition()) ||
@ -437,15 +437,15 @@ LinearScanAllocator::reifyAllocations()
// register.
LiveInterval *prevInterval = reg->getInterval(interval->index() - 1);
CodePosition start = interval->start();
InstructionData *data = &insData[start];
LInstruction *ins = insData[start];
MOZ_ASSERT(start == inputOf(data->ins()) || start == outputOf(data->ins()));
MOZ_ASSERT(start == inputOf(ins) || start == outputOf(ins));
if (start.subpos() == CodePosition::INPUT) {
if (!moveInput(inputOf(data->ins()), prevInterval, interval, reg->type()))
if (!moveInput(inputOf(ins), prevInterval, interval, reg->type()))
return false;
} else {
if (!moveAfter(outputOf(data->ins()), prevInterval, interval, reg->type()))
if (!moveAfter(outputOf(ins), prevInterval, interval, reg->type()))
return false;
}
@ -789,7 +789,7 @@ LinearScanAllocator::assign(LAllocation allocation)
// If this spill is inside a loop, and the definition is outside
// the loop, instead move the spill to outside the loop.
InstructionData *other = &insData[current->start()];
LInstruction *other = insData[current->start()];
uint32_t loopDepthAtDef = reg->block()->mir()->loopDepth();
uint32_t loopDepthAtSpill = other->block()->mir()->loopDepth();
if (loopDepthAtSpill > loopDepthAtDef)

View File

@ -474,10 +474,10 @@ RegisterAllocator::init()
for (size_t i = 0; i < graph.numBlocks(); i++) {
LBlock *block = graph.getBlock(i);
for (LInstructionIterator ins = block->begin(); ins != block->end(); ins++)
insData[*ins].init(*ins, block);
insData[ins->id()] = *ins;
for (size_t j = 0; j < block->numPhis(); j++) {
LPhi *phi = block->getPhi(j);
insData[phi].init(phi, block);
insData[phi->id()] = phi;
}
}
@ -485,38 +485,38 @@ RegisterAllocator::init()
}
LMoveGroup *
RegisterAllocator::getInputMoveGroup(uint32_t ins)
RegisterAllocator::getInputMoveGroup(uint32_t id)
{
InstructionData *data = &insData[ins];
MOZ_ASSERT(!data->ins()->isPhi());
MOZ_ASSERT(!data->ins()->isLabel());
LInstruction *ins = insData[id];
MOZ_ASSERT(!ins->isPhi());
MOZ_ASSERT(!ins->isLabel());
if (data->inputMoves())
return data->inputMoves();
if (ins->inputMoves())
return ins->inputMoves();
LMoveGroup *moves = LMoveGroup::New(alloc());
data->setInputMoves(moves);
data->block()->insertBefore(data->ins(), moves);
ins->setInputMoves(moves);
ins->block()->insertBefore(ins, moves);
return moves;
}
LMoveGroup *
RegisterAllocator::getMoveGroupAfter(uint32_t ins)
RegisterAllocator::getMoveGroupAfter(uint32_t id)
{
InstructionData *data = &insData[ins];
MOZ_ASSERT(!data->ins()->isPhi());
LInstruction *ins = insData[id];
MOZ_ASSERT(!ins->isPhi());
if (data->movesAfter())
return data->movesAfter();
if (ins->movesAfter())
return ins->movesAfter();
LMoveGroup *moves = LMoveGroup::New(alloc());
data->setMovesAfter(moves);
ins->setMovesAfter(moves);
if (data->ins()->isLabel())
data->block()->insertAfter(data->block()->getEntryMoveGroup(alloc()), moves);
if (ins->isLabel())
ins->block()->insertAfter(ins->block()->getEntryMoveGroup(alloc()), moves);
else
data->block()->insertAfter(data->ins(), moves);
ins->block()->insertAfter(ins, moves);
return moves;
}

View File

@ -217,45 +217,10 @@ class CodePosition
}
};
// Structure to track moves inserted before or after an instruction.
class InstructionData
{
LInstruction *ins_;
LBlock *block_;
LMoveGroup *inputMoves_;
LMoveGroup *movesAfter_;
public:
void init(LInstruction *ins, LBlock *block) {
MOZ_ASSERT(!ins_);
MOZ_ASSERT(!block_);
ins_ = ins;
block_ = block;
}
LInstruction *ins() const {
return ins_;
}
LBlock *block() const {
return block_;
}
void setInputMoves(LMoveGroup *moves) {
inputMoves_ = moves;
}
LMoveGroup *inputMoves() const {
return inputMoves_;
}
void setMovesAfter(LMoveGroup *moves) {
movesAfter_ = moves;
}
LMoveGroup *movesAfter() const {
return movesAfter_;
}
};
// Structure to track all moves inserted next to instructions in a graph.
class InstructionDataMap
{
FixedList<InstructionData> insData_;
FixedList<LInstruction *> insData_;
public:
InstructionDataMap()
@ -265,26 +230,20 @@ class InstructionDataMap
bool init(MIRGenerator *gen, uint32_t numInstructions) {
if (!insData_.init(gen->alloc(), numInstructions))
return false;
memset(&insData_[0], 0, sizeof(InstructionData) * numInstructions);
memset(&insData_[0], 0, sizeof(LInstruction *) * numInstructions);
return true;
}
InstructionData &operator[](CodePosition pos) {
LInstruction *&operator[](CodePosition pos) {
return operator[](pos.ins());
}
const InstructionData &operator[](CodePosition pos) const {
LInstruction *const &operator[](CodePosition pos) const {
return operator[](pos.ins());
}
InstructionData &operator[](LInstruction *ins) {
return operator[](ins->id());
}
const InstructionData &operator[](LInstruction *ins) const {
return operator[](ins->id());
}
InstructionData &operator[](uint32_t ins) {
LInstruction *&operator[](uint32_t ins) {
return insData_[ins];
}
const InstructionData &operator[](uint32_t ins) const {
LInstruction *const &operator[](uint32_t ins) const {
return insData_[ins];
}
};
@ -336,8 +295,8 @@ class RegisterAllocator
// All phis in a block write their outputs after all of them have
// read their inputs. Consequently, it doesn't make sense to talk
// about code positions in the middle of a series of phis.
if (insData[pos].ins()->isPhi()) {
while (insData[pos + 1].ins()->isPhi())
if (insData[pos]->isPhi()) {
while (insData[pos + 1]->isPhi())
++pos;
}
return CodePosition(pos, CodePosition::OUTPUT);
@ -349,8 +308,8 @@ class RegisterAllocator
// All phis in a block read their inputs before any of them write their
// outputs. Consequently, it doesn't make sense to talk about code
// positions in the middle of a series of phis.
if (insData[pos].ins()->isPhi()) {
while (pos > 0 && insData[pos - 1].ins()->isPhi())
if (insData[pos]->isPhi()) {
while (pos > 0 && insData[pos - 1]->isPhi())
--pos;
}
return CodePosition(pos, CodePosition::INPUT);
@ -365,8 +324,8 @@ class RegisterAllocator
return outputOf(block->lastId());
}
LMoveGroup *getInputMoveGroup(uint32_t ins);
LMoveGroup *getMoveGroupAfter(uint32_t ins);
LMoveGroup *getInputMoveGroup(uint32_t id);
LMoveGroup *getMoveGroupAfter(uint32_t id);
LMoveGroup *getInputMoveGroup(CodePosition pos) {
return getInputMoveGroup(pos.ins());
@ -381,7 +340,7 @@ class RegisterAllocator
// If moves are introduced between the instruction and the OSI point then
// safepoint information for the instruction may be incorrect.
while (true) {
LInstruction *next = insData[outputOf(ins).next()].ins();
LInstruction *next = insData[ins->id() + 1];
if (!next->isNop() && !next->isOsiPoint())
break;
ins = next;