Esempio n. 1
0
RegionDescPtr selectRegion(const RegionContext& context,
                           TransKind kind) {
  auto const mode = regionMode();

  FTRACE(1,
    "Select region: mode={} context:\n{}",
    static_cast<int>(mode), show(context)
  );

  auto region = [&]{
    try {
      switch (mode) {
        case RegionMode::None:
          return RegionDescPtr{nullptr};
        case RegionMode::Method:
          return selectMethod(context);
        case RegionMode::Tracelet:
          return selectTracelet(context, kind == TransKind::Profile);
      }
      not_reached();
    } catch (const std::exception& e) {
      FTRACE(1, "region selector threw: {}\n", e.what());
      return RegionDescPtr{nullptr};
    }
  }();

  if (region) {
    FTRACE(3, "{}", show(*region));
    always_assert(region->instrSize() <= RuntimeOption::EvalJitMaxRegionInstrs);
  } else {
    FTRACE(1, "no region selectable; using tracelet compiler\n");
  }

  return region;
}
RegionDescPtr selectRegion(const RegionContext& context,
                           const Transl::Tracelet* t) {
    auto const mode = regionMode();

    FTRACE(1,
           "Select region: mode={} context:\n{}",
           static_cast<int>(mode), show(context)
          );

    auto region = [&] {
        try {
            switch (mode) {
            case RegionMode::None:
                return RegionDescPtr{nullptr};
            case RegionMode::OneBC:
                return selectOneBC(context);
            case RegionMode::Method:
                return selectMethod(context);
            case RegionMode::Tracelet:
                return selectTracelet(context, 0);
            case RegionMode::Legacy:
                always_assert(t);
                return selectTraceletLegacy(*t);
            case RegionMode::HotBlock:
            case RegionMode::HotTrace:
                always_assert(0 &&
                              "unsupported region mode");
            }
            not_reached();
        } catch (const std::exception& e) {
            FTRACE(1, "region selector threw: {}\n", e.what());
            return RegionDescPtr{nullptr};
        }
    }();

    if (region) {
        FTRACE(3, "{}", show(*region));
    } else {
        FTRACE(1, "no region selectable; using tracelet compiler\n");
    }

    return region;
}
Esempio n. 3
0
bool RegionFormer::tryInline(uint32_t& instrSize) {
  assertx(m_inst.source == m_sk);
  assertx(m_inst.func() == curFunc());
  assertx(m_sk.resumed() == resumed());

  instrSize = 0;

  if (!m_inl.canInlineAt(m_inst.source, m_inst.funcd, *m_region)) {
    return false;
  }

  auto refuse = [this](const std::string& str) {
    FTRACE(2, "selectTracelet not inlining {}: {}\n",
           m_inst.toString(), str);
    return false;
  };

  auto callee = m_inst.funcd;

  // Make sure the FPushOp wasn't interpreted.
  if (m_irgs.fpiStack.empty()) {
    return refuse("fpistack empty; fpush was in a different region");
  }
  auto spillFrame = m_irgs.fpiStack.top().spillFrame;
  if (!spillFrame) {
    return refuse("couldn't find SpillFrame for FPushOp");
  }

  auto numArgs = m_inst.imm[0].u_IVA;
  auto numParams = callee->numParams();

  // Set up the region context, mapping stack slots in the caller to locals in
  // the callee.
  RegionContext ctx;
  ctx.func = callee;
  ctx.bcOffset = callee->getEntryForNumArgs(numArgs);
  ctx.spOffset = FPInvOffset{safe_cast<int32_t>(callee->numSlotsInFrame())};
  ctx.resumed = false;
  for (int i = 0; i < numArgs; ++i) {
    auto type = irgen::publicTopType(m_irgs, BCSPOffset{i});
    uint32_t paramIdx = numArgs - 1 - i;
    ctx.liveTypes.push_back({RegionDesc::Location::Local{paramIdx}, type});
  }

  for (unsigned i = numArgs; i < numParams; ++i) {
    // These locals will be populated by DV init funclets but they'll start
    // out as Uninit.
    ctx.liveTypes.push_back({RegionDesc::Location::Local{i}, TUninit});
  }

  FTRACE(1, "selectTracelet analyzing callee {} with context:\n{}",
         callee->fullName()->data(), show(ctx));
  auto region = selectTracelet(ctx, m_profiling, false /* noinline */);
  if (!region) {
    return refuse("failed to select region in callee");
  }

  instrSize = region->instrSize();
  auto newInstrSize = instrSize + m_numBCInstrs + m_pendingInlinedInstrs;
  if (newInstrSize > RuntimeOption::EvalJitMaxRegionInstrs) {
    return refuse("new region would be too large");
  }
  if (!m_inl.shouldInline(callee, *region)) {
    return refuse("shouldIRInline failed");
  }
  return true;
}