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

Side by Side Diff: src/hydrogen.cc

Issue 6903060: Version 3.3.2.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 8 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.h ('k') | src/hydrogen-instructions.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 } 637 }
638 638
639 639
640 void HGraph::Canonicalize() { 640 void HGraph::Canonicalize() {
641 if (!FLAG_use_canonicalizing) return; 641 if (!FLAG_use_canonicalizing) return;
642 HPhase phase("Canonicalize", this); 642 HPhase phase("Canonicalize", this);
643 for (int i = 0; i < blocks()->length(); ++i) { 643 for (int i = 0; i < blocks()->length(); ++i) {
644 HInstruction* instr = blocks()->at(i)->first(); 644 HInstruction* instr = blocks()->at(i)->first();
645 while (instr != NULL) { 645 while (instr != NULL) {
646 HValue* value = instr->Canonicalize(); 646 HValue* value = instr->Canonicalize();
647 if (value != instr) instr->ReplaceAndDelete(value); 647 if (value != instr) instr->DeleteAndReplaceWith(value);
648 instr = instr->next(); 648 instr = instr->next();
649 } 649 }
650 } 650 }
651 } 651 }
652 652
653 653
654 void HGraph::OrderBlocks() { 654 void HGraph::OrderBlocks() {
655 HPhase phase("Block ordering"); 655 HPhase phase("Block ordering");
656 BitVector visited(blocks_.length()); 656 BitVector visited(blocks_.length());
657 657
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); 719 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j));
720 } 720 }
721 } 721 }
722 } 722 }
723 } 723 }
724 724
725 725
726 void HGraph::EliminateRedundantPhis() { 726 void HGraph::EliminateRedundantPhis() {
727 HPhase phase("Redundant phi elimination", this); 727 HPhase phase("Redundant phi elimination", this);
728 728
729 // Worklist of phis that can potentially be eliminated. Initialized 729 // Worklist of phis that can potentially be eliminated. Initialized with
730 // with all phi nodes. When elimination of a phi node modifies 730 // all phi nodes. When elimination of a phi node modifies another phi node
731 // another phi node the modified phi node is added to the worklist. 731 // the modified phi node is added to the worklist.
732 ZoneList<HPhi*> worklist(blocks_.length()); 732 ZoneList<HPhi*> worklist(blocks_.length());
733 for (int i = 0; i < blocks_.length(); ++i) { 733 for (int i = 0; i < blocks_.length(); ++i) {
734 worklist.AddAll(*blocks_[i]->phis()); 734 worklist.AddAll(*blocks_[i]->phis());
735 } 735 }
736 736
737 while (!worklist.is_empty()) { 737 while (!worklist.is_empty()) {
738 HPhi* phi = worklist.RemoveLast(); 738 HPhi* phi = worklist.RemoveLast();
739 HBasicBlock* block = phi->block(); 739 HBasicBlock* block = phi->block();
740 740
741 // Skip phi node if it was already replaced. 741 // Skip phi node if it was already replaced.
742 if (block == NULL) continue; 742 if (block == NULL) continue;
743 743
744 // Get replacement value if phi is redundant. 744 // Get replacement value if phi is redundant.
745 HValue* value = phi->GetRedundantReplacement(); 745 HValue* replacement = phi->GetRedundantReplacement();
746 746
747 if (value != NULL) { 747 if (replacement != NULL) {
748 // Iterate through uses finding the ones that should be 748 // Iterate through the uses and replace them all.
749 // replaced. 749 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
750 SmallPointerList<HValue>* uses = phi->uses(); 750 HValue* value = it.value();
751 while (!uses->is_empty()) { 751 value->SetOperandAt(it.index(), replacement);
752 HValue* use = uses->RemoveLast(); 752 if (value->IsPhi()) worklist.Add(HPhi::cast(value));
753 if (use != NULL) {
754 phi->ReplaceAtUse(use, value);
755 if (use->IsPhi()) worklist.Add(HPhi::cast(use));
756 }
757 } 753 }
758 block->RemovePhi(phi); 754 block->RemovePhi(phi);
759 } 755 }
760 } 756 }
761 } 757 }
762 758
763 759
764 void HGraph::EliminateUnreachablePhis() { 760 void HGraph::EliminateUnreachablePhis() {
765 HPhase phase("Unreachable phi elimination", this); 761 HPhase phase("Unreachable phi elimination", this);
766 762
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 BitVector in_worklist(GetMaximumValueID()); 820 BitVector in_worklist(GetMaximumValueID());
825 for (int i = 0; i < worklist->length(); ++i) { 821 for (int i = 0; i < worklist->length(); ++i) {
826 ASSERT(!in_worklist.Contains(worklist->at(i)->id())); 822 ASSERT(!in_worklist.Contains(worklist->at(i)->id()));
827 in_worklist.Add(worklist->at(i)->id()); 823 in_worklist.Add(worklist->at(i)->id());
828 } 824 }
829 825
830 while (!worklist->is_empty()) { 826 while (!worklist->is_empty()) {
831 HValue* current = worklist->RemoveLast(); 827 HValue* current = worklist->RemoveLast();
832 in_worklist.Remove(current->id()); 828 in_worklist.Remove(current->id());
833 if (current->UpdateInferredType()) { 829 if (current->UpdateInferredType()) {
834 for (int j = 0; j < current->uses()->length(); j++) { 830 for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) {
835 HValue* use = current->uses()->at(j); 831 HValue* use = it.value();
836 if (!in_worklist.Contains(use->id())) { 832 if (!in_worklist.Contains(use->id())) {
837 in_worklist.Add(use->id()); 833 in_worklist.Add(use->id());
838 worklist->Add(use); 834 worklist->Add(use);
839 } 835 }
840 } 836 }
841 } 837 }
842 } 838 }
843 } 839 }
844 840
845 841
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 TraceGVN("Instruction %d kills\n", instr->id()); 1434 TraceGVN("Instruction %d kills\n", instr->id());
1439 } else if (instr->CheckFlag(HValue::kUseGVN)) { 1435 } else if (instr->CheckFlag(HValue::kUseGVN)) {
1440 HValue* other = map->Lookup(instr); 1436 HValue* other = map->Lookup(instr);
1441 if (other != NULL) { 1437 if (other != NULL) {
1442 ASSERT(instr->Equals(other) && other->Equals(instr)); 1438 ASSERT(instr->Equals(other) && other->Equals(instr));
1443 TraceGVN("Replacing value %d (%s) with value %d (%s)\n", 1439 TraceGVN("Replacing value %d (%s) with value %d (%s)\n",
1444 instr->id(), 1440 instr->id(),
1445 instr->Mnemonic(), 1441 instr->Mnemonic(),
1446 other->id(), 1442 other->id(),
1447 other->Mnemonic()); 1443 other->Mnemonic());
1448 instr->ReplaceAndDelete(other); 1444 instr->DeleteAndReplaceWith(other);
1449 } else { 1445 } else {
1450 map->Add(instr); 1446 map->Add(instr);
1451 } 1447 }
1452 } 1448 }
1453 instr = next; 1449 instr = next;
1454 } 1450 }
1455 1451
1456 // Recursively continue analysis for all immediately dominated blocks. 1452 // Recursively continue analysis for all immediately dominated blocks.
1457 int length = block->dominated_blocks()->length(); 1453 int length = block->dominated_blocks()->length();
1458 for (int i = 0; i < length; ++i) { 1454 for (int i = 0; i < length; ++i) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 if (r.IsSpecialization()) return; 1518 if (r.IsSpecialization()) return;
1523 ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation)); 1519 ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation));
1524 Representation inferred = current->InferredRepresentation(); 1520 Representation inferred = current->InferredRepresentation();
1525 if (inferred.IsSpecialization()) { 1521 if (inferred.IsSpecialization()) {
1526 current->ChangeRepresentation(inferred); 1522 current->ChangeRepresentation(inferred);
1527 AddDependantsToWorklist(current); 1523 AddDependantsToWorklist(current);
1528 } 1524 }
1529 } 1525 }
1530 1526
1531 1527
1532 void HInferRepresentation::AddDependantsToWorklist(HValue* current) { 1528 void HInferRepresentation::AddDependantsToWorklist(HValue* value) {
1533 for (int i = 0; i < current->uses()->length(); ++i) { 1529 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
1534 AddToWorklist(current->uses()->at(i)); 1530 AddToWorklist(it.value());
1535 } 1531 }
1536 for (int i = 0; i < current->OperandCount(); ++i) { 1532 for (int i = 0; i < value->OperandCount(); ++i) {
1537 AddToWorklist(current->OperandAt(i)); 1533 AddToWorklist(value->OperandAt(i));
1538 } 1534 }
1539 } 1535 }
1540 1536
1541 1537
1542 // This method calculates whether specializing the representation of the value 1538 // This method calculates whether specializing the representation of the value
1543 // given as the parameter has a benefit in terms of less necessary type 1539 // given as the parameter has a benefit in terms of less necessary type
1544 // conversions. If there is a benefit, then the representation of the value is 1540 // conversions. If there is a benefit, then the representation of the value is
1545 // specialized. 1541 // specialized.
1546 void HInferRepresentation::InferBasedOnUses(HValue* current) { 1542 void HInferRepresentation::InferBasedOnUses(HValue* value) {
1547 Representation r = current->representation(); 1543 Representation r = value->representation();
1548 if (r.IsSpecialization() || current->HasNoUses()) return; 1544 if (r.IsSpecialization() || value->HasNoUses()) return;
1549 ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation)); 1545 ASSERT(value->CheckFlag(HValue::kFlexibleRepresentation));
1550 Representation new_rep = TryChange(current); 1546 Representation new_rep = TryChange(value);
1551 if (!new_rep.IsNone()) { 1547 if (!new_rep.IsNone()) {
1552 if (!current->representation().Equals(new_rep)) { 1548 if (!value->representation().Equals(new_rep)) {
1553 current->ChangeRepresentation(new_rep); 1549 value->ChangeRepresentation(new_rep);
1554 AddDependantsToWorklist(current); 1550 AddDependantsToWorklist(value);
1555 } 1551 }
1556 } 1552 }
1557 } 1553 }
1558 1554
1559 1555
1560 Representation HInferRepresentation::TryChange(HValue* current) { 1556 Representation HInferRepresentation::TryChange(HValue* value) {
1561 // Array of use counts for each representation. 1557 // Array of use counts for each representation.
1562 int use_count[Representation::kNumRepresentations]; 1558 int use_count[Representation::kNumRepresentations] = { 0 };
1563 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1564 use_count[i] = 0;
1565 }
1566 1559
1567 for (int i = 0; i < current->uses()->length(); ++i) { 1560 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
1568 HValue* use = current->uses()->at(i); 1561 HValue* use = it.value();
1569 int index = use->LookupOperandIndex(0, current); 1562 Representation rep = use->RequiredInputRepresentation(it.index());
1570 Representation req_rep = use->RequiredInputRepresentation(index); 1563 if (rep.IsNone()) continue;
1571 if (req_rep.IsNone()) continue; 1564 if (use->IsPhi()) HPhi::cast(use)->AddIndirectUsesTo(&use_count[0]);
1572 if (use->IsPhi()) { 1565 ++use_count[rep.kind()];
1573 HPhi* phi = HPhi::cast(use);
1574 phi->AddIndirectUsesTo(&use_count[0]);
1575 }
1576 use_count[req_rep.kind()]++;
1577 } 1566 }
1578 int tagged_count = use_count[Representation::kTagged]; 1567 int tagged_count = use_count[Representation::kTagged];
1579 int double_count = use_count[Representation::kDouble]; 1568 int double_count = use_count[Representation::kDouble];
1580 int int32_count = use_count[Representation::kInteger32]; 1569 int int32_count = use_count[Representation::kInteger32];
1581 int non_tagged_count = double_count + int32_count; 1570 int non_tagged_count = double_count + int32_count;
1582 1571
1583 // If a non-loop phi has tagged uses, don't convert it to untagged. 1572 // If a non-loop phi has tagged uses, don't convert it to untagged.
1584 if (current->IsPhi() && !current->block()->IsLoopHeader()) { 1573 if (value->IsPhi() && !value->block()->IsLoopHeader()) {
1585 if (tagged_count > 0) return Representation::None(); 1574 if (tagged_count > 0) return Representation::None();
1586 } 1575 }
1587 1576
1588 if (non_tagged_count >= tagged_count) { 1577 if (non_tagged_count >= tagged_count) {
1589 // More untagged than tagged. 1578 // More untagged than tagged.
1590 if (double_count > 0) { 1579 if (double_count > 0) {
1591 // There is at least one usage that is a double => guess that the 1580 // There is at least one usage that is a double => guess that the
1592 // correct representation is double. 1581 // correct representation is double.
1593 return Representation::Double(); 1582 return Representation::Double();
1594 } else if (int32_count > 0) { 1583 } else if (int32_count > 0) {
1595 return Representation::Integer32(); 1584 return Representation::Integer32();
1596 } 1585 }
1597 } 1586 }
1598 return Representation::None(); 1587 return Representation::None();
1599 } 1588 }
1600 1589
1601 1590
1602 void HInferRepresentation::Analyze() { 1591 void HInferRepresentation::Analyze() {
1603 HPhase phase("Infer representations", graph_); 1592 HPhase phase("Infer representations", graph_);
1604 1593
1605 // (1) Initialize bit vectors and count real uses. Each phi 1594 // (1) Initialize bit vectors and count real uses. Each phi gets a
1606 // gets a bit-vector of length <number of phis>. 1595 // bit-vector of length <number of phis>.
1607 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); 1596 const ZoneList<HPhi*>* phi_list = graph_->phi_list();
1608 int num_phis = phi_list->length(); 1597 int phi_count = phi_list->length();
1609 ScopedVector<BitVector*> connected_phis(num_phis); 1598 ScopedVector<BitVector*> connected_phis(phi_count);
1610 for (int i = 0; i < num_phis; i++) { 1599 for (int i = 0; i < phi_count; ++i) {
1611 phi_list->at(i)->InitRealUses(i); 1600 phi_list->at(i)->InitRealUses(i);
1612 connected_phis[i] = new(zone()) BitVector(num_phis); 1601 connected_phis[i] = new(zone()) BitVector(phi_count);
1613 connected_phis[i]->Add(i); 1602 connected_phis[i]->Add(i);
1614 } 1603 }
1615 1604
1616 // (2) Do a fixed point iteration to find the set of connected phis. 1605 // (2) Do a fixed point iteration to find the set of connected phis. A
1617 // A phi is connected to another phi if its value is used either 1606 // phi is connected to another phi if its value is used either directly or
1618 // directly or indirectly through a transitive closure of the def-use 1607 // indirectly through a transitive closure of the def-use relation.
1619 // relation.
1620 bool change = true; 1608 bool change = true;
1621 while (change) { 1609 while (change) {
1622 change = false; 1610 change = false;
1623 for (int i = 0; i < num_phis; i++) { 1611 for (int i = 0; i < phi_count; ++i) {
1624 HPhi* phi = phi_list->at(i); 1612 HPhi* phi = phi_list->at(i);
1625 for (int j = 0; j < phi->uses()->length(); j++) { 1613 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
1626 HValue* use = phi->uses()->at(j); 1614 HValue* use = it.value();
1627 if (use->IsPhi()) { 1615 if (use->IsPhi()) {
1628 int phi_use = HPhi::cast(use)->phi_id(); 1616 int id = HPhi::cast(use)->phi_id();
1629 if (connected_phis[i]->UnionIsChanged(*connected_phis[phi_use])) { 1617 change = change ||
1630 change = true; 1618 connected_phis[i]->UnionIsChanged(*connected_phis[id]);
1631 }
1632 } 1619 }
1633 } 1620 }
1634 } 1621 }
1635 } 1622 }
1636 1623
1637 // (3) Sum up the non-phi use counts of all connected phis. 1624 // (3) Sum up the non-phi use counts of all connected phis. Don't include
1638 // Don't include the non-phi uses of the phi itself. 1625 // the non-phi uses of the phi itself.
1639 for (int i = 0; i < num_phis; i++) { 1626 for (int i = 0; i < phi_count; ++i) {
1640 HPhi* phi = phi_list->at(i); 1627 HPhi* phi = phi_list->at(i);
1641 for (BitVector::Iterator it(connected_phis.at(i)); 1628 for (BitVector::Iterator it(connected_phis.at(i));
1642 !it.Done(); 1629 !it.Done();
1643 it.Advance()) { 1630 it.Advance()) {
1644 int index = it.Current(); 1631 int index = it.Current();
1645 if (index != i) { 1632 if (index != i) {
1646 HPhi* it_use = phi_list->at(it.Current()); 1633 HPhi* it_use = phi_list->at(it.Current());
1647 phi->AddNonPhiUsesFrom(it_use); 1634 phi->AddNonPhiUsesFrom(it_use);
1648 } 1635 }
1649 } 1636 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 PropagateMinusZeroChecks(div->left(), visited); 1726 PropagateMinusZeroChecks(div->left(), visited);
1740 PropagateMinusZeroChecks(div->right(), visited); 1727 PropagateMinusZeroChecks(div->right(), visited);
1741 } 1728 }
1742 1729
1743 current = current->EnsureAndPropagateNotMinusZero(visited); 1730 current = current->EnsureAndPropagateNotMinusZero(visited);
1744 } 1731 }
1745 } 1732 }
1746 1733
1747 1734
1748 void HGraph::InsertRepresentationChangeForUse(HValue* value, 1735 void HGraph::InsertRepresentationChangeForUse(HValue* value,
1749 HValue* use, 1736 HValue* use_value,
1737 int use_index,
1750 Representation to) { 1738 Representation to) {
1751 // Insert the representation change right before its use. For phi-uses we 1739 // Insert the representation change right before its use. For phi-uses we
1752 // insert at the end of the corresponding predecessor. 1740 // insert at the end of the corresponding predecessor.
1753 HInstruction* next = NULL; 1741 HInstruction* next = NULL;
1754 if (use->IsPhi()) { 1742 if (use_value->IsPhi()) {
1755 int index = 0; 1743 next = use_value->block()->predecessors()->at(use_index)->end();
1756 while (use->OperandAt(index) != value) ++index;
1757 next = use->block()->predecessors()->at(index)->end();
1758 } else { 1744 } else {
1759 next = HInstruction::cast(use); 1745 next = HInstruction::cast(use_value);
1760 } 1746 }
1761 1747
1762 // For constants we try to make the representation change at compile 1748 // For constants we try to make the representation change at compile
1763 // time. When a representation change is not possible without loss of 1749 // time. When a representation change is not possible without loss of
1764 // information we treat constants like normal instructions and insert the 1750 // information we treat constants like normal instructions and insert the
1765 // change instructions for them. 1751 // change instructions for them.
1766 HInstruction* new_value = NULL; 1752 HInstruction* new_value = NULL;
1767 bool is_truncating = use->CheckFlag(HValue::kTruncatingToInt32); 1753 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32);
1768 if (value->IsConstant()) { 1754 if (value->IsConstant()) {
1769 HConstant* constant = HConstant::cast(value); 1755 HConstant* constant = HConstant::cast(value);
1770 // Try to create a new copy of the constant with the new representation. 1756 // Try to create a new copy of the constant with the new representation.
1771 new_value = is_truncating 1757 new_value = is_truncating
1772 ? constant->CopyToTruncatedInt32() 1758 ? constant->CopyToTruncatedInt32()
1773 : constant->CopyToRepresentation(to); 1759 : constant->CopyToRepresentation(to);
1774 } 1760 }
1775 1761
1776 if (new_value == NULL) { 1762 if (new_value == NULL) {
1777 new_value = 1763 new_value =
1778 new(zone()) HChange(value, value->representation(), to, is_truncating); 1764 new(zone()) HChange(value, value->representation(), to, is_truncating);
1779 } 1765 }
1780 1766
1781 new_value->InsertBefore(next); 1767 new_value->InsertBefore(next);
1782 value->ReplaceFirstAtUse(use, new_value, to); 1768 use_value->SetOperandAt(use_index, new_value);
1783 } 1769 }
1784 1770
1785 1771
1786 int CompareConversionUses(HValue* a, 1772 void HGraph::InsertRepresentationChangesForValue(HValue* value) {
1787 HValue* b, 1773 Representation r = value->representation();
1788 Representation a_rep, 1774 if (r.IsNone()) return;
1789 Representation b_rep) { 1775 if (value->HasNoUses()) return;
1790 if (a_rep.kind() > b_rep.kind()) { 1776
1791 // Make sure specializations are separated in the result array. 1777 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
1792 return 1; 1778 HValue* use_value = it.value();
1779 int use_index = it.index();
1780 Representation req = use_value->RequiredInputRepresentation(use_index);
1781 if (req.IsNone() || req.Equals(r)) continue;
1782 InsertRepresentationChangeForUse(value, use_value, use_index, req);
1793 } 1783 }
1794 // Put truncating conversions before non-truncating conversions. 1784 if (value->HasNoUses()) {
1795 bool a_truncate = a->CheckFlag(HValue::kTruncatingToInt32); 1785 ASSERT(value->IsConstant());
1796 bool b_truncate = b->CheckFlag(HValue::kTruncatingToInt32); 1786 value->DeleteAndReplaceWith(NULL);
1797 if (a_truncate != b_truncate) {
1798 return a_truncate ? -1 : 1;
1799 } 1787 }
1800 // Sort by increasing block ID.
1801 return a->block()->block_id() - b->block()->block_id();
1802 } 1788 }
1803 1789
1804 1790
1805 void HGraph::InsertRepresentationChangesForValue(
1806 HValue* current,
1807 ZoneList<HValue*>* to_convert,
1808 ZoneList<Representation>* to_convert_reps) {
1809 Representation r = current->representation();
1810 if (r.IsNone()) return;
1811 if (current->uses()->is_empty()) return;
1812
1813 // Collect the representation changes in a sorted list. This allows
1814 // us to avoid duplicate changes without searching the list.
1815 ASSERT(to_convert->is_empty());
1816 ASSERT(to_convert_reps->is_empty());
1817 for (int i = 0; i < current->uses()->length(); ++i) {
1818 HValue* use = current->uses()->at(i);
1819 // The occurrences index means the index within the operand array of "use"
1820 // at which "current" is used. While iterating through the use array we
1821 // also have to iterate over the different occurrence indices.
1822 int occurrence_index = 0;
1823 if (use->UsesMultipleTimes(current)) {
1824 occurrence_index = current->uses()->CountOccurrences(use, 0, i - 1);
1825 if (FLAG_trace_representation) {
1826 PrintF("Instruction %d is used multiple times at %d; occurrence=%d\n",
1827 current->id(),
1828 use->id(),
1829 occurrence_index);
1830 }
1831 }
1832 int operand_index = use->LookupOperandIndex(occurrence_index, current);
1833 Representation req = use->RequiredInputRepresentation(operand_index);
1834 if (req.IsNone() || req.Equals(r)) continue;
1835 int index = 0;
1836 while (index < to_convert->length() &&
1837 CompareConversionUses(to_convert->at(index),
1838 use,
1839 to_convert_reps->at(index),
1840 req) < 0) {
1841 ++index;
1842 }
1843 if (FLAG_trace_representation) {
1844 PrintF("Inserting a representation change to %s of %d for use at %d\n",
1845 req.Mnemonic(),
1846 current->id(),
1847 use->id());
1848 }
1849 to_convert->InsertAt(index, use);
1850 to_convert_reps->InsertAt(index, req);
1851 }
1852
1853 for (int i = 0; i < to_convert->length(); ++i) {
1854 HValue* use = to_convert->at(i);
1855 Representation r_to = to_convert_reps->at(i);
1856 InsertRepresentationChangeForUse(current, use, r_to);
1857 }
1858
1859 if (current->uses()->is_empty()) {
1860 ASSERT(current->IsConstant());
1861 current->Delete();
1862 }
1863 to_convert->Rewind(0);
1864 to_convert_reps->Rewind(0);
1865 }
1866
1867
1868 void HGraph::InsertRepresentationChanges() { 1791 void HGraph::InsertRepresentationChanges() {
1869 HPhase phase("Insert representation changes", this); 1792 HPhase phase("Insert representation changes", this);
1870 1793
1871 1794
1872 // Compute truncation flag for phis: Initially assume that all 1795 // Compute truncation flag for phis: Initially assume that all
1873 // int32-phis allow truncation and iteratively remove the ones that 1796 // int32-phis allow truncation and iteratively remove the ones that
1874 // are used in an operation that does not allow a truncating 1797 // are used in an operation that does not allow a truncating
1875 // conversion. 1798 // conversion.
1876 // TODO(fschneider): Replace this with a worklist-based iteration. 1799 // TODO(fschneider): Replace this with a worklist-based iteration.
1877 for (int i = 0; i < phi_list()->length(); i++) { 1800 for (int i = 0; i < phi_list()->length(); i++) {
1878 HPhi* phi = phi_list()->at(i); 1801 HPhi* phi = phi_list()->at(i);
1879 if (phi->representation().IsInteger32()) { 1802 if (phi->representation().IsInteger32()) {
1880 phi->SetFlag(HValue::kTruncatingToInt32); 1803 phi->SetFlag(HValue::kTruncatingToInt32);
1881 } 1804 }
1882 } 1805 }
1883 bool change = true; 1806 bool change = true;
1884 while (change) { 1807 while (change) {
1885 change = false; 1808 change = false;
1886 for (int i = 0; i < phi_list()->length(); i++) { 1809 for (int i = 0; i < phi_list()->length(); i++) {
1887 HPhi* phi = phi_list()->at(i); 1810 HPhi* phi = phi_list()->at(i);
1888 if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue; 1811 if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue;
1889 for (int j = 0; j < phi->uses()->length(); j++) { 1812 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
1890 HValue* use = phi->uses()->at(j); 1813 HValue* use = it.value();
1891 if (!use->CheckFlag(HValue::kTruncatingToInt32)) { 1814 if (!use->CheckFlag(HValue::kTruncatingToInt32)) {
1892 phi->ClearFlag(HValue::kTruncatingToInt32); 1815 phi->ClearFlag(HValue::kTruncatingToInt32);
1893 change = true; 1816 change = true;
1894 break; 1817 break;
1895 } 1818 }
1896 } 1819 }
1897 } 1820 }
1898 } 1821 }
1899 1822
1900 ZoneList<HValue*> value_list(4);
1901 ZoneList<Representation> rep_list(4);
1902 for (int i = 0; i < blocks_.length(); ++i) { 1823 for (int i = 0; i < blocks_.length(); ++i) {
1903 // Process phi instructions first. 1824 // Process phi instructions first.
1904 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { 1825 const ZoneList<HPhi*>* phis = blocks_[i]->phis();
1905 HPhi* phi = blocks_[i]->phis()->at(j); 1826 for (int j = 0; j < phis->length(); j++) {
1906 InsertRepresentationChangesForValue(phi, &value_list, &rep_list); 1827 InsertRepresentationChangesForValue(phis->at(j));
1907 } 1828 }
1908 1829
1909 // Process normal instructions. 1830 // Process normal instructions.
1910 HInstruction* current = blocks_[i]->first(); 1831 HInstruction* current = blocks_[i]->first();
1911 while (current != NULL) { 1832 while (current != NULL) {
1912 InsertRepresentationChangesForValue(current, &value_list, &rep_list); 1833 InsertRepresentationChangesForValue(current);
1913 current = current->next(); 1834 current = current->next();
1914 } 1835 }
1915 } 1836 }
1916 } 1837 }
1917 1838
1918 1839
1919 void HGraph::ComputeMinusZeroChecks() { 1840 void HGraph::ComputeMinusZeroChecks() {
1920 BitVector visited(GetMaximumValueID()); 1841 BitVector visited(GetMaximumValueID());
1921 for (int i = 0; i < blocks_.length(); ++i) { 1842 for (int i = 0; i < blocks_.length(); ++i) {
1922 for (HInstruction* current = blocks_[i]->first(); 1843 for (HInstruction* current = blocks_[i]->first();
(...skipping 3254 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 // assumed to stay the same for this instanceof. 5098 // assumed to stay the same for this instanceof.
5178 if (target.is_null()) { 5099 if (target.is_null()) {
5179 HContext* context = new(zone()) HContext; 5100 HContext* context = new(zone()) HContext;
5180 AddInstruction(context); 5101 AddInstruction(context);
5181 instr = new(zone()) HInstanceOf(context, left, right); 5102 instr = new(zone()) HInstanceOf(context, left, right);
5182 } else { 5103 } else {
5183 AddInstruction(new(zone()) HCheckFunction(right, target)); 5104 AddInstruction(new(zone()) HCheckFunction(right, target));
5184 instr = new(zone()) HInstanceOfKnownGlobal(left, target); 5105 instr = new(zone()) HInstanceOfKnownGlobal(left, target);
5185 } 5106 }
5186 } else if (op == Token::IN) { 5107 } else if (op == Token::IN) {
5187 return Bailout("Unsupported comparison: in"); 5108 instr = new(zone()) HIn(left, right);
5188 } else if (type_info.IsNonPrimitive()) { 5109 } else if (type_info.IsNonPrimitive()) {
5189 switch (op) { 5110 switch (op) {
5190 case Token::EQ: 5111 case Token::EQ:
5191 case Token::EQ_STRICT: { 5112 case Token::EQ_STRICT: {
5192 AddInstruction(new(zone()) HCheckNonSmi(left)); 5113 AddInstruction(new(zone()) HCheckNonSmi(left));
5193 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left)); 5114 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
5194 AddInstruction(new(zone()) HCheckNonSmi(right)); 5115 AddInstruction(new(zone()) HCheckNonSmi(right));
5195 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right)); 5116 AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
5196 instr = new(zone()) HCompareJSObjectEq(left, right); 5117 instr = new(zone()) HCompareJSObjectEq(left, right);
5197 break; 5118 break;
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
5936 phi->PrintTo(&trace_); 5857 phi->PrintTo(&trace_);
5937 trace_.Add("\n"); 5858 trace_.Add("\n");
5938 } 5859 }
5939 } 5860 }
5940 5861
5941 { 5862 {
5942 Tag HIR_tag(this, "HIR"); 5863 Tag HIR_tag(this, "HIR");
5943 HInstruction* instruction = current->first(); 5864 HInstruction* instruction = current->first();
5944 while (instruction != NULL) { 5865 while (instruction != NULL) {
5945 int bci = 0; 5866 int bci = 0;
5946 int uses = instruction->uses()->length(); 5867 int uses = instruction->UseCount();
5947 trace_.Add("%d %d ", bci, uses); 5868 trace_.Add("%d %d ", bci, uses);
5948 instruction->PrintNameTo(&trace_); 5869 instruction->PrintNameTo(&trace_);
5949 trace_.Add(" "); 5870 trace_.Add(" ");
5950 instruction->PrintTo(&trace_); 5871 instruction->PrintTo(&trace_);
5951 trace_.Add(" <|@\n"); 5872 trace_.Add(" <|@\n");
5952 instruction = instruction->next(); 5873 instruction = instruction->next();
5953 } 5874 }
5954 } 5875 }
5955 5876
5956 5877
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
6150 } 6071 }
6151 } 6072 }
6152 6073
6153 #ifdef DEBUG 6074 #ifdef DEBUG
6154 if (graph_ != NULL) graph_->Verify(); 6075 if (graph_ != NULL) graph_->Verify();
6155 if (allocator_ != NULL) allocator_->Verify(); 6076 if (allocator_ != NULL) allocator_->Verify();
6156 #endif 6077 #endif
6157 } 6078 }
6158 6079
6159 } } // namespace v8::internal 6080 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698