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

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: Addressed review comments. 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
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 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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 } 798 }
788 799
789 // Verify that instructions that can be eliminated by GVN have overridden 800 // Verify that instructions that can be eliminated by GVN have overridden
790 // HValue::DataEquals. The default implementation is UNREACHABLE. We 801 // HValue::DataEquals. The default implementation is UNREACHABLE. We
791 // don't actually care whether DataEquals returns true or false here. 802 // don't actually care whether DataEquals returns true or false here.
792 if (CheckFlag(kUseGVN)) DataEquals(this); 803 if (CheckFlag(kUseGVN)) DataEquals(this);
793 } 804 }
794 #endif 805 #endif
795 806
796 807
808 HNumericConstraint* HNumericConstraint::AddToGraph(
809 HValue* constrained_value,
810 NumericRelation relation,
811 HValue* related_value,
812 HInstruction* insertion_point) {
813 if (insertion_point == NULL) {
814 if (constrained_value->IsInstruction()) {
815 insertion_point = HInstruction::cast(constrained_value);
816 } else if (constrained_value->IsPhi()) {
817 insertion_point = constrained_value->block()->first();
818 } else {
819 UNREACHABLE();
820 }
821 }
822 HNumericConstraint* result =
823 new(insertion_point->block()->zone()) HNumericConstraint(
824 constrained_value, relation, related_value);
825 result->InsertAfter(insertion_point);
826 return result;
827 }
828
829
830 void HNumericConstraint::PrintDataTo(StringStream* stream) {
831 stream->Add("(");
832 constrained_value()->PrintNameTo(stream);
833 stream->Add(" %s ", relation().Mnemonic());
834 related_value()->PrintNameTo(stream);
835 stream->Add(")");
836 }
837
838
797 void HDummyUse::PrintDataTo(StringStream* stream) { 839 void HDummyUse::PrintDataTo(StringStream* stream) {
798 value()->PrintNameTo(stream); 840 value()->PrintNameTo(stream);
799 } 841 }
800 842
801 843
802 void HUnaryCall::PrintDataTo(StringStream* stream) { 844 void HUnaryCall::PrintDataTo(StringStream* stream) {
803 value()->PrintNameTo(stream); 845 value()->PrintNameTo(stream);
804 stream->Add(" "); 846 stream->Add(" ");
805 stream->Add("#%d", argument_count()); 847 stream->Add("#%d", argument_count());
806 } 848 }
807 849
808 850
809 void HBinaryCall::PrintDataTo(StringStream* stream) { 851 void HBinaryCall::PrintDataTo(StringStream* stream) {
810 first()->PrintNameTo(stream); 852 first()->PrintNameTo(stream);
811 stream->Add(" "); 853 stream->Add(" ");
812 second()->PrintNameTo(stream); 854 second()->PrintNameTo(stream);
813 stream->Add(" "); 855 stream->Add(" ");
814 stream->Add("#%d", argument_count()); 856 stream->Add("#%d", argument_count());
815 } 857 }
816 858
817 859
860 void HBoundsCheck::AddInformativeDefinitions() {
Jakob Kummerow 2013/02/13 13:20:56 Please add a comment here: // TODO(mmassi): Exec
861 if (index()->IsRelationTrue(NumericRelation::Ge(),
862 block()->graph()->GetConstant0()) &&
863 index()->IsRelationTrue(NumericRelation::Lt(), length())) {
864 set_skip_check(true);
865 }
866 }
867
868
869 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation,
870 HValue* related_value) {
871 if (related_value == length()) {
872 // A HBoundsCheck is smaller than the length it compared against.
873 return NumericRelation::Lt().Implies(relation);
874 } else if (related_value == block()->graph()->GetConstant0()) {
875 // A HBoundsCheck is greater than or equal to zero.
876 return NumericRelation::Ge().Implies(relation);
877 } else {
878 return false;
879 }
880 }
881
882
818 void HBoundsCheck::PrintDataTo(StringStream* stream) { 883 void HBoundsCheck::PrintDataTo(StringStream* stream) {
819 index()->PrintNameTo(stream); 884 index()->PrintNameTo(stream);
820 stream->Add(" "); 885 stream->Add(" ");
821 length()->PrintNameTo(stream); 886 length()->PrintNameTo(stream);
887 if (skip_check()) {
888 stream->Add(" [DISABLED]");
889 }
822 } 890 }
823 891
824 892
825 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { 893 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) {
826 ASSERT(CheckFlag(kFlexibleRepresentation)); 894 ASSERT(CheckFlag(kFlexibleRepresentation));
827 Representation r; 895 Representation r;
828 if (key_mode_ == DONT_ALLOW_SMI_KEY || 896 if (key_mode_ == DONT_ALLOW_SMI_KEY ||
829 !length()->representation().IsTagged()) { 897 !length()->representation().IsTagged()) {
830 r = Representation::Integer32(); 898 r = Representation::Integer32();
831 } else if (index()->representation().IsTagged() || 899 } else if (index()->representation().IsTagged() ||
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 if (!right()->range()->CanBeZero()) { 1536 if (!right()->range()->CanBeZero()) {
1469 ClearFlag(HValue::kCanBeDivByZero); 1537 ClearFlag(HValue::kCanBeDivByZero);
1470 } 1538 }
1471 return result; 1539 return result;
1472 } else { 1540 } else {
1473 return HValue::InferRange(zone); 1541 return HValue::InferRange(zone);
1474 } 1542 }
1475 } 1543 }
1476 1544
1477 1545
1546 void HPhi::AddInformativeDefinitions() {
1547 if (OperandCount() == 2) {
1548 for (int operand_index = 0; operand_index < 2; operand_index++) {
1549 int other_operand_index = (operand_index + 1) % 2;
1550
1551 // Add an idef that "discards" the OSR entry block branch.
1552 if (OperandAt(operand_index)->block()->is_osr_entry()) {
1553 HNumericConstraint::AddToGraph(
1554 this, NumericRelation::Eq(), OperandAt(other_operand_index));
Jakob Kummerow 2013/02/13 13:20:56 nit: 4 spaces indentation is enough
1555 }
1556
1557 static NumericRelation relations[] = {
1558 NumericRelation::Ge(),
1559 NumericRelation::Le()
1560 };
1561
1562 // Check if this phi is an induction variable.
Jakob Kummerow 2013/02/13 13:20:56 Please extend this comment to convey the reasoning
1563 for (int relation_index = 0; relation_index < 2; relation_index++) {
1564 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index],
1565 this)) {
1566 HNumericConstraint::AddToGraph(this,
1567 relations[relation_index],
1568 OperandAt(other_operand_index));
1569 }
1570 }
1571 }
1572 }
1573 }
1574
1575
1478 Range* HMathMinMax::InferRange(Zone* zone) { 1576 Range* HMathMinMax::InferRange(Zone* zone) {
1479 if (representation().IsInteger32()) { 1577 if (representation().IsInteger32()) {
1480 Range* a = left()->range(); 1578 Range* a = left()->range();
1481 Range* b = right()->range(); 1579 Range* b = right()->range();
1482 Range* res = a->Copy(zone); 1580 Range* res = a->Copy(zone);
1483 if (operation_ == kMathMax) { 1581 if (operation_ == kMathMax) {
1484 res->CombinedMax(b); 1582 res->CombinedMax(b);
1485 } else { 1583 } else {
1486 ASSERT(operation_ == kMathMin); 1584 ASSERT(operation_ == kMathMin);
1487 res->CombinedMin(b); 1585 res->CombinedMin(b);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 result->Sar(c->Integer32Value()); 1979 result->Sar(c->Integer32Value());
1882 result->set_can_be_minus_zero(false); 1980 result->set_can_be_minus_zero(false);
1883 return result; 1981 return result;
1884 } 1982 }
1885 } 1983 }
1886 } 1984 }
1887 return HValue::InferRange(zone); 1985 return HValue::InferRange(zone);
1888 } 1986 }
1889 1987
1890 1988
1989
Jakob Kummerow 2013/02/13 13:20:56 nit: unneeded whitespace
1891 Range* HShl::InferRange(Zone* zone) { 1990 Range* HShl::InferRange(Zone* zone) {
1892 if (right()->IsConstant()) { 1991 if (right()->IsConstant()) {
1893 HConstant* c = HConstant::cast(right()); 1992 HConstant* c = HConstant::cast(right());
1894 if (c->HasInteger32Value()) { 1993 if (c->HasInteger32Value()) {
1895 Range* result = (left()->range() != NULL) 1994 Range* result = (left()->range() != NULL)
1896 ? left()->range()->Copy(zone) 1995 ? left()->range()->Copy(zone)
1897 : new(zone) Range(); 1996 : new(zone) Range();
1898 result->Shl(c->Integer32Value()); 1997 result->Shl(c->Integer32Value());
1899 result->set_can_be_minus_zero(false); 1998 result->set_can_be_minus_zero(false);
1900 return result; 1999 return result;
(...skipping 28 matching lines...) Expand all
1929 } 2028 }
1930 2029
1931 2030
1932 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { 2031 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) {
1933 stream->Add(Token::Name(token())); 2032 stream->Add(Token::Name(token()));
1934 stream->Add(" "); 2033 stream->Add(" ");
1935 HControlInstruction::PrintDataTo(stream); 2034 HControlInstruction::PrintDataTo(stream);
1936 } 2035 }
1937 2036
1938 2037
2038 void HCompareIDAndBranch::AddInformativeDefinitions() {
2039 NumericRelation r = NumericRelation::FromToken(token());
2040 if (r.IsNone()) return;
2041
2042 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first());
2043 HNumericConstraint::AddToGraph(
2044 left(), r.Negated(), right(), SuccessorAt(1)->first());
2045 }
2046
2047
1939 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { 2048 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
1940 stream->Add(Token::Name(token())); 2049 stream->Add(Token::Name(token()));
1941 stream->Add(" "); 2050 stream->Add(" ");
1942 left()->PrintNameTo(stream); 2051 left()->PrintNameTo(stream);
1943 stream->Add(" "); 2052 stream->Add(" ");
1944 right()->PrintNameTo(stream); 2053 right()->PrintNameTo(stream);
1945 HControlInstruction::PrintDataTo(stream); 2054 HControlInstruction::PrintDataTo(stream);
1946 } 2055 }
1947 2056
1948 2057
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 3050
2942 3051
2943 void HCheckFunction::Verify() { 3052 void HCheckFunction::Verify() {
2944 HInstruction::Verify(); 3053 HInstruction::Verify();
2945 ASSERT(HasNoUses()); 3054 ASSERT(HasNoUses());
2946 } 3055 }
2947 3056
2948 #endif 3057 #endif
2949 3058
2950 } } // namespace v8::internal 3059 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698