@@ -4489,115 +4489,96 @@ IR::LabelInstr* BasicBlock::CanProveConditionalBranch(IR::BranchInstr *branch, G
4489
4489
return newTarget;
4490
4490
}
4491
4491
4492
- void
4493
- BasicBlock::CheckLegalityAndFoldPathDepBranches (GlobOpt* globOpt)
4492
+ Value*
4493
+ BasicBlock::UpdateValueForCopyTypeInstr (GlobOpt* globOpt, GlobHashTable* localSymToValueMap, IR::Instr* instr )
4494
4494
{
4495
- IR::LabelInstr * lastBranchTarget = nullptr ;
4496
- IR::Instr *currentInlineeEnd = nullptr , *unskippedInlineeEnd = nullptr ;
4497
- GlobHashTable * localSymToValueMap = nullptr ;
4498
- BVSparse<JitArenaAllocator> * currentPathDefines = nullptr ;
4495
+ Value* dstValue = nullptr ;
4496
+ if (instr->m_opcode == Js::OpCode::LdFld)
4497
+ {
4498
+ // Special handling for LdFld
4499
+ Assert (instr->GetSrc1 ()->IsSymOpnd ());
4500
+ IR::SymOpnd* symOpnd = instr->GetSrc1 ()->AsSymOpnd ();
4499
4501
4500
- auto UpdateValueForCopyTypeInstr = [&](IR::Instr *instr) -> Value* {
4501
- Value * dstValue = nullptr ;
4502
- if (instr->m_opcode == Js::OpCode::LdFld)
4502
+ if (symOpnd->m_sym ->IsPropertySym ())
4503
4503
{
4504
- // Special handling for LdFld
4505
- Assert ( instr-> GetSrc1 ()-> IsSymOpnd () );
4506
- IR::SymOpnd *symOpnd = instr-> GetSrc1 ()->AsSymOpnd () ;
4507
-
4508
- if (symOpnd-> m_sym -> IsPropertySym () )
4504
+ PropertySym* originalPropertySym = symOpnd-> m_sym -> AsPropertySym ();
4505
+ Value* const objectValue = FindValueInLocalThenGlobalValueTableAndUpdate (globOpt, localSymToValueMap, instr, nullptr , originalPropertySym-> m_stackSym );
4506
+ Sym* objSym = objectValue ? objectValue-> GetValueInfo ()->GetSymStore () : nullptr ;
4507
+ PropertySym* prop = PropertySym::Find (objSym ? objSym-> m_id : originalPropertySym-> m_stackSym -> m_id , originalPropertySym-> m_propertyId , globOpt-> func );
4508
+ if (prop )
4509
4509
{
4510
- PropertySym * originalPropertySym = symOpnd->m_sym ->AsPropertySym ();
4511
- Value *const objectValue = FindValueInLocalThenGlobalValueTableAndUpdate (globOpt, localSymToValueMap, instr, nullptr , originalPropertySym->m_stackSym );
4512
- Sym* objSym = objectValue ? objectValue->GetValueInfo ()->GetSymStore () : nullptr ;
4513
- PropertySym *prop = PropertySym::Find (objSym ? objSym->m_id : originalPropertySym->m_stackSym ->m_id , originalPropertySym->m_propertyId , globOpt->func );
4514
- if (prop)
4515
- {
4516
- dstValue = FindValueInLocalThenGlobalValueTableAndUpdate (globOpt, localSymToValueMap, instr, instr->GetDst ()->GetStackSym (), prop);
4517
- }
4518
- else
4519
- {
4520
- Value ** localDstValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetStackSym ());
4521
- dstValue = *localDstValue = nullptr ;
4522
- }
4523
- }
4524
- }
4525
- else if (instr->GetSrc1 ()->GetStackSym ())
4526
- {
4527
- StackSym* src1Sym = instr->GetSrc1 ()->GetStackSym ();
4528
- dstValue = FindValueInLocalThenGlobalValueTableAndUpdate (globOpt, localSymToValueMap, instr, instr->GetDst ()->GetSym (), src1Sym);
4529
- }
4530
- else if (instr->GetSrc1 ()->IsIntConstOpnd ())
4531
- {
4532
- Value **localValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetSym ());
4533
- dstValue = *localValue = globOpt->GetIntConstantValue (instr->GetSrc1 ()->AsIntConstOpnd ()->AsInt32 (), instr);
4534
- }
4535
- else if (instr->GetSrc1 ()->IsInt64ConstOpnd ())
4536
- {
4537
- Value **localValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetSym ());
4538
- dstValue = *localValue = globOpt->GetIntConstantValue (instr->GetSrc1 ()->AsInt64ConstOpnd ()->GetValue (), instr);
4539
- }
4540
- else
4541
- {
4542
- ValueType src1Value = instr->GetSrc1 ()->GetValueType ();
4543
- Value **localValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetSym ());
4544
- if (src1Value.IsUndefined () || src1Value.IsBoolean ())
4545
- {
4546
- dstValue = *localValue = globOpt->GetVarConstantValue (instr->GetSrc1 ()->AsAddrOpnd ());
4510
+ dstValue = FindValueInLocalThenGlobalValueTableAndUpdate (globOpt, localSymToValueMap, instr, instr->GetDst ()->GetStackSym (), prop);
4547
4511
}
4548
4512
else
4549
4513
{
4550
- dstValue = *localValue = nullptr ;
4514
+ Value** localDstValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetStackSym ());
4515
+ dstValue = *localDstValue = nullptr ;
4551
4516
}
4552
4517
}
4553
- return dstValue;
4554
- };
4555
-
4556
- FOREACH_INSTR_IN_BLOCK (instr, this )
4518
+ }
4519
+ else if (instr->GetSrc1 ()->GetStackSym ())
4557
4520
{
4558
- if (OpCodeAttr::HasDeadFallThrough (instr->m_opcode ))
4521
+ StackSym* src1Sym = instr->GetSrc1 ()->GetStackSym ();
4522
+ dstValue = FindValueInLocalThenGlobalValueTableAndUpdate (globOpt, localSymToValueMap, instr, instr->GetDst ()->GetSym (), src1Sym);
4523
+ }
4524
+ else if (instr->GetSrc1 ()->IsIntConstOpnd ())
4525
+ {
4526
+ Value** localValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetSym ());
4527
+ dstValue = *localValue = globOpt->GetIntConstantValue (instr->GetSrc1 ()->AsIntConstOpnd ()->AsInt32 (), instr);
4528
+ }
4529
+ else if (instr->GetSrc1 ()->IsInt64ConstOpnd ())
4530
+ {
4531
+ Value** localValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetSym ());
4532
+ dstValue = *localValue = globOpt->GetIntConstantValue (instr->GetSrc1 ()->AsInt64ConstOpnd ()->GetValue (), instr);
4533
+ }
4534
+ else
4535
+ {
4536
+ ValueType src1Value = instr->GetSrc1 ()->GetValueType ();
4537
+ Value** localValue = localSymToValueMap->FindOrInsertNew (instr->GetDst ()->GetSym ());
4538
+ if (src1Value.IsUndefined () || src1Value.IsBoolean ())
4559
4539
{
4560
- return ;
4540
+ dstValue = *localValue = globOpt-> GetVarConstantValue (instr-> GetSrc1 ()-> AsAddrOpnd ()) ;
4561
4541
}
4562
- if (instr-> m_opcode == Js::OpCode::InlineeEnd)
4542
+ else
4563
4543
{
4564
- unskippedInlineeEnd = currentInlineeEnd = instr ;
4544
+ dstValue = *localValue = nullptr ;
4565
4545
}
4566
- } NEXT_INSTR_IN_BLOCK;
4567
-
4568
- IR::Instr * instr = this ->GetLastInstr ();
4569
-
4570
- // We have to first check the legality and only then allocate expensive data structures on the tempArena, because most block will have instructions we cant skip
4546
+ }
4547
+ return dstValue;
4548
+ }
4571
4549
4550
+ bool
4551
+ BasicBlock::IsLegalForPathDepBranches (IR::Instr* instr)
4552
+ {
4572
4553
while (instr)
4573
4554
{
4574
4555
if (!instr->IsBranchInstr () && !instr->IsLabelInstr () && !IsLegalOpcodeForPathDepBrFold (instr))
4575
4556
{
4576
- return ;
4557
+ return false ;
4577
4558
}
4578
4559
if (instr->IsLabelInstr ())
4579
4560
{
4580
4561
if (instr->AsLabelInstr ()->m_isLoopTop )
4581
4562
{
4582
4563
// don't cross over to loops
4583
- return ;
4564
+ return false ;
4584
4565
}
4585
4566
}
4586
4567
if (instr->IsBranchInstr ())
4587
4568
{
4588
- IR::BranchInstr * branch = instr->AsBranchInstr ();
4569
+ IR::BranchInstr* branch = instr->AsBranchInstr ();
4589
4570
if (branch->IsUnconditional ())
4590
4571
{
4591
4572
if (!branch->GetTarget ())
4592
4573
{
4593
- return ;
4574
+ return false ;
4594
4575
}
4595
4576
instr = branch->GetTarget ();
4596
4577
}
4597
4578
else
4598
4579
{
4599
4580
// Found only legal instructions until a conditional branch, build expensive data structures and check provability
4600
- break ;
4581
+ return true ;
4601
4582
}
4602
4583
}
4603
4584
else
@@ -4606,7 +4587,38 @@ BasicBlock::CheckLegalityAndFoldPathDepBranches(GlobOpt* globOpt)
4606
4587
}
4607
4588
}
4608
4589
4609
- instr = this ->GetLastInstr ();
4590
+ Assert (UNREACHED);
4591
+ return false ;
4592
+ }
4593
+
4594
+ void
4595
+ BasicBlock::CheckLegalityAndFoldPathDepBranches (GlobOpt* globOpt)
4596
+ {
4597
+ IR::LabelInstr * lastBranchTarget = nullptr ;
4598
+ IR::Instr *currentInlineeEnd = nullptr , *unskippedInlineeEnd = nullptr ;
4599
+ GlobHashTable * localSymToValueMap = nullptr ;
4600
+ BVSparse<JitArenaAllocator> * currentPathDefines = nullptr ;
4601
+
4602
+ FOREACH_INSTR_IN_BLOCK (instr, this )
4603
+ {
4604
+ if (OpCodeAttr::HasDeadFallThrough (instr->m_opcode ))
4605
+ {
4606
+ return ;
4607
+ }
4608
+ if (instr->m_opcode == Js::OpCode::InlineeEnd)
4609
+ {
4610
+ unskippedInlineeEnd = currentInlineeEnd = instr;
4611
+ }
4612
+ } NEXT_INSTR_IN_BLOCK;
4613
+
4614
+ IR::Instr * instr = this ->GetLastInstr ();
4615
+
4616
+ // We have to first check the legality and only then allocate expensive data structures on the tempArena, because most block will have instructions we cant skip
4617
+ if (!IsLegalForPathDepBranches (instr))
4618
+ {
4619
+ return ;
4620
+ }
4621
+
4610
4622
// Allocate hefty structures, we will not free them because OptBlock does a Reset on the tempAlloc
4611
4623
localSymToValueMap = GlobHashTable::New (globOpt->tempAlloc , 8 );
4612
4624
currentPathDefines = JitAnew (globOpt->tempAlloc , BVSparse<JitArenaAllocator>, globOpt->tempAlloc );
@@ -4654,7 +4666,7 @@ BasicBlock::CheckLegalityAndFoldPathDepBranches(GlobOpt* globOpt)
4654
4666
4655
4667
if (IsCopyTypeInstr (instr))
4656
4668
{
4657
- Value *dstValue = UpdateValueForCopyTypeInstr (instr);
4669
+ Value *dstValue = UpdateValueForCopyTypeInstr (globOpt, localSymToValueMap, instr);
4658
4670
if (instr->m_opcode == Js::OpCode::LdFld && !dstValue)
4659
4671
{
4660
4672
// We cannot skip a LdFld if we didnt find its valueInfo in the localValueTable
0 commit comments