Skip to content

Commit

Permalink
Refine and filter bespoke sink layouts by the known layout
Browse files Browse the repository at this point in the history
Summary:
We might profile that a given array sink is likely to see a particular array
layout, but we might also know something about the actual layout we are
getting and that might contradict or refine the prediction.

So, take advantage of that knowledge and avoid emitting dead checks that always
side exit.

Differential Revision: D57518393

fbshipit-source-id: ddfb68597472d8575d1e29b4fcdfbdd94421a153
  • Loading branch information
jano authored and facebook-github-bot committed May 18, 2024
1 parent 4b4bb8a commit e13ee2a
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 9 deletions.
12 changes: 7 additions & 5 deletions hphp/runtime/base/bespoke/layout-selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,8 @@ ArrayLayout layoutForSource(SrcKey sk) {
// Computes the layouts for a given sink by looking at the layouts for each
// TransID. If there are <= 2 total layouts then they are returned in frequency
// order. If there are more than 2 layouts, they will be unioned and returned.
SinkLayouts layoutsForSink(const jit::TransIDSet& ids, SrcKey sk) {
SinkLayouts layoutsForSink(
const jit::TransIDSet& ids, SrcKey sk, ArrayLayout knownLayout) {
auto result = SinkLayouts{};

// Track layout frequencies across the multiple layouts
Expand All @@ -1031,8 +1032,9 @@ SinkLayouts layoutsForSink(const jit::TransIDSet& ids, SrcKey sk) {

// Record the frequencies for each layout
for (auto const& layout : sls.layouts) {
layoutFrequencies[layout.layout.toUint16()] +=
layout.coverage * transCounter;
auto const l = layout.layout & knownLayout;
if (l == ArrayLayout::Bottom()) continue;
layoutFrequencies[l.toUint16()] += layout.coverage * transCounter;
}
}
}
Expand Down Expand Up @@ -1060,14 +1062,14 @@ SinkLayouts layoutsForSink(const jit::TransIDSet& ids, SrcKey sk) {
}

if (sl.layout == ArrayLayout::Bottom()) {
return {{{ArrayLayout::Top(), 1.0}}, false};
return {{{knownLayout, 1.0}}, false};
}

result.layouts = {std::move(sl)};
}

if (result.layouts.empty()) {
return {{{ArrayLayout::Top(), 1.0}}, false};
return {{{knownLayout, 1.0}}, false};
}

return result;
Expand Down
6 changes: 5 additions & 1 deletion hphp/runtime/base/bespoke/layout-selection.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ using LayoutWeightVector =
// Layout selection. We'll call selectBespokeLayouts in RTA, and then we'll
// be able to use layoutForSource / layoutForSink for optimized code.
jit::ArrayLayout layoutForSource(SrcKey sk);
SinkLayouts layoutsForSink(const jit::TransIDSet& ids, SrcKey sk);
SinkLayouts layoutsForSink(
const jit::TransIDSet& ids,
SrcKey sk,
jit::ArrayLayout knownLayout
);
void selectBespokeLayouts();

}
Expand Down
3 changes: 2 additions & 1 deletion hphp/runtime/vm/jit/irgen-bespoke.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1841,7 +1841,8 @@ void handleSink(IRGS& env, const NormalizedInstruction& ni,

emitLogArrayReach(env, loc, sk);

auto const sinkLayouts = bespoke::layoutsForSink(env.profTransIDs, ni.source);
auto const sinkLayouts = bespoke::layoutsForSink(
env.profTransIDs, ni.source, type.arrSpec().layout());

if (isIteratorOp(sk.op())) {
emitVanilla(env);
Expand Down
6 changes: 4 additions & 2 deletions hphp/runtime/vm/jit/irgen-iter-spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,9 +697,11 @@ bool specializeIterInit(IRGS& env, Offset doneOffset,
auto const layout = [&]{
if (!allowBespokeArrayLikes()) return ArrayLayout::Vanilla();
if (!arrayTypeCouldBeBespoke(baseDT)) return ArrayLayout::Vanilla();
auto const sl = bespoke::layoutsForSink(env.profTransIDs, curSrcKey(env));
auto const knownLayout = base->type().arrSpec().layout();
auto const sl = bespoke::layoutsForSink(
env.profTransIDs, curSrcKey(env), knownLayout);
assertx(sl.layouts.size() == 1);
return sl.sideExit ? sl.layouts[0].layout : ArrayLayout::Top();
return sl.layouts[0].layout;
}();
auto const accessor = getAccessor(baseDT, keyTypes, layout, data);

Expand Down

0 comments on commit e13ee2a

Please sign in to comment.