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

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: Discard OSR values. 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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 return false; 398 return false;
399 } 399 }
400 } 400 }
401 401
402 402
403 bool HValue::TestDominanceUsingProcessedFlag(HValue* dominator, 403 bool HValue::TestDominanceUsingProcessedFlag(HValue* dominator,
404 HValue* dominated) { 404 HValue* dominated) {
405 if (dominator->block() != dominated->block()) { 405 if (dominator->block() != dominated->block()) {
406 return dominator->block()->Dominates(dominated->block()); 406 return dominator->block()->Dominates(dominated->block());
407 } else { 407 } else {
408 // If both arguments are in the same block we check if "dominator" has 408 // If both arguments are in the same block we check if dominator is a phi
409 // already been processed or if it is a phi: if yes it dominates the other. 409 // or if dominated has not already been processed: in either case we know
410 return dominator->CheckFlag(kIDefsProcessingDone) || dominator->IsPhi(); 410 // that dominator precedes dominated.
411 return dominator->IsPhi() || !dominated->CheckFlag(kIDefsProcessingDone);
411 } 412 }
412 } 413 }
413 414
414 415
415 bool HValue::IsDefinedAfter(HBasicBlock* other) const { 416 bool HValue::IsDefinedAfter(HBasicBlock* other) const {
416 return block()->block_id() > other->block_id(); 417 return block()->block_id() > other->block_id();
417 } 418 }
418 419
419 420
420 HUseListNode* HUseListNode::tail() { 421 HUseListNode* HUseListNode::tail() {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 switch (opcode()) { 518 switch (opcode()) {
518 #define MAKE_CASE(type) case k##type: return #type; 519 #define MAKE_CASE(type) case k##type: return #type;
519 HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE) 520 HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE)
520 #undef MAKE_CASE 521 #undef MAKE_CASE
521 case kPhi: return "Phi"; 522 case kPhi: return "Phi";
522 default: return ""; 523 default: return "";
523 } 524 }
524 } 525 }
525 526
526 527
528 bool HValue::IsInteger32Constant() {
529 return IsConstant() && HConstant::cast(this)->HasInteger32Value();
530 }
531
532
533 int32_t HValue::GetInteger32Constant() {
534 ASSERT(IsInteger32Constant());
535 return HConstant::cast(this)->Integer32Value();
536 }
537
538
527 void HValue::SetOperandAt(int index, HValue* value) { 539 void HValue::SetOperandAt(int index, HValue* value) {
528 RegisterUse(index, value); 540 RegisterUse(index, value);
529 InternalSetOperandAt(index, value); 541 InternalSetOperandAt(index, value);
530 } 542 }
531 543
532 544
533 void HValue::DeleteAndReplaceWith(HValue* other) { 545 void HValue::DeleteAndReplaceWith(HValue* other) {
534 // We replace all uses first, so Delete can assert that there are none. 546 // We replace all uses first, so Delete can assert that there are none.
535 if (other != NULL) ReplaceAllUsesWith(other); 547 if (other != NULL) ReplaceAllUsesWith(other);
536 ASSERT(HasNoUses()); 548 ASSERT(HasNoUses());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 PrintChangesTo(stream); 695 PrintChangesTo(stream);
684 PrintTypeTo(stream); 696 PrintTypeTo(stream);
685 } 697 }
686 698
687 699
688 void HInstruction::PrintMnemonicTo(StringStream* stream) { 700 void HInstruction::PrintMnemonicTo(StringStream* stream) {
689 stream->Add("%s ", Mnemonic()); 701 stream->Add("%s ", Mnemonic());
690 } 702 }
691 703
692 704
705 HValue* HValue::AddNumericConstraint(HInstruction* insertion_point,
706 HValue* related_value,
707 NumericRelation relation) {
708 return HNumericConstraint::New(
709 insertion_point, this, related_value, relation);
710 }
711
712
693 void HInstruction::Unlink() { 713 void HInstruction::Unlink() {
694 ASSERT(IsLinked()); 714 ASSERT(IsLinked());
695 ASSERT(!IsControlInstruction()); // Must never move control instructions. 715 ASSERT(!IsControlInstruction()); // Must never move control instructions.
696 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. 716 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these.
697 ASSERT(previous_ != NULL); 717 ASSERT(previous_ != NULL);
698 previous_->next_ = next_; 718 previous_->next_ = next_;
699 if (next_ == NULL) { 719 if (next_ == NULL) {
700 ASSERT(block()->last() == this); 720 ASSERT(block()->last() == this);
701 block()->set_last(previous_); 721 block()->set_last(previous_);
702 } else { 722 } else {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 } 807 }
788 808
789 // Verify that instructions that can be eliminated by GVN have overridden 809 // Verify that instructions that can be eliminated by GVN have overridden
790 // HValue::DataEquals. The default implementation is UNREACHABLE. We 810 // HValue::DataEquals. The default implementation is UNREACHABLE. We
791 // don't actually care whether DataEquals returns true or false here. 811 // don't actually care whether DataEquals returns true or false here.
792 if (CheckFlag(kUseGVN)) DataEquals(this); 812 if (CheckFlag(kUseGVN)) DataEquals(this);
793 } 813 }
794 #endif 814 #endif
795 815
796 816
817 HNumericConstraint* HNumericConstraint::New(HInstruction* insertion_point,
818 HValue* constrained_value,
819 HValue* related_value,
820 NumericRelation relation) {
821 HNumericConstraint* result =
822 new(insertion_point->block()->zone()) HNumericConstraint(
823 constrained_value, related_value, relation);
824 result->InsertAfter(insertion_point);
825 return result;
826 }
827
828
829 void HNumericConstraint::PrintDataTo(StringStream* stream) {
830 stream->Add("(");
831 constrained_value()->PrintNameTo(stream);
832 stream->Add(" %s ", relation().Mnemonic());
833 related_value()->PrintNameTo(stream);
834 stream->Add(")");
835 }
836
837
797 void HDummyUse::PrintDataTo(StringStream* stream) { 838 void HDummyUse::PrintDataTo(StringStream* stream) {
798 value()->PrintNameTo(stream); 839 value()->PrintNameTo(stream);
799 } 840 }
800 841
801 842
802 void HUnaryCall::PrintDataTo(StringStream* stream) { 843 void HUnaryCall::PrintDataTo(StringStream* stream) {
803 value()->PrintNameTo(stream); 844 value()->PrintNameTo(stream);
804 stream->Add(" "); 845 stream->Add(" ");
805 stream->Add("#%d", argument_count()); 846 stream->Add("#%d", argument_count());
806 } 847 }
807 848
808 849
809 void HBinaryCall::PrintDataTo(StringStream* stream) { 850 void HBinaryCall::PrintDataTo(StringStream* stream) {
810 first()->PrintNameTo(stream); 851 first()->PrintNameTo(stream);
811 stream->Add(" "); 852 stream->Add(" ");
812 second()->PrintNameTo(stream); 853 second()->PrintNameTo(stream);
813 stream->Add(" "); 854 stream->Add(" ");
814 stream->Add("#%d", argument_count()); 855 stream->Add("#%d", argument_count());
815 } 856 }
816 857
817 858
859 void HBoundsCheck::AddInformativeDefinitions() {
860 if (index()->IsRelationTrue(
861 NumericRelation::Ge(), block()->graph()->GetConstant0())
862 && index()->IsRelationTrue(NumericRelation::Lt(), length())) {
863 set_skip_check(true);
864 }
865 }
866
867
868 bool HBoundsCheck::CheckRelation(NumericRelation relation,
869 HValue* related_value) {
870 if (related_value == length()) {
871 return NumericRelation::Lt().Implies(relation);
872 } else if (related_value == block()->graph()->GetConstant0()) {
873 return NumericRelation::Ge().Implies(relation);
874 } else {
875 return false;
876 }
877 }
878
879
818 void HBoundsCheck::PrintDataTo(StringStream* stream) { 880 void HBoundsCheck::PrintDataTo(StringStream* stream) {
819 index()->PrintNameTo(stream); 881 index()->PrintNameTo(stream);
820 stream->Add(" "); 882 stream->Add(" ");
821 length()->PrintNameTo(stream); 883 length()->PrintNameTo(stream);
884 if (skip_check()) {
885 stream->Add(" [DISABLED]");
886 }
822 } 887 }
823 888
824 889
825 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { 890 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) {
826 ASSERT(CheckFlag(kFlexibleRepresentation)); 891 ASSERT(CheckFlag(kFlexibleRepresentation));
827 Representation r; 892 Representation r;
828 if (key_mode_ == DONT_ALLOW_SMI_KEY || 893 if (key_mode_ == DONT_ALLOW_SMI_KEY ||
829 !length()->representation().IsTagged()) { 894 !length()->representation().IsTagged()) {
830 r = Representation::Integer32(); 895 r = Representation::Integer32();
831 } else if (index()->representation().IsTagged() || 896 } else if (index()->representation().IsTagged() ||
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 if (!right()->range()->CanBeZero()) { 1533 if (!right()->range()->CanBeZero()) {
1469 ClearFlag(HValue::kCanBeDivByZero); 1534 ClearFlag(HValue::kCanBeDivByZero);
1470 } 1535 }
1471 return result; 1536 return result;
1472 } else { 1537 } else {
1473 return HValue::InferRange(zone); 1538 return HValue::InferRange(zone);
1474 } 1539 }
1475 } 1540 }
1476 1541
1477 1542
1543 void HPhi::AddInformativeDefinitions() {
1544 // Add an idef that "discards" the OSR entry block branch.
1545 if (OperandCount() == 2) {
1546 if (OperandAt(0)->block()->is_osr_entry()) {
Jakob Kummerow 2013/02/12 15:10:42 Let's fold this into the loop-based refactoring of
Massi 2013/02/13 11:56:43 Done.
1547 AddNumericConstraint(
1548 block()->first(), OperandAt(1), NumericRelation::Eq());
1549 } else if (OperandAt(1)->block()->is_osr_entry()) {
1550 AddNumericConstraint(
1551 block()->first(), OperandAt(0), NumericRelation::Eq());
1552 }
1553 }
1554
1555 // Check if this phi is an induction variable.
1556 HValue* induction_base = NULL;
1557 NumericRelation relation = NumericRelation::None();
1558 if (OperandCount() == 2) {
1559 if (OperandAt(0)->IsRelationTrue(NumericRelation::Ge(), this)) {
1560 induction_base = OperandAt(1);
1561 relation = NumericRelation::Ge();
1562 } else if (OperandAt(0)->IsRelationTrue(NumericRelation::Le(), this)) {
1563 induction_base = OperandAt(1);
1564 relation = NumericRelation::Ge();
1565 } else if (OperandAt(1)->IsRelationTrue(NumericRelation::Ge(), this)) {
1566 induction_base = OperandAt(0);
1567 relation = NumericRelation::Ge();
1568 } else if (OperandAt(1)->IsRelationTrue(NumericRelation::Le(), this)) {
1569 induction_base = OperandAt(0);
1570 relation = NumericRelation::Ge();
1571 }
1572 }
1573
1574 if (induction_base == NULL) return;
1575
1576 AddNumericConstraint(block()->first(), induction_base, relation);
1577 }
1578
1579
1478 Range* HMathMinMax::InferRange(Zone* zone) { 1580 Range* HMathMinMax::InferRange(Zone* zone) {
1479 if (representation().IsInteger32()) { 1581 if (representation().IsInteger32()) {
1480 Range* a = left()->range(); 1582 Range* a = left()->range();
1481 Range* b = right()->range(); 1583 Range* b = right()->range();
1482 Range* res = a->Copy(zone); 1584 Range* res = a->Copy(zone);
1483 if (operation_ == kMathMax) { 1585 if (operation_ == kMathMax) {
1484 res->CombinedMax(b); 1586 res->CombinedMax(b);
1485 } else { 1587 } else {
1486 ASSERT(operation_ == kMathMin); 1588 ASSERT(operation_ == kMathMin);
1487 res->CombinedMin(b); 1589 res->CombinedMin(b);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 result->Sar(c->Integer32Value()); 1983 result->Sar(c->Integer32Value());
1882 result->set_can_be_minus_zero(false); 1984 result->set_can_be_minus_zero(false);
1883 return result; 1985 return result;
1884 } 1986 }
1885 } 1987 }
1886 } 1988 }
1887 return HValue::InferRange(zone); 1989 return HValue::InferRange(zone);
1888 } 1990 }
1889 1991
1890 1992
1993 bool HShr::CheckRelation(NumericRelation relation, HValue* other) {
1994 if (right()->IsInteger32Constant()) {
1995 HValue* base = left();
1996 int32_t bits = right()->GetInteger32Constant();
1997 if (relation.IsExtendable(-bits) &&
1998 base->IsRelationTrue(NumericRelation::Ge(),
1999 block()->graph()->GetConstant0())) {
2000 return base->IsRelationTrue(relation, other);
2001 } else {
2002 return false;
2003 }
2004 } else {
2005 return false;
2006 }
2007 }
2008
2009
1891 Range* HShl::InferRange(Zone* zone) { 2010 Range* HShl::InferRange(Zone* zone) {
1892 if (right()->IsConstant()) { 2011 if (right()->IsConstant()) {
1893 HConstant* c = HConstant::cast(right()); 2012 HConstant* c = HConstant::cast(right());
1894 if (c->HasInteger32Value()) { 2013 if (c->HasInteger32Value()) {
1895 Range* result = (left()->range() != NULL) 2014 Range* result = (left()->range() != NULL)
1896 ? left()->range()->Copy(zone) 2015 ? left()->range()->Copy(zone)
1897 : new(zone) Range(); 2016 : new(zone) Range();
1898 result->Shl(c->Integer32Value()); 2017 result->Shl(c->Integer32Value());
1899 result->set_can_be_minus_zero(false); 2018 result->set_can_be_minus_zero(false);
1900 return result; 2019 return result;
1901 } 2020 }
1902 } 2021 }
1903 return HValue::InferRange(zone); 2022 return HValue::InferRange(zone);
1904 } 2023 }
1905 2024
1906 2025
2026 bool HShl::CheckRelation(NumericRelation relation, HValue* other) {
2027 if (right()->IsInteger32Constant()) {
2028 HValue* base = left();
2029 int32_t bits = right()->GetInteger32Constant();
2030 if (relation.IsExtendable(bits) &&
2031 base->IsRelationTrue(NumericRelation::Ge(),
2032 block()->graph()->GetConstant0())) {
2033 return base->IsRelationTrue(relation, other);
2034 } else {
2035 return false;
2036 }
2037 } else {
2038 return false;
2039 }
2040 }
2041
2042
1907 Range* HLoadKeyed::InferRange(Zone* zone) { 2043 Range* HLoadKeyed::InferRange(Zone* zone) {
1908 switch (elements_kind()) { 2044 switch (elements_kind()) {
1909 case EXTERNAL_PIXEL_ELEMENTS: 2045 case EXTERNAL_PIXEL_ELEMENTS:
1910 return new(zone) Range(0, 255); 2046 return new(zone) Range(0, 255);
1911 case EXTERNAL_BYTE_ELEMENTS: 2047 case EXTERNAL_BYTE_ELEMENTS:
1912 return new(zone) Range(-128, 127); 2048 return new(zone) Range(-128, 127);
1913 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2049 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1914 return new(zone) Range(0, 255); 2050 return new(zone) Range(0, 255);
1915 case EXTERNAL_SHORT_ELEMENTS: 2051 case EXTERNAL_SHORT_ELEMENTS:
1916 return new(zone) Range(-32768, 32767); 2052 return new(zone) Range(-32768, 32767);
(...skipping 12 matching lines...) Expand all
1929 } 2065 }
1930 2066
1931 2067
1932 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { 2068 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) {
1933 stream->Add(Token::Name(token())); 2069 stream->Add(Token::Name(token()));
1934 stream->Add(" "); 2070 stream->Add(" ");
1935 HControlInstruction::PrintDataTo(stream); 2071 HControlInstruction::PrintDataTo(stream);
1936 } 2072 }
1937 2073
1938 2074
2075 void HCompareIDAndBranch::AddInformativeDefinitions() {
2076 NumericRelation r = NumericRelation::FromToken(token());
2077 if (r == NumericRelation::None()) return;
2078
2079 left()->AddNumericConstraint(SuccessorAt(0)->first(), right(), r.Reversed());
2080 left()->AddNumericConstraint(SuccessorAt(1)->first(), right(), r);
2081 }
2082
2083
1939 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { 2084 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
1940 stream->Add(Token::Name(token())); 2085 stream->Add(Token::Name(token()));
1941 stream->Add(" "); 2086 stream->Add(" ");
1942 left()->PrintNameTo(stream); 2087 left()->PrintNameTo(stream);
1943 stream->Add(" "); 2088 stream->Add(" ");
1944 right()->PrintNameTo(stream); 2089 right()->PrintNameTo(stream);
1945 HControlInstruction::PrintDataTo(stream); 2090 HControlInstruction::PrintDataTo(stream);
1946 } 2091 }
1947 2092
1948 2093
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 3086
2942 3087
2943 void HCheckFunction::Verify() { 3088 void HCheckFunction::Verify() {
2944 HInstruction::Verify(); 3089 HInstruction::Verify();
2945 ASSERT(HasNoUses()); 3090 ASSERT(HasNoUses());
2946 } 3091 }
2947 3092
2948 #endif 3093 #endif
2949 3094
2950 } } // namespace v8::internal 3095 } } // 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