Skip to content

Commit ec904a5

Browse files
committed
Disable hoisting invariants when there is a yield in loop bodies
1 parent 40e4a3e commit ec904a5

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/Backend/FlowGraph.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ FlowGraph::Build(void)
196196
BasicBlock * currBlock = nullptr;
197197
BasicBlock * nextBlock = nullptr;
198198
bool hasCall = false;
199+
bool hasYield = false;
199200

200201
FOREACH_INSTR_IN_FUNC_BACKWARD_EDITING(instr, instrPrev, func)
201202
{
@@ -208,7 +209,9 @@ FlowGraph::Build(void)
208209
nextBlock = currBlock;
209210
currBlock = this->AddBlock(instr->m_next, currLastInstr, nextBlock);
210211
currBlock->hasCall = hasCall;
212+
currBlock->hasYield = hasYield;
211213
hasCall = false;
214+
hasYield = false;
212215
}
213216

214217
currLastInstr = instr;
@@ -243,7 +246,9 @@ FlowGraph::Build(void)
243246
nextBlock = currBlock;
244247
currBlock = this->AddBlock(instr, currLastInstr, nextBlock);
245248
currBlock->hasCall = hasCall;
249+
currBlock->hasYield = hasYield;
246250
hasCall = false;
251+
hasYield = false;
247252
currLastInstr = nullptr;
248253
}
249254

@@ -350,6 +355,11 @@ FlowGraph::Build(void)
350355
break;
351356
}
352357

358+
if (instr->m_opcode == Js::OpCode::Yield)
359+
{
360+
hasYield = true;
361+
}
362+
353363
if (OpCodeAttr::UseAllFields(instr->m_opcode))
354364
{
355365
// UseAllFields opcode are call instruction or opcode that would call.
@@ -1400,6 +1410,10 @@ FlowGraph::WalkLoopBlocks(BasicBlock *block, Loop *loop, JitArenaAllocator *temp
14001410
{
14011411
loop->SetHasCall();
14021412
}
1413+
if (pred->loop->hasYield)
1414+
{
1415+
loop->SetHasYield();
1416+
}
14031417
loop->SetImplicitCallFlags(pred->loop->GetImplicitCallFlags());
14041418
}
14051419
// Add pred to loop bit vector
@@ -1430,6 +1444,10 @@ FlowGraph::AddBlockToLoop(BasicBlock *block, Loop *loop)
14301444
{
14311445
loop->SetHasCall();
14321446
}
1447+
if (block->hasYield)
1448+
{
1449+
loop->SetHasYield();
1450+
}
14331451
}
14341452

14351453
///----------------------------------------------------------------------------
@@ -3500,6 +3518,29 @@ Loop::SetHasCall()
35003518
while (current != nullptr);
35013519
}
35023520

3521+
void
3522+
Loop::SetHasYield()
3523+
{
3524+
Loop* current = this;
3525+
do
3526+
{
3527+
if (current->hasYield)
3528+
{
3529+
#if DBG
3530+
current = current->parent;
3531+
while (current)
3532+
{
3533+
Assert(current->hasYield);
3534+
current = current->parent;
3535+
}
3536+
#endif
3537+
break;
3538+
}
3539+
current->hasYield = true;
3540+
current = current->parent;
3541+
} while (current != nullptr);
3542+
}
3543+
35033544
void
35043545
Loop::SetImplicitCallFlags(Js::ImplicitCallFlags newFlags)
35053546
{
@@ -3570,7 +3611,7 @@ Loop::CanHoistInvariants() const
35703611
return false;
35713612
}
35723613

3573-
return true;
3614+
return !this->hasYield;
35743615
}
35753616

35763617
IR::LabelInstr *

lib/Backend/FlowGraph.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ class BasicBlock
371371
uint8 isDead:1;
372372
uint8 isLoopHeader:1;
373373
uint8 hasCall:1;
374+
uint8 hasYield:1;
374375
uint8 isVisited:1;
375376
uint8 isAirLockCompensationBlock:1;
376377
uint8 beginsBailOnNoProfile:1;
@@ -429,6 +430,7 @@ class BasicBlock
429430
isDead(false),
430431
isLoopHeader(false),
431432
hasCall(false),
433+
hasYield(false),
432434
liveFixedFields(nullptr),
433435
upwardExposedUses(nullptr),
434436
upwardExposedFields(nullptr),
@@ -614,6 +616,7 @@ class Loop
614616
bool hasDeadStoreCollectionPass : 1;
615617
bool hasDeadStorePrepass : 1;
616618
bool hasCall : 1;
619+
bool hasYield : 1;
617620
bool hasHoistedFields : 1;
618621
bool needImplicitCallBailoutChecksForJsArrayCheckHoist : 1;
619622
bool allFieldsKilled : 1;
@@ -763,6 +766,7 @@ class Loop
763766
bool CanHoistInvariants() const;
764767
bool CanDoFieldCopyProp();
765768
void SetHasCall();
769+
void SetHasYield();
766770
IR::LabelInstr * GetLoopTopInstr() const;
767771
void SetLoopTopInstr(IR::LabelInstr * loopTop);
768772
Func * GetFunc() const { return GetLoopTopInstr()->m_func; }

0 commit comments

Comments
 (0)