Skip to content

Commit 069c0d0

Browse files
paulbissfacebook-github-bot
authored andcommitted
Simplify BeginInlining sequence
Summary: - We always side-exit when performing an InlineCall so the complicated tracking we do here is no longer necessary - `BeginInlining` doesn't really mark the start of an inlined region, it defines the frame pointer via an lea so rename it `DefCalleeFP` - `EndInlining` is really more logically paired with `EnterInlineFrame`, it has memory effects that end in the inlined region, so rename it `LeaveInlineFrame` - Defining the inline frame pointer can sometimes make merging diamond control flow induced by `CheckType` difficult so hoist it to the start of the unit. Since we constant propagate `lea` instructions this shouldn't matter. Reviewed By: jano Differential Revision: D72073596 fbshipit-source-id: 9d1cb1f455a008918db3d0b7d71b3f04b065387d
1 parent 5991647 commit 069c0d0

34 files changed

+194
-306
lines changed

hphp/doc/ir.specification

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,18 +1614,17 @@ To string conversions:
16141614

16151615
8. Call & Return
16161616

1617-
| BeginInlining<func, offset>, D(FramePtr), S(StkPtr), NF
1617+
| DefCalleeFP<func, offset>, D(FramePtr), S(StkPtr) S(FramePtr), NF
16181618

16191619
Defines a new frame pointer for an ActRec at callBCOff for use in an inlined
1620-
region. In resumed contexts the new frame is computed relative to S0 as S1 is
1621-
not a stack location.
1620+
region. The frame is defined relative to S0, and S1 is the parent frame.
16221621

16231622
| EnterInlineFrame, ND, S(FramePtr), NF
16241623

16251624
Marks the start of an inlined function whose stack resides offset cells below
16261625
the SP.
16271626

1628-
| EndInlining, ND, S(FramePtr), NF
1627+
| LeaveInlineFrame, ND, S(FramePtr), NF
16291628

16301629
Marks the end of an inlined function. S0 is no longer a valid frame location.
16311630

@@ -1664,7 +1663,7 @@ This is achieved by calling the inlineSideExit stub and using registers to pass
16641663
all relevant ActRec fields. The stub finishes initialization of the ActRec and
16651664
jumps to S3.
16661665

1667-
It could be viewed as performing a work similar to a combination of EndInlining,
1666+
It could be viewed as performing a work similar to a combination of LeaveInlineFrame,
16681667
ReqBindJmp and CallFuncEntry.
16691668

16701669
| EnterFrame, D(FramePtr), S(FramePtr) S(FramePtr) S(Int) S(Int), NF

hphp/runtime/base/backtrace.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,7 @@ TypedValue* BTFrame::local(int n) const {
134134

135135
if (m_frameId != kRootIFrameID) {
136136
auto const ifr = jit::getInlineFrame(m_frameId);
137-
auto const pubSB = Stack::anyFrameStackBase(m_fp);
138-
auto const rootSB = m_pubFrameId != kRootIFrameID
139-
? pubSB + jit::getInlineFrame(m_pubFrameId).sbToRootSbOff
140-
: pubSB;
137+
auto const rootSB = Stack::anyFrameStackBase(m_fp);
141138
auto const mySB = rootSB - ifr.sbToRootSbOff;
142139
auto const fp = (ActRec*)(mySB + ifr.func->numSlotsInFrame());
143140
return frame_local(fp, n);
@@ -224,10 +221,9 @@ BTFrame initBTFrameAt(jit::CTCA ip, BTFrame frm) {
224221

225222
if (auto const stk = jit::inlineStackAt(ip)) {
226223
FTRACE_MOD(Trace::fixup, 3,
227-
"IStack fp={} ip={} frame={} pubFrame={} callOff={}\n",
228-
frm.fpInternal(), ip, stk->frame, stk->pubFrame, stk->callOff);
229-
return BTFrame::iframe(
230-
frm.fpInternal(), stk->callOff, stk->frame, stk->pubFrame);
224+
"IStack fp={} ip={} frame={} callOff={}\n",
225+
frm.fpInternal(), ip, stk->frame, stk->callOff);
226+
return BTFrame::iframe(frm.fpInternal(), stk->callOff, stk->frame);
231227
}
232228

233229
if (frm.bcOff() != kInvalidOffset) return frm;
@@ -252,13 +248,12 @@ BTFrame getPrevActRec(
252248
fp, frm.frameIdInternal(), ifr.parent,
253249
ifr.func->fullName()->data(), ifr.callOff, ifr.sbToRootSbOff);
254250

255-
if (ifr.parent == frm.pubFrameIdInternal()) {
251+
if (ifr.parent == kRootIFrameID) {
256252
// Reached published frame, continue following the FP chain.
257253
return BTFrame::regular(fp, ifr.callOff);
258254
}
259255

260-
return BTFrame::iframe(
261-
fp, ifr.callOff, ifr.parent, frm.pubFrameIdInternal());
256+
return BTFrame::iframe(fp, ifr.callOff, ifr.parent);
262257
}
263258

264259
// Handle AsyncFunctionWaitHandle tail frame.

hphp/runtime/base/backtrace.h

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ struct BacktraceArgs {
289289
* ____________________ | inl2->base())
290290
* | | |
291291
* | frame: inl2 | |
292-
* | pubFrame: caller | |
293292
* | callOff ----------+---------------------------+
294293
* |____________________|
295294
*
@@ -317,7 +316,6 @@ struct IFrame {
317316

318317
struct IStack {
319318
IFrameID frame; // leaf frame in this stack
320-
IFrameID pubFrame; // the last published frame to which vmfp() points to
321319
Offset callOff;
322320

323321
template<class SerDe> void serde(SerDe& sd) {
@@ -346,12 +344,10 @@ struct BTFrame {
346344

347345
// Inlined frame that does not have a materialized ActRec. IFrame backed by
348346
// `frameID` contains the metadata necessary to reconstruct the frame.
349-
// The nearest published frame `fp` is represented by `pubFrameId`.
350-
static BTFrame iframe(ActRec* fp, Offset bcOff,
351-
IFrameID frameId, IFrameID pubFrameId) {
347+
static BTFrame iframe(ActRec* fp, Offset bcOff, IFrameID frameId) {
352348
assertx(fp != nullptr);
353-
assertx(frameId != kRootIFrameID && frameId != pubFrameId);
354-
return BTFrame{fp, bcOff, frameId, pubFrameId};
349+
assertx(frameId != kRootIFrameID);
350+
return BTFrame{fp, bcOff, frameId};
355351
}
356352

357353
static BTFrame afwhTailFrame(ActRec* fp, Offset bcOff,
@@ -362,7 +358,7 @@ struct BTFrame {
362358
}
363359

364360
BTFrame withFP(ActRec* fp) const {
365-
return BTFrame{fp, m_bcOff, m_frameId, m_pubFrameId};
361+
return BTFrame{fp, m_bcOff, m_frameId};
366362
}
367363

368364
operator bool() const { return m_fp != nullptr; }
@@ -378,10 +374,6 @@ struct BTFrame {
378374
// instead use the helpers above.
379375
ActRec* fpInternal() const { return m_fp; }
380376
IFrameID frameIdInternal() const { return m_frameId; }
381-
IFrameID pubFrameIdInternal() const {
382-
assertx(m_frameId != kRootIFrameID);
383-
return m_pubFrameId;
384-
}
385377
int8_t afwhTailFrameIdxInternal() const {
386378
assertx(m_frameId == kRootIFrameID);
387379
return m_afwhTailFrameIdx;
@@ -391,21 +383,18 @@ struct BTFrame {
391383

392384
private:
393385
BTFrame() = default;
394-
BTFrame(ActRec* fp, Offset bcOff, IFrameID frameId, IFrameID pubFrameId)
395-
: m_fp(fp), m_bcOff(bcOff), m_frameId(frameId), m_pubFrameId(pubFrameId) {}
386+
BTFrame(ActRec* fp, Offset bcOff, IFrameID frameId)
387+
: m_fp(fp), m_bcOff(bcOff), m_frameId(frameId) {}
396388
BTFrame(ActRec* fp, Offset bcOff, int8_t afwhTailFrameIdx)
397389
: m_fp(fp), m_bcOff(bcOff), m_frameId(kRootIFrameID)
398390
, m_afwhTailFrameIdx(afwhTailFrameIdx) {}
399391

400392
ActRec* m_fp{nullptr};
401393
Offset m_bcOff{kInvalidOffset};
402394
IFrameID m_frameId{kRootIFrameID};
403-
union {
404-
// Used if m_frameId != kRootIFrameID
405-
IFrameID m_pubFrameId;
406-
// Used if m_frameId == kRootIFrameID, this is afwh tail frame if >= 0
407-
int8_t m_afwhTailFrameIdx;
408-
};
395+
396+
// Used if m_frameId == kRootIFrameID, this is afwh tail frame if >= 0
397+
int8_t m_afwhTailFrameIdx;
409398
};
410399

411400
Array createBacktrace(const BacktraceArgs& backtraceArgs);

hphp/runtime/test/alias-class.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,13 +480,13 @@ TEST(AliasClass, FrameUnion) {
480480
IRUnit unit{test_context};
481481
auto const bcctx = BCContext { BCMarker::Dummy(), 0 };
482482
auto const dsData = DefStackData { SBInvOffset { 0 }, SBInvOffset { 0 } };
483-
auto const biData = BeginInliningData {
483+
auto const biData = DefCalleeFPData {
484484
IRSPRelOffset { 0 }, nullptr, 1, SrcKey {}, IRSPRelOffset { 0 },
485485
SBInvOffset { 0 }, 0
486486
};
487487
auto const SP = unit.gen(DefRegSP, bcctx, dsData)->dst();
488488
auto const FP1 = unit.gen(DefFP, bcctx, DefFPData { std::nullopt })->dst();
489-
auto const FP2 = unit.gen(BeginInlining, bcctx, biData, SP)->dst();
489+
auto const FP2 = unit.gen(DefCalleeFP, bcctx, biData, SP)->dst();
490490

491491
AliasClass const local1 = ALocal { FP1, 0 };
492492
AliasClass const localR = ALocal { FP1, AliasIdSet::IdRange(0, 2) };

hphp/runtime/vm/jit/analysis.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,16 @@ SSATmp* least_common_ancestor(SSATmp* s1, SSATmp* s2) {
147147

148148
const Func* funcFromFP(const SSATmp* fp) {
149149
auto const inst = canonical(fp)->inst();
150-
if (inst->is(BeginInlining)) return inst->extra<BeginInlining>()->func;
150+
if (inst->is(DefCalleeFP)) return inst->extra<DefCalleeFP>()->func;
151151
always_assert(inst->is(DefFP, DefFuncEntryFP, EnterFrame));
152152
return inst->marker().func();
153153
}
154154

155155
uint32_t frameDepthIndex(const SSATmp* fp) {
156156
always_assert(fp->isA(TFramePtr));
157157
fp = canonical(fp);
158-
if (fp->inst()->is(BeginInlining)) {
159-
auto const extra = fp->inst()->extra<BeginInlining>();
158+
if (fp->inst()->is(DefCalleeFP)) {
159+
auto const extra = fp->inst()->extra<DefCalleeFP>();
160160
return extra->depth;
161161
}
162162
return 0;
@@ -165,7 +165,7 @@ uint32_t frameDepthIndex(const SSATmp* fp) {
165165
Optional<IRSPRelOffset> offsetOfFrame(const SSATmp *fp) {
166166
assertx(fp->isA(TFramePtr));
167167
auto const inst = canonical(fp)->inst();
168-
if (inst->is(BeginInlining)) return inst->extra<BeginInlining>()->spOffset;
168+
if (inst->is(DefCalleeFP)) return inst->extra<DefCalleeFP>()->spOffset;
169169
if (inst->is(DefFP)) return inst->extra<DefFP>()->offset;
170170
if (inst->is(EnterFrame)) return IRSPRelOffset { 0 };
171171
always_assert(false);

hphp/runtime/vm/jit/bc-marker.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ SBInvOffset BCMarker::fixupSBOff() const {
5353
assertx(valid());
5454
if (fp() == fixupFP()) return SBInvOffset{0};
5555
auto const begin_inlining = fp()->inst();
56-
assertx(begin_inlining->is(BeginInlining));
57-
auto const fpSBOffset = begin_inlining->extra<BeginInlining>()->sbOffset;
56+
assertx(begin_inlining->is(DefCalleeFP));
57+
auto const fpSBOffset = begin_inlining->extra<DefCalleeFP>()->sbOffset;
5858

5959
auto const fixupFPStackBaseOffset = [&] {
60-
if (fixupFP()->inst()->is(BeginInlining)) {
61-
return fixupFP()->inst()->extra<BeginInlining>()->sbOffset;
60+
if (fixupFP()->inst()->is(DefCalleeFP)) {
61+
return fixupFP()->inst()->extra<DefCalleeFP>()->sbOffset;
6262
}
6363
assertx(fixupFP()->inst()->is(DefFP, EnterFrame));
6464
auto const defSP = fp()->inst()->src(0)->inst();
@@ -74,7 +74,7 @@ SrcKey BCMarker::fixupSk() const {
7474

7575
auto curFP = fp();
7676
do {
77-
assertx(curFP->inst()->is(BeginInlining));
77+
assertx(curFP->inst()->is(DefCalleeFP));
7878
// Walking the FP chain created from the marker is suspect, but we aren't
7979
// using it to materialize the fp SSATmp, or offsets based on the begin
8080
// inlinings. We are only materializing srckey info.

hphp/runtime/vm/jit/bc-marker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ struct BCMarker {
123123

124124
// Normally, the fixup SrcKey is the same as the SrcKey for the marker,
125125
// however, when inlining has dropped an inner frame the fixup SrcKey will
126-
// be inside the parent frame (corresponding to the BeginInlining of the first
126+
// be inside the parent frame (corresponding to the DefCalleeFP of the first
127127
// unpublished frame) so that its offset is relative to the live ActRec.
128128
SrcKey fixupSk() const;
129129

hphp/runtime/vm/jit/cg-meta.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,9 @@ void insertStacks(
8686
IFrameID start, const std::vector<std::pair<TCA,IStack>>& stacks
8787
) {
8888
for (auto& stk : stacks) {
89-
assertx(stk.second.frame != stk.second.pubFrame);
9089
auto off = stackAddrToOffset(stk.first);
9190
auto val = stk.second;
9291
val.frame += start;
93-
if (val.pubFrame != kRootIFrameID) val.pubFrame += start;
9492

9593
if (auto pos = s_inlineStacks.find(off)) {
9694
*pos = val;

hphp/runtime/vm/jit/dce.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,8 @@ bool canDCE(const IRInstruction& inst) {
705705
case StMROProp:
706706
case CheckMROProp:
707707
case FinishMemberOp:
708-
case BeginInlining:
709-
case EndInlining:
708+
case DefCalleeFP:
709+
case LeaveInlineFrame:
710710
case EnterInlineFrame:
711711
case SetOpTV:
712712
case OutlineSetOp:
@@ -987,8 +987,8 @@ void processCatchBlock(IRUnit& unit, DceState& state, Block* block,
987987
// If the catch block occurs within an inlined frame the outer stack
988988
// locations (those above the inlined frame) are not dead and cannot be
989989
// elided as we may not throw through the outer callers.
990-
if (block->back().src(0)->inst()->is(BeginInlining)) {
991-
auto const extra = block->back().src(0)->inst()->extra<BeginInlining>();
990+
if (block->back().src(0)->inst()->is(DefCalleeFP)) {
991+
auto const extra = block->back().src(0)->inst()->extra<DefCalleeFP>();
992992
auto const spOff = extra->spOffset;
993993
assertx(stackTop <= spOff);
994994
if (spOff < stackTop + numTrackedSlots) {

hphp/runtime/vm/jit/extra-data.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,8 +2545,8 @@ struct ProfileCallTargetData : IRExtraData {
25452545
rds::Handle handle;
25462546
};
25472547

2548-
struct BeginInliningData : IRExtraData {
2549-
BeginInliningData(IRSPRelOffset offset, const Func* func, unsigned depth,
2548+
struct DefCalleeFPData : IRExtraData {
2549+
DefCalleeFPData(IRSPRelOffset offset, const Func* func, unsigned depth,
25502550
SrcKey returnSk, IRSPRelOffset sbOffset,
25512551
SBInvOffset returnSPOff, int cost)
25522552
: spOffset(offset)
@@ -2575,7 +2575,7 @@ struct BeginInliningData : IRExtraData {
25752575
);
25762576
}
25772577

2578-
bool equals(const BeginInliningData& o) const {
2578+
bool equals(const DefCalleeFPData& o) const {
25792579
return
25802580
spOffset == o.spOffset && func == o.func && depth == o.depth &&
25812581
returnSk == o.returnSk && sbOffset == o.sbOffset &&
@@ -3117,7 +3117,7 @@ X(DefRegSP, DefStackData);
31173117
X(LdStk, IRSPRelOffsetData);
31183118
X(LdStkAddr, IRSPRelOffsetData);
31193119
X(StFrameMeta, StFrameMetaData);
3120-
X(BeginInlining, BeginInliningData);
3120+
X(DefCalleeFP, DefCalleeFPData);
31213121
X(ReqBindJmp, ReqBindJmpData);
31223122
X(ReqInterpBBNoTranslate, ReqBindJmpData);
31233123
X(ReqRetranslate, IRSPRelOffsetData);

0 commit comments

Comments
 (0)