mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 17:16:12 +00:00
Bug 844779 - IonMonkey: Make loops contiguous. r=h4writer
This commit is contained in:
parent
33b91e228f
commit
239431849c
@ -1515,6 +1515,19 @@ OptimizeMIR(MIRGenerator *mir)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make loops contiguious. We do this after GVN/UCE and range analysis,
|
||||
// which can remove CFG edges, exposing more blocks that can be moved.
|
||||
{
|
||||
AutoTraceLog log(logger, TraceLogger::MakeLoopsContiguous);
|
||||
if (!MakeLoopsContiguous(graph))
|
||||
return false;
|
||||
IonSpewPass("Make loops contiguous");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Make loops contiguous"))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Passes after this point must not move instructions; these analyses
|
||||
// depend on knowing the final order in which instructions will execute.
|
||||
|
||||
|
@ -2563,3 +2563,96 @@ jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
|
||||
script->setNeedsArgsObj(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reorder the blocks in the loop starting at the given header to be contiguous.
|
||||
static void
|
||||
MakeLoopContiguous(MIRGraph &graph, MBasicBlock *header, MBasicBlock *backedge, size_t numMarked)
|
||||
{
|
||||
MOZ_ASSERT(header->isMarked(), "Loop header is not part of loop");
|
||||
MOZ_ASSERT(backedge->isMarked(), "Loop backedge is not part of loop");
|
||||
|
||||
// If there are any blocks between the loop header and the loop backedge
|
||||
// that are not part of the loop, prepare to move them to the end. We keep
|
||||
// them in order, which preserves RPO.
|
||||
ReversePostorderIterator insertIter = graph.rpoBegin(backedge);
|
||||
insertIter++;
|
||||
MBasicBlock *insertPt = *insertIter;
|
||||
|
||||
// Visit all the blocks from the loop header to the loop backedge.
|
||||
size_t headerId = header->id();
|
||||
size_t inLoopId = headerId;
|
||||
size_t afterLoopId = inLoopId + numMarked;
|
||||
ReversePostorderIterator i = graph.rpoBegin(header);
|
||||
for (;;) {
|
||||
MBasicBlock *block = *i++;
|
||||
MOZ_ASSERT(block->id() >= header->id() && block->id() <= backedge->id(),
|
||||
"Loop backedge should be last block in loop");
|
||||
|
||||
if (block->isMarked()) {
|
||||
// This block is in the loop.
|
||||
block->unmark();
|
||||
block->setId(inLoopId++);
|
||||
// If we've reached the loop backedge, we're done!
|
||||
if (block == backedge)
|
||||
break;
|
||||
} else {
|
||||
// This block is not in the loop. Move it to the end.
|
||||
graph.moveBlockBefore(insertPt, block);
|
||||
block->setId(afterLoopId++);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(header->id() == headerId, "Loop header id changed");
|
||||
MOZ_ASSERT(inLoopId == headerId + numMarked, "Wrong number of blocks kept in loop");
|
||||
MOZ_ASSERT(afterLoopId == (insertIter != graph.rpoEnd() ? insertPt->id() : graph.numBlocks()),
|
||||
"Wrong number of blocks moved out of loop");
|
||||
}
|
||||
|
||||
// Reorder the blocks in the graph so that loops are contiguous.
|
||||
bool
|
||||
jit::MakeLoopsContiguous(MIRGraph &graph)
|
||||
{
|
||||
MBasicBlock *osrBlock = graph.osrBlock();
|
||||
Vector<MBasicBlock *, 1, IonAllocPolicy> inlooplist(graph.alloc());
|
||||
|
||||
// Visit all loop headers (in any order).
|
||||
for (MBasicBlockIterator i(graph.begin()); i != graph.end(); i++) {
|
||||
MBasicBlock *header = *i;
|
||||
if (!header->isLoopHeader())
|
||||
continue;
|
||||
|
||||
// Mark all the blocks in the loop by marking all blocks in a path
|
||||
// between the backedge and the loop header.
|
||||
MBasicBlock *backedge = header->backedge();
|
||||
size_t numMarked = 1;
|
||||
backedge->mark();
|
||||
if (!inlooplist.append(backedge))
|
||||
return false;
|
||||
do {
|
||||
MBasicBlock *block = inlooplist.popCopy();
|
||||
MOZ_ASSERT(block->id() >= header->id() && block->id() <= backedge->id(),
|
||||
"Non-OSR predecessor of loop block not between header and backedge");
|
||||
if (block == header)
|
||||
continue;
|
||||
for (size_t p = 0; p < block->numPredecessors(); p++) {
|
||||
MBasicBlock *pred = block->getPredecessor(p);
|
||||
if (pred->isMarked())
|
||||
continue;
|
||||
// Ignore paths entering the loop in the middle from an OSR
|
||||
// entry. They won't pass through the loop header and they
|
||||
// aren't part of the loop.
|
||||
if (osrBlock && osrBlock->dominates(pred) && !osrBlock->dominates(header))
|
||||
continue;
|
||||
++numMarked;
|
||||
pred->mark();
|
||||
if (!inlooplist.append(pred))
|
||||
return false;
|
||||
}
|
||||
} while (!inlooplist.empty());
|
||||
|
||||
// Move all blocks between header and backedge that aren't marked to
|
||||
// the end of the loop, making the loop itself contiguous.
|
||||
MakeLoopContiguous(graph, header, backedge, numMarked);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -31,6 +31,9 @@ enum Observability {
|
||||
bool
|
||||
EliminatePhis(MIRGenerator *mir, MIRGraph &graph, Observability observe);
|
||||
|
||||
bool
|
||||
MakeLoopsContiguous(MIRGraph &graph);
|
||||
|
||||
bool
|
||||
EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph);
|
||||
|
||||
|
@ -616,6 +616,11 @@ class MIRGraph
|
||||
blocks_.remove(block);
|
||||
blocks_.pushBack(block);
|
||||
}
|
||||
void moveBlockBefore(MBasicBlock *at, MBasicBlock *block) {
|
||||
JS_ASSERT(block->id());
|
||||
blocks_.remove(block);
|
||||
blocks_.insertBefore(at, block);
|
||||
}
|
||||
size_t numBlocks() const {
|
||||
return numBlocks_;
|
||||
}
|
||||
|
@ -137,6 +137,7 @@ namespace jit {
|
||||
_(RenumberBlocks) \
|
||||
_(DominatorTree) \
|
||||
_(PhiAnalysis) \
|
||||
_(MakeLoopsContiguous) \
|
||||
_(ApplyTypes) \
|
||||
_(ParallelSafetyAnalysis) \
|
||||
_(AliasAnalysis) \
|
||||
|
Loading…
Reference in New Issue
Block a user