Index: runtime/vm/flow_graph_inliner.cc |
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc |
index 8f8eeecc88ec002fa95f244265c36c327e2e5c79..1bc197e306287eeb3db6fb6b2144cbe7b90149c0 100644 |
--- a/runtime/vm/flow_graph_inliner.cc |
+++ b/runtime/vm/flow_graph_inliner.cc |
@@ -1544,7 +1544,7 @@ bool PolymorphicInliner::CheckNonInlinedDuplicate(const Function& target) { |
bool PolymorphicInliner::TryInliningPoly(const TargetInfo& target_info) { |
if ((!FLAG_precompiled_mode || |
owner_->inliner_->use_speculative_inlining()) && |
- target_info.cid_start == target_info.cid_end && |
+ target_info.IsSingleCid() && |
TryInlineRecognizedMethod(target_info.cid_start, *target_info.target)) { |
owner_->inlined_ = true; |
return true; |
@@ -1575,7 +1575,7 @@ bool PolymorphicInliner::TryInliningPoly(const TargetInfo& target_info) { |
RedefinitionInstr* redefinition = new (Z) RedefinitionInstr(actual->Copy(Z)); |
redefinition->set_ssa_temp_index( |
owner_->caller_graph()->alloc_ssa_temp_index()); |
- if (target_info.cid_start == target_info.cid_end) { |
+ if (target_info.IsSingleCid()) { |
redefinition->UpdateType(CompileType::FromCid(target_info.cid_start)); |
} |
redefinition->InsertAfter(callee_graph->graph_entry()->normal_entry()); |
@@ -1694,31 +1694,25 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { |
new (Z) LoadClassIdInstr(new (Z) Value(receiver)); |
load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index()); |
cursor = AppendInstruction(cursor, load_cid); |
- bool follow_with_deopt = false; |
for (intptr_t i = 0; i < inlined_variants_.length(); ++i) { |
const CidRange& variant = inlined_variants_[i]; |
- bool test_is_range = (variant.cid_start != variant.cid_end); |
+ 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 |
- // complete. TODO(erikcorry): Enhance CheckClassIdInstr so it can take an |
- // arbitrary CidRangeTarget. Currently we don't go into this branch if the |
- // last test is a range test - instead we set the follow_with_deopt flag. |
- if (is_last_test && (!test_is_range || call_->complete()) && |
- non_inlined_variants_->is_empty()) { |
+ // complete. |
+ if (is_last_test && non_inlined_variants_->is_empty()) { |
// If it is the last variant use a check class id instruction which can |
// deoptimize, followed unconditionally by the body. Omit the check if |
// we know that we have covered all possible classes. |
if (!call_->complete()) { |
- ASSERT(!test_is_range); // See condition above. |
RedefinitionInstr* cid_redefinition = |
new RedefinitionInstr(new (Z) Value(load_cid)); |
cid_redefinition->set_ssa_temp_index( |
owner_->caller_graph()->alloc_ssa_temp_index()); |
cursor = AppendInstruction(cursor, cid_redefinition); |
- CheckClassIdInstr* check_class_id = |
- new (Z) CheckClassIdInstr(new (Z) Value(cid_redefinition), |
- variant.cid_start, call_->deopt_id()); |
+ CheckClassIdInstr* check_class_id = new (Z) CheckClassIdInstr( |
+ new (Z) Value(cid_redefinition), variant, call_->deopt_id()); |
check_class_id->InheritDeoptTarget(zone(), call_); |
cursor = AppendInstruction(cursor, check_class_id); |
} |
@@ -1760,7 +1754,6 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { |
} |
cursor = NULL; |
} else { |
- if (is_last_test && test_is_range) follow_with_deopt = true; |
// For all variants except the last, use a branch on the loaded class |
// id. |
const Smi& cid = Smi::ZoneHandle(Smi::New(variant.cid_start)); |
@@ -1907,14 +1900,6 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { |
exit_collector_->AddExit(fallback_return); |
cursor = NULL; |
} else { |
- if (follow_with_deopt) { |
- DeoptimizeInstr* deopt = new DeoptimizeInstr( |
- ICData::kDeoptPolymorphicInstanceCallTestFail, call_->deopt_id()); |
- deopt->InheritDeoptTarget(zone(), call_); |
- cursor = AppendInstruction(cursor, deopt); |
- cursor = NULL; |
- } |
- |
// Remove push arguments of the call. |
for (intptr_t i = 0; i < call_->ArgumentCount(); ++i) { |
PushArgumentInstr* push = call_->PushArgumentAt(i); |