void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) { Timer timer(Timer::optimize); assertx(checkEverything(unit)); fullDCE(unit); printUnit(6, unit, " after initial DCE "); assertx(checkEverything(unit)); if (RuntimeOption::EvalHHIRTypeCheckHoisting) { doPass(unit, hoistTypeChecks, DCE::Minimal); } if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(unit, optimizePredictions, DCE::None); } if (RuntimeOption::EvalHHIRSimplification) { doPass(unit, simplifyPass, DCE::Full); doPass(unit, cleanCfg, DCE::None); } if (RuntimeOption::EvalHHIRGlobalValueNumbering) { doPass(unit, gvn, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) { doPass(unit, optimizeLoads, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) { doPass(unit, optimizeStores, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) { doPass(unit, optimizeRefcounts2, DCE::Full); } if (RuntimeOption::EvalHHIRLICM && RuntimeOption::EvalJitLoops && cfgHasLoop(unit) && kind != TransKind::Profile) { doPass(unit, optimizeLoopInvariantCode, DCE::Minimal); } doPass(unit, removeExitPlaceholders, DCE::Full); if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(unit, insertAsserts, DCE::None); } // Perform final cleanup passes to collapse any critical edges that were // split, and simplify our instructions before shipping off to codegen. doPass(unit, cleanCfg, DCE::None); if (kind != TransKind::Profile && RuntimeOption::EvalHHIRSimplification) { doPass(unit, simplifyPass, DCE::Full); } }
void optimize(IRUnit& unit, TransKind kind) { Timer timer(Timer::optimize, unit.logEntry().get_pointer()); assertx(checkEverything(unit)); fullDCE(unit); printUnit(6, unit, " after initial DCE "); assertx(checkEverything(unit)); if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(unit, optimizePredictions, DCE::None); } if (RuntimeOption::EvalHHIRSimplification) { doPass(unit, simplifyPass, DCE::Full); doPass(unit, cleanCfg, DCE::None); } if (RuntimeOption::EvalHHIRGlobalValueNumbering) { doPass(unit, gvn, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) { doPass(unit, optimizeLoads, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) { doPass(unit, optimizeStores, DCE::Full); } if (RuntimeOption::EvalHHIRPartialInlineFrameOpts) { doPass(unit, optimizeInlineReturns, DCE::Full); } doPass(unit, optimizePhis, DCE::Full); if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) { doPass(unit, optimizeRefcounts, DCE::Full); } if (RuntimeOption::EvalHHIRLICM && cfgHasLoop(unit) && kind != TransKind::Profile) { doPass(unit, optimizeLoopInvariantCode, DCE::Minimal); } doPass(unit, simplifyOrdStrIdx, DCE::Minimal); doPass(unit, removeExitPlaceholders, DCE::Full); if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(unit, insertAsserts, DCE::None); } // Perform final cleanup passes to collapse any critical edges that were // split, and simplify our instructions before shipping off to codegen. doPass(unit, cleanCfg, DCE::None); if (kind != TransKind::Profile && RuntimeOption::EvalHHIRGlobalValueNumbering) { doPass(unit, gvn, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRSimplification) { doPass(unit, simplifyPass, DCE::Full); } doPass(unit, fixBlockHints, DCE::None); }
void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) { Timer timer(Timer::optimize); assertx(checkEverything(unit)); auto const hasLoop = RuntimeOption::EvalJitLoops && cfgHasLoop(unit); auto const func = unit.entry()->front().marker().func(); auto const regionMode = pgoRegionMode(*func); auto const traceMode = kind != TransKind::Optimize || regionMode == PGORegionMode::Hottrace; // TODO (#5792564): Guard relaxation doesn't work with loops. // TODO (#6599498): Guard relaxation is broken in wholecfg mode. if (shouldHHIRRelaxGuards() && !hasLoop && traceMode) { Timer _t(Timer::optimize_relaxGuards); const bool simple = kind == TransKind::Profile && (RuntimeOption::EvalJitRegionSelector == "tracelet" || RuntimeOption::EvalJitRegionSelector == "method"); RelaxGuardsFlags flags = (RelaxGuardsFlags) (RelaxReflow | (simple ? RelaxSimple : RelaxNormal)); auto changed = relaxGuards(unit, *irBuilder.guards(), flags); if (changed) { printUnit(6, unit, "after guard relaxation"); mandatoryDCE(unit); // relaxGuards can leave unreachable preds. } if (RuntimeOption::EvalHHIRSimplification) { doPass(unit, simplifyPass, DCE::Minimal); doPass(unit, cleanCfg, DCE::None); } } fullDCE(unit); printUnit(6, unit, " after initial DCE "); assertx(checkEverything(unit)); if (RuntimeOption::EvalHHIRTypeCheckHoisting) { doPass(unit, hoistTypeChecks, DCE::None); } if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(unit, optimizePredictions, DCE::None); } if (RuntimeOption::EvalHHIRSimplification) { doPass(unit, simplifyPass, DCE::Full); doPass(unit, cleanCfg, DCE::None); } if (RuntimeOption::EvalHHIRGlobalValueNumbering) { doPass(unit, gvn, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) { doPass(unit, optimizeLoads, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) { doPass(unit, optimizeStores, DCE::Full); } if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) { doPass(unit, optimizeRefcounts2, DCE::Full); } if (RuntimeOption::EvalHHIRLICM) { if (kind != TransKind::Profile && hasLoop) { // The clean pass is just to stress lack of pre_headers for now, since // LICM is a disabled prototype pass. doPass(unit, cleanCfg, DCE::None); doPass(unit, optimizeLoopInvariantCode, DCE::Minimal); } } doPass(unit, removeExitPlaceholders, DCE::Full); if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(unit, insertAsserts, DCE::None); } }