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

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

Issue 10919008: Unbox phis that were proven to be of type Double. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments Created 8 years, 3 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/intermediate_language_test.cc ('k') | runtime/vm/isolate.h » ('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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 UNREACHABLE(); 242 UNREACHABLE();
243 return OVERFLOW; 243 return OVERFLOW;
244 } 244 }
245 } 245 }
246 246
247 247
248 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 248 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
249 const intptr_t kNumInputs = 2; 249 const intptr_t kNumInputs = 2;
250 const bool is_checked_strict_equal = 250 const bool is_checked_strict_equal =
251 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 251 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
252 if ((receiver_class_id() == kSmiCid) || 252 if (receiver_class_id() == kDoubleCid) {
253 (receiver_class_id() == kDoubleCid) || 253 const intptr_t kNumTemps = 0;
254 is_checked_strict_equal) { 254 LocationSummary* locs =
255 const intptr_t kNumTemps = 1; 255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
256 locs->set_in(0, Location::RequiresXmmRegister());
257 locs->set_in(1, Location::RequiresXmmRegister());
258 locs->set_out(Location::RequiresRegister());
259 return locs;
260 }
261 if ((receiver_class_id() == kSmiCid) || is_checked_strict_equal) {
262 const intptr_t kNumTemps = 1;
256 LocationSummary* locs = 263 LocationSummary* locs =
257 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 264 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
258 locs->set_in(0, Location::RequiresRegister()); 265 locs->set_in(0, Location::RequiresRegister());
259 locs->set_in(1, Location::RequiresRegister()); 266 locs->set_in(1, Location::RequiresRegister());
260 locs->set_temp(0, Location::RequiresRegister()); 267 locs->set_temp(0, Location::RequiresRegister());
261 locs->set_out(Location::RequiresRegister()); 268 locs->set_out(Location::RequiresRegister());
262 return locs; 269 return locs;
263 } 270 }
264 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 271 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
265 const intptr_t kNumTemps = 1; 272 const intptr_t kNumTemps = 1;
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 default: 590 default:
584 UNREACHABLE(); 591 UNREACHABLE();
585 return OVERFLOW; 592 return OVERFLOW;
586 } 593 }
587 } 594 }
588 595
589 596
590 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 597 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
591 const LocationSummary& locs, 598 const LocationSummary& locs,
592 Token::Kind kind, 599 Token::Kind kind,
593 BranchInstr* branch, 600 BranchInstr* branch) {
594 intptr_t deopt_id) { 601 XmmRegister left = locs.in(0).xmm_reg();
595 Register left = locs.in(0).reg(); 602 XmmRegister right = locs.in(1).xmm_reg();
596 Register right = locs.in(1).reg();
597 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
598 Register temp = locs.temp(0).reg();
599 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptDoubleComparison);
600 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
601 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
602 603
603 Condition true_condition = TokenKindToDoubleCondition(kind); 604 Condition true_condition = TokenKindToDoubleCondition(kind);
604 if (branch != NULL) { 605 if (branch != NULL) {
605 compiler->EmitDoubleCompareBranch( 606 compiler->EmitDoubleCompareBranch(
606 true_condition, XMM0, XMM1, branch); 607 true_condition, left, right, branch);
607 } else { 608 } else {
608 compiler->EmitDoubleCompareBool( 609 compiler->EmitDoubleCompareBool(
609 true_condition, XMM0, XMM1, locs.out().reg()); 610 true_condition, left, right, locs.out().reg());
610 } 611 }
611 } 612 }
612 613
613 614
614 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 615 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
615 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); 616 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
616 BranchInstr* kNoBranch = NULL; 617 BranchInstr* kNoBranch = NULL;
617 if (receiver_class_id() == kSmiCid) { 618 if (receiver_class_id() == kSmiCid) {
618 // Deoptimizes if both arguments not Smi. 619 // Deoptimizes if both arguments not Smi.
619 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch, deopt_id()); 620 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch, deopt_id());
620 return; 621 return;
621 } 622 }
622 if (receiver_class_id() == kDoubleCid) { 623 if (receiver_class_id() == kDoubleCid) {
623 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 624 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
624 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch, deopt_id()); 625 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
625 return; 626 return;
626 } 627 }
627 const bool is_checked_strict_equal = 628 const bool is_checked_strict_equal =
628 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 629 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
629 if (is_checked_strict_equal) { 630 if (is_checked_strict_equal) {
630 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, 631 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
631 deopt_id()); 632 deopt_id());
632 return; 633 return;
633 } 634 }
634 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 635 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 17 matching lines...) Expand all
652 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, 653 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
653 BranchInstr* branch) { 654 BranchInstr* branch) {
654 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 655 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
655 if (receiver_class_id() == kSmiCid) { 656 if (receiver_class_id() == kSmiCid) {
656 // Deoptimizes if both arguments not Smi. 657 // Deoptimizes if both arguments not Smi.
657 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 658 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
658 return; 659 return;
659 } 660 }
660 if (receiver_class_id() == kDoubleCid) { 661 if (receiver_class_id() == kDoubleCid) {
661 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 662 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
662 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 663 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
663 return; 664 return;
664 } 665 }
665 const bool is_checked_strict_equal = 666 const bool is_checked_strict_equal =
666 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 667 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
667 if (is_checked_strict_equal) { 668 if (is_checked_strict_equal) {
668 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, 669 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
669 deopt_id()); 670 deopt_id());
670 return; 671 return;
671 } 672 }
672 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 673 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 11 matching lines...) Expand all
684 Token::kEQ, // kNE reverse occurs at branch. 685 Token::kEQ, // kNE reverse occurs at branch.
685 locs()); 686 locs());
686 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 687 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
687 __ CompareObject(RAX, compiler->bool_true()); 688 __ CompareObject(RAX, compiler->bool_true());
688 branch->EmitBranchOnCondition(compiler, branch_condition); 689 branch->EmitBranchOnCondition(compiler, branch_condition);
689 } 690 }
690 691
691 692
692 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 693 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
693 const intptr_t kNumInputs = 2; 694 const intptr_t kNumInputs = 2;
694 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { 695 if (operands_class_id() == kDoubleCid) {
696 const intptr_t kNumTemps = 0;
697 LocationSummary* summary =
698 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
699 summary->set_in(0, Location::RequiresXmmRegister());
700 summary->set_in(1, Location::RequiresXmmRegister());
701 summary->set_out(Location::RequiresRegister());
702 return summary;
703 } else if (operands_class_id() == kSmiCid) {
695 const intptr_t kNumTemps = 1; 704 const intptr_t kNumTemps = 1;
696 LocationSummary* summary = 705 LocationSummary* summary =
697 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
698 summary->set_in(0, Location::RequiresRegister()); 707 summary->set_in(0, Location::RequiresRegister());
699 summary->set_in(1, Location::RequiresRegister()); 708 summary->set_in(1, Location::RequiresRegister());
700 summary->set_out(Location::RequiresRegister()); 709 summary->set_out(Location::RequiresRegister());
701 summary->set_temp(0, Location::RequiresRegister()); 710 summary->set_temp(0, Location::RequiresRegister());
702 return summary; 711 return summary;
703 } 712 }
704 const intptr_t kNumTemps = 0; 713 const intptr_t kNumTemps = 0;
705 LocationSummary* locs = 714 LocationSummary* locs =
706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 715 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
707 // Pick arbitrary fixed input registers because this is a call. 716 // Pick arbitrary fixed input registers because this is a call.
708 locs->set_in(0, Location::RegisterLocation(RAX)); 717 locs->set_in(0, Location::RegisterLocation(RAX));
709 locs->set_in(1, Location::RegisterLocation(RCX)); 718 locs->set_in(1, Location::RegisterLocation(RCX));
710 locs->set_out(Location::RegisterLocation(RAX)); 719 locs->set_out(Location::RegisterLocation(RAX));
711 return locs; 720 return locs;
712 } 721 }
713 722
714 723
715 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 724 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
716 if (operands_class_id() == kSmiCid) { 725 if (operands_class_id() == kSmiCid) {
717 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, deopt_id()); 726 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, deopt_id());
718 return; 727 return;
719 } 728 }
720 if (operands_class_id() == kDoubleCid) { 729 if (operands_class_id() == kDoubleCid) {
721 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, deopt_id()); 730 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
722 return; 731 return;
723 } 732 }
724 733
725 // Push arguments for the call. 734 // Push arguments for the call.
726 // TODO(fschneider): Split this instruction into different types to avoid 735 // TODO(fschneider): Split this instruction into different types to avoid
727 // explicitly pushing arguments to the call here. 736 // explicitly pushing arguments to the call here.
728 Register left = locs()->in(0).reg(); 737 Register left = locs()->in(0).reg();
729 Register right = locs()->in(1).reg(); 738 Register right = locs()->in(1).reg();
730 __ pushq(left); 739 __ pushq(left);
731 __ pushq(right); 740 __ pushq(right);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 } 778 }
770 779
771 780
772 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, 781 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
773 BranchInstr* branch) { 782 BranchInstr* branch) {
774 if (operands_class_id() == kSmiCid) { 783 if (operands_class_id() == kSmiCid) {
775 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 784 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
776 return; 785 return;
777 } 786 }
778 if (operands_class_id() == kDoubleCid) { 787 if (operands_class_id() == kDoubleCid) {
779 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 788 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
780 return; 789 return;
781 } 790 }
782 EmitNativeCode(compiler); 791 EmitNativeCode(compiler);
783 __ CompareObject(RAX, compiler->bool_true()); 792 __ CompareObject(RAX, compiler->bool_true());
784 branch->EmitBranchOnCondition(compiler, EQUAL); 793 branch->EmitBranchOnCondition(compiler, EQUAL);
785 } 794 }
786 795
787 796
788 LocationSummary* NativeCallComp::MakeLocationSummary() const { 797 LocationSummary* NativeCallComp::MakeLocationSummary() const {
789 const intptr_t kNumInputs = 0; 798 const intptr_t kNumInputs = 0;
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) 1837 explicit BoxDoubleSlowPath(BoxDoubleComp* computation)
1829 : computation_(computation) { } 1838 : computation_(computation) { }
1830 1839
1831 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1840 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1832 __ Bind(entry_label()); 1841 __ Bind(entry_label());
1833 const Class& double_class = compiler->double_class(); 1842 const Class& double_class = compiler->double_class();
1834 const Code& stub = 1843 const Code& stub =
1835 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1844 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1836 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1845 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1837 1846
1838 // TODO(vegorov): here stack map needs to be set up correctly to skip
1839 // double registers.
1840 LocationSummary* locs = computation_->locs(); 1847 LocationSummary* locs = computation_->locs();
1841 locs->live_registers()->Remove(locs->out()); 1848 locs->live_registers()->Remove(locs->out());
1842 1849
1843 compiler->SaveLiveRegisters(locs); 1850 compiler->SaveLiveRegisters(locs);
1844 compiler->GenerateCall(computation_->instance_call()->token_pos(), 1851 compiler->GenerateCall(computation_->token_pos(),
1845 &label, 1852 &label,
1846 PcDescriptors::kOther, 1853 PcDescriptors::kOther,
1847 locs); 1854 locs);
1848 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); 1855 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX);
1849 compiler->RestoreLiveRegisters(locs); 1856 compiler->RestoreLiveRegisters(locs);
1850 1857
1851 __ jmp(exit_label()); 1858 __ jmp(exit_label());
1852 } 1859 }
1853 1860
1854 private: 1861 private:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 return summary; 1893 return summary;
1887 } 1894 }
1888 1895
1889 1896
1890 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1897 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1891 const intptr_t v_cid = value()->ResultCid(); 1898 const intptr_t v_cid = value()->ResultCid();
1892 1899
1893 const Register value = locs()->in(0).reg(); 1900 const Register value = locs()->in(0).reg();
1894 const XmmRegister result = locs()->out().xmm_reg(); 1901 const XmmRegister result = locs()->out().xmm_reg();
1895 if (v_cid != kDoubleCid) { 1902 if (v_cid != kDoubleCid) {
1896 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1903 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
1897 kDeoptBinaryDoubleOp);
1898 compiler->LoadDoubleOrSmiToXmm(result, 1904 compiler->LoadDoubleOrSmiToXmm(result,
1899 value, 1905 value,
1900 locs()->temp(0).reg(), 1906 locs()->temp(0).reg(),
1901 deopt); 1907 deopt);
1902 } else { 1908 } else {
1903 __ movsd(result, FieldAddress(value, Double::value_offset())); 1909 __ movsd(result, FieldAddress(value, Double::value_offset()));
1904 } 1910 }
1905 } 1911 }
1906 1912
1907 1913
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
2221 } 2227 }
2222 __ j(ABOVE_EQUAL, deopt); 2228 __ j(ABOVE_EQUAL, deopt);
2223 } 2229 }
2224 2230
2225 2231
2226 } // namespace dart 2232 } // namespace dart
2227 2233
2228 #undef __ 2234 #undef __
2229 2235
2230 #endif // defined TARGET_ARCH_X64 2236 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_test.cc ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698