| Index: runtime/vm/flow_graph_inliner.cc
|
| diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
|
| index 65c37415495fe331a2acc600cf65aca6347e4dc5..da50c0d00f46bb6f010ffccbc04abb35c6464d11 100644
|
| --- a/runtime/vm/flow_graph_inliner.cc
|
| +++ b/runtime/vm/flow_graph_inliner.cc
|
| @@ -1672,7 +1672,6 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
| cursor = AppendInstruction(cursor, load_cid);
|
| for (intptr_t i = 0; i < inlined_variants_.length(); ++i) {
|
| const CidRange& variant = inlined_variants_[i];
|
| - bool test_is_range = !variant.IsSingleCid();
|
| bool is_last_test = (i == inlined_variants_.length() - 1);
|
| // 1. Guard the body with a class id check. We don't need any check if
|
| // it's the last test and global analysis has told us that the call is
|
| @@ -1732,47 +1731,21 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
| } else {
|
| // For all variants except the last, use a branch on the loaded class
|
| // id.
|
| - const Smi& cid = Smi::ZoneHandle(Smi::New(variant.cid_start));
|
| - ConstantInstr* cid_constant = owner_->caller_graph()->GetConstant(cid);
|
| - BranchInstr* branch;
|
| - BranchInstr* upper_limit_branch = NULL;
|
| + ComparisonInstr* compare;
|
| BlockEntryInstr* cid_test_entry_block = current_block;
|
| - if (test_is_range) {
|
| - // Double branch for testing a range of Cids. TODO(erikcorry): Make a
|
| - // special instruction that uses subtraction and unsigned comparison to
|
| - // do this with a single branch.
|
| - const Smi& cid_end = Smi::ZoneHandle(Smi::New(variant.cid_end));
|
| - ConstantInstr* cid_constant_end =
|
| - owner_->caller_graph()->GetConstant(cid_end);
|
| - RelationalOpInstr* compare_top = new RelationalOpInstr(
|
| - call_->instance_call()->token_pos(), Token::kLTE,
|
| - new Value(load_cid), new Value(cid_constant_end), kSmiCid,
|
| - call_->deopt_id());
|
| - BranchInstr* branch_top = upper_limit_branch =
|
| - new BranchInstr(compare_top, Thread::kNoDeoptId);
|
| - branch_top->InheritDeoptTarget(zone(), call_);
|
| - cursor = AppendInstruction(cursor, branch_top);
|
| - current_block->set_last_instruction(branch_top);
|
| -
|
| - TargetEntryInstr* below_target = new TargetEntryInstr(
|
| - AllocateBlockId(), try_idx, Thread::kNoDeoptId);
|
| - below_target->InheritDeoptTarget(zone(), call_);
|
| - current_block->AddDominatedBlock(below_target);
|
| - cursor = current_block = below_target;
|
| - *branch_top->true_successor_address() = below_target;
|
| -
|
| - RelationalOpInstr* compare_bottom = new RelationalOpInstr(
|
| - call_->instance_call()->token_pos(), Token::kGTE,
|
| - new Value(load_cid), new Value(cid_constant), kSmiCid,
|
| - call_->deopt_id());
|
| - branch = new BranchInstr(compare_bottom, Thread::kNoDeoptId);
|
| - } else {
|
| - StrictCompareInstr* compare = new StrictCompareInstr(
|
| + if (variant.IsSingleCid()) {
|
| + const Smi& cid = Smi::ZoneHandle(Smi::New(variant.cid_start));
|
| + ConstantInstr* cid_constant = owner_->caller_graph()->GetConstant(cid);
|
| + compare = new StrictCompareInstr(
|
| call_->instance_call()->token_pos(), Token::kEQ_STRICT,
|
| new Value(load_cid), new Value(cid_constant),
|
| /* number_check = */ false, Thread::kNoDeoptId);
|
| - branch = new BranchInstr(compare, Thread::kNoDeoptId);
|
| + } else {
|
| + compare = new SmiRangeComparisonInstr(
|
| + call_->instance_call()->token_pos(), new Value(load_cid),
|
| + variant.cid_start, variant.cid_end);
|
| }
|
| + BranchInstr* branch = new BranchInstr(compare, Thread::kNoDeoptId);
|
|
|
| branch->InheritDeoptTarget(zone(), call_);
|
| cursor = AppendInstruction(cursor, branch);
|
| @@ -1823,31 +1796,6 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
| cid_test_entry_block->AddDominatedBlock(false_target);
|
|
|
| cursor = current_block = false_target;
|
| -
|
| - if (test_is_range) {
|
| - // If we tested against a range of Cids there are two different tests
|
| - // that can go to the no-cid-match target.
|
| - JoinEntryInstr* join =
|
| - new JoinEntryInstr(AllocateBlockId(), try_idx, Thread::kNoDeoptId);
|
| - TargetEntryInstr* false_target2 = new TargetEntryInstr(
|
| - AllocateBlockId(), try_idx, Thread::kNoDeoptId);
|
| - *upper_limit_branch->false_successor_address() = false_target2;
|
| - cid_test_entry_block->AddDominatedBlock(false_target2);
|
| - cid_test_entry_block->AddDominatedBlock(join);
|
| - GotoInstr* goto_1 = new GotoInstr(join, Thread::kNoDeoptId);
|
| - GotoInstr* goto_2 = new GotoInstr(join, Thread::kNoDeoptId);
|
| - false_target->LinkTo(goto_1);
|
| - false_target2->LinkTo(goto_2);
|
| - false_target->set_last_instruction(goto_1);
|
| - false_target2->set_last_instruction(goto_2);
|
| -
|
| - join->InheritDeoptTarget(zone(), call_);
|
| - false_target2->InheritDeoptTarget(zone(), call_);
|
| - goto_1->InheritDeoptTarget(zone(), call_);
|
| - goto_2->InheritDeoptTarget(zone(), call_);
|
| -
|
| - cursor = current_block = join;
|
| - }
|
| }
|
| }
|
|
|
|
|