@@ -6362,29 +6362,10 @@ bool BoolAndIntStaticAndTypeMismatch(Value* src1Val, Value* src2Val, Js::Var src
6362
6362
(src2ValInfo->IsNumber() && src2Var && src1ValInfo->IsBoolean() && src2Var != Js::TaggedInt::ToVarUnchecked(0) && src2Var != Js::TaggedInt::ToVarUnchecked(1));
6363
6363
}
6364
6364
6365
+
6365
6366
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 )
6367
6368
{
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
-
6388
6369
auto AreSourcesEqual = [&](Value * val1, Value * val2) -> bool
6389
6370
{
6390
6371
// NaN !== NaN, and objects can have valueOf/toString
@@ -6397,91 +6378,90 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6397
6378
//Assert(!src1Var || !Js::JavascriptOperators::IsObject(src1Var));
6398
6379
//Assert(!src2Var || !Js::JavascriptOperators::IsObject(src2Var));
6399
6380
6400
- BOOL result;
6381
+ int64 left64, right64;
6382
+ int left, right;
6401
6383
int32 constVal;
6384
+
6402
6385
switch (instr->m_opcode)
6403
6386
{
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) \
6405
6428
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 )) \
6408
6431
{ \
6409
- result = (TYPE)left64 CMP (TYPE)right64 ; \
6432
+ * result = left CMP right ; \
6410
6433
} \
6411
- else if (AreSourcesEqual(src1Val, src2Val)) \
6434
+ else if (src1Val && src2Val && AreSourcesEqual(src1Val, src2Val)) \
6412
6435
{ \
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()); \
6414
6445
} \
6415
6446
else \
6416
6447
{ \
6417
6448
return false; \
6418
6449
} \
6419
6450
break;
6420
6451
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
6485
6465
case Js::OpCode::BrSrEq_A:
6486
6466
case Js::OpCode::BrSrNotNeq_A:
6487
6467
if (!src1Var || !src2Var)
@@ -6500,13 +6480,13 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6500
6480
(src2ValInfo->IsBoolean() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenBoolean()) ||
6501
6481
(src2ValInfo->IsNumber() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenNumber()) ||
6502
6482
(src2ValInfo->IsString() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenString())
6503
- )
6483
+ )
6504
6484
{
6505
- result = false;
6485
+ * result = false;
6506
6486
}
6507
6487
else if (AreSourcesEqual(src1Val, src2Val))
6508
6488
{
6509
- result = true;
6489
+ * result = true;
6510
6490
}
6511
6491
else
6512
6492
{
@@ -6520,7 +6500,7 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6520
6500
// TODO: OOP JIT, const folding
6521
6501
return false;
6522
6502
}
6523
- result = Js::JavascriptOperators::StrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6503
+ * result = Js::JavascriptOperators::StrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6524
6504
}
6525
6505
break;
6526
6506
@@ -6542,13 +6522,13 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6542
6522
(src2ValInfo->IsBoolean() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenBoolean()) ||
6543
6523
(src2ValInfo->IsNumber() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenNumber()) ||
6544
6524
(src2ValInfo->IsString() && src1ValInfo->IsDefinite() && !src1ValInfo->HasBeenString())
6545
- )
6525
+ )
6546
6526
{
6547
- result = true;
6527
+ * result = true;
6548
6528
}
6549
6529
else if (AreSourcesEqual(src1Val, src2Val))
6550
6530
{
6551
- result = false;
6531
+ * result = false;
6552
6532
}
6553
6533
else
6554
6534
{
@@ -6562,23 +6542,23 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6562
6542
// TODO: OOP JIT, const folding
6563
6543
return false;
6564
6544
}
6565
- result = Js::JavascriptOperators::NotStrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6545
+ * result = Js::JavascriptOperators::NotStrictEqual(src1Var, src2Var, this->func->GetScriptContext());
6566
6546
}
6567
6547
break;
6568
6548
6569
6549
case Js::OpCode::BrFalse_A:
6570
6550
case Js::OpCode::BrTrue_A:
6571
6551
{
6572
6552
ValueInfo *const src1ValueInfo = src1Val->GetValueInfo();
6573
- if(src1ValueInfo->IsNull() || src1ValueInfo->IsUndefined())
6553
+ if (src1ValueInfo->IsNull() || src1ValueInfo->IsUndefined())
6574
6554
{
6575
- result = instr->m_opcode == Js::OpCode::BrFalse_A;
6555
+ * result = instr->m_opcode == Js::OpCode::BrFalse_A;
6576
6556
break;
6577
6557
}
6578
- if(src1ValueInfo->IsObject() && src1ValueInfo->GetObjectType() > ObjectType::Object)
6558
+ if (src1ValueInfo->IsObject() && src1ValueInfo->GetObjectType() > ObjectType::Object)
6579
6559
{
6580
6560
// 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;
6582
6562
break;
6583
6563
}
6584
6564
@@ -6591,10 +6571,10 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6591
6571
{
6592
6572
return false;
6593
6573
}
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)
6596
6576
{
6597
- result = !result;
6577
+ * result = !(* result) ;
6598
6578
}
6599
6579
break;
6600
6580
}
@@ -6607,13 +6587,44 @@ GlobOpt::OptConstFoldBranch(IR::Instr *instr, Value *src1Val, Value*src2Val, Val
6607
6587
return false;
6608
6588
}
6609
6589
6610
- result = constVal == 0;
6590
+ * result = constVal == 0;
6611
6591
break;
6612
6592
6613
6593
default:
6614
6594
return false;
6615
- #undef BRANCH
6616
6595
}
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
+
6617
6628
6618
6629
this->OptConstFoldBr(!!result, instr);
6619
6630
0 commit comments