Skip to content

Commit 9976ab2

Browse files
committed
[MERGE #5663 @pleath] Remove redundant aux slot ptr loads
Merge pull request #5663 from pleath:auxslotopt Modify and re-enable this optimization. Track availability of previously loaded aux slot pointers independently of type symbols. Also track upward-exposed uses so that we can avoid unnecessary reloads. (Note that the optimization relies on the change to disable dead-storing of type checks on property stores.)
2 parents 50eaeec + 8c5332b commit 9976ab2

File tree

10 files changed

+214
-89
lines changed

10 files changed

+214
-89
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ BackwardPass::MergeSuccBlocksInfo(BasicBlock * block)
720720
this->func->GetDebugNumberSet(debugStringBuffer),
721721
block->GetBlockNum(), blockSucc->GetBlockNum());
722722

723-
auto fixupFrom = [block, blockSucc, this](Bucket<AddPropertyCacheBucket> &bucket)
723+
auto fixupFrom = [block, blockSucc, upwardExposedUses, this](Bucket<AddPropertyCacheBucket> &bucket)
724724
{
725725
AddPropertyCacheBucket *fromData = &bucket.element;
726726
if (fromData->GetInitialType() == nullptr ||
@@ -729,10 +729,10 @@ BackwardPass::MergeSuccBlocksInfo(BasicBlock * block)
729729
return;
730730
}
731731

732-
this->InsertTypeTransitionsAtPriorSuccessors(block, blockSucc, bucket.value, fromData);
732+
this->InsertTypeTransitionsAtPriorSuccessors(block, blockSucc, bucket.value, fromData, upwardExposedUses);
733733
};
734734

735-
auto fixupTo = [blockSucc, this](Bucket<AddPropertyCacheBucket> &bucket)
735+
auto fixupTo = [blockSucc, upwardExposedUses, this](Bucket<AddPropertyCacheBucket> &bucket)
736736
{
737737
AddPropertyCacheBucket *toData = &bucket.element;
738738
if (toData->GetInitialType() == nullptr ||
@@ -741,7 +741,7 @@ BackwardPass::MergeSuccBlocksInfo(BasicBlock * block)
741741
return;
742742
}
743743

744-
this->InsertTypeTransitionAtBlock(blockSucc, bucket.value, toData);
744+
this->InsertTypeTransitionAtBlock(blockSucc, bucket.value, toData, upwardExposedUses);
745745
};
746746

747747
if (blockSucc->stackSymToFinalType != nullptr)
@@ -4614,7 +4614,7 @@ BackwardPass::ProcessNewScObject(IR::Instr* instr)
46144614
Assert(pBucket->GetInitialType() == ctorCache->GetType());
46154615
if (!this->IsPrePass())
46164616
{
4617-
this->InsertTypeTransition(instr->m_next, objSym, pBucket);
4617+
this->InsertTypeTransition(instr->m_next, objSym, pBucket, block->upwardExposedUses);
46184618
}
46194619
#if DBG
46204620
pBucket->deadStoreUnavailableInitialType = pBucket->GetInitialType();
@@ -5192,7 +5192,7 @@ BackwardPass::ProcessPropertySymOpndUse(IR::PropertySymOpnd * opnd)
51925192
pBucket->GetFinalType() != nullptr &&
51935193
pBucket->GetFinalType() != pBucket->GetInitialType())
51945194
{
5195-
this->InsertTypeTransition(this->currentInstr->m_next, baseSym, pBucket);
5195+
this->InsertTypeTransition(this->currentInstr->m_next, baseSym, pBucket, block->upwardExposedUses);
51965196
pBucket->SetFinalType(pBucket->GetInitialType());
51975197
}
51985198
}
@@ -5211,9 +5211,6 @@ BackwardPass::ProcessPropertySymOpndUse(IR::PropertySymOpnd * opnd)
52115211
void
52125212
BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *block)
52135213
{
5214-
StackSym *auxSlotPtrSym = nullptr;
5215-
bool auxSlotPtrUpwardExposed = false;
5216-
52175214
Assert(tag == Js::DeadStorePhase);
52185215
Assert(opnd->IsTypeCheckSeqCandidate());
52195216

@@ -5280,7 +5277,6 @@ BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *
52805277
#endif
52815278

52825279
bucket->AddToGuardedPropertyOps(opnd->GetObjTypeSpecFldId());
5283-
auxSlotPtrUpwardExposed = PHASE_ON(Js::ReuseAuxSlotPtrPhase, this->func) && opnd->UsesAuxSlot() && !opnd->IsLoadedFromProto() && opnd->IsTypeChecked();
52845280

52855281
if (opnd->NeedsMonoCheck())
52865282
{
@@ -5327,12 +5323,6 @@ BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *
53275323
bucket->SetGuardedPropertyOps(nullptr);
53285324
JitAdelete(this->tempAlloc, guardedPropertyOps);
53295325
block->stackSymToGuardedProperties->Clear(objSym->m_id);
5330-
auxSlotPtrSym = opnd->GetAuxSlotPtrSym();
5331-
if (auxSlotPtrSym)
5332-
{
5333-
this->currentBlock->upwardExposedUses->Clear(auxSlotPtrSym->m_id);
5334-
}
5335-
auxSlotPtrUpwardExposed = false;
53365326
}
53375327
}
53385328
#if DBG
@@ -5351,11 +5341,25 @@ BackwardPass::TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *
53515341
opnd->SetGuardedPropOp(opnd->GetObjTypeSpecFldId());
53525342
}
53535343

5354-
if (auxSlotPtrUpwardExposed)
5344+
if (opnd->UsesAuxSlot() && opnd->IsTypeCheckSeqParticipant() && !opnd->HasTypeMismatch() && !opnd->IsLoadedFromProto())
53555345
{
5356-
// This is an upward-exposed use of the aux slot pointer.
5357-
auxSlotPtrSym = opnd->EnsureAuxSlotPtrSym(this->func);
5358-
this->currentBlock->upwardExposedUses->Set(auxSlotPtrSym->m_id);
5346+
bool auxSlotPtrUpwardExposed = false;
5347+
StackSym *auxSlotPtrSym = opnd->GetAuxSlotPtrSym();
5348+
if (opnd->IsAuxSlotPtrSymAvailable())
5349+
{
5350+
// This is an upward-exposed use of the aux slot pointer.
5351+
Assert(auxSlotPtrSym);
5352+
auxSlotPtrUpwardExposed = this->currentBlock->upwardExposedUses->TestAndSet(auxSlotPtrSym->m_id);
5353+
}
5354+
else if (auxSlotPtrSym != nullptr)
5355+
{
5356+
// The aux slot pointer is not upward-exposed at this point.
5357+
auxSlotPtrUpwardExposed = this->currentBlock->upwardExposedUses->TestAndClear(auxSlotPtrSym->m_id);
5358+
}
5359+
if (!this->IsPrePass() && auxSlotPtrUpwardExposed)
5360+
{
5361+
opnd->SetProducesAuxSlotPtr(true);
5362+
}
53595363
}
53605364
}
53615365

@@ -5611,16 +5615,18 @@ BackwardPass::TrackAddPropertyTypes(IR::PropertySymOpnd *opnd, BasicBlock *block
56115615
}
56125616

56135617
void
5614-
BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, int symId, AddPropertyCacheBucket *data)
5618+
BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
56155619
{
56165620
StackSym *objSym = this->func->m_symTable->FindStackSym(symId);
56175621
Assert(objSym);
5618-
this->InsertTypeTransition(instrInsertBefore, objSym, data);
5622+
this->InsertTypeTransition(instrInsertBefore, objSym, data, upwardExposedUses);
56195623
}
56205624

56215625
void
5622-
BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSym, AddPropertyCacheBucket *data)
5626+
BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSym, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
56235627
{
5628+
Assert(!this->IsPrePass());
5629+
56245630
IR::RegOpnd *baseOpnd = IR::RegOpnd::New(objSym, TyMachReg, this->func);
56255631
baseOpnd->SetIsJITOptimizedReg(true);
56265632

@@ -5637,7 +5643,7 @@ BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSy
56375643
IR::Instr *adjustTypeInstr =
56385644
IR::Instr::New(Js::OpCode::AdjustObjType, finalTypeOpnd, baseOpnd, initialTypeOpnd, this->func);
56395645

5640-
if (this->currentBlock->upwardExposedUses)
5646+
if (upwardExposedUses)
56415647
{
56425648
// If this type change causes a slot adjustment, the aux slot pointer (if any) will be reloaded here, so take it out of upwardExposedUses.
56435649
int oldCount;
@@ -5651,7 +5657,10 @@ BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSy
56515657
StackSym *auxSlotPtrSym = baseOpnd->m_sym->GetAuxSlotPtrSym();
56525658
if (auxSlotPtrSym)
56535659
{
5654-
this->currentBlock->upwardExposedUses->Clear(auxSlotPtrSym->m_id);
5660+
if (upwardExposedUses->Test(auxSlotPtrSym->m_id))
5661+
{
5662+
adjustTypeInstr->m_opcode = Js::OpCode::AdjustObjTypeReloadAuxSlotPtr;
5663+
}
56555664
}
56565665
}
56575666
}
@@ -5660,7 +5669,7 @@ BackwardPass::InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSy
56605669
}
56615670

56625671
void
5663-
BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPropertyCacheBucket *data)
5672+
BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
56645673
{
56655674
if (!this->IsPrePass())
56665675
{
@@ -5669,11 +5678,11 @@ BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPro
56695678
{
56705679
// The instr with the bailout is something like a branch that may not fall through.
56715680
// Insert the transitions instead at the beginning of each successor block.
5672-
this->InsertTypeTransitionsAtPriorSuccessors(this->currentBlock, nullptr, symId, data);
5681+
this->InsertTypeTransitionsAtPriorSuccessors(this->currentBlock, nullptr, symId, data, upwardExposedUses);
56735682
}
56745683
else
56755684
{
5676-
this->InsertTypeTransition(instr->m_next, symId, data);
5685+
this->InsertTypeTransition(instr->m_next, symId, data, upwardExposedUses);
56775686
}
56785687
}
56795688
// Note: we could probably clear this entry out of the table, but I don't know
@@ -5682,7 +5691,7 @@ BackwardPass::InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPro
56825691
}
56835692

56845693
void
5685-
BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPropertyCacheBucket *data)
5694+
BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses)
56865695
{
56875696
bool inserted = false;
56885697
FOREACH_INSTR_IN_BLOCK(instr, block)
@@ -5705,7 +5714,7 @@ BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPrope
57055714
}
57065715
else
57075716
{
5708-
this->InsertTypeTransition(instr, symId, data);
5717+
this->InsertTypeTransition(instr, symId, data, upwardExposedUses);
57095718
inserted = true;
57105719
break;
57115720
}
@@ -5715,7 +5724,7 @@ BackwardPass::InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPrope
57155724
if (!inserted)
57165725
{
57175726
Assert(block->GetLastInstr()->m_next);
5718-
this->InsertTypeTransition(block->GetLastInstr()->m_next, symId, data);
5727+
this->InsertTypeTransition(block->GetLastInstr()->m_next, symId, data, upwardExposedUses);
57195728
}
57205729
}
57215730

@@ -5724,7 +5733,8 @@ BackwardPass::InsertTypeTransitionsAtPriorSuccessors(
57245733
BasicBlock *block,
57255734
BasicBlock *blockSucc,
57265735
int symId,
5727-
AddPropertyCacheBucket *data)
5736+
AddPropertyCacheBucket *data,
5737+
BVSparse<JitArenaAllocator>* upwardExposedUses)
57285738
{
57295739
// For each successor of block prior to blockSucc, adjust the type.
57305740
FOREACH_SUCCESSOR_BLOCK(blockFix, block)
@@ -5734,7 +5744,7 @@ BackwardPass::InsertTypeTransitionsAtPriorSuccessors(
57345744
return;
57355745
}
57365746

5737-
this->InsertTypeTransitionAtBlock(blockFix, symId, data);
5747+
this->InsertTypeTransitionAtBlock(blockFix, symId, data, upwardExposedUses);
57385748
}
57395749
NEXT_SUCCESSOR_BLOCK;
57405750
}
@@ -5752,7 +5762,7 @@ BackwardPass::InsertTypeTransitionsAtPotentialKills()
57525762
// Also do this for ctor cache updates, to avoid putting a type in the ctor cache that extends past
57535763
// the end of the ctor that the cache covers.
57545764
this->ForEachAddPropertyCacheBucket([&](int symId, AddPropertyCacheBucket *data)->bool {
5755-
this->InsertTypeTransitionAfterInstr(instr, symId, data);
5765+
this->InsertTypeTransitionAfterInstr(instr, symId, data, this->currentBlock->upwardExposedUses);
57565766
return false;
57575767
});
57585768
}
@@ -5778,7 +5788,7 @@ BackwardPass::InsertTypeTransitionsAtPotentialKills()
57785788
if (this->TransitionUndoesObjectHeaderInlining(data))
57795789
{
57805790
// We're transitioning from inlined to non-inlined, so we can't push it up any farther.
5781-
this->InsertTypeTransitionAfterInstr(instr, symId, data);
5791+
this->InsertTypeTransitionAfterInstr(instr, symId, data, this->currentBlock->upwardExposedUses);
57825792
}
57835793
return false;
57845794
});

lib/Backend/BackwardPass.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,11 @@ class BackwardPass
135135
void TrackObjTypeSpecProperties(IR::PropertySymOpnd *opnd, BasicBlock *block);
136136
void TrackObjTypeSpecWriteGuards(IR::PropertySymOpnd *opnd, BasicBlock *block);
137137
void TrackAddPropertyTypes(IR::PropertySymOpnd *opnd, BasicBlock *block);
138-
void InsertTypeTransition(IR::Instr *instrInsertBefore, int symId, AddPropertyCacheBucket *data);
139-
void InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSym, AddPropertyCacheBucket *data);
140-
void InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPropertyCacheBucket *data);
141-
void InsertTypeTransitionsAtPriorSuccessors(BasicBlock *block, BasicBlock *blockSucc, int symId, AddPropertyCacheBucket *data);
142-
void InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPropertyCacheBucket *data);
138+
void InsertTypeTransition(IR::Instr *instrInsertBefore, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses);
139+
void InsertTypeTransition(IR::Instr *instrInsertBefore, StackSym *objSym, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses);
140+
void InsertTypeTransitionAtBlock(BasicBlock *block, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses);
141+
void InsertTypeTransitionsAtPriorSuccessors(BasicBlock *block, BasicBlock *blockSucc, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses);
142+
void InsertTypeTransitionAfterInstr(IR::Instr *instr, int symId, AddPropertyCacheBucket *data, BVSparse<JitArenaAllocator>* upwardExposedUses);
143143
void InsertTypeTransitionsAtPotentialKills();
144144
bool TransitionUndoesObjectHeaderInlining(AddPropertyCacheBucket *data) const;
145145

lib/Backend/GlobOpt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ GlobOpt::GlobOpt(Func * func)
8787
updateInductionVariableValueNumber(false),
8888
isPerformingLoopBackEdgeCompensation(false),
8989
currentRegion(nullptr),
90+
auxSlotPtrSyms(nullptr),
9091
changedSymsAfterIncBailoutCandidate(nullptr),
9192
doTypeSpec(
9293
!IsTypeSpecPhaseOff(func)),
@@ -350,6 +351,8 @@ GlobOpt::ForwardPass()
350351
// changedSymsAfterIncBailoutCandidate helps track building incremental bailout in ForwardPass
351352
this->changedSymsAfterIncBailoutCandidate = JitAnew(alloc, BVSparse<JitArenaAllocator>, alloc);
352353

354+
this->auxSlotPtrSyms = JitAnew(alloc, BVSparse<JitArenaAllocator>, alloc);
355+
353356
#if DBG
354357
this->byteCodeUsesBeforeOpt = JitAnew(this->alloc, BVSparse<JitArenaAllocator>, this->alloc);
355358
if (Js::Configuration::Global.flags.Trace.IsEnabled(Js::FieldCopyPropPhase) && this->DoFunctionFieldCopyProp())
@@ -431,6 +434,7 @@ GlobOpt::ForwardPass()
431434

432435
// this->alloc will be freed right after return, no need to free it here
433436
this->changedSymsAfterIncBailoutCandidate = nullptr;
437+
this->auxSlotPtrSyms = nullptr;
434438

435439
END_CODEGEN_PHASE(this->func, Js::ForwardPhase);
436440
}

lib/Backend/GlobOpt.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,8 @@ class GlobOpt
459459

460460
BVSparse<JitArenaAllocator> * changedSymsAfterIncBailoutCandidate;
461461

462+
BVSparse<JitArenaAllocator> * auxSlotPtrSyms;
463+
462464
JitArenaAllocator * alloc;
463465
JitArenaAllocator * tempAlloc;
464466

@@ -933,6 +935,8 @@ class GlobOpt
933935
bool CheckIfInstrInTypeCheckSeqEmitsTypeCheck(IR::Instr* instr, IR::PropertySymOpnd *opnd);
934936
template<bool makeChanges>
935937
bool ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd, BasicBlock* block, bool updateExistingValue, bool* emitsTypeCheckOut = nullptr, bool* changesTypeValueOut = nullptr, bool *isObjTypeChecked = nullptr);
938+
StackSym * EnsureAuxSlotPtrSym(IR::PropertySymOpnd *opnd);
939+
void KillAuxSlotPtrSyms(IR::PropertySymOpnd *opnd, BasicBlock *block, bool isObjTypeSpecialized);
936940
void KillObjectHeaderInlinedTypeSyms(BasicBlock *block, bool isObjTypeSpecialized, SymID symId = SymID_Invalid);
937941
bool HasLiveObjectHeaderInlinedTypeSym(BasicBlock *block, bool isObjTypeSpecialized, SymID symId = SymID_Invalid);
938942
template<class Fn>

0 commit comments

Comments
 (0)