Esempio n. 1
0
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");
  }
}
Esempio n. 2
0
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");
  }
}