@@ -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);
0 commit comments