@@ -353,12 +353,10 @@ IRBuilder::Build()
353
353
if (tempCount > 0 )
354
354
{
355
355
this ->tempMap = AnewArrayZ (m_tempAlloc, SymID, tempCount);
356
- this ->fbvTempUsed = BVFixed::New<JitArenaAllocator>(tempCount, m_tempAlloc);
357
356
}
358
357
else
359
358
{
360
359
this ->tempMap = nullptr ;
361
- this ->fbvTempUsed = nullptr ;
362
360
}
363
361
364
362
m_func->m_headInstr = IR::EntryInstr::New (Js::OpCode::FunctionEntry, m_func);
@@ -1224,7 +1222,6 @@ IRBuilder::BuildSrcStackSymID(Js::RegSlot regSlot)
1224
1222
this ->SetMappedTemp (regSlot, symID);
1225
1223
this ->EnsureLoopBodyLoadSlot (symID);
1226
1224
}
1227
- this ->SetTempUsed (regSlot, TRUE );
1228
1225
}
1229
1226
else
1230
1227
{
@@ -1315,7 +1312,7 @@ IRBuilder::BuildSrcOpnd(Js::RegSlot srcRegSlot, IRType type)
1315
1312
// /----------------------------------------------------------------------------
1316
1313
1317
1314
IR::RegOpnd *
1318
- IRBuilder::BuildDstOpnd (Js::RegSlot dstRegSlot, IRType type, bool isCatchObjectSym)
1315
+ IRBuilder::BuildDstOpnd (Js::RegSlot dstRegSlot, IRType type, bool isCatchObjectSym, bool reuseTemp )
1319
1316
{
1320
1317
StackSym * symDst;
1321
1318
SymID symID;
@@ -1336,24 +1333,20 @@ IRBuilder::BuildDstOpnd(Js::RegSlot dstRegSlot, IRType type, bool isCatchObjectS
1336
1333
1337
1334
// This is a def of a temp. Create a new sym ID for it if it's been used since its last def.
1338
1335
// !!!NOTE: always process an instruction's temp uses before its temp defs!!!
1339
- if (this ->GetTempUsed (dstRegSlot))
1336
+
1337
+ symID = this ->GetMappedTemp (dstRegSlot);
1338
+ if (symID == 0 )
1340
1339
{
1341
- symID = m_func-> m_symTable -> NewID ();
1342
- this -> SetTempUsed (dstRegSlot, FALSE );
1340
+ // First time we've seen the temp. Just use the number that the front end gave it.
1341
+ symID = static_cast <SymID> (dstRegSlot);
1343
1342
this ->SetMappedTemp (dstRegSlot, symID);
1344
1343
}
1345
- else
1344
+ else if (!reuseTemp)
1346
1345
{
1347
- symID = this ->GetMappedTemp (dstRegSlot);
1348
- // The temp hasn't been used since its last def. There are 2 possibilities:
1349
- if (symID == 0 )
1350
- {
1351
- // First time we've seen the temp. Just use the number that the front end gave it.
1352
- symID = static_cast <SymID>(dstRegSlot);
1353
- this ->SetMappedTemp (dstRegSlot, symID);
1354
- }
1346
+ // Byte code has not told us to reuse the mapped temp at this def, so don't. Make a new one.
1347
+ symID = m_func->m_symTable ->NewID ();
1348
+ this ->SetMappedTemp (dstRegSlot, symID);
1355
1349
}
1356
-
1357
1350
}
1358
1351
else
1359
1352
{
@@ -1506,6 +1499,7 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
1506
1499
IR::Opnd * srcOpnd = nullptr ;
1507
1500
bool isNotInt = false ;
1508
1501
bool dstIsCatchObject = false ;
1502
+ bool reuseLoc = false ;
1509
1503
ValueType dstValueType;
1510
1504
switch (newOpcode)
1511
1505
{
@@ -1560,6 +1554,9 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
1560
1554
isNotInt = true ;
1561
1555
break ;
1562
1556
1557
+ case Js::OpCode::LdLocalObj_ReuseLoc:
1558
+ reuseLoc = true ;
1559
+ // fall through
1563
1560
case Js::OpCode::LdLocalObj:
1564
1561
if (!m_func->GetJITFunctionBody ()->HasScopeObject ())
1565
1562
{
@@ -1636,6 +1633,9 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
1636
1633
break ;
1637
1634
}
1638
1635
1636
+ case Js::OpCode::LdFalse_ReuseLoc:
1637
+ reuseLoc = true ;
1638
+ // fall through
1639
1639
case Js::OpCode::LdFalse:
1640
1640
{
1641
1641
const auto addrOpnd = IR::AddrOpnd::New (m_func->GetScriptContextInfo ()->GetFalseAddr (), IR::AddrOpndKindDynamicVar, m_func, true );
@@ -1645,6 +1645,9 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
1645
1645
break ;
1646
1646
}
1647
1647
1648
+ case Js::OpCode::LdTrue_ReuseLoc:
1649
+ reuseLoc = true ;
1650
+ // fall through
1648
1651
case Js::OpCode::LdTrue:
1649
1652
{
1650
1653
const auto addrOpnd = IR::AddrOpnd::New (m_func->GetScriptContextInfo ()->GetTrueAddr (), IR::AddrOpndKindDynamicVar, m_func, true );
@@ -1666,12 +1669,6 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
1666
1669
isNotInt = TRUE ;
1667
1670
break ;
1668
1671
1669
- case Js::OpCode::Unused:
1670
- // Don't generate anything. Just indicate that the temp reg is used.
1671
- Assert (this ->RegIsTemp (dstRegSlot));
1672
- this ->SetTempUsed (dstRegSlot, TRUE );
1673
- return ;
1674
-
1675
1672
case Js::OpCode::InitUndecl:
1676
1673
srcOpnd = IR::AddrOpnd::New (m_func->GetScriptContextInfo ()->GetUndeclBlockVarAddr (), IR::AddrOpndKindDynamicVar, m_func, true );
1677
1674
srcOpnd->SetValueType (ValueType::PrimitiveOrObject);
@@ -1705,7 +1702,7 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
1705
1702
}
1706
1703
}
1707
1704
1708
- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, dstIsCatchObject);
1705
+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, dstIsCatchObject, reuseLoc );
1709
1706
dstOpnd->SetValueType (dstValueType);
1710
1707
StackSym * dstSym = dstOpnd->m_sym ;
1711
1708
dstSym->m_isCatchObjectSym = dstIsCatchObject;
@@ -1773,9 +1770,25 @@ IRBuilder::BuildReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, Js::Re
1773
1770
{
1774
1771
IR::RegOpnd * src1Opnd = this ->BuildSrcOpnd (R1);
1775
1772
StackSym * symSrc1 = src1Opnd->m_sym ;
1773
+ bool reuseLoc = false ;
1776
1774
1777
1775
switch (newOpcode)
1778
1776
{
1777
+ case Js::OpCode::Ld_A_ReuseLoc:
1778
+ newOpcode = Js::OpCode::Ld_A;
1779
+ reuseLoc = true ;
1780
+ break ;
1781
+
1782
+ case Js::OpCode::Typeof_ReuseLoc:
1783
+ newOpcode = Js::OpCode::Typeof;
1784
+ reuseLoc = true ;
1785
+ break ;
1786
+
1787
+ case Js::OpCode::UnwrapWithObj_ReuseLoc:
1788
+ newOpcode = Js::OpCode::UnwrapWithObj;
1789
+ reuseLoc = true ;
1790
+ break ;
1791
+
1779
1792
case Js::OpCode::SpreadObjectLiteral:
1780
1793
// fall through
1781
1794
case Js::OpCode::SetComputedNameVar:
@@ -1807,7 +1820,7 @@ IRBuilder::BuildReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, Js::Re
1807
1820
}
1808
1821
}
1809
1822
1810
- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (R0);
1823
+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (R0, TyVar, false , reuseLoc );
1811
1824
StackSym * dstSym = dstOpnd->m_sym ;
1812
1825
1813
1826
IR::Instr * instr = nullptr ;
@@ -2380,7 +2393,7 @@ IRBuilder::BuildReg2B1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSl
2380
2393
2381
2394
IR::Instr * instr;
2382
2395
IR::RegOpnd * srcOpnd = this ->BuildSrcOpnd (srcRegSlot);
2383
- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot);
2396
+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, false , true );
2384
2397
2385
2398
IR::IndirOpnd * indir1Opnd = IR::IndirOpnd::New (dstOpnd, index, TyVar, m_func);
2386
2399
@@ -2417,22 +2430,23 @@ IRBuilder::BuildReg3B1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSl
2417
2430
IR::Instr * instr;
2418
2431
IR::RegOpnd * src1Opnd = this ->BuildSrcOpnd (src1RegSlot);
2419
2432
IR::RegOpnd * src2Opnd = this ->BuildSrcOpnd (src2RegSlot);
2420
- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot);
2421
- dstOpnd->SetValueType (ValueType::String);
2433
+ IR::RegOpnd * dstOpnd = nullptr ;
2422
2434
2423
2435
IR::Instr * newConcatStrMulti = nullptr ;
2424
2436
switch (newOpcode)
2425
2437
{
2426
2438
case Js::OpCode::NewConcatStrMulti:
2427
-
2439
+ dstOpnd = this -> BuildDstOpnd (dstRegSlot);
2428
2440
newConcatStrMulti = IR::Instr::New (Js::OpCode::NewConcatStrMulti, dstOpnd, IR::IntConstOpnd::New (index, TyUint32, m_func), m_func);
2429
2441
index = 0 ;
2430
2442
break ;
2431
2443
case Js::OpCode::SetConcatStrMultiItem2:
2444
+ dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, false , true );
2432
2445
break ;
2433
2446
default :
2434
2447
Assert (false );
2435
2448
};
2449
+ dstOpnd->SetValueType (ValueType::String);
2436
2450
IR::IndirOpnd * indir1Opnd = IR::IndirOpnd::New (dstOpnd, index, TyVar, m_func);
2437
2451
IR::IndirOpnd * indir2Opnd = IR::IndirOpnd::New (dstOpnd, index + 1 , TyVar, m_func);
2438
2452
@@ -3152,15 +3166,20 @@ IRBuilder::BuildElementC(Js::OpCode newOpcode, uint32 offset, Js::RegSlot fieldR
3152
3166
PropertyKind propertyKind = PropertyKindData;
3153
3167
IR::SymOpnd * fieldSymOpnd = this ->BuildFieldOpnd (newOpcode, fieldRegSlot, propertyId, propertyIdIndex, propertyKind);
3154
3168
IR::RegOpnd * regOpnd;
3169
+ bool reuseLoc = false ;
3155
3170
3156
3171
switch (newOpcode)
3157
3172
{
3173
+ case Js::OpCode::DeleteFld_ReuseLoc:
3174
+ newOpcode = Js::OpCode::DeleteFld;
3175
+ reuseLoc = true ;
3176
+ // fall through
3158
3177
case Js::OpCode::DeleteFld:
3159
3178
case Js::OpCode::DeleteRootFld:
3160
3179
case Js::OpCode::DeleteFldStrict:
3161
3180
case Js::OpCode::DeleteRootFldStrict:
3162
3181
// Load
3163
- regOpnd = this ->BuildDstOpnd (regSlot);
3182
+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
3164
3183
instr = IR::Instr::New (newOpcode, regOpnd, fieldSymOpnd, m_func);
3165
3184
break ;
3166
3185
@@ -3482,6 +3501,7 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3482
3501
StackSym * stackFuncPtrSym = nullptr ;
3483
3502
SymID symID = m_func->GetJITFunctionBody ()->GetLocalClosureReg ();
3484
3503
bool isLdSlotThatWasNotProfiled = false ;
3504
+ bool reuseLoc = false ;
3485
3505
StackSym* closureSym = m_func->GetLocalClosureSym ();
3486
3506
3487
3507
uint scopeSlotSize = this ->IsParamScopeDone () ? m_func->GetJITFunctionBody ()->GetScopeSlotArraySize () : m_func->GetJITFunctionBody ()->GetParamScopeSlotArraySize ();
@@ -3679,9 +3699,12 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3679
3699
this ->AddInstr (instr, offset);
3680
3700
break ;
3681
3701
3702
+ case Js::OpCode::LdEnvObj_ReuseLoc:
3703
+ reuseLoc = true ;
3704
+ // fall through
3682
3705
case Js::OpCode::LdEnvObj:
3683
3706
fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::LdSlotArr, this ->GetEnvReg (), slotId, (Js::PropertyIdIndexType)-1 , PropertyKindSlotArray);
3684
- regOpnd = this ->BuildDstOpnd (regSlot);
3707
+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
3685
3708
instr = IR::Instr::New (Js::OpCode::LdSlotArr, regOpnd, fieldOpnd, m_func);
3686
3709
this ->AddInstr (instr, offset);
3687
3710
@@ -4255,9 +4278,14 @@ IRBuilder::BuildElementP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlo
4255
4278
propertyId = this ->m_func ->GetJITFunctionBody ()->GetPropertyIdFromCacheId (inlineCacheIndex);
4256
4279
4257
4280
Js::RegSlot instance = this ->GetEnvRegForEvalCode ();
4281
+ bool reuseLoc = false ;
4258
4282
4259
4283
switch (newOpcode)
4260
4284
{
4285
+ case Js::OpCode::LdLocalFld_ReuseLoc:
4286
+ reuseLoc = true ;
4287
+ newOpcode = Js::OpCode::LdLocalFld;
4288
+ // fall through
4261
4289
case Js::OpCode::LdLocalFld:
4262
4290
if (m_func->GetLocalClosureSym ()->HasByteCodeRegSlot ())
4263
4291
{
@@ -4272,7 +4300,7 @@ IRBuilder::BuildElementP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlo
4272
4300
{
4273
4301
fieldSymOpnd->AsPropertySymOpnd ()->TryDisableRuntimePolymorphicCache ();
4274
4302
}
4275
- regOpnd = this ->BuildDstOpnd (regSlot);
4303
+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
4276
4304
4277
4305
instr = nullptr ;
4278
4306
if (isProfiled)
@@ -4485,8 +4513,13 @@ IRBuilder::BuildElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot insta
4485
4513
4486
4514
IR::Instr * instr = nullptr ;
4487
4515
bool isLdFldThatWasNotProfiled = false ;
4516
+ bool reuseLoc = false ;
4488
4517
switch (newOpcode)
4489
4518
{
4519
+ case Js::OpCode::LdFld_ReuseLoc:
4520
+ reuseLoc = true ;
4521
+ newOpcode = Js::OpCode::LdFld;
4522
+ // fall through
4490
4523
case Js::OpCode::LdFldForTypeOf:
4491
4524
case Js::OpCode::LdFld:
4492
4525
case Js::OpCode::LdLen_A:
@@ -4502,7 +4535,7 @@ IRBuilder::BuildElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot insta
4502
4535
case Js::OpCode::ScopedLdMethodFld:
4503
4536
// Load
4504
4537
// LdMethodFromFlags is backend only. Don't need to be added here.
4505
- regOpnd = this ->BuildDstOpnd (regSlot);
4538
+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
4506
4539
4507
4540
if (isProfiled)
4508
4541
{
@@ -4879,6 +4912,7 @@ IRBuilder::BuildElementU(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instan
4879
4912
IR::RegOpnd * regOpnd;
4880
4913
IR::SymOpnd * fieldSymOpnd;
4881
4914
Js::PropertyId propertyId = m_func->GetJITFunctionBody ()->GetReferencedPropertyId (propertyIdIndex);
4915
+ bool reuseLoc = false ;
4882
4916
4883
4917
switch (newOpcode)
4884
4918
{
@@ -4926,10 +4960,14 @@ IRBuilder::BuildElementU(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instan
4926
4960
instr = IR::Instr::New (newOpcode, fieldSymOpnd, regOpnd, m_func);
4927
4961
break ;
4928
4962
4963
+ case Js::OpCode::DeleteLocalFld_ReuseLoc:
4964
+ newOpcode = Js::OpCode::DeleteLocalFld;
4965
+ reuseLoc = true ;
4966
+ // fall through
4929
4967
case Js::OpCode::DeleteLocalFld:
4930
4968
newOpcode = Js::OpCode::DeleteFld;
4931
4969
fieldSymOpnd = BuildFieldOpnd (newOpcode, m_func->GetJITFunctionBody ()->GetLocalClosureReg (), propertyId, propertyIdIndex, PropertyKindData);
4932
- regOpnd = BuildDstOpnd (instance);
4970
+ regOpnd = BuildDstOpnd (instance, TyVar, false , reuseLoc );
4933
4971
instr = IR::Instr::New (newOpcode, regOpnd, fieldSymOpnd, m_func);
4934
4972
break ;
4935
4973
@@ -7278,7 +7316,7 @@ void
7278
7316
IRBuilder::BuildBrLocalProperty (Js::OpCode newOpcode, uint32 offset)
7279
7317
{
7280
7318
Assert (!OpCodeAttr::HasMultiSizeLayout (newOpcode));
7281
- Assert (newOpcode == Js::OpCode::BrOnNoLocalProperty );
7319
+ Assert (newOpcode == Js::OpCode::BrOnHasLocalProperty );
7282
7320
7283
7321
const unaligned Js::OpLayoutBrLocalProperty *branchInsn = m_jnReader.BrLocalProperty ();
7284
7322
@@ -7322,7 +7360,8 @@ IRBuilder::BuildBrEnvProperty(Js::OpCode newOpcode, uint32 offset)
7322
7360
fieldSym = PropertySym::New (regOpnd->m_sym , propertyId, branchInsn->PropertyIdIndex , (uint)-1 , PropertyKindData, m_func);
7323
7361
fieldOpnd = IR::SymOpnd::New (fieldSym, TyVar, m_func);
7324
7362
7325
- branchInstr = IR::BranchInstr::New (newOpcode == Js::OpCode::BrOnNoEnvProperty ? Js::OpCode::BrOnNoProperty : Js::OpCode::BrOnNoLocalProperty, nullptr , fieldOpnd, m_func);
7363
+ Assert (newOpcode == Js::OpCode::BrOnHasEnvProperty || newOpcode == Js::OpCode::BrOnHasLocalEnvProperty);
7364
+ branchInstr = IR::BranchInstr::New (newOpcode == Js::OpCode::BrOnHasEnvProperty ? Js::OpCode::BrOnHasProperty : Js::OpCode::BrOnHasLocalProperty, nullptr , fieldOpnd, m_func);
7326
7365
this ->AddBranchInstr (branchInstr, offset, targetOffset);
7327
7366
}
7328
7367
0 commit comments