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