@@ -13149,6 +13149,37 @@ GlobOpt::OptArraySrc(IR::Instr ** const instrRef, Value ** src1Val, Value ** src
1314913149 arraySrcOpt.Optimize();
1315013150}
1315113151
13152+ void
13153+ GlobOpt::ProcessNoImplicitCallArrayUses(IR::RegOpnd * baseOpnd, IR::ArrayRegOpnd * baseArrayOpnd, IR::Instr * instr, bool isLikelyJsArray, bool useNoMissingValues)
13154+ {
13155+ if (isLikelyJsArray)
13156+ {
13157+ // Insert an instruction to indicate to the dead-store pass that implicit calls need to be kept disabled until this
13158+ // instruction. Operations other than LdElem, StElem and IsIn don't benefit much from arrays having no missing values,
13159+ // so no need to ensure that the array still has no missing values. For a particular array, if none of the accesses
13160+ // benefit much from the no-missing-values information, it may be beneficial to avoid checking for no missing
13161+ // values, especially in the case for a single array access, where the cost of the check could be relatively
13162+ // significant. An StElem has to do additional checks in the common path if the array may have missing values, and
13163+ // a StElem that operates on an array that has no missing values is more likely to keep the no-missing-values info
13164+ // on the array more precise, so it still benefits a little from the no-missing-values info.
13165+ this->CaptureNoImplicitCallUses(baseOpnd, isLikelyJsArray);
13166+ }
13167+ else if (baseArrayOpnd && baseArrayOpnd->HeadSegmentLengthSym())
13168+ {
13169+ // A typed array's array buffer may be transferred to a web worker as part of an implicit call, in which case the typed
13170+ // array's length is set to zero. Insert an instruction to indicate to the dead-store pass that implicit calls need to
13171+ // be disabled until this instruction.
13172+ IR::RegOpnd *const headSegmentLengthOpnd =
13173+ IR::RegOpnd::New(
13174+ baseArrayOpnd->HeadSegmentLengthSym(),
13175+ baseArrayOpnd->HeadSegmentLengthSym()->GetType(),
13176+ instr->m_func);
13177+
13178+ const IR::AutoReuseOpnd autoReuseHeadSegmentLengthOpnd(headSegmentLengthOpnd, instr->m_func);
13179+ this->CaptureNoImplicitCallUses(headSegmentLengthOpnd, false);
13180+ }
13181+ }
13182+
1315213183void
1315313184GlobOpt::CaptureNoImplicitCallUses(
1315413185 IR::Opnd *opnd,
@@ -17038,11 +17069,27 @@ GlobOpt::EmitMemop(Loop * loop, LoopCount *loopCount, const MemOpEmitData* emitD
1703817069 }
1703917070#endif
1704017071
17072+ Assert(noImplicitCallUsesToInsert->Count() == 0);
17073+ bool isLikelyJsArray;
17074+ if (emitData->stElemInstr->GetDst()->IsIndirOpnd())
17075+ {
17076+ baseOpnd = emitData->stElemInstr->GetDst()->AsIndirOpnd()->GetBaseOpnd();
17077+ isLikelyJsArray = baseOpnd->GetValueType().IsLikelyArrayOrObjectWithArray();
17078+ ProcessNoImplicitCallArrayUses(baseOpnd, baseOpnd->IsArrayRegOpnd() ? baseOpnd->AsArrayRegOpnd() : nullptr, emitData->stElemInstr, isLikelyJsArray, true);
17079+ }
1704117080 RemoveMemOpSrcInstr(memopInstr, emitData->stElemInstr, emitData->block);
1704217081 if (!isMemset)
1704317082 {
17083+ if (((MemCopyEmitData*)emitData)->ldElemInstr->GetSrc1()->IsIndirOpnd())
17084+ {
17085+ baseOpnd = ((MemCopyEmitData*)emitData)->ldElemInstr->GetSrc1()->AsIndirOpnd()->GetBaseOpnd();
17086+ isLikelyJsArray = baseOpnd->GetValueType().IsLikelyArrayOrObjectWithArray();
17087+ ProcessNoImplicitCallArrayUses(baseOpnd, baseOpnd->IsArrayRegOpnd() ? baseOpnd->AsArrayRegOpnd() : nullptr, emitData->stElemInstr, isLikelyJsArray, true);
17088+ }
1704417089 RemoveMemOpSrcInstr(memopInstr, ((MemCopyEmitData*)emitData)->ldElemInstr, emitData->block);
1704517090 }
17091+ InsertNoImplicitCallUses(memopInstr);
17092+ noImplicitCallUsesToInsert->Clear();
1704617093}
1704717094
1704817095bool
0 commit comments