| 3493 | } |
| 3494 | |
| 3495 | void BeMCContext::CreateBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx) |
| 3496 | { |
| 3497 | // This is an empirically determined binary switching limit |
| 3498 | if (endIdx - startIdx >= 18) |
| 3499 | { |
| 3500 | int gteLabel = mCurLabelIdx++; |
| 3501 | |
| 3502 | auto mcDefaultBlock = GetOperand(switchInst->mDefaultBlock); |
| 3503 | |
| 3504 | int midIdx = startIdx + (endIdx - startIdx) / 2; |
| 3505 | auto& switchCase = switchInst->mCases[midIdx]; |
| 3506 | auto switchBlock = GetOperand(switchCase.mBlock); |
| 3507 | auto mcValue = GetOperand(switchInst->mValue); |
| 3508 | auto valueType = GetType(mcValue); |
| 3509 | |
| 3510 | AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue)); |
| 3511 | AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(gteLabel), BeMCOperand::FromCmpKind(BeCmpKind_SGE)); |
| 3512 | switchBlock.mBlock->AddPred(mActiveBlock); |
| 3513 | |
| 3514 | CreateBinarySwitchSection(switchInst, startIdx, midIdx); |
| 3515 | AllocInst(BeMCInstKind_Br, mcDefaultBlock); |
| 3516 | CreateLabel(-1, gteLabel); |
| 3517 | CreateBinarySwitchSection(switchInst, midIdx, endIdx); |
| 3518 | return; |
| 3519 | } |
| 3520 | |
| 3521 | for (int caseIdx = startIdx; caseIdx < endIdx; caseIdx++) |
| 3522 | { |
| 3523 | auto& switchCase = switchInst->mCases[caseIdx]; |
| 3524 | auto switchBlock = GetOperand(switchCase.mBlock); |
| 3525 | auto mcValue = GetOperand(switchInst->mValue); |
| 3526 | AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue)); |
| 3527 | AllocInst(BeMCInstKind_CondBr, switchBlock, BeMCOperand::FromCmpKind(BeCmpKind_EQ)); |
| 3528 | switchBlock.mBlock->AddPred(mActiveBlock); |
| 3529 | } |
| 3530 | } |
| 3531 | |
| 3532 | void BeMCContext::CreateCondBr(BeMCBlock* mcBlock, BeMCOperand& testVal, const BeMCOperand& trueBlock, const BeMCOperand& falseBlock) |
| 3533 | { |