зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1238592 - IonMonkey: Optimize away any OSR fixup blocks that are ultimately unreachable. r=nbp
This commit is contained in:
Родитель
f4dbe46a7b
Коммит
ef9e8b9a0d
|
@ -200,14 +200,14 @@ FlagAllOperandsAsHavingRemovedUses(MBasicBlock* block)
|
|||
|
||||
// Flag observable operands of the entry resume point as having removed uses.
|
||||
MResumePoint* rp = block->entryResumePoint();
|
||||
do {
|
||||
while (rp) {
|
||||
for (size_t i = 0, e = rp->numOperands(); i < e; i++) {
|
||||
if (!rp->isObservableOperand(i))
|
||||
continue;
|
||||
rp->getOperand(i)->setUseRemovedUnchecked();
|
||||
}
|
||||
rp = rp->caller();
|
||||
} while (rp);
|
||||
}
|
||||
|
||||
// Flag Phi inputs of the successors has having removed uses.
|
||||
MPhiVector worklist;
|
||||
|
@ -1921,6 +1921,17 @@ jit::RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph, uint32_t numMarked
|
|||
// since we may have removed edges even if we didn't remove any blocks.
|
||||
graph.unmarkBlocks();
|
||||
} else {
|
||||
// As we are going to remove edges and basic blocks, we have to mark
|
||||
// instructions which would be needed by baseline if we were to
|
||||
// bailout.
|
||||
for (PostorderIterator it(graph.poBegin()); it != graph.poEnd();) {
|
||||
MBasicBlock* block = *it++;
|
||||
if (!block->isMarked())
|
||||
continue;
|
||||
|
||||
FlagAllOperandsAsHavingRemovedUses(block);
|
||||
}
|
||||
|
||||
// Find unmarked blocks and remove them.
|
||||
for (ReversePostorderIterator iter(graph.rpoBegin()); iter != graph.rpoEnd();) {
|
||||
MBasicBlock* block = *iter++;
|
||||
|
|
|
@ -461,6 +461,7 @@ ValueNumberer::fixupOSROnlyLoop(MBasicBlock* block, MBasicBlock* backedge)
|
|||
block->setLoopHeader(backedge);
|
||||
|
||||
JitSpew(JitSpew_GVN, " Created fake block%u", fake->id());
|
||||
hasOSRFixups_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1075,6 +1076,52 @@ ValueNumberer::visitGraph()
|
|||
return true;
|
||||
}
|
||||
|
||||
// OSR fixups serve the purpose of representing the non-OSR entry into a loop
|
||||
// when the only real entry is an OSR entry into the middle. However, if the
|
||||
// entry into the middle is subsequently folded away, the loop may actually
|
||||
// have become unreachable. Mark-and-sweep all blocks to remove all such code.
|
||||
bool ValueNumberer::cleanupOSRFixups()
|
||||
{
|
||||
// Mark.
|
||||
Vector<MBasicBlock*, 0, JitAllocPolicy> worklist(graph_.alloc());
|
||||
unsigned numMarked = 2;
|
||||
graph_.entryBlock()->mark();
|
||||
graph_.osrBlock()->mark();
|
||||
if (!worklist.append(graph_.entryBlock()) || !worklist.append(graph_.osrBlock()))
|
||||
return false;
|
||||
while (!worklist.empty()) {
|
||||
MBasicBlock* block = worklist.popCopy();
|
||||
for (size_t i = 0, e = block->numSuccessors(); i != e; ++i) {
|
||||
MBasicBlock* succ = block->getSuccessor(i);
|
||||
if (!succ->isMarked()) {
|
||||
++numMarked;
|
||||
succ->mark();
|
||||
if (!worklist.append(succ))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// The one special thing we do during this mark pass is to mark
|
||||
// loop predecessors of reachable blocks as reachable. These blocks are
|
||||
// the OSR fixups blocks which need to remain if the loop remains,
|
||||
// though they can be removed if the loop is removed.
|
||||
if (block->isLoopHeader()) {
|
||||
MBasicBlock* pred = block->loopPredecessor();
|
||||
if (!pred->isMarked() && pred->numPredecessors() == 0) {
|
||||
MOZ_ASSERT(pred->numSuccessors() == 1,
|
||||
"OSR fixup block should have exactly one successor");
|
||||
MOZ_ASSERT(pred != graph_.entryBlock(),
|
||||
"OSR fixup block shouldn't be the entry block");
|
||||
MOZ_ASSERT(pred != graph_.osrBlock(),
|
||||
"OSR fixup block shouldn't be the OSR entry block");
|
||||
pred->mark();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// And sweep.
|
||||
return RemoveUnmarkedBlocks(mir_, graph_, numMarked);
|
||||
}
|
||||
|
||||
ValueNumberer::ValueNumberer(MIRGenerator* mir, MIRGraph& graph)
|
||||
: mir_(mir), graph_(graph),
|
||||
values_(graph.alloc()),
|
||||
|
@ -1085,7 +1132,8 @@ ValueNumberer::ValueNumberer(MIRGenerator* mir, MIRGraph& graph)
|
|||
rerun_(false),
|
||||
blocksRemoved_(false),
|
||||
updateAliasAnalysis_(false),
|
||||
dependenciesBroken_(false)
|
||||
dependenciesBroken_(false),
|
||||
hasOSRFixups_(false)
|
||||
{}
|
||||
|
||||
bool
|
||||
|
@ -1162,5 +1210,10 @@ ValueNumberer::run(UpdateAliasAnalysisFlag updateAliasAnalysis)
|
|||
runs, uint64_t(graph_.numBlocks()));
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(hasOSRFixups_)) {
|
||||
cleanupOSRFixups();
|
||||
hasOSRFixups_ = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ class ValueNumberer
|
|||
bool blocksRemoved_; // Have any blocks been removed?
|
||||
bool updateAliasAnalysis_; // Do we care about AliasAnalysis?
|
||||
bool dependenciesBroken_; // Have we broken AliasAnalysis?
|
||||
bool hasOSRFixups_; // Have we created any OSR fixup blocks?
|
||||
|
||||
enum UseRemovedOption {
|
||||
DontSetUseRemoved,
|
||||
|
@ -100,6 +101,7 @@ class ValueNumberer
|
|||
bool visitBlock(MBasicBlock* block, const MBasicBlock* root);
|
||||
bool visitDominatorTree(MBasicBlock* root);
|
||||
bool visitGraph();
|
||||
bool cleanupOSRFixups();
|
||||
|
||||
public:
|
||||
ValueNumberer(MIRGenerator* mir, MIRGraph& graph);
|
||||
|
|
Загрузка…
Ссылка в новой задаче