Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 13878017: Convert EqualityCompare to StrictCompare if reciever is either null or guaranteed to have default e… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 } 63 }
64 } 64 }
65 } else if (instr->IsPolymorphicInstanceCall()) { 65 } else if (instr->IsPolymorphicInstanceCall()) {
66 SpecializePolymorphicInstanceCall(instr->AsPolymorphicInstanceCall()); 66 SpecializePolymorphicInstanceCall(instr->AsPolymorphicInstanceCall());
67 } else if (instr->IsStrictCompare()) { 67 } else if (instr->IsStrictCompare()) {
68 VisitStrictCompare(instr->AsStrictCompare()); 68 VisitStrictCompare(instr->AsStrictCompare());
69 } else if (instr->IsBranch()) { 69 } else if (instr->IsBranch()) {
70 ComparisonInstr* compare = instr->AsBranch()->comparison(); 70 ComparisonInstr* compare = instr->AsBranch()->comparison();
71 if (compare->IsStrictCompare()) { 71 if (compare->IsStrictCompare()) {
72 VisitStrictCompare(compare->AsStrictCompare()); 72 VisitStrictCompare(compare->AsStrictCompare());
73 } else if (compare->IsEqualityCompare()) {
74 StrictifyEqualityCompare(compare->AsEqualityCompare(),
75 instr->AsBranch());
73 } 76 }
74 } 77 }
75 } 78 }
76 current_iterator_ = NULL; 79 current_iterator_ = NULL;
77 } 80 }
78 } 81 }
79 82
80 83
81 // Attempt to build ICData for call using propagated class-ids. 84 // Attempt to build ICData for call using propagated class-ids.
82 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { 85 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
(...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 comp->set_operands_class_id(kMintCid); 2180 comp->set_operands_class_id(kMintCid);
2178 } 2181 }
2179 } 2182 }
2180 2183
2181 2184
2182 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpInstr* instr) { 2185 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpInstr* instr) {
2183 HandleRelationalOp(instr); 2186 HandleRelationalOp(instr);
2184 } 2187 }
2185 2188
2186 2189
2190 bool FlowGraphOptimizer::CanStrictifyEqualityCompare(
srdjan 2013/04/18 16:54:49 Can this be a const function?
Vyacheslav Egorov (Google) 2013/04/18 19:48:36 Made it static.
2191 EqualityCompareInstr* compare) {
2192 // If one of the inputs is null this is a strict comparison.
2193 if (compare->left()->BindsToConstantNull() ||
2194 compare->right()->BindsToConstantNull()) {
2195 return true;
2196 }
2197
2198 if (compare->left()->Type()->IsNone()) {
2199 return false; // We might be running prior to any type propagation passes.
2200 }
2201
2202 // Try resolving target function using propagated cid for the receiver.
2203 // If receiver is either null or has default equality operator then
2204 // we can convert such comparison to a strict one.
2205 const intptr_t receiver_cid =
2206 compare->left()->Type()->ToNullableCid();
2207
2208 if (receiver_cid == kDynamicCid) {
2209 return false;
2210 }
2211
2212 const Class& receiver_class = Class::Handle(
2213 Isolate::Current()->class_table()->At(receiver_cid));
2214 const Function& function = Function::Handle(
2215 Resolver::ResolveDynamicForReceiverClass(
2216 receiver_class,
2217 Symbols::EqualOperator(),
2218 2,
2219 0));
srdjan 2013/04/18 16:54:49 Don't you need to look up the super chain if any (
srdjan 2013/04/18 17:28:59 Correction: ResolveDynamicForReceiverClass goes up
Vyacheslav Egorov (Google) 2013/04/18 19:48:36 Object has kInstanceCid cid that is how it works.
2220
2221 if (function.IsNull()) {
2222 return false;
2223 }
2224
2225 return (Class::Handle(function.Owner()).id() == kInstanceCid);
2226 }
2227
2228
2229 template <typename T>
2230 bool FlowGraphOptimizer::StrictifyEqualityCompare(EqualityCompareInstr* compare,
2231 T current_instruction) {
srdjan 2013/04/18 16:54:49 Can this be a const function?
srdjan 2013/04/18 16:54:49 I assume that it is templated bcause current_instr
Vyacheslav Egorov (Google) 2013/04/18 19:48:36 Made it const.
Vyacheslav Egorov (Google) 2013/04/18 19:48:36 Yes, for the same reason the HandleEqualityCompare
2232 if (CanStrictifyEqualityCompare(compare)) {
2233 Token::Kind strict_kind = (compare->kind() == Token::kEQ) ?
2234 Token::kEQ_STRICT : Token::kNE_STRICT;
2235 StrictCompareInstr* strict_comp =
2236 new StrictCompareInstr(strict_kind,
2237 compare->left()->CopyWithType(),
2238 compare->right()->CopyWithType());
2239 current_instruction->ReplaceWith(strict_comp, current_iterator());
2240 return true;
2241 }
2242 return false;
2243 }
2244
2245
2187 template <typename T> 2246 template <typename T>
2188 void FlowGraphOptimizer::HandleEqualityCompare(EqualityCompareInstr* comp, 2247 void FlowGraphOptimizer::HandleEqualityCompare(EqualityCompareInstr* comp,
2189 T current_instruction) { 2248 T current_instruction) {
2190 // If one of the inputs is null, no ICdata will be collected. 2249 if (StrictifyEqualityCompare(comp, current_instruction)) {
2191 if (comp->left()->BindsToConstantNull() ||
2192 comp->right()->BindsToConstantNull()) {
2193 Token::Kind strict_kind = (comp->kind() == Token::kEQ) ?
2194 Token::kEQ_STRICT : Token::kNE_STRICT;
2195 StrictCompareInstr* strict_comp =
2196 new StrictCompareInstr(strict_kind,
2197 comp->left()->Copy(),
2198 comp->right()->Copy());
2199 current_instruction->ReplaceWith(strict_comp, current_iterator());
2200 return; 2250 return;
2201 } 2251 }
2252
2202 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) { 2253 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) {
2203 return; 2254 return;
2204 } 2255 }
2256
2205 ASSERT(comp->ic_data()->num_args_tested() == 2); 2257 ASSERT(comp->ic_data()->num_args_tested() == 2);
2206 if (comp->ic_data()->NumberOfChecks() == 1) { 2258 if (comp->ic_data()->NumberOfChecks() == 1) {
2207 GrowableArray<intptr_t> class_ids; 2259 GrowableArray<intptr_t> class_ids;
2208 Function& target = Function::Handle(); 2260 Function& target = Function::Handle();
2209 comp->ic_data()->GetCheckAt(0, &class_ids, &target); 2261 comp->ic_data()->GetCheckAt(0, &class_ids, &target);
2210 // TODO(srdjan): allow for mixed mode int/double comparison. 2262 // TODO(srdjan): allow for mixed mode int/double comparison.
2211 2263
2212 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) { 2264 if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
2213 InsertBefore(current_instruction, 2265 InsertBefore(current_instruction,
2214 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()), 2266 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 AddCheckClass(comp->right()->definition(), 2312 AddCheckClass(comp->right()->definition(),
2261 unary_checks_1, 2313 unary_checks_1,
2262 comp->deopt_id(), 2314 comp->deopt_id(),
2263 current_instruction->env(), 2315 current_instruction->env(),
2264 current_instruction); 2316 current_instruction);
2265 comp->set_receiver_class_id(kSmiCid); 2317 comp->set_receiver_class_id(kSmiCid);
2266 } 2318 }
2267 } 2319 }
2268 2320
2269 2321
2322
2323
2270 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) { 2324 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) {
2271 HandleEqualityCompare(instr, instr); 2325 HandleEqualityCompare(instr, instr);
2272 } 2326 }
2273 2327
2274 2328
2275 void FlowGraphOptimizer::VisitBranch(BranchInstr* instr) { 2329 void FlowGraphOptimizer::VisitBranch(BranchInstr* instr) {
2276 ComparisonInstr* comparison = instr->comparison(); 2330 ComparisonInstr* comparison = instr->comparison();
2277 if (comparison->IsRelationalOp()) { 2331 if (comparison->IsRelationalOp()) {
2278 HandleRelationalOp(comparison->AsRelationalOp()); 2332 HandleRelationalOp(comparison->AsRelationalOp());
2279 } else if (comparison->IsEqualityCompare()) { 2333 } else if (comparison->IsEqualityCompare()) {
(...skipping 2780 matching lines...) Expand 10 before | Expand all | Expand 10 after
5060 if (changed) { 5114 if (changed) {
5061 // We may have changed the block order and the dominator tree. 5115 // We may have changed the block order and the dominator tree.
5062 flow_graph->DiscoverBlocks(); 5116 flow_graph->DiscoverBlocks();
5063 GrowableArray<BitVector*> dominance_frontier; 5117 GrowableArray<BitVector*> dominance_frontier;
5064 flow_graph->ComputeDominators(&dominance_frontier); 5118 flow_graph->ComputeDominators(&dominance_frontier);
5065 } 5119 }
5066 } 5120 }
5067 5121
5068 5122
5069 } // namespace dart 5123 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698