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

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

Issue 10867012: Add a smi-check instruction for arithmetic smi operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 8 years, 4 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/code_generator.h ('k') | runtime/vm/il_printer.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) 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/cha.h" 7 #include "vm/cha.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/hash_map.h" 9 #include "vm/hash_map.h"
10 #include "vm/il_printer.h" 10 #include "vm/il_printer.h"
(...skipping 16 matching lines...) Expand all
27 27
28 28
29 void FlowGraphOptimizer::OptimizeComputations() { 29 void FlowGraphOptimizer::OptimizeComputations() {
30 for (intptr_t i = 0; i < block_order_.length(); ++i) { 30 for (intptr_t i = 0; i < block_order_.length(); ++i) {
31 BlockEntryInstr* entry = block_order_[i]; 31 BlockEntryInstr* entry = block_order_[i];
32 entry->Accept(this); 32 entry->Accept(this);
33 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 33 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
34 BindInstr* instr = it.Current()->AsBind(); 34 BindInstr* instr = it.Current()->AsBind();
35 if (instr != NULL) { 35 if (instr != NULL) {
36 Definition* result = instr->computation()->TryReplace(instr); 36 Definition* result = instr->computation()->TryReplace(instr);
37 if (result != NULL) { 37 if (result != instr) {
38 // Replace uses and remove the current instructions via the iterator. 38 if (result != NULL) {
39 instr->ReplaceUsesWith(result); 39 instr->ReplaceUsesWith(result);
40 if (FLAG_trace_optimization) {
41 OS::Print("Replacing v%d with v%d\n",
42 instr->ssa_temp_index(),
43 result->ssa_temp_index());
44 }
45 } else if (FLAG_trace_optimization) {
46 OS::Print("Removing v%d.\n", instr->ssa_temp_index());
47 }
40 it.RemoveCurrentFromGraph(); 48 it.RemoveCurrentFromGraph();
41 if (FLAG_trace_optimization) {
42 OS::Print("Replacing v%d with v%d\n",
43 instr->ssa_temp_index(),
44 result->ssa_temp_index());
45 }
46 } 49 }
47 } 50 }
48 } 51 }
49 } 52 }
50 } 53 }
51 54
52 55
53 static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) { 56 static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) {
54 ASSERT(ic_data.num_args_tested() > 0); 57 ASSERT(ic_data.num_args_tested() > 0);
55 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 58 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 if (ic_data.NumberOfChecks() != 1) return kIllegalCid; 190 if (ic_data.NumberOfChecks() != 1) return kIllegalCid;
188 ASSERT(HasOneTarget(ic_data)); 191 ASSERT(HasOneTarget(ic_data));
189 192
190 Function& target = Function::Handle(); 193 Function& target = Function::Handle();
191 intptr_t class_id; 194 intptr_t class_id;
192 ic_data.GetOneClassCheckAt(0, &class_id, &target); 195 ic_data.GetOneClassCheckAt(0, &class_id, &target);
193 return class_id; 196 return class_id;
194 } 197 }
195 198
196 199
200 // Insert a check computation before an instruction and set the environment
201 // of the check to the same as the instruction.
202 static void InsertCheckBefore(BindInstr* instr,
203 Computation* check,
204 Environment* env) {
205 BindInstr* check_instr = new BindInstr(BindInstr::kUnused, check);
206 check_instr->InsertBefore(instr);
207 ASSERT(env != NULL);
208 // Attach an environment to the check instruction.
209 check_instr->set_env(env);
210 }
211
212
197 static void AddCheckClass(BindInstr* instr, 213 static void AddCheckClass(BindInstr* instr,
198 InstanceCallComp* comp, 214 InstanceCallComp* comp,
199 Value* value) { 215 Value* value) {
200 // Type propagation has not run yet, we cannot eliminate the check. 216 // Type propagation has not run yet, we cannot eliminate the check.
201 CheckClassComp* check = new CheckClassComp(value, comp); 217 CheckClassComp* check = new CheckClassComp(value, comp);
202 const ICData& unary_checks = 218 const ICData& unary_checks =
203 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks()); 219 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
204 check->set_ic_data(&unary_checks); 220 check->set_ic_data(&unary_checks);
205 BindInstr* check_instr = new BindInstr(BindInstr::kUnused, check); 221 InsertCheckBefore(instr, check, instr->env());
206 ASSERT(instr->env() != NULL); // Always the case with SSA. 222 // Detach environment from the original instruction because it can't
207 // Attach the original environment to the check instruction. 223 // deoptimize.
208 check_instr->set_env(instr->env()); 224 instr->set_env(NULL);
209 check_instr->InsertBefore(instr);
210 } 225 }
211 226
212 227
213 bool FlowGraphOptimizer::TryReplaceWithArrayOp(BindInstr* instr, 228 bool FlowGraphOptimizer::TryReplaceWithArrayOp(BindInstr* instr,
214 InstanceCallComp* comp, 229 InstanceCallComp* comp,
215 Token::Kind op_kind) { 230 Token::Kind op_kind) {
216 // TODO(fschneider): Optimize []= operator in checked mode as well. 231 // TODO(fschneider): Optimize []= operator in checked mode as well.
217 if (op_kind == Token::kASSIGN_INDEX && FLAG_enable_type_checks) return false; 232 if (op_kind == Token::kASSIGN_INDEX && FLAG_enable_type_checks) return false;
218 233
219 const intptr_t class_id = ReceiverClassId(comp); 234 const intptr_t class_id = ReceiverClassId(comp);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 comp, 325 comp,
311 left, 326 left,
312 right); 327 right);
313 bin_op->set_ic_data(comp->ic_data()); 328 bin_op->set_ic_data(comp->ic_data());
314 instr->set_computation(bin_op); 329 instr->set_computation(bin_op);
315 RemovePushArguments(comp); 330 RemovePushArguments(comp);
316 } else { 331 } else {
317 ASSERT(operands_type == kSmiCid); 332 ASSERT(operands_type == kSmiCid);
318 Value* left = comp->ArgumentAt(0)->value(); 333 Value* left = comp->ArgumentAt(0)->value();
319 Value* right = comp->ArgumentAt(1)->value(); 334 Value* right = comp->ArgumentAt(1)->value();
335 // Insert two smi checks and attach a copy of the original
336 // environment because the smi operation can still deoptimize.
337 InsertCheckBefore(instr,
338 new CheckSmiComp(left, comp),
339 instr->env()->Copy());
340 InsertCheckBefore(instr,
341 new CheckSmiComp(right, comp),
342 instr->env()->Copy());
320 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind, 343 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind,
321 comp, 344 comp,
322 left, 345 left,
323 right); 346 right);
324 bin_op->set_ic_data(comp->ic_data()); 347 bin_op->set_ic_data(comp->ic_data());
325 instr->set_computation(bin_op); 348 instr->set_computation(bin_op);
326 RemovePushArguments(comp); 349 RemovePushArguments(comp);
327 } 350 }
328 return true; 351 return true;
329 } 352 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 if (target.kind() == RawFunction::kImplicitGetter) { 407 if (target.kind() == RawFunction::kImplicitGetter) {
385 if (!HasOneTarget(ic_data)) { 408 if (!HasOneTarget(ic_data)) {
386 // TODO(srdjan): Implement for mutiple targets. 409 // TODO(srdjan): Implement for mutiple targets.
387 return false; 410 return false;
388 } 411 }
389 // Inline implicit instance getter. 412 // Inline implicit instance getter.
390 const String& field_name = 413 const String& field_name =
391 String::Handle(Field::NameFromGetter(comp->function_name())); 414 String::Handle(Field::NameFromGetter(comp->function_name()));
392 const Field& field = Field::Handle(GetField(class_ids[0], field_name)); 415 const Field& field = Field::Handle(GetField(class_ids[0], field_name));
393 ASSERT(!field.IsNull()); 416 ASSERT(!field.IsNull());
417
394 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()); 418 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value());
395 instr->set_env(NULL);
396 LoadInstanceFieldComp* load = 419 LoadInstanceFieldComp* load =
397 new LoadInstanceFieldComp(field, 420 new LoadInstanceFieldComp(field,
398 comp->ArgumentAt(0)->value(), 421 comp->ArgumentAt(0)->value(),
399 NULL); // Can not deoptimize. 422 NULL); // Can not deoptimize.
400 instr->set_computation(load); 423 instr->set_computation(load);
401 RemovePushArguments(comp); 424 RemovePushArguments(comp);
402 return true; 425 return true;
403 } 426 }
404 427
405 // Not an implicit getter. 428 // Not an implicit getter.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 // TODO(srdjan): Inline special setters. 589 // TODO(srdjan): Inline special setters.
567 return false; 590 return false;
568 } 591 }
569 // Inline implicit instance setter. 592 // Inline implicit instance setter.
570 const String& field_name = 593 const String& field_name =
571 String::Handle(Field::NameFromSetter(comp->function_name())); 594 String::Handle(Field::NameFromSetter(comp->function_name()));
572 const Field& field = Field::Handle(GetField(class_id, field_name)); 595 const Field& field = Field::Handle(GetField(class_id, field_name));
573 ASSERT(!field.IsNull()); 596 ASSERT(!field.IsNull());
574 597
575 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()); 598 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value());
576 instr->set_env(NULL);
577 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( 599 StoreInstanceFieldComp* store = new StoreInstanceFieldComp(
578 field, 600 field,
579 comp->ArgumentAt(0)->value(), 601 comp->ArgumentAt(0)->value(),
580 comp->ArgumentAt(1)->value(), 602 comp->ArgumentAt(1)->value(),
581 NULL); // Can not deoptimize. 603 NULL); // Can not deoptimize.
582 instr->set_computation(store); 604 instr->set_computation(store);
583 RemovePushArguments(comp); 605 RemovePushArguments(comp);
584 return true; 606 return true;
585 } 607 }
586 608
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 OS::Print("Replacing v%d with v%d\n", 975 OS::Print("Replacing v%d with v%d\n",
954 instr->ssa_temp_index(), 976 instr->ssa_temp_index(),
955 result->ssa_temp_index()); 977 result->ssa_temp_index());
956 } 978 }
957 } 979 }
958 } 980 }
959 } 981 }
960 982
961 983
962 } // namespace dart 984 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698