예제 #1
0
/*
 * Records any type/reffiness predictions we depend on in the region. Guards
 * for locals and stack cells that are not used will be eliminated by the call
 * to relaxGuards.
 */
void RegionFormer::recordDependencies() {
  // Record the incrementally constructed reffiness predictions.
  assertx(!m_region->empty());
  auto& frontBlock = *m_region->blocks().front();
  for (auto const& dep : m_refDeps.m_arMap) {
    frontBlock.addReffinessPred(m_startSk, {dep.second.m_mask,
                                            dep.second.m_vals,
                                            dep.first});
  }

  // Relax guards and record the ones that survived.
  auto& firstBlock = *m_region->blocks().front();
  auto blockStart = firstBlock.start();
  auto& unit = m_irgs.unit;
  auto const doRelax = RuntimeOption::EvalHHIRRelaxGuards;
  bool changed = false;
  if (doRelax) {
    Timer _t(Timer::selectTracelet_relaxGuards);
    // The IR is going to be discarded immediately, so skip reflowing
    // the types in relaxGuards to save JIT time.
    RelaxGuardsFlags flags = m_profiling ? RelaxSimple : RelaxNormal;
    changed = relaxGuards(unit, *m_irgs.irb->guards(), flags);
  }

  auto guardMap = std::map<RegionDesc::Location,Type>{};
  ITRACE(2, "Visiting guards\n");
  visitGuards(unit, [&](const RegionDesc::Location& loc, Type type) {
    Trace::Indent indent;
    ITRACE(3, "{}: {}\n", show(loc), type);
    if (type <= TCls) return;
    auto inret = guardMap.insert(std::make_pair(loc, type));
    if (inret.second) return;
    auto& oldTy = inret.first->second;
    if (oldTy == TGen) {
      // This is the case that we see an inner type prediction for a GuardLoc
      // that got relaxed to Gen.
      return;
    }
    oldTy &= type;
  });

  for (auto& kv : guardMap) {
    if (kv.second == TGen) {
      // Guard was relaxed to Gen---don't record it.
      continue;
    }
    auto const preCond = RegionDesc::TypedLocation { kv.first, kv.second };
    ITRACE(1, "selectTracelet adding guard {}\n", show(preCond));
    firstBlock.addPreCondition(blockStart, preCond);
  }

  if (changed) {
    printUnit(3, unit, " after guard relaxation ", nullptr,
              m_irgs.irb->guards());
  }

}
예제 #2
0
/*
 * Records any type/reffiness predictions we depend on in the region.
 */
void recordDependencies(Env& env) {
  // Record the incrementally constructed reffiness predictions.
  assertx(!env.region->empty());
  auto& frontBlock = *env.region->blocks().front();
  for (auto const& dep : env.refDeps.m_arMap) {
    frontBlock.addReffinessPred({dep.second.m_mask, dep.second.m_vals,
                                 dep.first});
  }

  // Relax guards and record the ones that survived.
  auto& firstBlock = *env.region->blocks().front();
  auto& unit = env.irgs.unit;
  auto guardMap = std::map<RegionDesc::Location,Type>{};
  ITRACE(2, "Visiting guards\n");
  auto hintMap = std::map<RegionDesc::Location,Type>{};
  auto catMap = std::map<RegionDesc::Location,DataTypeCategory>{};
  const auto& guards = env.irgs.irb->guards()->guards;
  visitGuards(unit, [&](IRInstruction* guard, const RegionDesc::Location& loc,
                        Type type, bool hint) {
    Trace::Indent indent;
    ITRACE(3, "{}: {}\n", show(loc), type);
    if (type <= TCls) return;
    auto& whichMap = hint ? hintMap : guardMap;
    auto inret = whichMap.insert(std::make_pair(loc, type));
    if (inret.second) {
      if (!hint) {
        catMap[loc] = folly::get_default(guards, guard).category;
      }
      return;
    }
    auto& oldTy = inret.first->second;
    oldTy &= type;
    if (!hint) {
      auto& oldCat = catMap[loc];
      auto newCat = folly::get_default(guards, guard).category;
      oldCat = std::max(oldCat, newCat);
    }
  });

  for (auto& kv : guardMap) {
    auto const hint_it = hintMap.find(kv.first);
    // If we have a hinted type that's better than the guarded type, we want to
    // keep it around.  This can really only when a guard is relaxed away to
    // Gen because we knew something was a BoxedCell statically, but we may
    // need to keep information about what inner type we were predicting.
    if (hint_it != end(hintMap) && hint_it->second < kv.second) {
      auto const pred = RegionDesc::TypedLocation {
        hint_it->first,
        hint_it->second
      };
      FTRACE(1, "selectTracelet adding prediction {}\n", show(pred));
      firstBlock.addPredicted(pred);
    }
    if (kv.second == TGen) {
      // Guard was relaxed to Gen---don't record it.  But if there's a hint, we
      // may have needed that (recorded already above).
      continue;
    }
    auto const preCond = RegionDesc::GuardedLocation { kv.first, kv.second,
                                                       catMap[kv.first] };
    ITRACE(1, "selectTracelet adding guard {}\n", show(preCond));
    firstBlock.addPreCondition(preCond);
  }
}
예제 #3
0
/*
 * Records any type/reffiness predictions we depend on in the region.
 */
void recordDependencies(Env& env) {
  // Record the incrementally constructed reffiness predictions.
  assertx(!env.region->empty());
  auto& frontBlock = *env.region->blocks().front();
  for (auto const& dep : env.refDeps.m_arMap) {
    frontBlock.addReffinessPred({dep.second.m_mask, dep.second.m_vals,
                                 dep.first});
  }

  // Relax guards and record the ones that survived.
  auto& firstBlock = *env.region->blocks().front();
  auto& unit = env.irgs.unit;
  auto guardMap = std::map<Location,Type>{};
  ITRACE(2, "Visiting guards\n");
  auto hintMap = std::map<Location,Type>{};
  auto catMap = std::map<Location,DataTypeCategory>{};
  const auto& guards = env.irgs.irb->guards()->guards;
  auto predictionMap = std::map<Location,Type>{};
  visitGuards(unit, [&] (const IRInstruction* guard,
                         const Location& loc,
                         Type type, bool hint) {
    Trace::Indent indent;
    ITRACE(3, "{}: {}\n", show(loc), type);
    assertx(type <= TGen);
    auto& whichMap = hint ? hintMap : guardMap;
    auto inret = whichMap.insert(std::make_pair(loc, type));
    // Unconstrained pseudo-main guards will be relaxed to Gen by the guard
    // relaxation pass. Since we don't allow loading TGen locals
    // in pseudo-main, save the predicted type here.
    if (guard->marker().func()->isPseudoMain()) {
      auto ret = predictionMap.insert(std::make_pair(loc,type));
      if (ret.second) {
        FTRACE(1, "selectTracelet saving prediction for PseudoMain {}\n",
            show(RegionDesc::TypedLocation {loc, type}));
      } else {
        auto& oldTy = ret.first->second;
        oldTy &= type;
      }
    }
    if (inret.second) {
      if (!hint) {
        catMap[loc] = folly::get_default(guards, guard).category;
      }
      return;
    }
    auto& oldTy = inret.first->second;
    oldTy &= type;
    if (!hint) {
      auto& oldCat = catMap[loc];
      auto newCat = folly::get_default(guards, guard).category;
      oldCat = std::max(oldCat, newCat);
    }
  });

  for (auto& kv : guardMap) {
    auto const hint_it = hintMap.find(kv.first);
    // If we have a hinted type that's better than the guarded type, we want to
    // keep it around.  This can really only when a guard is relaxed away to
    // Gen because we knew something was a BoxedCell statically, but we may
    // need to keep information about what inner type we were predicting.
    if (hint_it != end(hintMap) && hint_it->second < kv.second) {
      FTRACE(1, "selectTracelet adding prediction {}\n",
            show(RegionDesc::TypedLocation {hint_it->first, hint_it->second}));
      predictionMap.insert(*hint_it);
    }
    if (kv.second == TGen) {
      // Guard was relaxed to Gen---don't record it.  But if there's a hint, we
      // may have needed that (recorded already above).
      continue;
    }
    auto const preCond = RegionDesc::GuardedLocation {
      kv.first, kv.second,
      catMap[kv.first]
    };
    ITRACE(1, "selectTracelet adding guard {}\n", show(preCond));
    firstBlock.addPreCondition(preCond);
  }

  // Predictions are already sorted by location, so we can simply compare
  // the type-prediction vectors for different blocks later.
  for (auto& pred : predictionMap) {
    firstBlock.addPredicted(RegionDesc::TypedLocation{pred.first, pred.second});
  }
}