Skip to content

Commit 9cf6b2f

Browse files
committed
Update logic whether to restore const symbol
1 parent 0ca0c29 commit 9cf6b2f

File tree

4 files changed

+69
-76
lines changed

4 files changed

+69
-76
lines changed

lib/Backend/LinearScan.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3233,7 +3233,7 @@ LinearScan::InsertStore(IR::Instr *instr, StackSym *sym, RegNum reg)
32333233
}
32343234

32353235
// LinearScan::InsertLoad
3236-
void
3236+
IR::Instr*
32373237
LinearScan::InsertLoad(IR::Instr *instr, StackSym *sym, RegNum reg)
32383238
{
32393239
IR::Opnd *src;
@@ -3305,6 +3305,8 @@ LinearScan::InsertLoad(IR::Instr *instr, StackSym *sym, RegNum reg)
33053305
}
33063306
}
33073307
#endif
3308+
3309+
return load;
33083310
}
33093311

33103312
uint8

lib/Backend/LinearScan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class LinearScan
134134
void InsertStores(Lifetime *lifetime, RegNum reg, IR::Instr *insertionInstr);
135135
void InsertStore(IR::Instr *instr, StackSym *sym, RegNum reg);
136136
void InsertLoads(StackSym *sym, RegNum reg);
137-
void InsertLoad(IR::Instr *instr, StackSym *sym, RegNum reg);
137+
IR::Instr* InsertLoad(IR::Instr *instr, StackSym *sym, RegNum reg);
138138
void SetDstReg(IR::Instr *instr);
139139
void SetSrcRegs(IR::Instr *instr);
140140
void SetUses(IR::Instr *instr, IR::Opnd *opnd);

lib/Backend/amd64/LinearScanMD.cpp

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ void LinearScanMD::GeneratorBailIn::InsertRestoreSymbols(
558558
StackSym* stackSym = this->func->m_symTable->FindStackSym(symId);
559559
Lifetime* lifetime = stackSym->scratch.linearScan.lifetime;
560560

561-
if (this->NeedsReloadingValueWhenBailIn(stackSym))
561+
if (this->NeedsReloadingValueWhenBailIn(stackSym, lifetime))
562562
{
563563
Js::RegSlot regSlot = stackSym->GetByteCodeRegSlot();
564564
IR::Opnd* srcOpnd = IR::IndirOpnd::New(
@@ -570,11 +570,62 @@ void LinearScanMD::GeneratorBailIn::InsertRestoreSymbols(
570570

571571
if (lifetime->isSpilled)
572572
{
573-
this->InsertRestoreStackSymbol(stackSym, srcOpnd, insertionPoint);
573+
Assert(!stackSym->IsConst());
574+
// Stack restores require an extra register since we can't move an indir directly to an indir on amd64
575+
IR::SymOpnd* dstOpnd = IR::SymOpnd::New(stackSym, stackSym->GetType(), this->func);
576+
LinearScan::InsertMove(this->rcxRegOpnd, srcOpnd, insertionPoint.instrInsertStackSym);
577+
LinearScan::InsertMove(dstOpnd, this->rcxRegOpnd, insertionPoint.instrInsertStackSym);
574578
}
575579
else
576580
{
577-
this->InsertRestoreRegSymbol(stackSym, srcOpnd, insertionPoint);
581+
// Register restores must come after stack restores so that we have RAX and RCX free to
582+
// use for stack restores and further RAX must be restored last since it holds the
583+
// pointer to the InterpreterStackFrame from which we are restoring values.
584+
// We must also track these restores using RecordDef in case the symbols are spilled.
585+
586+
IR::Instr* instr;
587+
588+
if (stackSym->IsConst())
589+
{
590+
instr = this->linearScanMD->linearScan->InsertLoad(insertionPoint.instrInsertRegSym, stackSym, lifetime->reg);
591+
}
592+
else
593+
{
594+
IR::RegOpnd* dstRegOpnd = IR::RegOpnd::New(stackSym, stackSym->GetType(), this->func);
595+
dstRegOpnd->SetReg(lifetime->reg);
596+
instr = LinearScan::InsertMove(dstRegOpnd, srcOpnd, insertionPoint.instrInsertRegSym);
597+
}
598+
599+
if (insertionPoint.instrInsertRegSym == insertionPoint.instrInsertStackSym)
600+
{
601+
// This is the first register sym, make sure we don't insert stack stores
602+
// after this instruction so we can ensure rax and rcx remain free to use
603+
// for restoring spilled stack syms.
604+
insertionPoint.instrInsertStackSym = instr;
605+
}
606+
607+
if (lifetime->reg == RegRAX)
608+
{
609+
// Ensure rax is restored last
610+
Assert(insertionPoint.instrInsertRegSym != insertionPoint.instrInsertStackSym);
611+
612+
insertionPoint.instrInsertRegSym = instr;
613+
614+
if (insertionPoint.raxRestoreInstr != nullptr)
615+
{
616+
AssertMsg(false, "this is unexpected until copy prop is enabled");
617+
// rax was mapped to multiple bytecode registers. Obviously only the first
618+
// restore we do will work so change all following stores to `mov rax, rax`.
619+
// We still need to keep them around for RecordDef in case the corresponding
620+
// dst sym is spilled later on.
621+
insertionPoint.raxRestoreInstr->FreeSrc1();
622+
insertionPoint.raxRestoreInstr->SetSrc1(this->raxRegOpnd);
623+
}
624+
625+
insertionPoint.raxRestoreInstr = instr;
626+
}
627+
628+
this->linearScanMD->linearScan->RecordDef(lifetime, instr, 0);
578629
}
579630
}
580631
else
@@ -595,12 +646,18 @@ void LinearScanMD::GeneratorBailIn::InsertRestoreSymbols(
595646
NEXT_BITSET_IN_SPARSEBV;
596647
}
597648

598-
bool LinearScanMD::GeneratorBailIn::NeedsReloadingValueWhenBailIn(StackSym* sym) const
649+
bool LinearScanMD::GeneratorBailIn::NeedsReloadingValueWhenBailIn(StackSym* sym, Lifetime* lifetime) const
599650
{
600-
// We load constant values before the generator resume jump table, no need to reload
601-
if (this->func->GetJITFunctionBody()->RegIsConstant(sym->GetByteCodeRegSlot()))
651+
if (sym->IsConst())
602652
{
603-
return false;
653+
if (this->func->GetJITFunctionBody()->RegIsConstant(sym->GetByteCodeRegSlot()))
654+
{
655+
return false;
656+
}
657+
else
658+
{
659+
return !lifetime->isSpilled;
660+
}
604661
}
605662

606663
// If we have for-in in the generator, don't need to reload the symbol again as it is done
@@ -614,60 +671,6 @@ bool LinearScanMD::GeneratorBailIn::NeedsReloadingValueWhenBailIn(StackSym* sym)
614671
return !this->initializedRegs.Test(sym->GetByteCodeRegSlot());
615672
}
616673

617-
void LinearScanMD::GeneratorBailIn::InsertRestoreRegSymbol(StackSym* stackSym, IR::Opnd* srcOpnd, BailInInsertionPoint& insertionPoint)
618-
{
619-
Lifetime* lifetime = stackSym->scratch.linearScan.lifetime;
620-
621-
// Register restores must come after stack restores so that we have RAX and RCX free to
622-
// use for stack restores and further RAX must be restored last since it holds the
623-
// pointer to the InterpreterStackFrame from which we are restoring values.
624-
// We must also track these restores using RecordDef in case the symbols are spilled.
625-
626-
IR::RegOpnd* dstRegOpnd = IR::RegOpnd::New(stackSym, stackSym->GetType(), this->func);
627-
dstRegOpnd->SetReg(lifetime->reg);
628-
629-
IR::Instr* instr = LinearScan::InsertMove(dstRegOpnd, srcOpnd, insertionPoint.instrInsertRegSym);
630-
631-
if (insertionPoint.instrInsertRegSym == insertionPoint.instrInsertStackSym)
632-
{
633-
// This is the first register sym, make sure we don't insert stack stores
634-
// after this instruction so we can ensure rax and rcx remain free to use
635-
// for restoring spilled stack syms.
636-
insertionPoint.instrInsertStackSym = instr;
637-
}
638-
639-
if (lifetime->reg == RegRAX)
640-
{
641-
// Ensure rax is restored last
642-
Assert(insertionPoint.instrInsertRegSym != insertionPoint.instrInsertStackSym);
643-
644-
insertionPoint.instrInsertRegSym = instr;
645-
646-
if (insertionPoint.raxRestoreInstr != nullptr)
647-
{
648-
AssertMsg(false, "this is unexpected until copy prop is enabled");
649-
// rax was mapped to multiple bytecode registers. Obviously only the first
650-
// restore we do will work so change all following stores to `mov rax, rax`.
651-
// We still need to keep them around for RecordDef in case the corresponding
652-
// dst sym is spilled later on.
653-
insertionPoint.raxRestoreInstr->FreeSrc1();
654-
insertionPoint.raxRestoreInstr->SetSrc1(this->raxRegOpnd);
655-
}
656-
657-
insertionPoint.raxRestoreInstr = instr;
658-
}
659-
660-
this->linearScanMD->linearScan->RecordDef(lifetime, instr, 0);
661-
}
662-
663-
void LinearScanMD::GeneratorBailIn::InsertRestoreStackSymbol(StackSym* stackSym, IR::Opnd* srcOpnd, BailInInsertionPoint& insertionPoint)
664-
{
665-
// Stack restores require an extra register since we can't move an indir directly to an indir on amd64
666-
IR::SymOpnd* dstOpnd = IR::SymOpnd::New(stackSym, stackSym->GetType(), this->func);
667-
LinearScan::InsertMove(this->rcxRegOpnd, srcOpnd, insertionPoint.instrInsertStackSym);
668-
LinearScan::InsertMove(dstOpnd, this->rcxRegOpnd, insertionPoint.instrInsertStackSym);
669-
}
670-
671674
IR::SymOpnd* LinearScanMD::GeneratorBailIn::CreateGeneratorObjectOpnd() const
672675
{
673676
StackSym* sym = StackSym::NewParamSlotSym(1, this->func);

lib/Backend/amd64/LinearScanMD.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,24 +106,12 @@ class LinearScanMD : public LinearScanMDShared
106106
IR::RegOpnd* const raxRegOpnd;
107107
IR::RegOpnd* const rcxRegOpnd;
108108

109-
bool NeedsReloadingValueWhenBailIn(StackSym* sym) const;
109+
bool NeedsReloadingValueWhenBailIn(StackSym* sym, Lifetime* lifetime) const;
110110
uint32 GetOffsetFromInterpreterStackFrame(Js::RegSlot regSlot) const;
111111
IR::SymOpnd* CreateGeneratorObjectOpnd() const;
112112

113113
void InsertSaveAndRestore(IR::Instr* start, IR::Instr* end, IR::RegOpnd* reg);
114114

115-
void InsertRestoreRegSymbol(
116-
StackSym* stackSym,
117-
IR::Opnd* srcOpnd,
118-
BailInInsertionPoint& insertionPoint
119-
);
120-
121-
void InsertRestoreStackSymbol(
122-
StackSym* stackSym,
123-
IR::Opnd* srcOpnd,
124-
BailInInsertionPoint& insertionPoint
125-
);
126-
127115
void InsertRestoreSymbols(
128116
BVSparse<JitArenaAllocator>* symbols,
129117
BailInInsertionPoint& insertionPoint,

0 commit comments

Comments
 (0)