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; |
- } |
} |
} |