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

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

Issue 215363004: Support for multiple register values (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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/flow_graph_type_propagator.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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 LoadIndexedInstr* load = new LoadIndexedInstr(new Value(instr), 296 LoadIndexedInstr* load = new LoadIndexedInstr(new Value(instr),
297 new Value(index_instr), 297 new Value(index_instr),
298 index_scale, 298 index_scale,
299 cid, 299 cid,
300 Isolate::kNoDeoptId); 300 Isolate::kNoDeoptId);
301 instr->ReplaceUsesWith(load); 301 instr->ReplaceUsesWith(load);
302 flow_graph()->InsertAfter(instr, load, NULL, Definition::kValue); 302 flow_graph()->InsertAfter(instr, load, NULL, Definition::kValue);
303 } 303 }
304 304
305 305
306 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr,
307 intptr_t index,
308 Representation rep,
309 intptr_t cid) {
310 ExtractNthOutputInstr* extract = new ExtractNthOutputInstr(new Value(instr),
311 index,
312 rep,
313 cid);
314 instr->ReplaceUsesWith(extract);
315 flow_graph()->InsertAfter(instr, extract, NULL, Definition::kValue);
316 }
317
318
306 // Dart: 319 // Dart:
307 // var x = d % 10; 320 // var x = d % 10;
308 // var y = d ~/ 10; 321 // var y = d ~/ 10;
309 // var z = x + y; 322 // var z = x + y;
310 // 323 //
311 // IL: 324 // IL:
312 // v4 <- %(v2, v3) 325 // v4 <- %(v2, v3)
313 // v5 <- ~/(v2, v3) 326 // v5 <- ~/(v2, v3)
314 // v6 <- +(v4, v5) 327 // v6 <- +(v4, v5)
315 // 328 //
(...skipping 24 matching lines...) Expand all
340 Definition* left_def = curr_instr->left()->definition(); 353 Definition* left_def = curr_instr->left()->definition();
341 Definition* right_def = curr_instr->right()->definition(); 354 Definition* right_def = curr_instr->right()->definition();
342 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { 355 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) {
343 BinarySmiOpInstr* other_binop = (*merge_candidates)[k]; 356 BinarySmiOpInstr* other_binop = (*merge_candidates)[k];
344 // 'other_binop' can be NULL if it was already merged. 357 // 'other_binop' can be NULL if it was already merged.
345 if ((other_binop != NULL) && 358 if ((other_binop != NULL) &&
346 (other_binop->op_kind() == other_kind) && 359 (other_binop->op_kind() == other_kind) &&
347 (other_binop->left()->definition() == left_def) && 360 (other_binop->left()->definition() == left_def) &&
348 (other_binop->right()->definition() == right_def)) { 361 (other_binop->right()->definition() == right_def)) {
349 (*merge_candidates)[k] = NULL; // Clear it. 362 (*merge_candidates)[k] = NULL; // Clear it.
350 // Append a LoadIndexed behind TRUNC_DIV and MOD.
351 ASSERT(curr_instr->HasUses()); 363 ASSERT(curr_instr->HasUses());
352 AppendLoadIndexedForMerged( 364 AppendExtractNthOutputForMerged(
353 curr_instr, 365 curr_instr,
354 MergedMathInstr::ResultIndexOf(curr_instr->op_kind()), 366 MergedMathInstr::OutputIndexOf(curr_instr->op_kind()),
355 kArrayCid); 367 kTagged, kSmiCid);
356 ASSERT(other_binop->HasUses()); 368 ASSERT(other_binop->HasUses());
357 AppendLoadIndexedForMerged( 369 AppendExtractNthOutputForMerged(
358 other_binop, 370 other_binop,
359 MergedMathInstr::ResultIndexOf(other_binop->op_kind()), 371 MergedMathInstr::OutputIndexOf(other_binop->op_kind()),
360 kArrayCid); 372 kTagged, kSmiCid);
361 373
362 ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(2); 374 ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(2);
363 args->Add(new Value(curr_instr->left()->definition())); 375 args->Add(new Value(curr_instr->left()->definition()));
364 args->Add(new Value(curr_instr->right()->definition())); 376 args->Add(new Value(curr_instr->right()->definition()));
365 377
366 // Replace with TruncDivMod. 378 // Replace with TruncDivMod.
367 MergedMathInstr* div_mod = new MergedMathInstr( 379 MergedMathInstr* div_mod = new MergedMathInstr(
368 args, 380 args,
369 curr_instr->deopt_id(), 381 curr_instr->deopt_id(),
370 MergedMathInstr::kTruncDivMod); 382 MergedMathInstr::kTruncDivMod);
(...skipping 18 matching lines...) Expand all
389 if (merge_candidates->length() < 2) { 401 if (merge_candidates->length() < 2) {
390 // Need at least a SIN and a COS. 402 // Need at least a SIN and a COS.
391 return; 403 return;
392 } 404 }
393 for (intptr_t i = 0; i < merge_candidates->length(); i++) { 405 for (intptr_t i = 0; i < merge_candidates->length(); i++) {
394 MathUnaryInstr* curr_instr = (*merge_candidates)[i]; 406 MathUnaryInstr* curr_instr = (*merge_candidates)[i];
395 if (curr_instr == NULL) { 407 if (curr_instr == NULL) {
396 // Instruction was merged already. 408 // Instruction was merged already.
397 continue; 409 continue;
398 } 410 }
399 ASSERT((curr_instr->kind() == MethodRecognizer::kMathSin) || 411 const intptr_t kind = curr_instr->kind();
400 (curr_instr->kind() == MethodRecognizer::kMathCos)); 412 ASSERT((kind == MethodRecognizer::kMathSin) ||
413 (kind == MethodRecognizer::kMathCos));
401 // Check if there is sin/cos binop with same inputs. 414 // Check if there is sin/cos binop with same inputs.
402 const intptr_t other_kind = 415 const intptr_t other_kind = (kind == MethodRecognizer::kMathSin) ?
403 (curr_instr->kind() == MethodRecognizer::kMathSin) ? 416 MethodRecognizer::kMathCos : MethodRecognizer::kMathSin;
404 MethodRecognizer::kMathCos : MethodRecognizer::kMathSin;
405 Definition* def = curr_instr->value()->definition(); 417 Definition* def = curr_instr->value()->definition();
406 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { 418 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) {
407 MathUnaryInstr* other_op = (*merge_candidates)[k]; 419 MathUnaryInstr* other_op = (*merge_candidates)[k];
408 // 'other_op' can be NULL if it was already merged. 420 // 'other_op' can be NULL if it was already merged.
409 if ((other_op != NULL) && (other_op->kind() == other_kind) && 421 if ((other_op != NULL) && (other_op->kind() == other_kind) &&
410 (other_op->value()->definition() == def)) { 422 (other_op->value()->definition() == def)) {
411 (*merge_candidates)[k] = NULL; // Clear it. 423 (*merge_candidates)[k] = NULL; // Clear it.
412 // Append a LoadIndexed behind SIN and COS.
413 ASSERT(curr_instr->HasUses()); 424 ASSERT(curr_instr->HasUses());
414 AppendLoadIndexedForMerged( 425 AppendExtractNthOutputForMerged(curr_instr,
415 curr_instr, 426 MergedMathInstr::OutputIndexOf(kind),
416 MergedMathInstr::ResultIndexOf(curr_instr->kind()), 427 kUnboxedDouble, kDoubleCid);
417 kTypedDataFloat64ArrayCid);
418 ASSERT(other_op->HasUses()); 428 ASSERT(other_op->HasUses());
419 AppendLoadIndexedForMerged( 429 AppendExtractNthOutputForMerged(
420 other_op, 430 other_op,
421 MergedMathInstr::ResultIndexOf(other_op->kind()), 431 MergedMathInstr::OutputIndexOf(other_kind),
422 kTypedDataFloat64ArrayCid); 432 kUnboxedDouble, kDoubleCid);
423 ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(1); 433 ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(1);
424 args->Add(new Value(curr_instr->value()->definition())); 434 args->Add(new Value(curr_instr->value()->definition()));
425
426 // Replace with SinCos. 435 // Replace with SinCos.
427 MergedMathInstr* sin_cos = new MergedMathInstr( 436 MergedMathInstr* sin_cos =
428 args, 437 new MergedMathInstr(args, curr_instr->DeoptimizationTarget(),
429 curr_instr->DeoptimizationTarget(), 438 MergedMathInstr::kSinCos);
430 MergedMathInstr::kSinCos);
431 curr_instr->ReplaceWith(sin_cos, current_iterator()); 439 curr_instr->ReplaceWith(sin_cos, current_iterator());
432 other_op->ReplaceUsesWith(sin_cos); 440 other_op->ReplaceUsesWith(sin_cos);
433 other_op->RemoveFromGraph(); 441 other_op->RemoveFromGraph();
434 // Only one merge possible. Because canonicalization happens later, 442 // Only one merge possible. Because canonicalization happens later,
435 // more candidates are possible. 443 // more candidates are possible.
436 // TODO(srdjan): Allow merging of sin/cos into sincos. 444 // TODO(srdjan): Allow merging of sin/cos into sincos.
437 break; 445 break;
438 } 446 }
439 } 447 }
440 } 448 }
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 if (unboxed != current) { 756 if (unboxed != current) {
749 phi->set_representation(unboxed); 757 phi->set_representation(unboxed);
750 return true; 758 return true;
751 } 759 }
752 760
753 return false; 761 return false;
754 } 762 }
755 763
756 764
757 void FlowGraphOptimizer::SelectRepresentations() { 765 void FlowGraphOptimizer::SelectRepresentations() {
758 // Convervatively unbox all phis that were proven to be of Double, 766 // Conservatively unbox all phis that were proven to be of Double,
759 // Float32x4, or Int32x4 type. 767 // Float32x4, or Int32x4 type.
760 for (intptr_t i = 0; i < block_order_.length(); ++i) { 768 for (intptr_t i = 0; i < block_order_.length(); ++i) {
761 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); 769 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
762 if (join_entry != NULL) { 770 if (join_entry != NULL) {
763 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { 771 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
764 PhiInstr* phi = it.Current(); 772 PhiInstr* phi = it.Current();
765 UnboxPhi(phi); 773 UnboxPhi(phi);
766 } 774 }
767 } 775 }
768 } 776 }
(...skipping 7137 matching lines...) Expand 10 before | Expand all | Expand 10 after
7906 SetValue(instr, non_constant_); 7914 SetValue(instr, non_constant_);
7907 } 7915 }
7908 7916
7909 7917
7910 void ConstantPropagator::VisitMergedMath(MergedMathInstr* instr) { 7918 void ConstantPropagator::VisitMergedMath(MergedMathInstr* instr) {
7911 // TODO(srdjan): Handle merged instruction. 7919 // TODO(srdjan): Handle merged instruction.
7912 SetValue(instr, non_constant_); 7920 SetValue(instr, non_constant_);
7913 } 7921 }
7914 7922
7915 7923
7924 void ConstantPropagator::VisitExtractNthOutput(ExtractNthOutputInstr* instr) {
7925 SetValue(instr, non_constant_);
7926 }
7927
7928
7916 void ConstantPropagator::VisitConstant(ConstantInstr* instr) { 7929 void ConstantPropagator::VisitConstant(ConstantInstr* instr) {
7917 SetValue(instr, instr->value()); 7930 SetValue(instr, instr->value());
7918 } 7931 }
7919 7932
7920 7933
7921 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { 7934 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) {
7922 // Should not be used outside of range analysis. 7935 // Should not be used outside of range analysis.
7923 UNREACHABLE(); 7936 UNREACHABLE();
7924 } 7937 }
7925 7938
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
9040 } 9053 }
9041 9054
9042 // Insert materializations at environment uses. 9055 // Insert materializations at environment uses.
9043 for (intptr_t i = 0; i < exits.length(); i++) { 9056 for (intptr_t i = 0; i < exits.length(); i++) {
9044 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 9057 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9045 } 9058 }
9046 } 9059 }
9047 9060
9048 9061
9049 } // namespace dart 9062 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698