@@ -1182,6 +1182,10 @@ void GlobOpt::InsertValueCompensation(
1182
1182
IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
1183
1183
Func *const func = insertBeforeInstr->m_func;
1184
1184
bool setLastInstrInPredecessor;
1185
+ // If this is a loop back edge, and the successor has been completed, don't attempt to update its block data.
1186
+ // The update is unnecessary, and the data has likely been freed.
1187
+ bool updateSuccessorBlockData = !this->isPerformingLoopBackEdgeCompensation || successor->GetDataUseCount() > 0;
1188
+
1185
1189
if(insertBeforeInstr->IsBranchInstr() || insertBeforeInstr->m_opcode == Js::OpCode::BailTarget)
1186
1190
{
1187
1191
// Don't insert code between the branch and the corresponding ByteCodeUses instructions
@@ -1272,29 +1276,33 @@ void GlobOpt::InsertValueCompensation(
1272
1276
// Merge the head segment length value
1273
1277
Assert(predecessorBlockData.liveVarSyms->Test(predecessorHeadSegmentLengthSym->m_id));
1274
1278
predecessorBlockData.liveVarSyms->Set(mergedHeadSegmentLengthSym->m_id);
1275
- successorBlockData.liveVarSyms->Set(mergedHeadSegmentLengthSym->m_id);
1276
1279
Value *const predecessorHeadSegmentLengthValue =
1277
1280
predecessorBlockData.FindValue(predecessorHeadSegmentLengthSym);
1278
1281
Assert(predecessorHeadSegmentLengthValue);
1279
1282
predecessorBlockData.SetValue(predecessorHeadSegmentLengthValue, mergedHeadSegmentLengthSym);
1280
- Value *const mergedHeadSegmentLengthValue = successorBlockData.FindValue(mergedHeadSegmentLengthSym);
1281
- if(mergedHeadSegmentLengthValue )
1283
+
1284
+ if (updateSuccessorBlockData )
1282
1285
{
1283
- Assert(mergedHeadSegmentLengthValue->GetValueNumber() != predecessorHeadSegmentLengthValue->GetValueNumber());
1284
- if(predecessorHeadSegmentLengthValue->GetValueInfo() != mergedHeadSegmentLengthValue->GetValueInfo())
1286
+ successorBlockData.liveVarSyms->Set(mergedHeadSegmentLengthSym->m_id);
1287
+ Value *const mergedHeadSegmentLengthValue = successorBlockData.FindValue(mergedHeadSegmentLengthSym);
1288
+ if(mergedHeadSegmentLengthValue)
1285
1289
{
1286
- mergedHeadSegmentLengthValue->SetValueInfo(
1287
- ValueInfo::MergeLikelyIntValueInfo(
1288
- this->alloc,
1289
- mergedHeadSegmentLengthValue,
1290
- predecessorHeadSegmentLengthValue,
1291
- mergedHeadSegmentLengthValue->GetValueInfo()->Type()
1292
- .Merge(predecessorHeadSegmentLengthValue->GetValueInfo()->Type())));
1290
+ Assert(mergedHeadSegmentLengthValue->GetValueNumber() != predecessorHeadSegmentLengthValue->GetValueNumber());
1291
+ if(predecessorHeadSegmentLengthValue->GetValueInfo() != mergedHeadSegmentLengthValue->GetValueInfo())
1292
+ {
1293
+ mergedHeadSegmentLengthValue->SetValueInfo(
1294
+ ValueInfo::MergeLikelyIntValueInfo(
1295
+ this->alloc,
1296
+ mergedHeadSegmentLengthValue,
1297
+ predecessorHeadSegmentLengthValue,
1298
+ mergedHeadSegmentLengthValue->GetValueInfo()->Type()
1299
+ .Merge(predecessorHeadSegmentLengthValue->GetValueInfo()->Type())));
1300
+ }
1301
+ }
1302
+ else
1303
+ {
1304
+ successorBlockData.SetValue(CopyValue(predecessorHeadSegmentLengthValue), mergedHeadSegmentLengthSym);
1293
1305
}
1294
- }
1295
- else
1296
- {
1297
- successorBlockData.SetValue(CopyValue(predecessorHeadSegmentLengthValue), mergedHeadSegmentLengthSym);
1298
1306
}
1299
1307
}
1300
1308
@@ -1315,27 +1323,31 @@ void GlobOpt::InsertValueCompensation(
1315
1323
// Merge the length value
1316
1324
Assert(predecessorBlockData.liveVarSyms->Test(predecessorLengthSym->m_id));
1317
1325
predecessorBlockData.liveVarSyms->Set(mergedLengthSym->m_id);
1318
- successorBlockData.liveVarSyms->Set(mergedLengthSym->m_id);
1319
1326
Value *const predecessorLengthValue = predecessorBlockData.FindValue(predecessorLengthSym);
1320
1327
Assert(predecessorLengthValue);
1321
1328
predecessorBlockData.SetValue(predecessorLengthValue, mergedLengthSym);
1322
- Value *const mergedLengthValue = successorBlockData.FindValue(mergedLengthSym);
1323
- if(mergedLengthValue )
1329
+
1330
+ if (updateSuccessorBlockData )
1324
1331
{
1325
- Assert(mergedLengthValue->GetValueNumber() != predecessorLengthValue->GetValueNumber());
1326
- if(predecessorLengthValue->GetValueInfo() != mergedLengthValue->GetValueInfo())
1332
+ successorBlockData.liveVarSyms->Set(mergedLengthSym->m_id);
1333
+ Value *const mergedLengthValue = successorBlockData.FindValue(mergedLengthSym);
1334
+ if(mergedLengthValue)
1327
1335
{
1328
- mergedLengthValue->SetValueInfo(
1329
- ValueInfo::MergeLikelyIntValueInfo(
1330
- this->alloc,
1331
- mergedLengthValue,
1332
- predecessorLengthValue,
1333
- mergedLengthValue->GetValueInfo()->Type().Merge(predecessorLengthValue->GetValueInfo()->Type())));
1336
+ Assert(mergedLengthValue->GetValueNumber() != predecessorLengthValue->GetValueNumber());
1337
+ if(predecessorLengthValue->GetValueInfo() != mergedLengthValue->GetValueInfo())
1338
+ {
1339
+ mergedLengthValue->SetValueInfo(
1340
+ ValueInfo::MergeLikelyIntValueInfo(
1341
+ this->alloc,
1342
+ mergedLengthValue,
1343
+ predecessorLengthValue,
1344
+ mergedLengthValue->GetValueInfo()->Type().Merge(predecessorLengthValue->GetValueInfo()->Type())));
1345
+ }
1346
+ }
1347
+ else
1348
+ {
1349
+ successorBlockData.SetValue(CopyValue(predecessorLengthValue), mergedLengthSym);
1334
1350
}
1335
- }
1336
- else
1337
- {
1338
- successorBlockData.SetValue(CopyValue(predecessorLengthValue), mergedLengthSym);
1339
1351
}
1340
1352
}
1341
1353
@@ -2116,6 +2128,7 @@ bool GlobOpt::CollectMemcopyStElementI(IR::Instr *instr, Loop *loop)
2116
2128
2117
2129
// Consider: Can we remove the count field?
2118
2130
memcopyInfo->count++;
2131
+ AssertOrFailFast(memcopyInfo->count <= 1);
2119
2132
memcopyInfo->base = baseSymID;
2120
2133
2121
2134
return true;
@@ -2277,6 +2290,7 @@ GlobOpt::CollectMemOpInfo(IR::Instr *instrBegin, IR::Instr *instr, Value *src1Va
2277
2290
{
2278
2291
inductionVariableChangeInfo.unroll++;
2279
2292
}
2293
+
2280
2294
inductionVariableChangeInfo.isIncremental = isIncr;
2281
2295
loop->memOpInfo->inductionVariableChangeInfoMap->Item(inductionSymID, inductionVariableChangeInfo);
2282
2296
if (sym->m_id != inductionSymID)
@@ -17007,6 +17021,7 @@ GlobOpt::GetOrGenerateLoopCountForMemOp(Loop *loop)
17007
17021
IR::Opnd *
17008
17022
GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::Instr *insertBeforeInstr)
17009
17023
{
17024
+ AssertOrFailFast(unroll != Js::Constants::InvalidLoopUnrollFactor);
17010
17025
LoopCount *loopCount = loop->loopCount;
17011
17026
IR::Opnd *sizeOpnd = nullptr;
17012
17027
Assert(loopCount);
@@ -17410,13 +17425,14 @@ GlobOpt::EmitMemop(Loop * loop, LoopCount *loopCount, const MemOpEmitData* emitD
17410
17425
RemoveMemOpSrcInstr(memopInstr, emitData->stElemInstr, emitData->block);
17411
17426
if (!isMemset)
17412
17427
{
17413
- if (((MemCopyEmitData*)emitData)->ldElemInstr->GetSrc1()->IsIndirOpnd())
17428
+ IR::Instr* ldElemInstr = ((MemCopyEmitData*)emitData)->ldElemInstr;
17429
+ if (ldElemInstr->GetSrc1()->IsIndirOpnd())
17414
17430
{
17415
- baseOpnd = ((MemCopyEmitData*)emitData)-> ldElemInstr->GetSrc1()->AsIndirOpnd()->GetBaseOpnd();
17431
+ baseOpnd = ldElemInstr->GetSrc1()->AsIndirOpnd()->GetBaseOpnd();
17416
17432
isLikelyJsArray = baseOpnd->GetValueType().IsLikelyArrayOrObjectWithArray();
17417
- ProcessNoImplicitCallArrayUses(baseOpnd, baseOpnd->IsArrayRegOpnd() ? baseOpnd->AsArrayRegOpnd() : nullptr, emitData->stElemInstr , isLikelyJsArray, true);
17433
+ ProcessNoImplicitCallArrayUses(baseOpnd, baseOpnd->IsArrayRegOpnd() ? baseOpnd->AsArrayRegOpnd() : nullptr, ldElemInstr , isLikelyJsArray, true);
17418
17434
}
17419
- RemoveMemOpSrcInstr(memopInstr, ((MemCopyEmitData*)emitData)-> ldElemInstr, emitData->block);
17435
+ RemoveMemOpSrcInstr(memopInstr, ldElemInstr, emitData->block);
17420
17436
}
17421
17437
InsertNoImplicitCallUses(memopInstr);
17422
17438
noImplicitCallUsesToInsert->Clear();
0 commit comments