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

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
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 ExtractNthOutputInstr* extract = new ExtractNthOutputInstr(new Value(instr),
310 index,
311 rep);
312 instr->ReplaceUsesWith(extract);
313 flow_graph()->InsertAfter(instr, extract, NULL, Definition::kValue);
314 }
315
316
306 // Dart: 317 // Dart:
307 // var x = d % 10; 318 // var x = d % 10;
308 // var y = d ~/ 10; 319 // var y = d ~/ 10;
309 // var z = x + y; 320 // var z = x + y;
310 // 321 //
311 // IL: 322 // IL:
312 // v4 <- %(v2, v3) 323 // v4 <- %(v2, v3)
313 // v5 <- ~/(v2, v3) 324 // v5 <- ~/(v2, v3)
314 // v6 <- +(v4, v5) 325 // v6 <- +(v4, v5)
315 // 326 //
(...skipping 24 matching lines...) Expand all
340 Definition* left_def = curr_instr->left()->definition(); 351 Definition* left_def = curr_instr->left()->definition();
341 Definition* right_def = curr_instr->right()->definition(); 352 Definition* right_def = curr_instr->right()->definition();
342 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { 353 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) {
343 BinarySmiOpInstr* other_binop = (*merge_candidates)[k]; 354 BinarySmiOpInstr* other_binop = (*merge_candidates)[k];
344 // 'other_binop' can be NULL if it was already merged. 355 // 'other_binop' can be NULL if it was already merged.
345 if ((other_binop != NULL) && 356 if ((other_binop != NULL) &&
346 (other_binop->op_kind() == other_kind) && 357 (other_binop->op_kind() == other_kind) &&
347 (other_binop->left()->definition() == left_def) && 358 (other_binop->left()->definition() == left_def) &&
348 (other_binop->right()->definition() == right_def)) { 359 (other_binop->right()->definition() == right_def)) {
349 (*merge_candidates)[k] = NULL; // Clear it. 360 (*merge_candidates)[k] = NULL; // Clear it.
350 // Append a LoadIndexed behind TRUNC_DIV and MOD.
351 ASSERT(curr_instr->HasUses()); 361 ASSERT(curr_instr->HasUses());
352 AppendLoadIndexedForMerged( 362 AppendExtractNthOutputForMerged(
353 curr_instr, 363 curr_instr,
354 MergedMathInstr::ResultIndexOf(curr_instr->op_kind()), 364 MergedMath2Instr::OutputIndexOf(curr_instr->op_kind()),
355 kArrayCid); 365 kTagged);
356 ASSERT(other_binop->HasUses()); 366 ASSERT(other_binop->HasUses());
357 AppendLoadIndexedForMerged( 367 AppendExtractNthOutputForMerged(
358 other_binop, 368 other_binop,
359 MergedMathInstr::ResultIndexOf(other_binop->op_kind()), 369 MergedMath2Instr::OutputIndexOf(other_binop->op_kind()),
360 kArrayCid); 370 kTagged);
361 371
362 ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(2); 372 ZoneGrowableArray<Value*>* args = new ZoneGrowableArray<Value*>(2);
363 args->Add(new Value(curr_instr->left()->definition())); 373 args->Add(new Value(curr_instr->left()->definition()));
364 args->Add(new Value(curr_instr->right()->definition())); 374 args->Add(new Value(curr_instr->right()->definition()));
365 375
366 // Replace with TruncDivMod. 376 // Replace with TruncDivMod.
367 MergedMathInstr* div_mod = new MergedMathInstr( 377 MergedMath2Instr* div_mod = new MergedMath2Instr(
368 args, 378 args,
369 curr_instr->deopt_id(), 379 curr_instr->deopt_id(),
370 MergedMathInstr::kTruncDivMod); 380 MergedMath2Instr::kTruncDivMod);
371 curr_instr->ReplaceWith(div_mod, current_iterator()); 381 curr_instr->ReplaceWith(div_mod, current_iterator());
382 div_mod->set_ssa_temp_index2(flow_graph()->alloc_ssa_temp_index());
372 other_binop->ReplaceUsesWith(div_mod); 383 other_binop->ReplaceUsesWith(div_mod);
373 other_binop->RemoveFromGraph(); 384 other_binop->RemoveFromGraph();
374 // Only one merge possible. Because canonicalization happens later, 385 // Only one merge possible. Because canonicalization happens later,
375 // more candidates are possible. 386 // more candidates are possible.
376 // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod. 387 // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod.
377 break; 388 break;
378 } 389 }
379 } 390 }
380 } 391 }
381 } 392 }
382 393
383 394
384 void FlowGraphOptimizer::TryMergeMathUnary( 395 void FlowGraphOptimizer::TryMergeMathUnary(
385 GrowableArray<MathUnaryInstr*>* merge_candidates) { 396 GrowableArray<MathUnaryInstr*>* merge_candidates) {
386 if (!FlowGraphCompiler::SupportsSinCos()) { 397 if (!FlowGraphCompiler::SupportsSinCos()) {
387 return; 398 return;
388 } 399 }
389 if (merge_candidates->length() < 2) { 400 if (merge_candidates->length() < 2) {
390 // Need at least a SIN and a COS. 401 // Need at least a SIN and a COS.
391 return; 402 return;
392 } 403 }
393 for (intptr_t i = 0; i < merge_candidates->length(); i++) { 404 for (intptr_t i = 0; i < merge_candidates->length(); i++) {
394 MathUnaryInstr* curr_instr = (*merge_candidates)[i]; 405 MathUnaryInstr* curr_instr = (*merge_candidates)[i];
395 if (curr_instr == NULL) { 406 if (curr_instr == NULL) {
396 // Instruction was merged already. 407 // Instruction was merged already.
397 continue; 408 continue;
398 } 409 }
399 ASSERT((curr_instr->kind() == MethodRecognizer::kMathSin) || 410 const intptr_t kind = curr_instr->kind();
400 (curr_instr->kind() == MethodRecognizer::kMathCos)); 411 ASSERT((kind == MethodRecognizer::kMathSin) ||
412 (kind == MethodRecognizer::kMathCos));
401 // Check if there is sin/cos binop with same inputs. 413 // Check if there is sin/cos binop with same inputs.
402 const intptr_t other_kind = 414 const intptr_t other_kind = (kind == MethodRecognizer::kMathSin) ?
403 (curr_instr->kind() == MethodRecognizer::kMathSin) ? 415 MethodRecognizer::kMathCos : MethodRecognizer::kMathSin;
404 MethodRecognizer::kMathCos : MethodRecognizer::kMathSin;
405 Definition* def = curr_instr->value()->definition(); 416 Definition* def = curr_instr->value()->definition();
406 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) { 417 for (intptr_t k = i + 1; k < merge_candidates->length(); k++) {
407 MathUnaryInstr* other_op = (*merge_candidates)[k]; 418 MathUnaryInstr* other_op = (*merge_candidates)[k];
408 // 'other_op' can be NULL if it was already merged. 419 // 'other_op' can be NULL if it was already merged.
409 if ((other_op != NULL) && (other_op->kind() == other_kind) && 420 if ((other_op != NULL) && (other_op->kind() == other_kind) &&
410 (other_op->value()->definition() == def)) { 421 (other_op->value()->definition() == def)) {
411 (*merge_candidates)[k] = NULL; // Clear it. 422 (*merge_candidates)[k] = NULL; // Clear it.
412 // Append a LoadIndexed behind SIN and COS.
413 ASSERT(curr_instr->HasUses()); 423 ASSERT(curr_instr->HasUses());
414 AppendLoadIndexedForMerged( 424 // TODO(johnmccutchan): Fix up input indexes.
415 curr_instr, 425 AppendExtractNthOutputForMerged(curr_instr,
416 MergedMathInstr::ResultIndexOf(curr_instr->kind()), 426 MergedMath2Instr::OutputIndexOf(kind),
417 kTypedDataFloat64ArrayCid); 427 kUnboxedDouble);
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 MergedMath2Instr::OutputIndexOf(other_kind),
422 kTypedDataFloat64ArrayCid); 432 kUnboxedDouble);
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 MergedMath2Instr* sin_cos =
428 args, 437 new MergedMath2Instr(args, curr_instr->DeoptimizationTarget(),
429 curr_instr->DeoptimizationTarget(), 438 MergedMath2Instr::kSinCos);
430 MergedMathInstr::kSinCos);
431 curr_instr->ReplaceWith(sin_cos, current_iterator()); 439 curr_instr->ReplaceWith(sin_cos, current_iterator());
440 sin_cos->set_ssa_temp_index2(flow_graph()->alloc_ssa_temp_index());
432 other_op->ReplaceUsesWith(sin_cos); 441 other_op->ReplaceUsesWith(sin_cos);
433 other_op->RemoveFromGraph(); 442 other_op->RemoveFromGraph();
434 // Only one merge possible. Because canonicalization happens later, 443 // Only one merge possible. Because canonicalization happens later,
435 // more candidates are possible. 444 // more candidates are possible.
436 // TODO(srdjan): Allow merging of sin/cos into sincos. 445 // TODO(srdjan): Allow merging of sin/cos into sincos.
437 break; 446 break;
438 } 447 }
439 } 448 }
440 } 449 }
441 } 450 }
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 if (unboxed != current) { 757 if (unboxed != current) {
749 phi->set_representation(unboxed); 758 phi->set_representation(unboxed);
750 return true; 759 return true;
751 } 760 }
752 761
753 return false; 762 return false;
754 } 763 }
755 764
756 765
757 void FlowGraphOptimizer::SelectRepresentations() { 766 void FlowGraphOptimizer::SelectRepresentations() {
758 // Convervatively unbox all phis that were proven to be of Double, 767 // Conservatively unbox all phis that were proven to be of Double,
759 // Float32x4, or Int32x4 type. 768 // Float32x4, or Int32x4 type.
760 for (intptr_t i = 0; i < block_order_.length(); ++i) { 769 for (intptr_t i = 0; i < block_order_.length(); ++i) {
761 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); 770 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
762 if (join_entry != NULL) { 771 if (join_entry != NULL) {
763 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { 772 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
764 PhiInstr* phi = it.Current(); 773 PhiInstr* phi = it.Current();
765 UnboxPhi(phi); 774 UnboxPhi(phi);
766 } 775 }
767 } 776 }
768 } 777 }
(...skipping 7137 matching lines...) Expand 10 before | Expand all | Expand 10 after
7906 SetValue(instr, non_constant_); 7915 SetValue(instr, non_constant_);
7907 } 7916 }
7908 7917
7909 7918
7910 void ConstantPropagator::VisitMergedMath(MergedMathInstr* instr) { 7919 void ConstantPropagator::VisitMergedMath(MergedMathInstr* instr) {
7911 // TODO(srdjan): Handle merged instruction. 7920 // TODO(srdjan): Handle merged instruction.
7912 SetValue(instr, non_constant_); 7921 SetValue(instr, non_constant_);
7913 } 7922 }
7914 7923
7915 7924
7925 void ConstantPropagator::VisitMergedMath2(MergedMath2Instr* instr) {
7926 SetValue(instr, non_constant_);
7927 }
7928
7929
7930 void ConstantPropagator::VisitExtractNthOutput(ExtractNthOutputInstr* instr) {
7931 SetValue(instr, non_constant_);
7932 }
7933
7934
7916 void ConstantPropagator::VisitConstant(ConstantInstr* instr) { 7935 void ConstantPropagator::VisitConstant(ConstantInstr* instr) {
7917 SetValue(instr, instr->value()); 7936 SetValue(instr, instr->value());
7918 } 7937 }
7919 7938
7920 7939
7921 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { 7940 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) {
7922 // Should not be used outside of range analysis. 7941 // Should not be used outside of range analysis.
7923 UNREACHABLE(); 7942 UNREACHABLE();
7924 } 7943 }
7925 7944
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
9040 } 9059 }
9041 9060
9042 // Insert materializations at environment uses. 9061 // Insert materializations at environment uses.
9043 for (intptr_t i = 0; i < exits.length(); i++) { 9062 for (intptr_t i = 0; i < exits.length(); i++) {
9044 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 9063 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9045 } 9064 }
9046 } 9065 }
9047 9066
9048 9067
9049 } // namespace dart 9068 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698