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

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 last 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
« 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 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() {
861 // TODO(mmassi): Executing this code during AddInformativeDefinitions
862 // is a hack. Move it to some other HPhase.
863 if (index()->IsRelationTrue(NumericRelation::Ge(),
864 block()->graph()->GetConstant0()) &&
865 index()->IsRelationTrue(NumericRelation::Lt(), length())) {
866 set_skip_check(true);
867 }
868 }
869
870
871 bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation,
872 HValue* related_value) {
873 if (related_value == length()) {
874 // A HBoundsCheck is smaller than the length it compared against.
875 return NumericRelation::Lt().Implies(relation);
876 } else if (related_value == block()->graph()->GetConstant0()) {
877 // A HBoundsCheck is greater than or equal to zero.
878 return NumericRelation::Ge().Implies(relation);
879 } else {
880 return false;
881 }
882 }
883
884
818 void HBoundsCheck::PrintDataTo(StringStream* stream) { 885 void HBoundsCheck::PrintDataTo(StringStream* stream) {
819 index()->PrintNameTo(stream); 886 index()->PrintNameTo(stream);
820 stream->Add(" "); 887 stream->Add(" ");
821 length()->PrintNameTo(stream); 888 length()->PrintNameTo(stream);
889 if (skip_check()) {
890 stream->Add(" [DISABLED]");
891 }
822 } 892 }
823 893
824 894
825 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { 895 void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) {
826 ASSERT(CheckFlag(kFlexibleRepresentation)); 896 ASSERT(CheckFlag(kFlexibleRepresentation));
827 Representation r; 897 Representation r;
828 if (key_mode_ == DONT_ALLOW_SMI_KEY || 898 if (key_mode_ == DONT_ALLOW_SMI_KEY ||
829 !length()->representation().IsTagged()) { 899 !length()->representation().IsTagged()) {
830 r = Representation::Integer32(); 900 r = Representation::Integer32();
831 } else if (index()->representation().IsTagged() || 901 } else if (index()->representation().IsTagged() ||
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 if (!right()->range()->CanBeZero()) { 1538 if (!right()->range()->CanBeZero()) {
1469 ClearFlag(HValue::kCanBeDivByZero); 1539 ClearFlag(HValue::kCanBeDivByZero);
1470 } 1540 }
1471 return result; 1541 return result;
1472 } else { 1542 } else {
1473 return HValue::InferRange(zone); 1543 return HValue::InferRange(zone);
1474 } 1544 }
1475 } 1545 }
1476 1546
1477 1547
1548 void HPhi::AddInformativeDefinitions() {
1549 if (OperandCount() == 2) {
1550 for (int operand_index = 0; operand_index < 2; operand_index++) {
1551 int other_operand_index = (operand_index + 1) % 2;
1552
1553 // Add an idef that "discards" the OSR entry block branch.
1554 if (OperandAt(operand_index)->block()->is_osr_entry()) {
1555 HNumericConstraint::AddToGraph(
1556 this, NumericRelation::Eq(), OperandAt(other_operand_index));
1557 }
1558
1559 static NumericRelation relations[] = {
1560 NumericRelation::Ge(),
1561 NumericRelation::Le()
1562 };
1563
1564 // Check if this phi is an induction variable. If, e.g., we know that
1565 // its first input is greater than the phi itself, then that must be
1566 // the back edge, and the phi is always greater than its second input.
1567 for (int relation_index = 0; relation_index < 2; relation_index++) {
1568 if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index],
1569 this)) {
1570 HNumericConstraint::AddToGraph(this,
1571 relations[relation_index],
1572 OperandAt(other_operand_index));
1573 }
1574 }
1575 }
1576 }
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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 } 2031 }
1930 2032
1931 2033
1932 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { 2034 void HStringCompareAndBranch::PrintDataTo(StringStream* stream) {
1933 stream->Add(Token::Name(token())); 2035 stream->Add(Token::Name(token()));
1934 stream->Add(" "); 2036 stream->Add(" ");
1935 HControlInstruction::PrintDataTo(stream); 2037 HControlInstruction::PrintDataTo(stream);
1936 } 2038 }
1937 2039
1938 2040
2041 void HCompareIDAndBranch::AddInformativeDefinitions() {
2042 NumericRelation r = NumericRelation::FromToken(token());
2043 if (r.IsNone()) return;
2044
2045 HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first());
2046 HNumericConstraint::AddToGraph(
2047 left(), r.Negated(), right(), SuccessorAt(1)->first());
2048 }
2049
2050
1939 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { 2051 void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
1940 stream->Add(Token::Name(token())); 2052 stream->Add(Token::Name(token()));
1941 stream->Add(" "); 2053 stream->Add(" ");
1942 left()->PrintNameTo(stream); 2054 left()->PrintNameTo(stream);
1943 stream->Add(" "); 2055 stream->Add(" ");
1944 right()->PrintNameTo(stream); 2056 right()->PrintNameTo(stream);
1945 HControlInstruction::PrintDataTo(stream); 2057 HControlInstruction::PrintDataTo(stream);
1946 } 2058 }
1947 2059
1948 2060
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 3053
2942 3054
2943 void HCheckFunction::Verify() { 3055 void HCheckFunction::Verify() {
2944 HInstruction::Verify(); 3056 HInstruction::Verify();
2945 ASSERT(HasNoUses()); 3057 ASSERT(HasNoUses());
2946 } 3058 }
2947 3059
2948 #endif 3060 #endif
2949 3061
2950 } } // namespace v8::internal 3062 } } // 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