@@ -1167,6 +1167,10 @@ void GlobOpt::InsertValueCompensation(
1167
1167
IR::Instr *insertBeforeInstr = predecessor->GetLastInstr();
1168
1168
Func *const func = insertBeforeInstr->m_func;
1169
1169
bool setLastInstrInPredecessor;
1170
+ // If this is a loop back edge, and the successor has been completed, don't attempt to update its block data.
1171
+ // The update is unnecessary, and the data has likely been freed.
1172
+ bool updateSuccessorBlockData = !this->isPerformingLoopBackEdgeCompensation || successor->GetDataUseCount() > 0;
1173
+
1170
1174
if(insertBeforeInstr->IsBranchInstr() || insertBeforeInstr->m_opcode == Js::OpCode::BailTarget)
1171
1175
{
1172
1176
// Don't insert code between the branch and the corresponding ByteCodeUses instructions
@@ -1257,29 +1261,33 @@ void GlobOpt::InsertValueCompensation(
1257
1261
// Merge the head segment length value
1258
1262
Assert(predecessorBlockData.liveVarSyms->Test(predecessorHeadSegmentLengthSym->m_id));
1259
1263
predecessorBlockData.liveVarSyms->Set(mergedHeadSegmentLengthSym->m_id);
1260
- successorBlockData.liveVarSyms->Set(mergedHeadSegmentLengthSym->m_id);
1261
1264
Value *const predecessorHeadSegmentLengthValue =
1262
1265
predecessorBlockData.FindValue(predecessorHeadSegmentLengthSym);
1263
1266
Assert(predecessorHeadSegmentLengthValue);
1264
1267
predecessorBlockData.SetValue(predecessorHeadSegmentLengthValue, mergedHeadSegmentLengthSym);
1265
- Value *const mergedHeadSegmentLengthValue = successorBlockData.FindValue(mergedHeadSegmentLengthSym);
1266
- if(mergedHeadSegmentLengthValue )
1268
+
1269
+ if (updateSuccessorBlockData )
1267
1270
{
1268
- Assert(mergedHeadSegmentLengthValue->GetValueNumber() != predecessorHeadSegmentLengthValue->GetValueNumber());
1269
- if(predecessorHeadSegmentLengthValue->GetValueInfo() != mergedHeadSegmentLengthValue->GetValueInfo())
1271
+ successorBlockData.liveVarSyms->Set(mergedHeadSegmentLengthSym->m_id);
1272
+ Value *const mergedHeadSegmentLengthValue = successorBlockData.FindValue(mergedHeadSegmentLengthSym);
1273
+ if(mergedHeadSegmentLengthValue)
1270
1274
{
1271
- mergedHeadSegmentLengthValue->SetValueInfo(
1272
- ValueInfo::MergeLikelyIntValueInfo(
1273
- this->alloc,
1274
- mergedHeadSegmentLengthValue,
1275
- predecessorHeadSegmentLengthValue,
1276
- mergedHeadSegmentLengthValue->GetValueInfo()->Type()
1277
- .Merge(predecessorHeadSegmentLengthValue->GetValueInfo()->Type())));
1275
+ Assert(mergedHeadSegmentLengthValue->GetValueNumber() != predecessorHeadSegmentLengthValue->GetValueNumber());
1276
+ if(predecessorHeadSegmentLengthValue->GetValueInfo() != mergedHeadSegmentLengthValue->GetValueInfo())
1277
+ {
1278
+ mergedHeadSegmentLengthValue->SetValueInfo(
1279
+ ValueInfo::MergeLikelyIntValueInfo(
1280
+ this->alloc,
1281
+ mergedHeadSegmentLengthValue,
1282
+ predecessorHeadSegmentLengthValue,
1283
+ mergedHeadSegmentLengthValue->GetValueInfo()->Type()
1284
+ .Merge(predecessorHeadSegmentLengthValue->GetValueInfo()->Type())));
1285
+ }
1286
+ }
1287
+ else
1288
+ {
1289
+ successorBlockData.SetValue(CopyValue(predecessorHeadSegmentLengthValue), mergedHeadSegmentLengthSym);
1278
1290
}
1279
- }
1280
- else
1281
- {
1282
- successorBlockData.SetValue(CopyValue(predecessorHeadSegmentLengthValue), mergedHeadSegmentLengthSym);
1283
1291
}
1284
1292
}
1285
1293
@@ -1300,27 +1308,31 @@ void GlobOpt::InsertValueCompensation(
1300
1308
// Merge the length value
1301
1309
Assert(predecessorBlockData.liveVarSyms->Test(predecessorLengthSym->m_id));
1302
1310
predecessorBlockData.liveVarSyms->Set(mergedLengthSym->m_id);
1303
- successorBlockData.liveVarSyms->Set(mergedLengthSym->m_id);
1304
1311
Value *const predecessorLengthValue = predecessorBlockData.FindValue(predecessorLengthSym);
1305
1312
Assert(predecessorLengthValue);
1306
1313
predecessorBlockData.SetValue(predecessorLengthValue, mergedLengthSym);
1307
- Value *const mergedLengthValue = successorBlockData.FindValue(mergedLengthSym);
1308
- if(mergedLengthValue )
1314
+
1315
+ if (updateSuccessorBlockData )
1309
1316
{
1310
- Assert(mergedLengthValue->GetValueNumber() != predecessorLengthValue->GetValueNumber());
1311
- if(predecessorLengthValue->GetValueInfo() != mergedLengthValue->GetValueInfo())
1317
+ successorBlockData.liveVarSyms->Set(mergedLengthSym->m_id);
1318
+ Value *const mergedLengthValue = successorBlockData.FindValue(mergedLengthSym);
1319
+ if(mergedLengthValue)
1312
1320
{
1313
- mergedLengthValue->SetValueInfo(
1314
- ValueInfo::MergeLikelyIntValueInfo(
1315
- this->alloc,
1316
- mergedLengthValue,
1317
- predecessorLengthValue,
1318
- mergedLengthValue->GetValueInfo()->Type().Merge(predecessorLengthValue->GetValueInfo()->Type())));
1321
+ Assert(mergedLengthValue->GetValueNumber() != predecessorLengthValue->GetValueNumber());
1322
+ if(predecessorLengthValue->GetValueInfo() != mergedLengthValue->GetValueInfo())
1323
+ {
1324
+ mergedLengthValue->SetValueInfo(
1325
+ ValueInfo::MergeLikelyIntValueInfo(
1326
+ this->alloc,
1327
+ mergedLengthValue,
1328
+ predecessorLengthValue,
1329
+ mergedLengthValue->GetValueInfo()->Type().Merge(predecessorLengthValue->GetValueInfo()->Type())));
1330
+ }
1331
+ }
1332
+ else
1333
+ {
1334
+ successorBlockData.SetValue(CopyValue(predecessorLengthValue), mergedLengthSym);
1319
1335
}
1320
- }
1321
- else
1322
- {
1323
- successorBlockData.SetValue(CopyValue(predecessorLengthValue), mergedLengthSym);
1324
1336
}
1325
1337
}
1326
1338
@@ -2087,6 +2099,7 @@ bool GlobOpt::CollectMemcopyStElementI(IR::Instr *instr, Loop *loop)
2087
2099
2088
2100
// Consider: Can we remove the count field?
2089
2101
memcopyInfo->count++;
2102
+ AssertOrFailFast(memcopyInfo->count <= 1);
2090
2103
memcopyInfo->base = baseSymID;
2091
2104
2092
2105
return true;
@@ -2226,7 +2239,14 @@ GlobOpt::CollectMemOpInfo(IR::Instr *instrBegin, IR::Instr *instr, Value *src1Va
2226
2239
{
2227
2240
Loop::InductionVariableChangeInfo inductionVariableChangeInfo = { 0, 0 };
2228
2241
inductionVariableChangeInfo = loop->memOpInfo->inductionVariableChangeInfoMap->Lookup(inductionSymID, inductionVariableChangeInfo);
2229
- inductionVariableChangeInfo.unroll++;
2242
+
2243
+ // If inductionVariableChangeInfo.unroll has been invalidated, do
2244
+ // not modify the Js::Constants::InvalidLoopUnrollFactor value
2245
+ if (inductionVariableChangeInfo.unroll != Js::Constants::InvalidLoopUnrollFactor)
2246
+ {
2247
+ inductionVariableChangeInfo.unroll++;
2248
+ }
2249
+
2230
2250
inductionVariableChangeInfo.isIncremental = isIncr;
2231
2251
loop->memOpInfo->inductionVariableChangeInfoMap->Item(inductionSymID, inductionVariableChangeInfo);
2232
2252
}
@@ -16677,6 +16697,7 @@ GlobOpt::GetOrGenerateLoopCountForMemOp(Loop *loop)
16677
16697
IR::Opnd *
16678
16698
GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::Instr *insertBeforeInstr)
16679
16699
{
16700
+ AssertOrFailFast(unroll != Js::Constants::InvalidLoopUnrollFactor);
16680
16701
LoopCount *loopCount = loop->loopCount;
16681
16702
IR::Opnd *sizeOpnd = nullptr;
16682
16703
Assert(loopCount);
@@ -16714,11 +16735,12 @@ GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::In
16714
16735
16715
16736
IR::Opnd *unrollOpnd = IR::IntConstOpnd::New(unroll, type, localFunc);
16716
16737
16717
- InsertInstr(IR::Instr::New(Js::OpCode::Mul_I4,
16718
- sizeOpnd,
16719
- loopCountOpnd,
16720
- unrollOpnd,
16721
- localFunc));
16738
+ IR::Instr* inductionChangeMultiplier = IR::Instr::New(
16739
+ Js::OpCode::Mul_I4, sizeOpnd, loopCountOpnd, unrollOpnd, localFunc);
16740
+
16741
+ InsertInstr(inductionChangeMultiplier);
16742
+
16743
+ inductionChangeMultiplier->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
16722
16744
16723
16745
}
16724
16746
}
0 commit comments