mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 844779 - IonMonkey: Make loops contiguous. r=h4writer
This commit is contained in:
parent
4482fb3908
commit
cdb1998179
@ -1515,6 +1515,19 @@ OptimizeMIR(MIRGenerator *mir)
|
|||||||
return false;
|
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
|
// Passes after this point must not move instructions; these analyses
|
||||||
// depend on knowing the final order in which instructions will execute.
|
// depend on knowing the final order in which instructions will execute.
|
||||||
|
|
||||||
|
@ -2563,3 +2563,96 @@ jit::AnalyzeArgumentsUsage(JSContext *cx, JSScript *scriptArg)
|
|||||||
script->setNeedsArgsObj(false);
|
script->setNeedsArgsObj(false);
|
||||||
return true;
|
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
|
bool
|
||||||
EliminatePhis(MIRGenerator *mir, MIRGraph &graph, Observability observe);
|
EliminatePhis(MIRGenerator *mir, MIRGraph &graph, Observability observe);
|
||||||
|
|
||||||
|
bool
|
||||||
|
MakeLoopsContiguous(MIRGraph &graph);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph);
|
EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph);
|
||||||
|
|
||||||
|
@ -616,6 +616,11 @@ class MIRGraph
|
|||||||
blocks_.remove(block);
|
blocks_.remove(block);
|
||||||
blocks_.pushBack(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 {
|
size_t numBlocks() const {
|
||||||
return numBlocks_;
|
return numBlocks_;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ namespace jit {
|
|||||||
_(RenumberBlocks) \
|
_(RenumberBlocks) \
|
||||||
_(DominatorTree) \
|
_(DominatorTree) \
|
||||||
_(PhiAnalysis) \
|
_(PhiAnalysis) \
|
||||||
|
_(MakeLoopsContiguous) \
|
||||||
_(ApplyTypes) \
|
_(ApplyTypes) \
|
||||||
_(ParallelSafetyAnalysis) \
|
_(ParallelSafetyAnalysis) \
|
||||||
_(AliasAnalysis) \
|
_(AliasAnalysis) \
|
||||||
|
Loading…
Reference in New Issue
Block a user