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

Side by Side Diff: src/hydrogen-instructions.cc

Issue 12226112: Infrastructure classes for evaluating numeric relations between values. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Detect induction variables. Created 7 years, 10 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 | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-ia32.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 switch (opcode()) { 517 switch (opcode()) {
518 #define MAKE_CASE(type) case k##type: return #type; 518 #define MAKE_CASE(type) case k##type: return #type;
519 HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE) 519 HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE)
520 #undef MAKE_CASE 520 #undef MAKE_CASE
521 case kPhi: return "Phi"; 521 case kPhi: return "Phi";
522 default: return ""; 522 default: return "";
523 } 523 }
524 } 524 }
525 525
526 526
527 bool HValue::IsInteger32Constant() {
528 return IsConstant() && HConstant::cast(this)->HasInteger32Value();
529 }
530
531
532 int32_t HValue::GetInteger32Constant() {
533 ASSERT(IsInteger32Constant());
534 return HConstant::cast(this)->Integer32Value();
535 }
536
537
527 void HValue::SetOperandAt(int index, HValue* value) { 538 void HValue::SetOperandAt(int index, HValue* value) {
528 RegisterUse(index, value); 539 RegisterUse(index, value);
529 InternalSetOperandAt(index, value); 540 InternalSetOperandAt(index, value);
530 } 541 }
531 542
532 543
533 void HValue::DeleteAndReplaceWith(HValue* other) { 544 void HValue::DeleteAndReplaceWith(HValue* other) {
534 // We replace all uses first, so Delete can assert that there are none. 545 // We replace all uses first, so Delete can assert that there are none.
535 if (other != NULL) ReplaceAllUsesWith(other); 546 if (other != NULL) ReplaceAllUsesWith(other);
536 ASSERT(HasNoUses()); 547 ASSERT(HasNoUses());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 PrintChangesTo(stream); 694 PrintChangesTo(stream);
684 PrintTypeTo(stream); 695 PrintTypeTo(stream);
685 } 696 }
686 697
687 698
688 void HInstruction::PrintMnemonicTo(StringStream* stream) { 699 void HInstruction::PrintMnemonicTo(StringStream* stream) {
689 stream->Add("%s ", Mnemonic()); 700 stream->Add("%s ", Mnemonic());
690 } 701 }
691 702
692 703
704 HValue* HValue::AddNumericConstraint(HInstruction* insertion_point,
705 HValue* related_value,
706 NumericRelation relation) {
707 return HNumericConstraint::New(
708 insertion_point, this, related_value, relation);
709 }
710
711
693 void HInstruction::Unlink() { 712 void HInstruction::Unlink() {
694 ASSERT(IsLinked()); 713 ASSERT(IsLinked());
695 ASSERT(!IsControlInstruction()); // Must never move control instructions. 714 ASSERT(!IsControlInstruction()); // Must never move control instructions.
696 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. 715 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these.
697 ASSERT(previous_ != NULL); 716 ASSERT(previous_ != NULL);
698 previous_->next_ = next_; 717 previous_->next_ = next_;
699 if (next_ == NULL) { 718 if (next_ == NULL) {
700 ASSERT(block()->last() == this); 719 ASSERT(block()->last() == this);
701 block()->set_last(previous_); 720 block()->set_last(previous_);
702 } else { 721 } else {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 } 806 }
788 807
789 // Verify that instructions that can be eliminated by GVN have overridden 808 // Verify that instructions that can be eliminated by GVN have overridden
790 // HValue::DataEquals. The default implementation is UNREACHABLE. We 809 // HValue::DataEquals. The default implementation is UNREACHABLE. We
791 // don't actually care whether DataEquals returns true or false here. 810 // don't actually care whether DataEquals returns true or false here.
792 if (CheckFlag(kUseGVN)) DataEquals(this); 811 if (CheckFlag(kUseGVN)) DataEquals(this);
793 } 812 }
794 #endif 813 #endif
795 814
796 815
816 HNumericConstraint* HNumericConstraint::New(HInstruction* insertion_point,
817 HValue* constrained_value,
818 HValue* related_value,
819 NumericRelation relation) {
820 HNumericConstraint* result =
821 new(insertion_point->block()->zone()) HNumericConstraint(
822 constrained_value, related_value, relation);
823 result->InsertAfter(insertion_point);
824 return result;
825 }
826
827
828 void HNumericConstraint::PrintDataTo(StringStream* stream) {
829 stream->Add("(");
830 constrained_value()->PrintNameTo(stream);
831 stream->Add(" %s ", relation().Mnemonic());
832 related_value()->PrintNameTo(stream);
833 stream->Add(")");
834 }
835
836
797 void HDummyUse::PrintDataTo(StringStream* stream) { 837 void HDummyUse::PrintDataTo(StringStream* stream) {
798 value()->PrintNameTo(stream); 838 value()->PrintNameTo(stream);
799 } 839 }
800 840
801 841
802 void HUnaryCall::PrintDataTo(StringStream* stream) { 842 void HUnaryCall::PrintDataTo(StringStream* stream) {
803 value()->PrintNameTo(stream); 843 value()->PrintNameTo(stream);
804 stream->Add(" "); 844 stream->Add(" ");
805 stream->Add("#%d", argument_count()); 845 stream->Add("#%d", argument_count());
806 } 846 }
807 847
808 848
809 void HBinaryCall::PrintDataTo(StringStream* stream) { 849 void HBinaryCall::PrintDataTo(StringStream* stream) {
810 first()->PrintNameTo(stream); 850 first()->PrintNameTo(stream);
811 stream->Add(" "); 851 stream->Add(" ");
812 second()->PrintNameTo(stream); 852 second()->PrintNameTo(stream);
813 stream->Add(" "); 853 stream->Add(" ");
814 stream->Add("#%d", argument_count()); 854 stream->Add("#%d", argument_count());
815 } 855 }
816 856
817 857
858 bool HBoundsCheck::CheckRelation(NumericRelation relation,
859 HValue* related_value) {
860 if (related_value == length()) {
861 return NumericRelation::Lt().Implies(relation);
862 } else if (related_value == block()->graph()->GetConstant0()) {
863 return NumericRelation::Ge().Implies(relation);
864 } else {
865 return false;
866 }
867 }
868
869
818 void HBoundsCheck::PrintDataTo(StringStream* stream) { 870 void HBoundsCheck::PrintDataTo(StringStream* stream) {
819 index()->PrintNameTo(stream); 871 index()->PrintNameTo(stream);
820 stream->Add(" "); 872 stream->Add(" ");
821 length()->PrintNameTo(stream); 873 length()->PrintNameTo(stream);
822 } 874 }
823 875
824 876
825 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { 877 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) {
826 ASSERT(CheckFlag(kFlexibleRepresentation)); 878 ASSERT(CheckFlag(kFlexibleRepresentation));
827 Representation r; 879 Representation r;
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 if (!right()->range()->CanBeZero()) { 1520 if (!right()->range()->CanBeZero()) {
1469 ClearFlag(HValue::kCanBeDivByZero); 1521 ClearFlag(HValue::kCanBeDivByZero);
1470 } 1522 }
1471 return result; 1523 return result;
1472 } else { 1524 } else {
1473 return HValue::InferRange(zone); 1525 return HValue::InferRange(zone);
1474 } 1526 }
1475 } 1527 }
1476 1528
1477 1529
1530 void HPhi::AddInformativeDefinitions() {
1531 HValue* induction_base = NULL;
1532 NumericRelation relation = NumericRelation::None();
1533 if (OperandCount() == 2) {
1534 if (OperandAt(0)->IsRelationTrue(NumericRelation::Ge(), this)) {
Jakob Kummerow 2013/02/12 15:10:42 I don't feel strongly about it, but you *could* av
Massi 2013/02/13 11:56:42 Done.
1535 induction_base = OperandAt(1);
1536 relation = NumericRelation::Ge();
1537 } else if (OperandAt(0)->IsRelationTrue(NumericRelation::Le(), this)) {
1538 induction_base = OperandAt(1);
1539 relation = NumericRelation::Ge();
Jakob Kummerow 2013/02/12 15:10:42 s/Ge/Le/
Massi 2013/02/13 11:56:42 Done.
1540 } else if (OperandAt(1)->IsRelationTrue(NumericRelation::Ge(), this)) {
1541 induction_base = OperandAt(0);
1542 relation = NumericRelation::Ge();
1543 } else if (OperandAt(1)->IsRelationTrue(NumericRelation::Le(), this)) {
1544 induction_base = OperandAt(0);
1545 relation = NumericRelation::Ge();
Jakob Kummerow 2013/02/12 15:10:42 s/Ge/Le/
Massi 2013/02/13 11:56:42 Done.
1546 }
1547 }
1548
1549 if (induction_base == NULL) return;
1550
1551 AddNumericConstraint(block()->first(), induction_base, relation);
1552 }
1553
1554
1478 Range* HMathMinMax::InferRange(Zone* zone) { 1555 Range* HMathMinMax::InferRange(Zone* zone) {
1479 if (representation().IsInteger32()) { 1556 if (representation().IsInteger32()) {
1480 Range* a = left()->range(); 1557 Range* a = left()->range();
1481 Range* b = right()->range(); 1558 Range* b = right()->range();
1482 Range* res = a->Copy(zone); 1559 Range* res = a->Copy(zone);
1483 if (operation_ == kMathMax) { 1560 if (operation_ == kMathMax) {
1484 res->CombinedMax(b); 1561 res->CombinedMax(b);
1485 } else { 1562 } else {
1486 ASSERT(operation_ == kMathMin); 1563 ASSERT(operation_ == kMathMin);
1487 res->CombinedMin(b); 1564 res->CombinedMin(b);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 result->Sar(c->Integer32Value()); 1958 result->Sar(c->Integer32Value());
1882 result->set_can_be_minus_zero(false); 1959 result->set_can_be_minus_zero(false);
1883 return result; 1960 return result;
1884 } 1961 }
1885 } 1962 }
1886 } 1963 }
1887 return HValue::InferRange(zone); 1964 return HValue::InferRange(zone);
1888 } 1965 }
1889 1966
1890 1967
1968 bool HShr::CheckRelation(NumericRelation relation, HValue* other) {
1969 if (right()->IsInteger32Constant()) {
1970 HValue* base = left();
1971 int32_t bits = right()->GetInteger32Constant();
1972 if (relation.IsExtendable(-bits) &&
1973 base->IsRelationTrue(NumericRelation::Ge(),
1974 block()->graph()->GetConstant0())) {
1975 return base->IsRelationTrue(relation, other);
1976 } else {
1977 return false;
1978 }
1979 } else {
1980 return false;
1981 }
1982 }
1983
1984
1891 Range* HShl::InferRange(Zone* zone) { 1985 Range* HShl::InferRange(Zone* zone) {
1892 if (right()->IsConstant()) { 1986 if (right()->IsConstant()) {
1893 HConstant* c = HConstant::cast(right()); 1987 HConstant* c = HConstant::cast(right());
1894 if (c->HasInteger32Value()) { 1988 if (c->HasInteger32Value()) {
1895 Range* result = (left()->range() != NULL) 1989 Range* result = (left()->range() != NULL)
1896 ? left()->range()->Copy(zone) 1990 ? left()->range()->Copy(zone)
1897 : new(zone) Range(); 1991 : new(zone) Range();
1898 result->Shl(c->Integer32Value()); 1992 result->Shl(c->Integer32Value());
1899 result->set_can_be_minus_zero(false); 1993 result->set_can_be_minus_zero(false);
1900 return result; 1994 return result;
1901 } 1995 }
1902 } 1996 }
1903 return HValue::InferRange(zone); 1997 return HValue::InferRange(zone);
1904 } 1998 }
1905 1999
1906 2000
2001 bool HShl::CheckRelation(NumericRelation relation, HValue* other) {
2002 if (right()->IsInteger32Constant()) {
2003 HValue* base = left();
2004 int32_t bits = right()->GetInteger32Constant();
2005 if (relation.IsExtendable(bits) &&
2006 base->IsRelationTrue(NumericRelation::Ge(),
2007 block()->graph()->GetConstant0())) {
2008 return base->IsRelationTrue(relation, other);
2009 } else {
2010 return false;
2011 }
2012 } else {
2013 return false;
2014 }
2015 }
2016
2017
1907 Range* HLoadKeyed::InferRange(Zone* zone) { 2018 Range* HLoadKeyed::InferRange(Zone* zone) {
1908 switch (elements_kind()) { 2019 switch (elements_kind()) {
1909 case EXTERNAL_PIXEL_ELEMENTS: 2020 case EXTERNAL_PIXEL_ELEMENTS:
1910 return new(zone) Range(0, 255); 2021 return new(zone) Range(0, 255);
1911 case EXTERNAL_BYTE_ELEMENTS: 2022 case EXTERNAL_BYTE_ELEMENTS:
1912 return new(zone) Range(-128, 127); 2023 return new(zone) Range(-128, 127);
1913 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2024 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1914 return new(zone) Range(0, 255); 2025 return new(zone) Range(0, 255);
1915 case EXTERNAL_SHORT_ELEMENTS: 2026 case EXTERNAL_SHORT_ELEMENTS:
1916 return new(zone) Range(-32768, 32767); 2027 return new(zone) Range(-32768, 32767);
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 3052
2942 3053
2943 void HCheckFunction::Verify() { 3054 void HCheckFunction::Verify() {
2944 HInstruction::Verify(); 3055 HInstruction::Verify();
2945 ASSERT(HasNoUses()); 3056 ASSERT(HasNoUses());
2946 } 3057 }
2947 3058
2948 #endif 3059 #endif
2949 3060
2950 } } // namespace v8::internal 3061 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698