| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 ForwardInstructionIterator it(entry); | 49 ForwardInstructionIterator it(entry); |
| 50 current_iterator_ = ⁢ | 50 current_iterator_ = ⁢ |
| 51 for (; !it.Done(); it.Advance()) { | 51 for (; !it.Done(); it.Advance()) { |
| 52 if (it.Current()->IsInstanceCall()) { | 52 if (it.Current()->IsInstanceCall()) { |
| 53 InstanceCallInstr* call = it.Current()->AsInstanceCall(); | 53 InstanceCallInstr* call = it.Current()->AsInstanceCall(); |
| 54 if (call->HasICData()) { | 54 if (call->HasICData()) { |
| 55 if (TryCreateICData(call)) { | 55 if (TryCreateICData(call)) { |
| 56 VisitInstanceCall(call); | 56 VisitInstanceCall(call); |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 } else if (it.Current()->IsPolymorphicInstanceCall()) { |
| 60 SpecializePolymophicInstanceCall( |
| 61 it.Current()->AsPolymorphicInstanceCall()); |
| 59 } else if (it.Current()->IsStrictCompare()) { | 62 } else if (it.Current()->IsStrictCompare()) { |
| 60 VisitStrictCompare(it.Current()->AsStrictCompare()); | 63 VisitStrictCompare(it.Current()->AsStrictCompare()); |
| 61 } else if (it.Current()->IsBranch()) { | 64 } else if (it.Current()->IsBranch()) { |
| 62 ComparisonInstr* compare = it.Current()->AsBranch()->comparison(); | 65 ComparisonInstr* compare = it.Current()->AsBranch()->comparison(); |
| 63 if (compare->IsStrictCompare()) { | 66 if (compare->IsStrictCompare()) { |
| 64 VisitStrictCompare(compare->AsStrictCompare()); | 67 VisitStrictCompare(compare->AsStrictCompare()); |
| 65 } | 68 } |
| 66 } | 69 } |
| 67 } | 70 } |
| 68 current_iterator_ = NULL; | 71 current_iterator_ = NULL; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 call->deopt_id(), | 113 call->deopt_id(), |
| 111 class_ids.length())); | 114 class_ids.length())); |
| 112 ic_data.AddReceiverCheck(class_ids[0], function); | 115 ic_data.AddReceiverCheck(class_ids[0], function); |
| 113 call->set_ic_data(&ic_data); | 116 call->set_ic_data(&ic_data); |
| 114 return true; | 117 return true; |
| 115 } | 118 } |
| 116 return false; | 119 return false; |
| 117 } | 120 } |
| 118 | 121 |
| 119 | 122 |
| 123 static const ICData& SpecializeICData(const ICData& ic_data, intptr_t cid) { |
| 124 ASSERT(ic_data.num_args_tested() == 1); |
| 125 |
| 126 if ((ic_data.NumberOfChecks() == 1) && |
| 127 (ic_data.GetReceiverClassIdAt(0) == cid)) { |
| 128 return ic_data; // Nothing to do |
| 129 } |
| 130 |
| 131 const ICData& new_ic_data = ICData::ZoneHandle(ICData::New( |
| 132 Function::Handle(ic_data.function()), |
| 133 String::Handle(ic_data.target_name()), |
| 134 ic_data.deopt_id(), |
| 135 ic_data.num_args_tested())); |
| 136 |
| 137 const Function& function = |
| 138 Function::Handle(ic_data.GetTargetForReceiverClassId(cid)); |
| 139 if (!function.IsNull()) { |
| 140 new_ic_data.AddReceiverCheck(cid, function); |
| 141 } |
| 142 |
| 143 return new_ic_data; |
| 144 } |
| 145 |
| 146 |
| 147 void FlowGraphOptimizer::SpecializePolymophicInstanceCall( |
| 148 PolymorphicInstanceCallInstr* call) { |
| 149 if (!call->with_checks()) { |
| 150 return; // Already specialized. |
| 151 } |
| 152 |
| 153 const intptr_t receiver_cid = call->ArgumentAt(0)->value()->ResultCid(); |
| 154 if (receiver_cid == kDynamicCid) { |
| 155 return; // No information about receiver was infered. |
| 156 } |
| 157 |
| 158 const ICData& ic_data = SpecializeICData(call->ic_data(), receiver_cid); |
| 159 |
| 160 const bool with_checks = false; |
| 161 PolymorphicInstanceCallInstr* specialized = |
| 162 new PolymorphicInstanceCallInstr(call->instance_call(), |
| 163 ic_data, |
| 164 with_checks); |
| 165 call->ReplaceWith(specialized, current_iterator()); |
| 166 } |
| 167 |
| 168 |
| 120 static void EnsureSSATempIndex(FlowGraph* graph, | 169 static void EnsureSSATempIndex(FlowGraph* graph, |
| 121 Definition* defn, | 170 Definition* defn, |
| 122 Definition* replacement) { | 171 Definition* replacement) { |
| 123 if ((replacement->ssa_temp_index() == -1) && | 172 if ((replacement->ssa_temp_index() == -1) && |
| 124 (defn->ssa_temp_index() != -1)) { | 173 (defn->ssa_temp_index() != -1)) { |
| 125 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index()); | 174 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index()); |
| 126 } | 175 } |
| 127 } | 176 } |
| 128 | 177 |
| 129 | 178 |
| (...skipping 4320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4450 | 4499 |
| 4451 if (FLAG_trace_constant_propagation) { | 4500 if (FLAG_trace_constant_propagation) { |
| 4452 OS::Print("\n==== After constant propagation ====\n"); | 4501 OS::Print("\n==== After constant propagation ====\n"); |
| 4453 FlowGraphPrinter printer(*graph_); | 4502 FlowGraphPrinter printer(*graph_); |
| 4454 printer.PrintBlocks(); | 4503 printer.PrintBlocks(); |
| 4455 } | 4504 } |
| 4456 } | 4505 } |
| 4457 | 4506 |
| 4458 | 4507 |
| 4459 } // namespace dart | 4508 } // namespace dart |
| OLD | NEW |