@@ -12746,6 +12746,8 @@ GlobOpt::DoTrackNewValueForKills(Value *const value)
12746
12746
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12747
12747
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12748
12748
12749
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12750
+
12749
12751
Loop *implicitCallsLoop;
12750
12752
if(currentBlock->next && !currentBlock->next->isDeleted && currentBlock->next->isLoopHeader)
12751
12753
{
@@ -12760,7 +12762,7 @@ GlobOpt::DoTrackNewValueForKills(Value *const value)
12760
12762
implicitCallsLoop = currentBlock->loop;
12761
12763
}
12762
12764
12763
- if(isJsArray)
12765
+ if(isJsArray || isVirtualTypedArray )
12764
12766
{
12765
12767
if(!DoArrayCheckHoist(valueInfo->Type(), implicitCallsLoop))
12766
12768
{
@@ -12779,7 +12781,7 @@ GlobOpt::DoTrackNewValueForKills(Value *const value)
12779
12781
VerifyArrayValueInfoForTracking(valueInfo, isJsArray, currentBlock);
12780
12782
#endif
12781
12783
12782
- if(!isJsArray)
12784
+ if(!isJsArray && !isVirtualTypedArray )
12783
12785
{
12784
12786
return;
12785
12787
}
@@ -12815,11 +12817,13 @@ GlobOpt::DoTrackCopiedValueForKills(Value *const value)
12815
12817
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12816
12818
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12817
12819
12820
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12821
+
12818
12822
#if DBG
12819
12823
VerifyArrayValueInfoForTracking(valueInfo, isJsArray, currentBlock);
12820
12824
#endif
12821
12825
12822
- if(!isJsArray && !(valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12826
+ if(!isJsArray && !isVirtualTypedArray && ! (valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12823
12827
{
12824
12828
return;
12825
12829
}
@@ -12862,11 +12866,13 @@ GlobOpt::DoTrackMergedValueForKills(
12862
12866
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
12863
12867
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
12864
12868
12869
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
12870
+
12865
12871
#if DBG
12866
12872
VerifyArrayValueInfoForTracking(valueInfo, isJsArray, currentBlock, true);
12867
12873
#endif
12868
12874
12869
- if(!isJsArray && !(valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12875
+ if(!isJsArray && !isVirtualTypedArray && ! (valueInfo->IsArrayValueInfo() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym()))
12870
12876
{
12871
12877
return;
12872
12878
}
@@ -12899,6 +12905,7 @@ GlobOpt::TrackValueInfoChangeForKills(BasicBlock *const block, Value *const valu
12899
12905
12900
12906
const bool trackOldValueInfo =
12901
12907
oldValueInfo->IsArrayOrObjectWithArray() ||
12908
+ oldValueInfo->IsOptimizedVirtualTypedArray() ||
12902
12909
(
12903
12910
oldValueInfo->IsOptimizedTypedArray() &&
12904
12911
oldValueInfo->IsArrayValueInfo() &&
@@ -12915,6 +12922,7 @@ GlobOpt::TrackValueInfoChangeForKills(BasicBlock *const block, Value *const valu
12915
12922
12916
12923
const bool trackNewValueInfo =
12917
12924
newValueInfo->IsArrayOrObjectWithArray() ||
12925
+ newValueInfo->IsOptimizedVirtualTypedArray() ||
12918
12926
(
12919
12927
newValueInfo->IsOptimizedTypedArray() &&
12920
12928
newValueInfo->IsArrayValueInfo() &&
@@ -12983,6 +12991,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
12983
12991
ValueInfo *const valueInfo = value->GetValueInfo();
12984
12992
Assert(
12985
12993
valueInfo->IsArrayOrObjectWithArray() ||
12994
+ valueInfo->IsOptimizedVirtualTypedArray() ||
12986
12995
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
12987
12996
if (valueInfo->IsArrayOrObjectWithArray() || valueInfo->IsOptimizedVirtualTypedArray())
12988
12997
{
@@ -13008,6 +13017,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
13008
13017
ValueInfo *const valueInfo = value->GetValueInfo();
13009
13018
Assert(
13010
13019
valueInfo->IsArrayOrObjectWithArray() ||
13020
+ valueInfo->IsOptimizedVirtualTypedArray() ||
13011
13021
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
13012
13022
if(!valueInfo->IsArrayOrObjectWithArray() || !valueInfo->HasNoMissingValues())
13013
13023
{
@@ -13028,6 +13038,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
13028
13038
ValueInfo *const valueInfo = value->GetValueInfo();
13029
13039
Assert(
13030
13040
valueInfo->IsArrayOrObjectWithArray() ||
13041
+ valueInfo->IsOptimizedVirtualTypedArray() ||
13031
13042
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
13032
13043
if(!valueInfo->IsArrayOrObjectWithArray() || valueInfo->HasVarElements())
13033
13044
{
@@ -13054,6 +13065,7 @@ GlobOpt::ProcessValueKills(IR::Instr *const instr)
13054
13065
ValueInfo *valueInfo = value->GetValueInfo();
13055
13066
Assert(
13056
13067
valueInfo->IsArrayOrObjectWithArray() ||
13068
+ valueInfo->IsOptimizedVirtualTypedArray() ||
13057
13069
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
13058
13070
if(!valueInfo->IsArrayOrObjectWithArray())
13059
13071
{
@@ -13129,8 +13141,9 @@ GlobOpt::ProcessValueKills(BasicBlock *const block, GlobOptBlockData *const bloc
13129
13141
ValueInfo *const valueInfo = value->GetValueInfo();
13130
13142
Assert(
13131
13143
valueInfo->IsArrayOrObjectWithArray() ||
13144
+ valueInfo->IsOptimizedVirtualTypedArray() ||
13132
13145
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
13133
- if(valueInfo->IsArrayOrObjectWithArray())
13146
+ if(valueInfo->IsArrayOrObjectWithArray() || valueInfo->IsOptimizedVirtualTypedArray() )
13134
13147
{
13135
13148
ChangeValueType(nullptr, value, valueInfo->Type().ToLikely(), false);
13136
13149
continue;
@@ -13163,18 +13176,21 @@ GlobOpt::ProcessValueKillsForLoopHeaderAfterBackEdgeMerge(BasicBlock *const bloc
13163
13176
ValueInfo *valueInfo = value->GetValueInfo();
13164
13177
Assert(
13165
13178
valueInfo->IsArrayOrObjectWithArray() ||
13179
+ valueInfo->IsOptimizedVirtualTypedArray() ||
13166
13180
valueInfo->IsOptimizedTypedArray() && valueInfo->AsArrayValueInfo()->HeadSegmentLengthSym());
13167
13181
13168
13182
const bool isJsArray = valueInfo->IsArrayOrObjectWithArray();
13169
13183
Assert(!isJsArray == valueInfo->IsOptimizedTypedArray());
13170
13184
13171
- if(isJsArray ? loopKills.KillsValueType(valueInfo->Type()) : loopKills.KillsTypedArrayHeadSegmentLengths())
13185
+ const bool isVirtualTypedArray = valueInfo->IsOptimizedVirtualTypedArray();
13186
+
13187
+ if((isJsArray || isVirtualTypedArray) ? loopKills.KillsValueType(valueInfo->Type()) : loopKills.KillsTypedArrayHeadSegmentLengths())
13172
13188
{
13173
13189
// Hoisting array checks and other related things for this type is disabled for the loop due to the kill, as
13174
13190
// compensation code is currently not added on back-edges. When merging values from a back-edge, the array value
13175
13191
// type cannot be definite, as that may require adding compensation code on the back-edge if the optimization pass
13176
13192
// chooses to not optimize the array.
13177
- if(isJsArray)
13193
+ if(isJsArray || isVirtualTypedArray )
13178
13194
{
13179
13195
ChangeValueType(nullptr, value, valueInfo->Type().ToLikely(), false);
13180
13196
}
@@ -16452,14 +16468,16 @@ void
16452
16468
GlobOpt::OptHoistUpdateValueType(
16453
16469
Loop* loop,
16454
16470
IR::Instr* instr,
16455
- IR::Opnd* srcOpnd ,
16471
+ IR::Opnd** srcOpndPtr /* All code paths that change src, should update srcOpndPtr*/ ,
16456
16472
Value* opndVal)
16457
16473
{
16458
- if (opndVal == nullptr || instr->m_opcode == Js::OpCode::FromVar)
16474
+ if (opndVal == nullptr || instr->m_opcode == Js::OpCode::FromVar || srcOpndPtr == nullptr || *srcOpndPtr == nullptr )
16459
16475
{
16460
16476
return;
16461
16477
}
16462
16478
16479
+ IR::Opnd* srcOpnd = *srcOpndPtr;
16480
+
16463
16481
Sym* opndSym = srcOpnd->GetSym();;
16464
16482
16465
16483
if (opndSym)
@@ -16472,8 +16490,11 @@ GlobOpt::OptHoistUpdateValueType(
16472
16490
16473
16491
if (srcOpnd->GetValueType() != opndValueTypeInLandingPad)
16474
16492
{
16493
+ srcOpnd->SetValueType(opndValueTypeInLandingPad);
16494
+
16475
16495
if (instr->m_opcode == Js::OpCode::SetConcatStrMultiItemBE)
16476
16496
{
16497
+ Assert(!opndSym->IsPropertySym());
16477
16498
Assert(!opndValueTypeInLandingPad.IsString());
16478
16499
Assert(instr->GetDst());
16479
16500
@@ -16484,6 +16505,9 @@ GlobOpt::OptHoistUpdateValueType(
16484
16505
IR::Instr::New(Js::OpCode::Conv_PrimStr, strOpnd, srcOpnd->Use(instr->m_func), instr->m_func);
16485
16506
instr->ReplaceSrc(srcOpnd, strOpnd);
16486
16507
16508
+ // Replace above will free srcOpnd, so reassign it
16509
+ *srcOpndPtr = srcOpnd = reinterpret_cast<IR::Opnd *>(strOpnd);
16510
+
16487
16511
if (loop->bailOutInfo->bailOutInstr)
16488
16512
{
16489
16513
loop->bailOutInfo->bailOutInstr->InsertBefore(convPrimStrInstr);
@@ -16492,9 +16516,10 @@ GlobOpt::OptHoistUpdateValueType(
16492
16516
{
16493
16517
landingPad->InsertAfter(convPrimStrInstr);
16494
16518
}
16495
- }
16496
16519
16497
- srcOpnd->SetValueType(opndValueTypeInLandingPad);
16520
+ // If we came here opndSym can't be PropertySym
16521
+ return;
16522
+ }
16498
16523
}
16499
16524
16500
16525
@@ -16528,7 +16553,7 @@ GlobOpt::OptHoistInvariant(
16528
16553
if (src1)
16529
16554
{
16530
16555
// We are hoisting this instruction possibly past other uses, which might invalidate the last use info. Clear it.
16531
- OptHoistUpdateValueType(loop, instr, src1, src1Val);
16556
+ OptHoistUpdateValueType(loop, instr, & src1, src1Val);
16532
16557
16533
16558
if (src1->IsRegOpnd())
16534
16559
{
@@ -16538,7 +16563,7 @@ GlobOpt::OptHoistInvariant(
16538
16563
IR::Opnd* src2 = instr->GetSrc2();
16539
16564
if (src2)
16540
16565
{
16541
- OptHoistUpdateValueType(loop, instr, src2, src2Val);
16566
+ OptHoistUpdateValueType(loop, instr, & src2, src2Val);
16542
16567
16543
16568
if (src2->IsRegOpnd())
16544
16569
{
0 commit comments