@@ -12554,6 +12554,8 @@ GlobOpt::DoTrackNewValueForKills(Value *const value)
12554
12554
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12555
12555
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12556
12556
12557
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12558
+
12557
12559
Loop *implicitCallsLoop;
12558
12560
if(currentBlock->next && !currentBlock->next->isDeleted && currentBlock->next->isLoopHeader)
12559
12561
{
@@ -12568,7 +12570,7 @@ GlobOpt::DoTrackNewValueForKills(Value *const value)
12568
12570
implicitCallsLoop = currentBlock->loop;
12569
12571
}
12570
12572
12571
- if(isJsArray)
12573
+ if(isJsArray || isVirtualTypedArray )
12572
12574
{
12573
12575
if(!DoArrayCheckHoist(valueInfo->Type(), implicitCallsLoop))
12574
12576
{
@@ -12587,7 +12589,7 @@ GlobOpt::DoTrackNewValueForKills(Value *const value)
12587
12589
VerifyArrayValueInfoForTracking(valueInfo, isJsArray, currentBlock);
12588
12590
#endif
12589
12591
12590
- if(!isJsArray)
12592
+ if(!isJsArray && !isVirtualTypedArray )
12591
12593
{
12592
12594
return;
12593
12595
}
@@ -12623,11 +12625,13 @@ GlobOpt::DoTrackCopiedValueForKills(Value *const value)
12623
12625
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12624
12626
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12625
12627
12628
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12629
+
12626
12630
#if DBG
12627
12631
VerifyArrayValueInfoForTracking(valueInfo, isJsArray, currentBlock);
12628
12632
#endif
12629
12633
12630
- if(!isJsArray && !(valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12634
+ if(!isJsArray && !isVirtualTypedArray && ! (valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12631
12635
{
12632
12636
return;
12633
12637
}
@@ -12670,11 +12674,13 @@ GlobOpt::DoTrackMergedValueForKills(
12670
12674
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12671
12675
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12672
12676
12677
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12678
+
12673
12679
#if DBG
12674
12680
VerifyArrayValueInfoForTracking(valueInfo, isJsArray, currentBlock, true);
12675
12681
#endif
12676
12682
12677
- if(!isJsArray && !(valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12683
+ if(!isJsArray && !isVirtualTypedArray && ! (valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12678
12684
{
12679
12685
return;
12680
12686
}
@@ -12707,6 +12713,7 @@ GlobOpt::TrackValueInfoChangeForKills(BasicBlock *const block, Value *const valu
12707
12713
12708
12714
const bool trackOldValueInfo =
12709
12715
oldValueInfo->IsArrayOrObjectWithArray() ||
12716
+ oldValueInfo->IsOptimizedVirtualTypedArray() ||
12710
12717
(
12711
12718
oldValueInfo->IsOptimizedTypedArray() &&
12712
12719
oldValueInfo->IsArrayValueInfo() &&
@@ -12723,6 +12730,7 @@ GlobOpt::TrackValueInfoChangeForKills(BasicBlock *const block, Value *const valu
12723
12730
12724
12731
const bool trackNewValueInfo =
12725
12732
newValueInfo->IsArrayOrObjectWithArray() ||
12733
+ newValueInfo->IsOptimizedVirtualTypedArray() ||
12726
12734
(
12727
12735
newValueInfo->IsOptimizedTypedArray() &&
12728
12736
newValueInfo->IsArrayValueInfo() &&
@@ -12791,6 +12799,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
12791
12799
ValueInfo *const valueInfo = value->GetValueInfo();
12792
12800
Assert(
12793
12801
valueInfo->IsArrayOrObjectWithArray() ||
12802
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12794
12803
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12795
12804
if (valueInfo->IsArrayOrObjectWithArray() || valueInfo->IsOptimizedVirtualTypedArray())
12796
12805
{
@@ -12816,6 +12825,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
12816
12825
ValueInfo *const valueInfo = value->GetValueInfo();
12817
12826
Assert(
12818
12827
valueInfo->IsArrayOrObjectWithArray() ||
12828
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12819
12829
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12820
12830
if(!valueInfo->IsArrayOrObjectWithArray() || !valueInfo->HasNoMissingValues())
12821
12831
{
@@ -12836,6 +12846,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
12836
12846
ValueInfo *const valueInfo = value->GetValueInfo();
12837
12847
Assert(
12838
12848
valueInfo->IsArrayOrObjectWithArray() ||
12849
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12839
12850
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12840
12851
if(!valueInfo->IsArrayOrObjectWithArray() || valueInfo->HasVarElements())
12841
12852
{
@@ -12862,6 +12873,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
12862
12873
ValueInfo *valueInfo = value->GetValueInfo();
12863
12874
Assert(
12864
12875
valueInfo->IsArrayOrObjectWithArray() ||
12876
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12865
12877
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12866
12878
if(!valueInfo->IsArrayOrObjectWithArray())
12867
12879
{
@@ -12937,8 +12949,9 @@ GlobOpt::ProcessValueKills(BasicBlock *const block, GlobOptBlockData *const bloc
12937
12949
ValueInfo *const valueInfo = value->GetValueInfo();
12938
12950
Assert(
12939
12951
valueInfo->IsArrayOrObjectWithArray() ||
12952
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12940
12953
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12941
- if(valueInfo->IsArrayOrObjectWithArray())
12954
+ if(valueInfo->IsArrayOrObjectWithArray() || valueInfo->IsOptimizedVirtualTypedArray() )
12942
12955
{
12943
12956
ChangeValueType(nullptr, value, valueInfo->Type().ToLikely(), false);
12944
12957
continue;
@@ -12971,18 +12984,21 @@ GlobOpt::ProcessValueKillsForLoopHeaderAfterBackEdgeMerge(BasicBlock *const bloc
12971
12984
ValueInfo *valueInfo = value->GetValueInfo();
12972
12985
Assert(
12973
12986
valueInfo->IsArrayOrObjectWithArray() ||
12987
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12974
12988
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12975
12989
12976
12990
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12977
12991
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12978
12992
12979
- if(isJsArray ? loopKills.KillsValueType(valueInfo->Type()) : loopKills.KillsTypedArrayHeadSegmentLengths())
12993
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12994
+
12995
+ if((isJsArray || isVirtualTypedArray) ? loopKills.KillsValueType(valueInfo->Type()) : loopKills.KillsTypedArrayHeadSegmentLengths())
12980
12996
{
12981
12997
// Hoisting array checks and other related things for this type is disabled for the loop due to the kill, as
12982
12998
// compensation code is currently not added on back-edges. When merging values from a back-edge, the array value
12983
12999
// type cannot be definite, as that may require adding compensation code on the back-edge if the optimization pass
12984
13000
// chooses to not optimize the array.
12985
- if(isJsArray)
13001
+ if(isJsArray || isVirtualTypedArray )
12986
13002
{
12987
13003
ChangeValueType(nullptr, value, valueInfo->Type().ToLikely(), false);
12988
13004
}
@@ -14472,14 +14488,16 @@ void
14472
14488
GlobOpt::OptHoistUpdateValueType(
14473
14489
Loop* loop,
14474
14490
IR::Instr* instr,
14475
- IR::Opnd* srcOpnd ,
14491
+ IR::Opnd** srcOpndPtr /* All code paths that change src, should update srcOpndPtr*/ ,
14476
14492
Value* opndVal)
14477
14493
{
14478
- if (opndVal == nullptr || instr->m_opcode == Js::OpCode::FromVar)
14494
+ if (opndVal == nullptr || instr->m_opcode == Js::OpCode::FromVar || srcOpndPtr == nullptr || *srcOpndPtr == nullptr )
14479
14495
{
14480
14496
return;
14481
14497
}
14482
14498
14499
+ IR::Opnd* srcOpnd = *srcOpndPtr;
14500
+
14483
14501
Sym* opndSym = srcOpnd->GetSym();;
14484
14502
14485
14503
if (opndSym)
@@ -14492,8 +14510,11 @@ GlobOpt::OptHoistUpdateValueType(
14492
14510
14493
14511
if (srcOpnd->GetValueType() != opndValueTypeInLandingPad)
14494
14512
{
14513
+ srcOpnd->SetValueType(opndValueTypeInLandingPad);
14514
+
14495
14515
if (instr->m_opcode == Js::OpCode::SetConcatStrMultiItemBE)
14496
14516
{
14517
+ Assert(!opndSym->IsPropertySym());
14497
14518
Assert(!opndValueTypeInLandingPad.IsString());
14498
14519
Assert(instr->GetDst());
14499
14520
@@ -14504,6 +14525,9 @@ GlobOpt::OptHoistUpdateValueType(
14504
14525
IR::Instr::New(Js::OpCode::Conv_PrimStr, strOpnd, srcOpnd->Use(instr->m_func), instr->m_func);
14505
14526
instr->ReplaceSrc(srcOpnd, strOpnd);
14506
14527
14528
+ // Replace above will free srcOpnd, so reassign it
14529
+ *srcOpndPtr = srcOpnd = reinterpret_cast<IR::Opnd *>(strOpnd);
14530
+
14507
14531
if (loop->bailOutInfo->bailOutInstr)
14508
14532
{
14509
14533
loop->bailOutInfo->bailOutInstr->InsertBefore(convPrimStrInstr);
@@ -14512,9 +14536,10 @@ GlobOpt::OptHoistUpdateValueType(
14512
14536
{
14513
14537
landingPad->InsertAfter(convPrimStrInstr);
14514
14538
}
14515
- }
14516
14539
14517
- srcOpnd->SetValueType(opndValueTypeInLandingPad);
14540
+ // If we came here opndSym can't be PropertySym
14541
+ return;
14542
+ }
14518
14543
}
14519
14544
14520
14545
@@ -14548,7 +14573,7 @@ GlobOpt::OptHoistInvariant(
14548
14573
if (src1)
14549
14574
{
14550
14575
// We are hoisting this instruction possibly past other uses, which might invalidate the last use info. Clear it.
14551
- OptHoistUpdateValueType(loop, instr, src1, src1Val);
14576
+ OptHoistUpdateValueType(loop, instr, & src1, src1Val);
14552
14577
14553
14578
if (src1->IsRegOpnd())
14554
14579
{
@@ -14558,7 +14583,7 @@ GlobOpt::OptHoistInvariant(
14558
14583
IR::Opnd* src2 = instr->GetSrc2();
14559
14584
if (src2)
14560
14585
{
14561
- OptHoistUpdateValueType(loop, instr, src2, src2Val);
14586
+ OptHoistUpdateValueType(loop, instr, & src2, src2Val);
14562
14587
14563
14588
if (src2->IsRegOpnd())
14564
14589
{
0 commit comments