void optimize(IRUnit& unit, TraceBuilder& traceBuilder) { auto finishPass = [&](const char* msg) { dumpTrace(6, unit, folly::format("after {}", msg).str().c_str()); assert(checkCfg(unit)); assert(checkTmpsSpanningCalls(unit)); if (debug) forEachTraceInst(unit, assertOperandTypes); }; auto doPass = [&](void (*fn)(IRUnit&), const char* msg) { fn(unit); finishPass(msg); }; auto dce = [&](const char* which) { if (!RuntimeOption::EvalHHIRDeadCodeElim) return; eliminateDeadCode(unit); finishPass(folly::format("{} DCE", which).str().c_str()); }; if (RuntimeOption::EvalHHIRRelaxGuards) { auto changed = relaxGuards(unit, *traceBuilder.guards()); if (changed) finishPass("guard relaxation"); } if (RuntimeOption::EvalHHIRRefcountOpts) { optimizeRefcounts(unit); finishPass("refcount opts"); } dce("initial"); if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(optimizePredictions, "prediction opts"); } if (RuntimeOption::EvalHHIRExtraOptPass && (RuntimeOption::EvalHHIRCse || RuntimeOption::EvalHHIRSimplification)) { traceBuilder.reoptimize(); finishPass("reoptimize"); // Cleanup any dead code left around by CSE/Simplification // Ideally, this would be controlled by a flag returned // by optimzeTrace indicating whether DCE is necessary dce("reoptimize"); } if (RuntimeOption::EvalHHIRJumpOpts) { doPass(optimizeJumps, "jumpopts"); dce("jump opts"); } if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(insertAsserts, "RefCnt asserts"); } }
void optimizeTrace(Trace* trace, TraceBuilder* traceBuilder) { IRFactory* irFactory = traceBuilder->factory(); auto finishPass = [&](const char* msg) { dumpTrace(6, trace, folly::format("after {}", msg).str().c_str()); assert(checkCfg(trace, *irFactory)); assert(checkTmpsSpanningCalls(trace, *irFactory)); if (debug) forEachTraceInst(trace, assertOperandTypes); }; auto doPass = [&](void (*fn)(Trace*, IRFactory*), const char* msg) { fn(trace, irFactory); finishPass(msg); }; auto dce = [&](const char* which) { if (!RuntimeOption::EvalHHIRDeadCodeElim) return; eliminateDeadCode(trace, irFactory); finishPass(folly::format("{} DCE", which).str().c_str()); }; dce("initial"); if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(optimizePredictions, "prediction opts"); } if (RuntimeOption::EvalHHIRExtraOptPass && (RuntimeOption::EvalHHIRCse || RuntimeOption::EvalHHIRSimplification)) { traceBuilder->reoptimize(); finishPass("reoptimize"); // Cleanup any dead code left around by CSE/Simplification // Ideally, this would be controlled by a flag returned // by optimzeTrace indicating whether DCE is necessary dce("reoptimize"); } if (RuntimeOption::EvalHHIRJumpOpts) { doPass(optimizeJumps, "jumpopts"); dce("jump opts"); } if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(insertAsserts, "RefCnt asserts"); } }