Skip to content

Commit 8ee91a5

Browse files
author
Meghana Gupta
committed
refactor OptConstFoldBranch code
1 parent 1e1a76b commit 8ee91a5

File tree

2 files changed

+121
-109
lines changed

2 files changed

+121
-109
lines changed

lib/Backend/GlobOpt.cpp

Lines changed: 120 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -6362,29 +6362,10 @@ bool BoolAndIntStaticAndTypeMismatch(Value* src1Val, Value* src2Val, Js::Var src
63626362
(src2ValInfo->IsNumber() && src2Var && src1ValInfo->IsBoolean() && src2Var != Js::TaggedInt::ToVarUnchecked(0) && src2Var != Js::TaggedInt::ToVarUnchecked(1));
63636363
}
63646364

6365+
63656366
bool
6366-
GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Value **pDstVal)
6367+
GlobOpt::CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2Val, Js::Var src1Var, Js::Var src2Var, bool *result)
63676368
{
6368-
if (!src1Val)
6369-
{
6370-
return false;
6371-
}
6372-
6373-
int64 left64, right64;
6374-
Js::Var src1Var = this->GetConstantVar(instr->GetSrc1(), src1Val);
6375-
6376-
Js::Var src2Var = nullptr;
6377-
6378-
if (instr->GetSrc2())
6379-
{
6380-
if (!src2Val)
6381-
{
6382-
return false;
6383-
}
6384-
6385-
src2Var = this->GetConstantVar(instr->GetSrc2(), src2Val);
6386-
}
6387-
63886369
auto AreSourcesEqual = [&](Value * val1, Value * val2) -> bool
63896370
{
63906371
// NaN !== NaN, and objects can have valueOf/toString
@@ -6397,91 +6378,90 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
63976378
//Assert(!src1Var || !Js::JavascriptOperators::IsObject(src1Var));
63986379
//Assert(!src2Var || !Js::JavascriptOperators::IsObject(src2Var));
63996380

6400-
BOOL result;
6381+
int64 left64, right64;
6382+
int left, right;
64016383
int32 constVal;
6384+
64026385
switch (instr->m_opcode)
64036386
{
6404-
#define BRANCH(OPCODE,CMP,TYPE,UNSIGNEDNESS) \
6387+
#define BRANCHSIGNED(OPCODE,CMP,TYPE,UNSIGNEDNESS) \
6388+
case Js::OpCode::##OPCODE: \
6389+
if (src1Val && src2Val) \
6390+
{ \
6391+
if (src1Val->GetValueInfo()->TryGetIntConstantValue(&left, UNSIGNEDNESS) && \
6392+
src2Val->GetValueInfo()->TryGetIntConstantValue(&right, UNSIGNEDNESS)) \
6393+
{ \
6394+
*result = (TYPE)left CMP(TYPE)right; \
6395+
} \
6396+
if (src1Val->GetValueInfo()->TryGetInt64ConstantValue(&left64, UNSIGNEDNESS) && \
6397+
src2Val->GetValueInfo()->TryGetInt64ConstantValue(&right64, UNSIGNEDNESS)) \
6398+
{ \
6399+
*result = (TYPE)left64 CMP(TYPE)right64; \
6400+
} \
6401+
else if (AreSourcesEqual(src1Val, src2Val)) \
6402+
{ \
6403+
*result = 0 CMP 0; \
6404+
} \
6405+
else \
6406+
{ \
6407+
return false; \
6408+
} \
6409+
} \
6410+
else \
6411+
{ \
6412+
return false; \
6413+
} \
6414+
break;
6415+
6416+
BRANCHSIGNED(BrEq_I4, == , int64, false)
6417+
BRANCHSIGNED(BrGe_I4, >= , int64, false)
6418+
BRANCHSIGNED(BrGt_I4, > , int64, false)
6419+
BRANCHSIGNED(BrLt_I4, < , int64, false)
6420+
BRANCHSIGNED(BrLe_I4, <= , int64, false)
6421+
BRANCHSIGNED(BrNeq_I4, != , int64, false)
6422+
BRANCHSIGNED(BrUnGe_I4, >= , uint64, true)
6423+
BRANCHSIGNED(BrUnGt_I4, > , uint64, true)
6424+
BRANCHSIGNED(BrUnLt_I4, < , uint64, true)
6425+
BRANCHSIGNED(BrUnLe_I4, <= , uint64, true)
6426+
#undef BRANCHSIGNED
6427+
#define BRANCH(OPCODE,CMP,VARCMPFUNC) \
64056428
case Js::OpCode::##OPCODE: \
6406-
if (src1Val->GetValueInfo()->TryGetInt64ConstantValue(&left64, UNSIGNEDNESS) && \
6407-
src2Val->GetValueInfo()->TryGetInt64ConstantValue(&right64, UNSIGNEDNESS)) \
6429+
if (src1Val && src2Val && src1Val->GetValueInfo()->TryGetIntConstantValue(&left) && \
6430+
src2Val->GetValueInfo()->TryGetIntConstantValue(&right)) \
64086431
{ \
6409-
result = (TYPE)left64 CMP (TYPE)right64; \
6432+
*result = left CMP right; \
64106433
} \
6411-
else if (AreSourcesEqual(src1Val, src2Val)) \
6434+
else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val)) \
64126435
{ \
6413-
result = 0 CMP 0; \
6436+
*result = 0 CMP 0; \
6437+
} \
6438+
else if (src1Var && src2Var) \
6439+
{ \
6440+
if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts)) \
6441+
{ \
6442+
return false; \
6443+
} \
6444+
*result = VARCMPFUNC(src1Var, src2Var, this->func->GetScriptContext()); \
64146445
} \
64156446
else \
64166447
{ \
64176448
return false; \
64186449
} \
64196450
break;
64206451

6421-
BRANCH(BrEq_I4, == , int64, false)
6422-
BRANCH(BrGe_I4, >= , int64, false)
6423-
BRANCH(BrGt_I4, >, int64, false)
6424-
BRANCH(BrLt_I4, <, int64, false)
6425-
BRANCH(BrLe_I4, <= , int64, false)
6426-
BRANCH(BrNeq_I4, != , int64, false)
6427-
BRANCH(BrUnGe_I4, >= , uint64, true)
6428-
BRANCH(BrUnGt_I4, >, uint64, true)
6429-
BRANCH(BrUnLt_I4, <, uint64, true)
6430-
BRANCH(BrUnLe_I4, <= , uint64, true)
6431-
case Js::OpCode::BrEq_A:
6432-
case Js::OpCode::BrNotNeq_A:
6433-
if (!src1Var || !src2Var)
6434-
{
6435-
if (BoolAndIntStaticAndTypeMismatch(src1Val, src2Val, src1Var, src2Var))
6436-
{
6437-
result = false;
6438-
}
6439-
else if (AreSourcesEqual(src1Val, src2Val))
6440-
{
6441-
result = true;
6442-
}
6443-
else
6444-
{
6445-
return false;
6446-
}
6447-
}
6448-
else
6449-
{
6450-
if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts))
6451-
{
6452-
// TODO: OOP JIT, const folding
6453-
return false;
6454-
}
6455-
result = Js::JavascriptOperators::Equal(src1Var, src2Var, this->func->GetScriptContext());
6456-
}
6457-
break;
6458-
case Js::OpCode::BrNeq_A:
6459-
case Js::OpCode::BrNotEq_A:
6460-
if (!src1Var || !src2Var)
6461-
{
6462-
if (BoolAndIntStaticAndTypeMismatch(src1Val, src2Val, src1Var, src2Var))
6463-
{
6464-
result = true;
6465-
}
6466-
else if (AreSourcesEqual(src1Val, src2Val))
6467-
{
6468-
result = false;
6469-
}
6470-
else
6471-
{
6472-
return false;
6473-
}
6474-
}
6475-
else
6476-
{
6477-
if (func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts))
6478-
{
6479-
// TODO: OOP JIT, const folding
6480-
return false;
6481-
}
6482-
result = Js::JavascriptOperators::NotEqual(src1Var, src2Var, this->func->GetScriptContext());
6483-
}
6484-
break;
6452+
BRANCH(BrEq_A, ==, Js::JavascriptOperators::Equal)
6453+
BRANCH(BrNotNeq_A, == , Js::JavascriptOperators::Equal)
6454+
BRANCH(BrGe_A, >= , Js::JavascriptOperators::GreaterEqual)
6455+
BRANCH(BrNotGe_A, <, !Js::JavascriptOperators::GreaterEqual)
6456+
BRANCH(BrLt_A, <, Js::JavascriptOperators::Less)
6457+
BRANCH(BrNotLt_A, >= , !Js::JavascriptOperators::Less)
6458+
BRANCH(BrGt_A, >, Js::JavascriptOperators::Greater)
6459+
BRANCH(BrNotGt_A, <= , !Js::JavascriptOperators::Greater)
6460+
BRANCH(BrLe_A, <= , Js::JavascriptOperators::LessEqual)
6461+
BRANCH(BrNotLe_A, >, !Js::JavascriptOperators::LessEqual)
6462+
BRANCH(BrNeq_A, != , Js::JavascriptOperators::NotEqual)
6463+
BRANCH(BrNotEq_A, != , Js::JavascriptOperators::NotEqual)
6464+
#undef BRANCH
64856465
case Js::OpCode::BrSrEq_A:
64866466
case Js::OpCode::BrSrNotNeq_A:
64876467
if (!src1Var || !src2Var)
@@ -6500,13 +6480,13 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
65006480
(src2ValInfo->IsBoolean() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenBoolean()) ||
65016481
(src2ValInfo->IsNumber() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenNumber()) ||
65026482
(src2ValInfo->IsString() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenString())
6503-
)
6483+
)
65046484
{
6505-
result = false;
6485+
*result = false;
65066486
}
65076487
else if (AreSourcesEqual(src1Val, src2Val))
65086488
{
6509-
result = true;
6489+
*result = true;
65106490
}
65116491
else
65126492
{
@@ -6520,7 +6500,7 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
65206500
// TODO: OOP JIT, const folding
65216501
return false;
65226502
}
6523-
result = Js::JavascriptOperators::StrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6503+
*result = Js::JavascriptOperators::StrictEqual(src1Var, src2Var, this->func->GetScriptContext());
65246504
}
65256505
break;
65266506

@@ -6542,13 +6522,13 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
65426522
(src2ValInfo->IsBoolean() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenBoolean()) ||
65436523
(src2ValInfo->IsNumber() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenNumber()) ||
65446524
(src2ValInfo->IsString() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenString())
6545-
)
6525+
)
65466526
{
6547-
result = true;
6527+
*result = true;
65486528
}
65496529
else if (AreSourcesEqual(src1Val, src2Val))
65506530
{
6551-
result = false;
6531+
*result = false;
65526532
}
65536533
else
65546534
{
@@ -6562,23 +6542,23 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
65626542
// TODO: OOP JIT, const folding
65636543
return false;
65646544
}
6565-
result = Js::JavascriptOperators::NotStrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6545+
*result = Js::JavascriptOperators::NotStrictEqual(src1Var, src2Var, this->func->GetScriptContext());
65666546
}
65676547
break;
65686548

65696549
case Js::OpCode::BrFalse_A:
65706550
case Js::OpCode::BrTrue_A:
65716551
{
65726552
ValueInfo *const src1ValueInfo = src1Val->GetValueInfo();
6573-
if(src1ValueInfo->IsNull() || src1ValueInfo->IsUndefined())
6553+
if (src1ValueInfo->IsNull() || src1ValueInfo->IsUndefined())
65746554
{
6575-
result = instr->m_opcode == Js::OpCode::BrFalse_A;
6555+
*result = instr->m_opcode == Js::OpCode::BrFalse_A;
65766556
break;
65776557
}
6578-
if(src1ValueInfo->IsObject() && src1ValueInfo->GetObjectType() > ObjectType::Object)
6558+
if (src1ValueInfo->IsObject() && src1ValueInfo->GetObjectType() > ObjectType::Object)
65796559
{
65806560
// Specific object types that are tracked are equivalent to 'true'
6581-
result = instr->m_opcode == Js::OpCode::BrTrue_A;
6561+
*result = instr->m_opcode == Js::OpCode::BrTrue_A;
65826562
break;
65836563
}
65846564

@@ -6591,10 +6571,10 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
65916571
{
65926572
return false;
65936573
}
6594-
result = Js::JavascriptConversion::ToBoolean(src1Var, this->func->GetScriptContext());
6595-
if(instr->m_opcode == Js::OpCode::BrFalse_A)
6574+
*result = Js::JavascriptConversion::ToBoolean(src1Var, this->func->GetScriptContext());
6575+
if (instr->m_opcode == Js::OpCode::BrFalse_A)
65966576
{
6597-
result = !result;
6577+
*result = !(*result);
65986578
}
65996579
break;
66006580
}
@@ -6607,13 +6587,44 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
66076587
return false;
66086588
}
66096589

6610-
result = constVal == 0;
6590+
*result = constVal == 0;
66116591
break;
66126592

66136593
default:
66146594
return false;
6615-
#undef BRANCH
66166595
}
6596+
return true;
6597+
}
6598+
6599+
bool
6600+
GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Value **pDstVal)
6601+
{
6602+
if (!src1Val)
6603+
{
6604+
return false;
6605+
}
6606+
6607+
Js::Var src1Var = this->GetConstantVar(instr->GetSrc1(), src1Val);
6608+
6609+
Js::Var src2Var = nullptr;
6610+
6611+
if (instr->GetSrc2())
6612+
{
6613+
if (!src2Val)
6614+
{
6615+
return false;
6616+
}
6617+
6618+
src2Var = this->GetConstantVar(instr->GetSrc2(), src2Val);
6619+
}
6620+
6621+
bool result;
6622+
6623+
if (!CanProveConditionalBranch(instr, src1Val, src2Val, src1Var, src2Var, &result))
6624+
{
6625+
return false;
6626+
}
6627+
66176628

66186629
this->OptConstFoldBr(!!result, instr);
66196630

lib/Backend/GlobOpt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ class GlobOpt
612612
bool OptConstFoldBinary(IR::Instr * *pInstr, const IntConstantBounds &src1IntConstantBounds, const IntConstantBounds &src2IntConstantBounds, Value **pDstVal);
613613
bool OptConstFoldUnary(IR::Instr * *pInstr, const int32 intConstantValue, const bool isUsingOriginalSrc1Value, Value **pDstVal);
614614
bool OptConstPeep(IR::Instr *instr, IR::Opnd *constSrc, Value **pDstVal, ValueInfo *vInfo);
615+
bool CanProveConditionalBranch(IR::Instr *instr, Value *src1Val, Value *src2Val, Js::Var src1Var, Js::Var src2Var, bool *result);
615616
bool OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Value **pDstVal);
616617
Js::Var GetConstantVar(IR::Opnd *opnd, Value *val);
617618
bool IsWorthSpecializingToInt32DueToSrc(IR::Opnd *const src, Value *const val);

0 commit comments

Comments
 (0)