@@ -353,12 +353,10 @@ IRBuilder::Build()
353353 if (tempCount > 0 )
354354 {
355355 this ->tempMap = AnewArrayZ (m_tempAlloc, SymID, tempCount);
356- this ->fbvTempUsed = BVFixed::New<JitArenaAllocator>(tempCount, m_tempAlloc);
357356 }
358357 else
359358 {
360359 this ->tempMap = nullptr ;
361- this ->fbvTempUsed = nullptr ;
362360 }
363361
364362 m_func->m_headInstr = IR::EntryInstr::New (Js::OpCode::FunctionEntry, m_func);
@@ -1224,7 +1222,6 @@ IRBuilder::BuildSrcStackSymID(Js::RegSlot regSlot)
12241222 this ->SetMappedTemp (regSlot, symID);
12251223 this ->EnsureLoopBodyLoadSlot (symID);
12261224 }
1227- this ->SetTempUsed (regSlot, TRUE );
12281225 }
12291226 else
12301227 {
@@ -1315,7 +1312,7 @@ IRBuilder::BuildSrcOpnd(Js::RegSlot srcRegSlot, IRType type)
13151312// /----------------------------------------------------------------------------
13161313
13171314IR::RegOpnd *
1318- IRBuilder::BuildDstOpnd (Js::RegSlot dstRegSlot, IRType type, bool isCatchObjectSym)
1315+ IRBuilder::BuildDstOpnd (Js::RegSlot dstRegSlot, IRType type, bool isCatchObjectSym, bool reuseTemp )
13191316{
13201317 StackSym * symDst;
13211318 SymID symID;
@@ -1336,24 +1333,20 @@ IRBuilder::BuildDstOpnd(Js::RegSlot dstRegSlot, IRType type, bool isCatchObjectS
13361333
13371334 // This is a def of a temp. Create a new sym ID for it if it's been used since its last def.
13381335 // !!!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 )
13401339 {
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);
13431342 this ->SetMappedTemp (dstRegSlot, symID);
13441343 }
1345- else
1344+ else if (!reuseTemp)
13461345 {
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);
13551349 }
1356-
13571350 }
13581351 else
13591352 {
@@ -1506,6 +1499,7 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
15061499 IR::Opnd * srcOpnd = nullptr ;
15071500 bool isNotInt = false ;
15081501 bool dstIsCatchObject = false ;
1502+ bool reuseLoc = false ;
15091503 ValueType dstValueType;
15101504 switch (newOpcode)
15111505 {
@@ -1560,6 +1554,9 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
15601554 isNotInt = true ;
15611555 break ;
15621556
1557+ case Js::OpCode::LdLocalObj_ReuseLoc:
1558+ reuseLoc = true ;
1559+ // fall through
15631560 case Js::OpCode::LdLocalObj:
15641561 if (!m_func->GetJITFunctionBody ()->HasScopeObject ())
15651562 {
@@ -1636,6 +1633,9 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
16361633 break ;
16371634 }
16381635
1636+ case Js::OpCode::LdFalse_ReuseLoc:
1637+ reuseLoc = true ;
1638+ // fall through
16391639 case Js::OpCode::LdFalse:
16401640 {
16411641 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)
16451645 break ;
16461646 }
16471647
1648+ case Js::OpCode::LdTrue_ReuseLoc:
1649+ reuseLoc = true ;
1650+ // fall through
16481651 case Js::OpCode::LdTrue:
16491652 {
16501653 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)
16661669 isNotInt = TRUE ;
16671670 break ;
16681671
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-
16751672 case Js::OpCode::InitUndecl:
16761673 srcOpnd = IR::AddrOpnd::New (m_func->GetScriptContextInfo ()->GetUndeclBlockVarAddr (), IR::AddrOpndKindDynamicVar, m_func, true );
16771674 srcOpnd->SetValueType (ValueType::PrimitiveOrObject);
@@ -1705,7 +1702,7 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
17051702 }
17061703 }
17071704
1708- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, dstIsCatchObject);
1705+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, dstIsCatchObject, reuseLoc );
17091706 dstOpnd->SetValueType (dstValueType);
17101707 StackSym * dstSym = dstOpnd->m_sym ;
17111708 dstSym->m_isCatchObjectSym = dstIsCatchObject;
@@ -1773,9 +1770,25 @@ IRBuilder::BuildReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, Js::Re
17731770{
17741771 IR::RegOpnd * src1Opnd = this ->BuildSrcOpnd (R1);
17751772 StackSym * symSrc1 = src1Opnd->m_sym ;
1773+ bool reuseLoc = false ;
17761774
17771775 switch (newOpcode)
17781776 {
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+
17791792 case Js::OpCode::SpreadObjectLiteral:
17801793 // fall through
17811794 case Js::OpCode::SetComputedNameVar:
@@ -1807,7 +1820,7 @@ IRBuilder::BuildReg2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0, Js::Re
18071820 }
18081821 }
18091822
1810- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (R0);
1823+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (R0, TyVar, false , reuseLoc );
18111824 StackSym * dstSym = dstOpnd->m_sym ;
18121825
18131826 IR::Instr * instr = nullptr ;
@@ -2380,7 +2393,7 @@ IRBuilder::BuildReg2B1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSl
23802393
23812394 IR::Instr * instr;
23822395 IR::RegOpnd * srcOpnd = this ->BuildSrcOpnd (srcRegSlot);
2383- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot);
2396+ IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, false , true );
23842397
23852398 IR::IndirOpnd * indir1Opnd = IR::IndirOpnd::New (dstOpnd, index, TyVar, m_func);
23862399
@@ -2417,22 +2430,23 @@ IRBuilder::BuildReg3B1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot dstRegSl
24172430 IR::Instr * instr;
24182431 IR::RegOpnd * src1Opnd = this ->BuildSrcOpnd (src1RegSlot);
24192432 IR::RegOpnd * src2Opnd = this ->BuildSrcOpnd (src2RegSlot);
2420- IR::RegOpnd * dstOpnd = this ->BuildDstOpnd (dstRegSlot);
2421- dstOpnd->SetValueType (ValueType::String);
2433+ IR::RegOpnd * dstOpnd = nullptr ;
24222434
24232435 IR::Instr * newConcatStrMulti = nullptr ;
24242436 switch (newOpcode)
24252437 {
24262438 case Js::OpCode::NewConcatStrMulti:
2427-
2439+ dstOpnd = this -> BuildDstOpnd (dstRegSlot);
24282440 newConcatStrMulti = IR::Instr::New (Js::OpCode::NewConcatStrMulti, dstOpnd, IR::IntConstOpnd::New (index, TyUint32, m_func), m_func);
24292441 index = 0 ;
24302442 break ;
24312443 case Js::OpCode::SetConcatStrMultiItem2:
2444+ dstOpnd = this ->BuildDstOpnd (dstRegSlot, TyVar, false , true );
24322445 break ;
24332446 default :
24342447 Assert (false );
24352448 };
2449+ dstOpnd->SetValueType (ValueType::String);
24362450 IR::IndirOpnd * indir1Opnd = IR::IndirOpnd::New (dstOpnd, index, TyVar, m_func);
24372451 IR::IndirOpnd * indir2Opnd = IR::IndirOpnd::New (dstOpnd, index + 1 , TyVar, m_func);
24382452
@@ -3152,15 +3166,20 @@ IRBuilder::BuildElementC(Js::OpCode newOpcode, uint32 offset, Js::RegSlot fieldR
31523166 PropertyKind propertyKind = PropertyKindData;
31533167 IR::SymOpnd * fieldSymOpnd = this ->BuildFieldOpnd (newOpcode, fieldRegSlot, propertyId, propertyIdIndex, propertyKind);
31543168 IR::RegOpnd * regOpnd;
3169+ bool reuseLoc = false ;
31553170
31563171 switch (newOpcode)
31573172 {
3173+ case Js::OpCode::DeleteFld_ReuseLoc:
3174+ newOpcode = Js::OpCode::DeleteFld;
3175+ reuseLoc = true ;
3176+ // fall through
31583177 case Js::OpCode::DeleteFld:
31593178 case Js::OpCode::DeleteRootFld:
31603179 case Js::OpCode::DeleteFldStrict:
31613180 case Js::OpCode::DeleteRootFldStrict:
31623181 // Load
3163- regOpnd = this ->BuildDstOpnd (regSlot);
3182+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
31643183 instr = IR::Instr::New (newOpcode, regOpnd, fieldSymOpnd, m_func);
31653184 break ;
31663185
@@ -3482,6 +3501,7 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
34823501 StackSym * stackFuncPtrSym = nullptr ;
34833502 SymID symID = m_func->GetJITFunctionBody ()->GetLocalClosureReg ();
34843503 bool isLdSlotThatWasNotProfiled = false ;
3504+ bool reuseLoc = false ;
34853505 StackSym* closureSym = m_func->GetLocalClosureSym ();
34863506
34873507 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
36793699 this ->AddInstr (instr, offset);
36803700 break ;
36813701
3702+ case Js::OpCode::LdEnvObj_ReuseLoc:
3703+ reuseLoc = true ;
3704+ // fall through
36823705 case Js::OpCode::LdEnvObj:
36833706 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 );
36853708 instr = IR::Instr::New (Js::OpCode::LdSlotArr, regOpnd, fieldOpnd, m_func);
36863709 this ->AddInstr (instr, offset);
36873710
@@ -4255,9 +4278,14 @@ IRBuilder::BuildElementP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlo
42554278 propertyId = this ->m_func ->GetJITFunctionBody ()->GetPropertyIdFromCacheId (inlineCacheIndex);
42564279
42574280 Js::RegSlot instance = this ->GetEnvRegForEvalCode ();
4281+ bool reuseLoc = false ;
42584282
42594283 switch (newOpcode)
42604284 {
4285+ case Js::OpCode::LdLocalFld_ReuseLoc:
4286+ reuseLoc = true ;
4287+ newOpcode = Js::OpCode::LdLocalFld;
4288+ // fall through
42614289 case Js::OpCode::LdLocalFld:
42624290 if (m_func->GetLocalClosureSym ()->HasByteCodeRegSlot ())
42634291 {
@@ -4272,7 +4300,7 @@ IRBuilder::BuildElementP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot regSlo
42724300 {
42734301 fieldSymOpnd->AsPropertySymOpnd ()->TryDisableRuntimePolymorphicCache ();
42744302 }
4275- regOpnd = this ->BuildDstOpnd (regSlot);
4303+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
42764304
42774305 instr = nullptr ;
42784306 if (isProfiled)
@@ -4485,8 +4513,13 @@ IRBuilder::BuildElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot insta
44854513
44864514 IR::Instr * instr = nullptr ;
44874515 bool isLdFldThatWasNotProfiled = false ;
4516+ bool reuseLoc = false ;
44884517 switch (newOpcode)
44894518 {
4519+ case Js::OpCode::LdFld_ReuseLoc:
4520+ reuseLoc = true ;
4521+ newOpcode = Js::OpCode::LdFld;
4522+ // fall through
44904523 case Js::OpCode::LdFldForTypeOf:
44914524 case Js::OpCode::LdFld:
44924525 case Js::OpCode::LdLen_A:
@@ -4502,7 +4535,7 @@ IRBuilder::BuildElementCP(Js::OpCode newOpcode, uint32 offset, Js::RegSlot insta
45024535 case Js::OpCode::ScopedLdMethodFld:
45034536 // Load
45044537 // LdMethodFromFlags is backend only. Don't need to be added here.
4505- regOpnd = this ->BuildDstOpnd (regSlot);
4538+ regOpnd = this ->BuildDstOpnd (regSlot, TyVar, false , reuseLoc );
45064539
45074540 if (isProfiled)
45084541 {
@@ -4879,6 +4912,7 @@ IRBuilder::BuildElementU(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instan
48794912 IR::RegOpnd * regOpnd;
48804913 IR::SymOpnd * fieldSymOpnd;
48814914 Js::PropertyId propertyId = m_func->GetJITFunctionBody ()->GetReferencedPropertyId (propertyIdIndex);
4915+ bool reuseLoc = false ;
48824916
48834917 switch (newOpcode)
48844918 {
@@ -4926,10 +4960,14 @@ IRBuilder::BuildElementU(Js::OpCode newOpcode, uint32 offset, Js::RegSlot instan
49264960 instr = IR::Instr::New (newOpcode, fieldSymOpnd, regOpnd, m_func);
49274961 break ;
49284962
4963+ case Js::OpCode::DeleteLocalFld_ReuseLoc:
4964+ newOpcode = Js::OpCode::DeleteLocalFld;
4965+ reuseLoc = true ;
4966+ // fall through
49294967 case Js::OpCode::DeleteLocalFld:
49304968 newOpcode = Js::OpCode::DeleteFld;
49314969 fieldSymOpnd = BuildFieldOpnd (newOpcode, m_func->GetJITFunctionBody ()->GetLocalClosureReg (), propertyId, propertyIdIndex, PropertyKindData);
4932- regOpnd = BuildDstOpnd (instance);
4970+ regOpnd = BuildDstOpnd (instance, TyVar, false , reuseLoc );
49334971 instr = IR::Instr::New (newOpcode, regOpnd, fieldSymOpnd, m_func);
49344972 break ;
49354973
@@ -7278,7 +7316,7 @@ void
72787316IRBuilder::BuildBrLocalProperty (Js::OpCode newOpcode, uint32 offset)
72797317{
72807318 Assert (!OpCodeAttr::HasMultiSizeLayout (newOpcode));
7281- Assert (newOpcode == Js::OpCode::BrOnNoLocalProperty );
7319+ Assert (newOpcode == Js::OpCode::BrOnHasLocalProperty );
72827320
72837321 const unaligned Js::OpLayoutBrLocalProperty *branchInsn = m_jnReader.BrLocalProperty ();
72847322
@@ -7322,7 +7360,8 @@ IRBuilder::BuildBrEnvProperty(Js::OpCode newOpcode, uint32 offset)
73227360 fieldSym = PropertySym::New (regOpnd->m_sym , propertyId, branchInsn->PropertyIdIndex , (uint)-1 , PropertyKindData, m_func);
73237361 fieldOpnd = IR::SymOpnd::New (fieldSym, TyVar, m_func);
73247362
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);
73267365 this ->AddBranchInstr (branchInstr, offset, targetOffset);
73277366}
73287367
0 commit comments