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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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.cc ('k') | runtime/vm/intermediate_language_test.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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 UNREACHABLE(); 233 UNREACHABLE();
234 return OVERFLOW; 234 return OVERFLOW;
235 } 235 }
236 } 236 }
237 237
238 238
239 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 239 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
240 const intptr_t kNumInputs = 2; 240 const intptr_t kNumInputs = 2;
241 const bool is_checked_strict_equal = 241 const bool is_checked_strict_equal =
242 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 242 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
243 if ((receiver_class_id() == kSmiCid) || 243 if (receiver_class_id() == kDoubleCid) {
244 (receiver_class_id() == kDoubleCid) || 244 const intptr_t kNumTemps = 0;
245 is_checked_strict_equal) { 245 LocationSummary* locs =
246 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
247 locs->set_in(0, Location::RequiresXmmRegister());
248 locs->set_in(1, Location::RequiresXmmRegister());
249 locs->set_out(Location::RequiresRegister());
250 return locs;
251 }
252 if ((receiver_class_id() == kSmiCid) || is_checked_strict_equal) {
246 const intptr_t kNumTemps = 1; 253 const intptr_t kNumTemps = 1;
247 LocationSummary* locs = 254 LocationSummary* locs =
248 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
249 locs->set_in(0, Location::RequiresRegister()); 256 locs->set_in(0, Location::RequiresRegister());
250 locs->set_in(1, Location::RequiresRegister()); 257 locs->set_in(1, Location::RequiresRegister());
251 locs->set_temp(0, Location::RequiresRegister()); 258 locs->set_temp(0, Location::RequiresRegister());
252 locs->set_out(Location::RequiresRegister()); 259 locs->set_out(Location::RequiresRegister());
253 return locs; 260 return locs;
254 } 261 }
255 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 262 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 default: 580 default:
574 UNREACHABLE(); 581 UNREACHABLE();
575 return OVERFLOW; 582 return OVERFLOW;
576 } 583 }
577 } 584 }
578 585
579 586
580 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 587 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
581 const LocationSummary& locs, 588 const LocationSummary& locs,
582 Token::Kind kind, 589 Token::Kind kind,
583 BranchInstr* branch, 590 BranchInstr* branch) {
584 intptr_t deopt_id) { 591 XmmRegister left = locs.in(0).xmm_reg();
585 Register left = locs.in(0).reg(); 592 XmmRegister right = locs.in(1).xmm_reg();
586 Register right = locs.in(1).reg();
587 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
588 Register temp = locs.temp(0).reg();
589 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptDoubleComparison);
590 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
591 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
592 593
593 Condition true_condition = TokenKindToDoubleCondition(kind); 594 Condition true_condition = TokenKindToDoubleCondition(kind);
594 if (branch != NULL) { 595 if (branch != NULL) {
595 compiler->EmitDoubleCompareBranch( 596 compiler->EmitDoubleCompareBranch(
596 true_condition, XMM0, XMM1, branch); 597 true_condition, left, right, branch);
597 } else { 598 } else {
598 compiler->EmitDoubleCompareBool( 599 compiler->EmitDoubleCompareBool(
599 true_condition, XMM0, XMM1, locs.out().reg()); 600 true_condition, left, right, locs.out().reg());
600 } 601 }
601 } 602 }
602 603
603 604
604 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 605 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
605 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 606 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
606 BranchInstr* kNoBranch = NULL; 607 BranchInstr* kNoBranch = NULL;
607 if (receiver_class_id() == kSmiCid) { 608 if (receiver_class_id() == kSmiCid) {
608 // Deoptimizes if both arguments not Smi. 609 // Deoptimizes if both arguments not Smi.
609 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch, deopt_id()); 610 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch, deopt_id());
610 return; 611 return;
611 } 612 }
612 if (receiver_class_id() == kDoubleCid) { 613 if (receiver_class_id() == kDoubleCid) {
613 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 614 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
614 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch, deopt_id());
615 return; 615 return;
616 } 616 }
617 const bool is_checked_strict_equal = 617 const bool is_checked_strict_equal =
618 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 618 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
619 if (is_checked_strict_equal) { 619 if (is_checked_strict_equal) {
620 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, 620 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
621 deopt_id()); 621 deopt_id());
622 return; 622 return;
623 } 623 }
624 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 624 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 12 matching lines...) Expand all
637 637
638 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, 638 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
639 BranchInstr* branch) { 639 BranchInstr* branch) {
640 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 640 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
641 if (receiver_class_id() == kSmiCid) { 641 if (receiver_class_id() == kSmiCid) {
642 // Deoptimizes if both arguments not Smi. 642 // Deoptimizes if both arguments not Smi.
643 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 643 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
644 return; 644 return;
645 } 645 }
646 if (receiver_class_id() == kDoubleCid) { 646 if (receiver_class_id() == kDoubleCid) {
647 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 647 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
648 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
649 return; 648 return;
650 } 649 }
651 const bool is_checked_strict_equal = 650 const bool is_checked_strict_equal =
652 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 651 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
653 if (is_checked_strict_equal) { 652 if (is_checked_strict_equal) {
654 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, 653 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
655 deopt_id()); 654 deopt_id());
656 return; 655 return;
657 } 656 }
658 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 657 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 11 matching lines...) Expand all
670 Token::kEQ, // kNE reverse occurs at branch. 669 Token::kEQ, // kNE reverse occurs at branch.
671 locs()); 670 locs());
672 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 671 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
673 __ CompareObject(EAX, compiler->bool_true()); 672 __ CompareObject(EAX, compiler->bool_true());
674 branch->EmitBranchOnCondition(compiler, branch_condition); 673 branch->EmitBranchOnCondition(compiler, branch_condition);
675 } 674 }
676 675
677 676
678 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 677 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
679 const intptr_t kNumInputs = 2; 678 const intptr_t kNumInputs = 2;
680 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { 679 if (operands_class_id() == kDoubleCid) {
680 const intptr_t kNumTemps = 0;
681 LocationSummary* summary =
682 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
683 summary->set_in(0, Location::RequiresXmmRegister());
684 summary->set_in(1, Location::RequiresXmmRegister());
685 summary->set_out(Location::RequiresRegister());
686 return summary;
687 } else if (operands_class_id() == kSmiCid) {
681 const intptr_t kNumTemps = 1; 688 const intptr_t kNumTemps = 1;
682 LocationSummary* summary = 689 LocationSummary* summary =
683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
684 summary->set_in(0, Location::RequiresRegister()); 691 summary->set_in(0, Location::RequiresRegister());
685 summary->set_in(1, Location::RequiresRegister()); 692 summary->set_in(1, Location::RequiresRegister());
686 summary->set_out(Location::RequiresRegister()); 693 summary->set_out(Location::RequiresRegister());
687 summary->set_temp(0, Location::RequiresRegister()); 694 summary->set_temp(0, Location::RequiresRegister());
688 return summary; 695 return summary;
689 } 696 }
690 const intptr_t kNumTemps = 0; 697 const intptr_t kNumTemps = 0;
691 LocationSummary* locs = 698 LocationSummary* locs =
692 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 699 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
693 // Pick arbitrary fixed input registers because this is a call. 700 // Pick arbitrary fixed input registers because this is a call.
694 locs->set_in(0, Location::RegisterLocation(EAX)); 701 locs->set_in(0, Location::RegisterLocation(EAX));
695 locs->set_in(1, Location::RegisterLocation(ECX)); 702 locs->set_in(1, Location::RegisterLocation(ECX));
696 locs->set_out(Location::RegisterLocation(EAX)); 703 locs->set_out(Location::RegisterLocation(EAX));
697 return locs; 704 return locs;
698 } 705 }
699 706
700 707
701 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 708 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
702 if (operands_class_id() == kSmiCid) { 709 if (operands_class_id() == kSmiCid) {
703 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, deopt_id()); 710 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, deopt_id());
704 return; 711 return;
705 } 712 }
706 if (operands_class_id() == kDoubleCid) { 713 if (operands_class_id() == kDoubleCid) {
707 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, deopt_id()); 714 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
708 return; 715 return;
709 } 716 }
710 717
711 // Push arguments for the call. 718 // Push arguments for the call.
712 // TODO(fschneider): Split this instruction into different types to avoid 719 // TODO(fschneider): Split this instruction into different types to avoid
713 // explicitly pushing arguments to the call here. 720 // explicitly pushing arguments to the call here.
714 Register left = locs()->in(0).reg(); 721 Register left = locs()->in(0).reg();
715 Register right = locs()->in(1).reg(); 722 Register right = locs()->in(1).reg();
716 __ pushl(left); 723 __ pushl(left);
717 __ pushl(right); 724 __ pushl(right);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 761 }
755 762
756 763
757 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, 764 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
758 BranchInstr* branch) { 765 BranchInstr* branch) {
759 if (operands_class_id() == kSmiCid) { 766 if (operands_class_id() == kSmiCid) {
760 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 767 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
761 return; 768 return;
762 } 769 }
763 if (operands_class_id() == kDoubleCid) { 770 if (operands_class_id() == kDoubleCid) {
764 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 771 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
765 return; 772 return;
766 } 773 }
767 EmitNativeCode(compiler); 774 EmitNativeCode(compiler);
768 __ CompareObject(EAX, compiler->bool_true()); 775 __ CompareObject(EAX, compiler->bool_true());
769 branch->EmitBranchOnCondition(compiler, EQUAL); 776 branch->EmitBranchOnCondition(compiler, EQUAL);
770 } 777 }
771 778
772 779
773 LocationSummary* NativeCallComp::MakeLocationSummary() const { 780 LocationSummary* NativeCallComp::MakeLocationSummary() const {
774 const intptr_t kNumInputs = 0; 781 const intptr_t kNumInputs = 0;
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) 1821 explicit BoxDoubleSlowPath(BoxDoubleComp* computation)
1815 : computation_(computation) { } 1822 : computation_(computation) { }
1816 1823
1817 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1824 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1818 __ Bind(entry_label()); 1825 __ Bind(entry_label());
1819 const Class& double_class = compiler->double_class(); 1826 const Class& double_class = compiler->double_class();
1820 const Code& stub = 1827 const Code& stub =
1821 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1828 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1822 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1829 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1823 1830
1824 // TODO(vegorov): here stack map needs to be set up correctly to skip
1825 // double registers.
1826 LocationSummary* locs = computation_->locs(); 1831 LocationSummary* locs = computation_->locs();
1827 locs->live_registers()->Remove(locs->out()); 1832 locs->live_registers()->Remove(locs->out());
1828 1833
1829 compiler->SaveLiveRegisters(locs); 1834 compiler->SaveLiveRegisters(locs);
1830 compiler->GenerateCall(computation_->instance_call()->token_pos(), 1835 compiler->GenerateCall(computation_->token_pos(),
1831 &label, 1836 &label,
1832 PcDescriptors::kOther, 1837 PcDescriptors::kOther,
1833 locs); 1838 locs);
1834 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); 1839 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX);
1835 compiler->RestoreLiveRegisters(locs); 1840 compiler->RestoreLiveRegisters(locs);
1836 1841
1837 __ jmp(exit_label()); 1842 __ jmp(exit_label());
1838 } 1843 }
1839 1844
1840 private: 1845 private:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 return summary; 1877 return summary;
1873 } 1878 }
1874 1879
1875 1880
1876 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1881 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1877 const intptr_t v_cid = value()->ResultCid(); 1882 const intptr_t v_cid = value()->ResultCid();
1878 1883
1879 const Register value = locs()->in(0).reg(); 1884 const Register value = locs()->in(0).reg();
1880 const XmmRegister result = locs()->out().xmm_reg(); 1885 const XmmRegister result = locs()->out().xmm_reg();
1881 if (v_cid != kDoubleCid) { 1886 if (v_cid != kDoubleCid) {
1882 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1887 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
1883 kDeoptBinaryDoubleOp);
1884 compiler->LoadDoubleOrSmiToXmm(result, 1888 compiler->LoadDoubleOrSmiToXmm(result,
1885 value, 1889 value,
1886 locs()->temp(0).reg(), 1890 locs()->temp(0).reg(),
1887 deopt); 1891 deopt);
1888 } else { 1892 } else {
1889 __ movsd(result, FieldAddress(value, Double::value_offset())); 1893 __ movsd(result, FieldAddress(value, Double::value_offset()));
1890 } 1894 }
1891 } 1895 }
1892 1896
1893 1897
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 } 2213 }
2210 __ j(ABOVE_EQUAL, deopt); 2214 __ j(ABOVE_EQUAL, deopt);
2211 } 2215 }
2212 2216
2213 2217
2214 } // namespace dart 2218 } // namespace dart
2215 2219
2216 #undef __ 2220 #undef __
2217 2221
2218 #endif // defined TARGET_ARCH_X64 2222 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698