@@ -984,28 +984,69 @@ void ByteCodeUsesInstr::SetBV(BVSparse<JitArenaAllocator>* newbv)
984
984
// a compare, but still need to generate them for bailouts. Without this, we cause
985
985
// problems because we end up with an instruction losing atomicity in terms of its
986
986
// bytecode use and generation lifetimes.
987
- void ByteCodeUsesInstr::Aggregate ()
987
+ void ByteCodeUsesInstr::AggregateFollowingByteCodeUses ()
988
988
{
989
989
IR::Instr* scanner = this ->m_next ;
990
990
while (scanner && scanner->m_opcode == Js::OpCode::ByteCodeUses && scanner->GetByteCodeOffset () == this ->GetByteCodeOffset () && scanner->GetDst () == nullptr )
991
991
{
992
992
IR::ByteCodeUsesInstr* target = scanner->AsByteCodeUsesInstr ();
993
- Assert (this ->m_func == target->m_func );
994
- if (target->byteCodeUpwardExposedUsed )
993
+ this ->Aggregate (target);
994
+ scanner = scanner->m_next ;
995
+ }
996
+ }
997
+
998
+ void ByteCodeUsesInstr::AggregatePrecedingByteCodeUses ()
999
+ {
1000
+ IR::Instr * instr = this ->m_prev ;
1001
+ while (instr && this ->CanAggregateByteCodeUsesAcrossInstr (instr))
1002
+ {
1003
+ if (instr->IsByteCodeUsesInstr ())
995
1004
{
996
- if (this ->byteCodeUpwardExposedUsed )
997
- {
998
- this ->byteCodeUpwardExposedUsed ->Or (target->byteCodeUpwardExposedUsed );
999
- JitAdelete (target->byteCodeUpwardExposedUsed ->GetAllocator (), target->byteCodeUpwardExposedUsed );
1000
- target->byteCodeUpwardExposedUsed = nullptr ;
1001
- }
1002
- else
1003
- {
1004
- this ->byteCodeUpwardExposedUsed = target->byteCodeUpwardExposedUsed ;
1005
- target->byteCodeUpwardExposedUsed = nullptr ;
1006
- }
1005
+ IR::ByteCodeUsesInstr* precedingByteCodeUsesInstr = instr->AsByteCodeUsesInstr ();
1006
+ this ->Aggregate (precedingByteCodeUsesInstr);
1007
+ }
1008
+ instr = instr->m_prev ;
1009
+ }
1010
+ }
1011
+
1012
+ void ByteCodeUsesInstr::Aggregate (ByteCodeUsesInstr * byteCodeUsesInstr)
1013
+ {
1014
+ Assert (this ->m_func == byteCodeUsesInstr->m_func );
1015
+ if (byteCodeUsesInstr->byteCodeUpwardExposedUsed )
1016
+ {
1017
+ if (this ->byteCodeUpwardExposedUsed )
1018
+ {
1019
+ this ->byteCodeUpwardExposedUsed ->Or (byteCodeUsesInstr->byteCodeUpwardExposedUsed );
1020
+ JitAdelete (byteCodeUsesInstr->byteCodeUpwardExposedUsed ->GetAllocator (), byteCodeUsesInstr->byteCodeUpwardExposedUsed );
1021
+ byteCodeUsesInstr->byteCodeUpwardExposedUsed = nullptr ;
1022
+ }
1023
+ else
1024
+ {
1025
+ this ->byteCodeUpwardExposedUsed = byteCodeUsesInstr->byteCodeUpwardExposedUsed ;
1026
+ byteCodeUsesInstr->byteCodeUpwardExposedUsed = nullptr ;
1027
+ }
1028
+ }
1029
+ }
1030
+
1031
+ bool Instr::CanAggregateByteCodeUsesAcrossInstr (Instr * instr)
1032
+ {
1033
+ if (instr->GetByteCodeOffset () != Js::Constants::NoByteCodeOffset)
1034
+ {
1035
+ return (instr->GetByteCodeOffset () == this ->GetByteCodeOffset ()) &&
1036
+ (instr->IsByteCodeUsesInstr () ||
1037
+ instr->m_opcode == Js::OpCode::ToVar);
1038
+ }
1039
+ else
1040
+ {
1041
+ if (instr->HasBailOutInfo ())
1042
+ {
1043
+ return (instr->GetBailOutInfo ()->bailOutOffset == this ->GetByteCodeOffset ()) &&
1044
+ instr->m_opcode == Js::OpCode::BailOnNotObject;
1045
+ }
1046
+ else
1047
+ {
1048
+ return (instr->m_opcode == Js::OpCode::Ld_A || instr->m_opcode == Js::OpCode::Ld_I4) && instr->GetSrc1 ()->IsImmediateOpnd (); // could have been inserted by PreLowerCanonicalize
1007
1049
}
1008
- scanner = scanner->m_next ;
1009
1050
}
1010
1051
}
1011
1052
@@ -2838,6 +2879,27 @@ IR::Instr *Instr::GetInsertBeforeByteCodeUsesInstr()
2838
2879
return insertBeforeInstr;
2839
2880
}
2840
2881
2882
+ IR::ByteCodeUsesInstr *
2883
+ Instr::GetFirstByteCodeUsesInstrBackward ()
2884
+ {
2885
+ IR::Instr * prevInstr = this ->m_prev ;
2886
+ while (prevInstr && this ->CanAggregateByteCodeUsesAcrossInstr (prevInstr))
2887
+ {
2888
+ if (prevInstr->IsByteCodeUsesInstr ())
2889
+ {
2890
+ return prevInstr->AsByteCodeUsesInstr ();
2891
+ }
2892
+ prevInstr = prevInstr->m_prev ;
2893
+ }
2894
+ return nullptr ;
2895
+ }
2896
+
2897
+ bool
2898
+ Instr::IsByteCodeUsesInstrFor (IR::Instr * instr) const
2899
+ {
2900
+ return this ->IsByteCodeUsesInstr () && this ->GetByteCodeOffset () == instr->GetByteCodeOffset ();
2901
+ }
2902
+
2841
2903
// /----------------------------------------------------------------------------
2842
2904
// /
2843
2905
// / Instr::GetOrCreateContinueLabel
@@ -3341,6 +3403,22 @@ void Instr::Move(IR::Instr* insertInstr)
3341
3403
insertInstr->InsertBefore (this );
3342
3404
}
3343
3405
3406
+ void Instr::AggregateByteCodeUses ()
3407
+ {
3408
+ // Currently, this only aggregates byteCodeUpwardExposedUsed of those ByteCodeUses instructions
3409
+ // associated with this instr which have at most a ToVar, Ld_A, Ld_I4, or a BailOnNotObject between them.
3410
+ IR::ByteCodeUsesInstr * primaryByteCodeUsesInstr = this ->GetFirstByteCodeUsesInstrBackward ();
3411
+ if (primaryByteCodeUsesInstr)
3412
+ {
3413
+ primaryByteCodeUsesInstr->AggregatePrecedingByteCodeUses ();
3414
+ if (primaryByteCodeUsesInstr != this ->m_prev )
3415
+ {
3416
+ primaryByteCodeUsesInstr->Unlink ();
3417
+ this ->InsertBefore (primaryByteCodeUsesInstr);
3418
+ }
3419
+ }
3420
+ }
3421
+
3344
3422
IR::Instr* Instr::GetBytecodeArgOutCapture ()
3345
3423
{
3346
3424
Assert (this ->m_opcode == Js::OpCode::ArgOut_A_Inline ||
0 commit comments