Eliminate unconditional jump from main trace to exit trace before DCE

I ran into this problem with the region JIT.  Without this fix, an
IncRef may appear to be dead in the main trace during ref-counting
optimization (performed along with DCE).
Esse commit está contido em:
Guilherme Ottoni
2013-07-19 10:02:11 -07:00
commit de Sara Golemon
commit 0ae5908b61
3 arquivos alterados com 34 adições e 23 exclusões
+14 -4
Ver Arquivo
@@ -296,10 +296,14 @@ void optimizeRefCount(IRTrace* trace, DceState& state, UseCounts& uses) {
/*
* Sink IncRefs consumed off trace.
* Assumptions: Flow graph must not have critical edges, and the instructions
* have been annotated already by the DCE algorithm. This pass uses
* the REFCOUNT_CONSUMED* flags to copy IncRefs from the main trace to each
* exit trace that consumes the incremented pointer.
* Assumptions:
* a) Flow graph must not have critical edges.
* b) The main trace doesn't unconditionally jump to an exit trace.
* c) The instructions have been annotated already by the DCE algorithm.
* This pass uses the REFCOUNT_CONSUMED* flags to copy IncRefs from the
* main trace to each exit trace that consumes the incremented pointer.
*
* Algorithm:
* 1. toSink = {}
* 2. iterate forwards over the main trace:
* * when a movable IncRef is found, insert into toSink list and mark
@@ -316,6 +320,8 @@ void optimizeRefCount(IRTrace* trace, DceState& state, UseCounts& uses) {
void sinkIncRefs(IRTrace* trace, IRFactory* irFactory, DceState& state) {
assert(trace->isMain());
assert(trace->back()->back()->op() != Jmp_);
auto copyPropTrace = [] (IRTrace* trace) {
forEachInst(trace, copyProp);
};
@@ -542,6 +548,10 @@ void eliminateDeadCode(IRTrace* trace, IRFactory* irFactory) {
BlockList blocks = removeUnreachable(trace, irFactory);
removeEmptyExitTraces();
// Ensure that main trace doesn't unconditionally jump to an exit
// trace. This invariant is needed by the ref-counting optimization.
eliminateUnconditionalJump(trace, irFactory);
// mark the essential instructions and add them to the initial
// work list; this will also mark reachable exit traces. All
// other instructions marked dead.
+18 -18
Ver Arquivo
@@ -26,25 +26,9 @@ namespace HPHP { namespace JIT {
TRACE_SET_MOD(hhir);
namespace {
//////////////////////////////////////////////////////////////////////
// If main trace ends with an unconditional jump, and the target is not
// reached by any other branch, then copy the target of the jump to the
// end of the trace
void elimUnconditionalJump(IRTrace* trace, IRFactory* irFactory) {
Block* lastBlock = trace->back();
auto lastInst = lastBlock->backIter(); // iterator to last instruction
IRInstruction& jmp = *lastInst;
if (jmp.op() == Jmp_ && jmp.taken()->numPreds() == 1) {
Block* target = jmp.taken();
lastBlock->splice(lastInst, target, target->skipHeader(), target->end(),
lastInst->marker());
jmp.convertToNop(); // unlink it from its Edge
lastBlock->erase(lastInst); // delete the jmp
}
}
namespace {
Block* findMainExitBlock(IRTrace* trace, IRFactory* irFactory) {
assert(trace->isMain());
@@ -214,8 +198,24 @@ void optimizeSideExits(IRTrace* trace, IRFactory* irFactory) {
//////////////////////////////////////////////////////////////////////
// If main trace ends with an unconditional jump, and the target is not
// reached by any other branch, then copy the target of the jump to the
// end of the trace
void eliminateUnconditionalJump(IRTrace* trace, IRFactory* irFactory) {
Block* lastBlock = trace->back();
auto lastInst = lastBlock->backIter(); // iterator to last instruction
IRInstruction& jmp = *lastInst;
if (jmp.op() == Jmp_ && jmp.taken()->numPreds() == 1) {
Block* target = jmp.taken();
lastBlock->splice(lastInst, target, target->skipHeader(), target->end(),
lastInst->marker());
jmp.convertToNop(); // unlink it from its Edge
lastBlock->erase(lastInst); // delete the jmp
}
}
void optimizeJumps(IRTrace* trace, IRFactory* irFactory) {
elimUnconditionalJump(trace, irFactory);
eliminateUnconditionalJump(trace, irFactory);
if (RuntimeOption::EvalHHIRDirectExit) {
optimizeCondTraceExit(trace, irFactory);
+2 -1
Ver Arquivo
@@ -32,8 +32,9 @@ class IRInstruction;
*/
void optimizeMemoryAccesses(IRTrace*, IRFactory*);
void optimizePredictions(IRTrace*, IRFactory*);
void eliminateDeadCode(IRTrace*, IRFactory*);
void optimizeJumps(IRTrace*, IRFactory*);
void eliminateUnconditionalJump(IRTrace*, IRFactory*);
void eliminateDeadCode(IRTrace*, IRFactory*);
/*
* Run all the optimization passes.