зеркало из 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.
|
// Flag observable operands of the entry resume point as having removed uses.
|
||||||
MResumePoint* rp = block->entryResumePoint();
|
MResumePoint* rp = block->entryResumePoint();
|
||||||
do {
|
while (rp) {
|
||||||
for (size_t i = 0, e = rp->numOperands(); i < e; i++) {
|
for (size_t i = 0, e = rp->numOperands(); i < e; i++) {
|
||||||
if (!rp->isObservableOperand(i))
|
if (!rp->isObservableOperand(i))
|
||||||
continue;
|
continue;
|
||||||
rp->getOperand(i)->setUseRemovedUnchecked();
|
rp->getOperand(i)->setUseRemovedUnchecked();
|
||||||
}
|
}
|
||||||
rp = rp->caller();
|
rp = rp->caller();
|
||||||
} while (rp);
|
}
|
||||||
|
|
||||||
// Flag Phi inputs of the successors has having removed uses.
|
// Flag Phi inputs of the successors has having removed uses.
|
||||||
MPhiVector worklist;
|
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.
|
// since we may have removed edges even if we didn't remove any blocks.
|
||||||
graph.unmarkBlocks();
|
graph.unmarkBlocks();
|
||||||
} else {
|
} 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.
|
// Find unmarked blocks and remove them.
|
||||||
for (ReversePostorderIterator iter(graph.rpoBegin()); iter != graph.rpoEnd();) {
|
for (ReversePostorderIterator iter(graph.rpoBegin()); iter != graph.rpoEnd();) {
|
||||||
MBasicBlock* block = *iter++;
|
MBasicBlock* block = *iter++;
|
||||||
|
|
|
@ -461,6 +461,7 @@ ValueNumberer::fixupOSROnlyLoop(MBasicBlock* block, MBasicBlock* backedge)
|
||||||
block->setLoopHeader(backedge);
|
block->setLoopHeader(backedge);
|
||||||
|
|
||||||
JitSpew(JitSpew_GVN, " Created fake block%u", fake->id());
|
JitSpew(JitSpew_GVN, " Created fake block%u", fake->id());
|
||||||
|
hasOSRFixups_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,6 +1076,52 @@ ValueNumberer::visitGraph()
|
||||||
return true;
|
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)
|
ValueNumberer::ValueNumberer(MIRGenerator* mir, MIRGraph& graph)
|
||||||
: mir_(mir), graph_(graph),
|
: mir_(mir), graph_(graph),
|
||||||
values_(graph.alloc()),
|
values_(graph.alloc()),
|
||||||
|
@ -1085,7 +1132,8 @@ ValueNumberer::ValueNumberer(MIRGenerator* mir, MIRGraph& graph)
|
||||||
rerun_(false),
|
rerun_(false),
|
||||||
blocksRemoved_(false),
|
blocksRemoved_(false),
|
||||||
updateAliasAnalysis_(false),
|
updateAliasAnalysis_(false),
|
||||||
dependenciesBroken_(false)
|
dependenciesBroken_(false),
|
||||||
|
hasOSRFixups_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1162,5 +1210,10 @@ ValueNumberer::run(UpdateAliasAnalysisFlag updateAliasAnalysis)
|
||||||
runs, uint64_t(graph_.numBlocks()));
|
runs, uint64_t(graph_.numBlocks()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MOZ_UNLIKELY(hasOSRFixups_)) {
|
||||||
|
cleanupOSRFixups();
|
||||||
|
hasOSRFixups_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ class ValueNumberer
|
||||||
bool blocksRemoved_; // Have any blocks been removed?
|
bool blocksRemoved_; // Have any blocks been removed?
|
||||||
bool updateAliasAnalysis_; // Do we care about AliasAnalysis?
|
bool updateAliasAnalysis_; // Do we care about AliasAnalysis?
|
||||||
bool dependenciesBroken_; // Have we broken AliasAnalysis?
|
bool dependenciesBroken_; // Have we broken AliasAnalysis?
|
||||||
|
bool hasOSRFixups_; // Have we created any OSR fixup blocks?
|
||||||
|
|
||||||
enum UseRemovedOption {
|
enum UseRemovedOption {
|
||||||
DontSetUseRemoved,
|
DontSetUseRemoved,
|
||||||
|
@ -100,6 +101,7 @@ class ValueNumberer
|
||||||
bool visitBlock(MBasicBlock* block, const MBasicBlock* root);
|
bool visitBlock(MBasicBlock* block, const MBasicBlock* root);
|
||||||
bool visitDominatorTree(MBasicBlock* root);
|
bool visitDominatorTree(MBasicBlock* root);
|
||||||
bool visitGraph();
|
bool visitGraph();
|
||||||
|
bool cleanupOSRFixups();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ValueNumberer(MIRGenerator* mir, MIRGraph& graph);
|
ValueNumberer(MIRGenerator* mir, MIRGraph& graph);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче