| OLD | NEW |
| 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 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 | 723 |
| 724 HBasicBlock* HGraph::CreateBasicBlock() { | 724 HBasicBlock* HGraph::CreateBasicBlock() { |
| 725 HBasicBlock* result = new(zone()) HBasicBlock(this); | 725 HBasicBlock* result = new(zone()) HBasicBlock(this); |
| 726 blocks_.Add(result); | 726 blocks_.Add(result); |
| 727 return result; | 727 return result; |
| 728 } | 728 } |
| 729 | 729 |
| 730 | 730 |
| 731 void HGraph::Canonicalize() { | 731 void HGraph::Canonicalize() { |
| 732 if (!FLAG_use_canonicalizing) return; | 732 if (!FLAG_use_canonicalizing) return; |
| 733 HPhase phase("H Canonicalize", this); | 733 HPhase phase("H_Canonicalize", this); |
| 734 for (int i = 0; i < blocks()->length(); ++i) { | 734 for (int i = 0; i < blocks()->length(); ++i) { |
| 735 HInstruction* instr = blocks()->at(i)->first(); | 735 HInstruction* instr = blocks()->at(i)->first(); |
| 736 while (instr != NULL) { | 736 while (instr != NULL) { |
| 737 HValue* value = instr->Canonicalize(); | 737 HValue* value = instr->Canonicalize(); |
| 738 if (value != instr) instr->DeleteAndReplaceWith(value); | 738 if (value != instr) instr->DeleteAndReplaceWith(value); |
| 739 instr = instr->next(); | 739 instr = instr->next(); |
| 740 } | 740 } |
| 741 } | 741 } |
| 742 } | 742 } |
| 743 | 743 |
| 744 | 744 |
| 745 void HGraph::OrderBlocks() { | 745 void HGraph::OrderBlocks() { |
| 746 HPhase phase("H Block ordering"); | 746 HPhase phase("H_Block ordering"); |
| 747 BitVector visited(blocks_.length(), zone()); | 747 BitVector visited(blocks_.length(), zone()); |
| 748 | 748 |
| 749 ZoneList<HBasicBlock*> reverse_result(8); | 749 ZoneList<HBasicBlock*> reverse_result(8); |
| 750 HBasicBlock* start = blocks_[0]; | 750 HBasicBlock* start = blocks_[0]; |
| 751 Postorder(start, &visited, &reverse_result, NULL); | 751 Postorder(start, &visited, &reverse_result, NULL); |
| 752 | 752 |
| 753 blocks_.Rewind(0); | 753 blocks_.Rewind(0); |
| 754 int index = 0; | 754 int index = 0; |
| 755 for (int i = reverse_result.length() - 1; i >= 0; --i) { | 755 for (int i = reverse_result.length() - 1; i >= 0; --i) { |
| 756 HBasicBlock* b = reverse_result[i]; | 756 HBasicBlock* b = reverse_result[i]; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 order->Contains(block->end()->FirstSuccessor()) || | 798 order->Contains(block->end()->FirstSuccessor()) || |
| 799 block->end()->FirstSuccessor()->IsLoopHeader()); | 799 block->end()->FirstSuccessor()->IsLoopHeader()); |
| 800 ASSERT(block->end()->SecondSuccessor() == NULL || | 800 ASSERT(block->end()->SecondSuccessor() == NULL || |
| 801 order->Contains(block->end()->SecondSuccessor()) || | 801 order->Contains(block->end()->SecondSuccessor()) || |
| 802 block->end()->SecondSuccessor()->IsLoopHeader()); | 802 block->end()->SecondSuccessor()->IsLoopHeader()); |
| 803 order->Add(block); | 803 order->Add(block); |
| 804 } | 804 } |
| 805 | 805 |
| 806 | 806 |
| 807 void HGraph::AssignDominators() { | 807 void HGraph::AssignDominators() { |
| 808 HPhase phase("H Assign dominators", this); | 808 HPhase phase("H_Assign dominators", this); |
| 809 for (int i = 0; i < blocks_.length(); ++i) { | 809 for (int i = 0; i < blocks_.length(); ++i) { |
| 810 HBasicBlock* block = blocks_[i]; | 810 HBasicBlock* block = blocks_[i]; |
| 811 if (block->IsLoopHeader()) { | 811 if (block->IsLoopHeader()) { |
| 812 // Only the first predecessor of a loop header is from outside the loop. | 812 // Only the first predecessor of a loop header is from outside the loop. |
| 813 // All others are back edges, and thus cannot dominate the loop header. | 813 // All others are back edges, and thus cannot dominate the loop header. |
| 814 block->AssignCommonDominator(block->predecessors()->first()); | 814 block->AssignCommonDominator(block->predecessors()->first()); |
| 815 block->AssignLoopSuccessorDominators(); | 815 block->AssignLoopSuccessorDominators(); |
| 816 } else { | 816 } else { |
| 817 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { | 817 for (int j = blocks_[i]->predecessors()->length() - 1; j >= 0; --j) { |
| 818 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); | 818 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); |
| 819 } | 819 } |
| 820 } | 820 } |
| 821 } | 821 } |
| 822 } | 822 } |
| 823 | 823 |
| 824 // Mark all blocks that are dominated by an unconditional soft deoptimize to | 824 // Mark all blocks that are dominated by an unconditional soft deoptimize to |
| 825 // prevent code motion across those blocks. | 825 // prevent code motion across those blocks. |
| 826 void HGraph::PropagateDeoptimizingMark() { | 826 void HGraph::PropagateDeoptimizingMark() { |
| 827 HPhase phase("H Propagate deoptimizing mark", this); | 827 HPhase phase("H_Propagate deoptimizing mark", this); |
| 828 MarkAsDeoptimizingRecursively(entry_block()); | 828 MarkAsDeoptimizingRecursively(entry_block()); |
| 829 } | 829 } |
| 830 | 830 |
| 831 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) { | 831 void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) { |
| 832 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 832 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
| 833 HBasicBlock* dominated = block->dominated_blocks()->at(i); | 833 HBasicBlock* dominated = block->dominated_blocks()->at(i); |
| 834 if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing(); | 834 if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing(); |
| 835 MarkAsDeoptimizingRecursively(dominated); | 835 MarkAsDeoptimizingRecursively(dominated); |
| 836 } | 836 } |
| 837 } | 837 } |
| 838 | 838 |
| 839 void HGraph::EliminateRedundantPhis() { | 839 void HGraph::EliminateRedundantPhis() { |
| 840 HPhase phase("H Redundant phi elimination", this); | 840 HPhase phase("H_Redundant phi elimination", this); |
| 841 | 841 |
| 842 // Worklist of phis that can potentially be eliminated. Initialized with | 842 // Worklist of phis that can potentially be eliminated. Initialized with |
| 843 // all phi nodes. When elimination of a phi node modifies another phi node | 843 // all phi nodes. When elimination of a phi node modifies another phi node |
| 844 // the modified phi node is added to the worklist. | 844 // the modified phi node is added to the worklist. |
| 845 ZoneList<HPhi*> worklist(blocks_.length()); | 845 ZoneList<HPhi*> worklist(blocks_.length()); |
| 846 for (int i = 0; i < blocks_.length(); ++i) { | 846 for (int i = 0; i < blocks_.length(); ++i) { |
| 847 worklist.AddAll(*blocks_[i]->phis()); | 847 worklist.AddAll(*blocks_[i]->phis()); |
| 848 } | 848 } |
| 849 | 849 |
| 850 while (!worklist.is_empty()) { | 850 while (!worklist.is_empty()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 864 value->SetOperandAt(it.index(), replacement); | 864 value->SetOperandAt(it.index(), replacement); |
| 865 if (value->IsPhi()) worklist.Add(HPhi::cast(value)); | 865 if (value->IsPhi()) worklist.Add(HPhi::cast(value)); |
| 866 } | 866 } |
| 867 block->RemovePhi(phi); | 867 block->RemovePhi(phi); |
| 868 } | 868 } |
| 869 } | 869 } |
| 870 } | 870 } |
| 871 | 871 |
| 872 | 872 |
| 873 void HGraph::EliminateUnreachablePhis() { | 873 void HGraph::EliminateUnreachablePhis() { |
| 874 HPhase phase("H Unreachable phi elimination", this); | 874 HPhase phase("H_Unreachable phi elimination", this); |
| 875 | 875 |
| 876 // Initialize worklist. | 876 // Initialize worklist. |
| 877 ZoneList<HPhi*> phi_list(blocks_.length()); | 877 ZoneList<HPhi*> phi_list(blocks_.length()); |
| 878 ZoneList<HPhi*> worklist(blocks_.length()); | 878 ZoneList<HPhi*> worklist(blocks_.length()); |
| 879 for (int i = 0; i < blocks_.length(); ++i) { | 879 for (int i = 0; i < blocks_.length(); ++i) { |
| 880 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { | 880 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { |
| 881 HPhi* phi = blocks_[i]->phis()->at(j); | 881 HPhi* phi = blocks_[i]->phis()->at(j); |
| 882 phi_list.Add(phi); | 882 phi_list.Add(phi); |
| 883 // We can't eliminate phis in the receiver position in the environment | 883 // We can't eliminate phis in the receiver position in the environment |
| 884 // because in case of throwing an error we need this value to | 884 // because in case of throwing an error we need this value to |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 if (FLAG_trace_range) { | 1003 if (FLAG_trace_range) { |
| 1004 va_list arguments; | 1004 va_list arguments; |
| 1005 va_start(arguments, msg); | 1005 va_start(arguments, msg); |
| 1006 OS::VPrint(msg, arguments); | 1006 OS::VPrint(msg, arguments); |
| 1007 va_end(arguments); | 1007 va_end(arguments); |
| 1008 } | 1008 } |
| 1009 } | 1009 } |
| 1010 | 1010 |
| 1011 | 1011 |
| 1012 void HRangeAnalysis::Analyze() { | 1012 void HRangeAnalysis::Analyze() { |
| 1013 HPhase phase("H Range analysis", graph_); | 1013 HPhase phase("H_Range analysis", graph_); |
| 1014 Analyze(graph_->entry_block()); | 1014 Analyze(graph_->entry_block()); |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 | 1017 |
| 1018 void HRangeAnalysis::Analyze(HBasicBlock* block) { | 1018 void HRangeAnalysis::Analyze(HBasicBlock* block) { |
| 1019 TraceRange("Analyzing block B%d\n", block->block_id()); | 1019 TraceRange("Analyzing block B%d\n", block->block_id()); |
| 1020 | 1020 |
| 1021 int last_changed_range = changed_ranges_.length() - 1; | 1021 int last_changed_range = changed_ranges_.length() - 1; |
| 1022 | 1022 |
| 1023 // Infer range based on control flow. | 1023 // Infer range based on control flow. |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1824 return Representation::Integer32(); | 1824 return Representation::Integer32(); |
| 1825 } | 1825 } |
| 1826 | 1826 |
| 1827 if (double_count > 0) return Representation::Double(); | 1827 if (double_count > 0) return Representation::Double(); |
| 1828 | 1828 |
| 1829 return Representation::None(); | 1829 return Representation::None(); |
| 1830 } | 1830 } |
| 1831 | 1831 |
| 1832 | 1832 |
| 1833 void HInferRepresentation::Analyze() { | 1833 void HInferRepresentation::Analyze() { |
| 1834 HPhase phase("H Infer representations", graph_); | 1834 HPhase phase("H_Infer representations", graph_); |
| 1835 | 1835 |
| 1836 // (1) Initialize bit vectors and count real uses. Each phi gets a | 1836 // (1) Initialize bit vectors and count real uses. Each phi gets a |
| 1837 // bit-vector of length <number of phis>. | 1837 // bit-vector of length <number of phis>. |
| 1838 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); | 1838 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
| 1839 int phi_count = phi_list->length(); | 1839 int phi_count = phi_list->length(); |
| 1840 ZoneList<BitVector*> connected_phis(phi_count); | 1840 ZoneList<BitVector*> connected_phis(phi_count); |
| 1841 for (int i = 0; i < phi_count; ++i) { | 1841 for (int i = 0; i < phi_count; ++i) { |
| 1842 phi_list->at(i)->InitRealUses(i); | 1842 phi_list->at(i)->InitRealUses(i); |
| 1843 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); | 1843 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); |
| 1844 connected_set->Add(i); | 1844 connected_set->Add(i); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 while (!worklist_.is_empty()) { | 1903 while (!worklist_.is_empty()) { |
| 1904 HValue* current = worklist_.RemoveLast(); | 1904 HValue* current = worklist_.RemoveLast(); |
| 1905 in_worklist_.Remove(current->id()); | 1905 in_worklist_.Remove(current->id()); |
| 1906 InferBasedOnInputs(current); | 1906 InferBasedOnInputs(current); |
| 1907 InferBasedOnUses(current); | 1907 InferBasedOnUses(current); |
| 1908 } | 1908 } |
| 1909 } | 1909 } |
| 1910 | 1910 |
| 1911 | 1911 |
| 1912 void HGraph::InitializeInferredTypes() { | 1912 void HGraph::InitializeInferredTypes() { |
| 1913 HPhase phase("H Inferring types", this); | 1913 HPhase phase("H_Inferring types", this); |
| 1914 InitializeInferredTypes(0, this->blocks_.length() - 1); | 1914 InitializeInferredTypes(0, this->blocks_.length() - 1); |
| 1915 } | 1915 } |
| 1916 | 1916 |
| 1917 | 1917 |
| 1918 void HGraph::InitializeInferredTypes(int from_inclusive, int to_inclusive) { | 1918 void HGraph::InitializeInferredTypes(int from_inclusive, int to_inclusive) { |
| 1919 for (int i = from_inclusive; i <= to_inclusive; ++i) { | 1919 for (int i = from_inclusive; i <= to_inclusive; ++i) { |
| 1920 HBasicBlock* block = blocks_[i]; | 1920 HBasicBlock* block = blocks_[i]; |
| 1921 | 1921 |
| 1922 const ZoneList<HPhi*>* phis = block->phis(); | 1922 const ZoneList<HPhi*>* phis = block->phis(); |
| 1923 for (int j = 0; j < phis->length(); j++) { | 1923 for (int j = 0; j < phis->length(); j++) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 | 2040 |
| 2041 // The only purpose of a HForceRepresentation is to represent the value | 2041 // The only purpose of a HForceRepresentation is to represent the value |
| 2042 // after the (possible) HChange instruction. We make it disappear. | 2042 // after the (possible) HChange instruction. We make it disappear. |
| 2043 if (value->IsForceRepresentation()) { | 2043 if (value->IsForceRepresentation()) { |
| 2044 value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); | 2044 value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); |
| 2045 } | 2045 } |
| 2046 } | 2046 } |
| 2047 | 2047 |
| 2048 | 2048 |
| 2049 void HGraph::InsertRepresentationChanges() { | 2049 void HGraph::InsertRepresentationChanges() { |
| 2050 HPhase phase("H Insert representation changes", this); | 2050 HPhase phase("H_Insert representation changes", this); |
| 2051 | 2051 |
| 2052 | 2052 |
| 2053 // Compute truncation flag for phis: Initially assume that all | 2053 // Compute truncation flag for phis: Initially assume that all |
| 2054 // int32-phis allow truncation and iteratively remove the ones that | 2054 // int32-phis allow truncation and iteratively remove the ones that |
| 2055 // are used in an operation that does not allow a truncating | 2055 // are used in an operation that does not allow a truncating |
| 2056 // conversion. | 2056 // conversion. |
| 2057 // TODO(fschneider): Replace this with a worklist-based iteration. | 2057 // TODO(fschneider): Replace this with a worklist-based iteration. |
| 2058 for (int i = 0; i < phi_list()->length(); i++) { | 2058 for (int i = 0; i < phi_list()->length(); i++) { |
| 2059 HPhi* phi = phi_list()->at(i); | 2059 HPhi* phi = phi_list()->at(i); |
| 2060 if (phi->representation().IsInteger32()) { | 2060 if (phi->representation().IsInteger32()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2097 for (int i = 0; i < phi->OperandCount(); ++i) { | 2097 for (int i = 0; i < phi->OperandCount(); ++i) { |
| 2098 HValue* input = phi->OperandAt(i); | 2098 HValue* input = phi->OperandAt(i); |
| 2099 if (input->IsPhi()) { | 2099 if (input->IsPhi()) { |
| 2100 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); | 2100 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
| 2101 } | 2101 } |
| 2102 } | 2102 } |
| 2103 } | 2103 } |
| 2104 | 2104 |
| 2105 | 2105 |
| 2106 void HGraph::MarkDeoptimizeOnUndefined() { | 2106 void HGraph::MarkDeoptimizeOnUndefined() { |
| 2107 HPhase phase("H MarkDeoptimizeOnUndefined", this); | 2107 HPhase phase("H_MarkDeoptimizeOnUndefined", this); |
| 2108 // Compute DeoptimizeOnUndefined flag for phis. | 2108 // Compute DeoptimizeOnUndefined flag for phis. |
| 2109 // Any phi that can reach a use with DeoptimizeOnUndefined set must | 2109 // Any phi that can reach a use with DeoptimizeOnUndefined set must |
| 2110 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with | 2110 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with |
| 2111 // double input representation, has this flag set. | 2111 // double input representation, has this flag set. |
| 2112 // The flag is used by HChange tagged->double, which must deoptimize | 2112 // The flag is used by HChange tagged->double, which must deoptimize |
| 2113 // if one of its uses has this flag set. | 2113 // if one of its uses has this flag set. |
| 2114 for (int i = 0; i < phi_list()->length(); i++) { | 2114 for (int i = 0; i < phi_list()->length(); i++) { |
| 2115 HPhi* phi = phi_list()->at(i); | 2115 HPhi* phi = phi_list()->at(i); |
| 2116 if (phi->representation().IsDouble()) { | 2116 if (phi->representation().IsDouble()) { |
| 2117 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | 2117 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2423 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 2423 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
| 2424 } | 2424 } |
| 2425 } | 2425 } |
| 2426 | 2426 |
| 2427 | 2427 |
| 2428 HGraph* HGraphBuilder::CreateGraph() { | 2428 HGraph* HGraphBuilder::CreateGraph() { |
| 2429 graph_ = new(zone()) HGraph(info()); | 2429 graph_ = new(zone()) HGraph(info()); |
| 2430 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 2430 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
| 2431 | 2431 |
| 2432 { | 2432 { |
| 2433 HPhase phase("H Block building"); | 2433 HPhase phase("H_Block building"); |
| 2434 current_block_ = graph()->entry_block(); | 2434 current_block_ = graph()->entry_block(); |
| 2435 | 2435 |
| 2436 Scope* scope = info()->scope(); | 2436 Scope* scope = info()->scope(); |
| 2437 if (scope->HasIllegalRedeclaration()) { | 2437 if (scope->HasIllegalRedeclaration()) { |
| 2438 Bailout("function with illegal redeclaration"); | 2438 Bailout("function with illegal redeclaration"); |
| 2439 return NULL; | 2439 return NULL; |
| 2440 } | 2440 } |
| 2441 SetUpScope(scope); | 2441 SetUpScope(scope); |
| 2442 | 2442 |
| 2443 // Add an edge to the body entry. This is warty: the graph's start | 2443 // Add an edge to the body entry. This is warty: the graph's start |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2508 rep.Analyze(); | 2508 rep.Analyze(); |
| 2509 | 2509 |
| 2510 graph()->MarkDeoptimizeOnUndefined(); | 2510 graph()->MarkDeoptimizeOnUndefined(); |
| 2511 graph()->InsertRepresentationChanges(); | 2511 graph()->InsertRepresentationChanges(); |
| 2512 | 2512 |
| 2513 graph()->InitializeInferredTypes(); | 2513 graph()->InitializeInferredTypes(); |
| 2514 graph()->Canonicalize(); | 2514 graph()->Canonicalize(); |
| 2515 | 2515 |
| 2516 // Perform common subexpression elimination and loop-invariant code motion. | 2516 // Perform common subexpression elimination and loop-invariant code motion. |
| 2517 if (FLAG_use_gvn) { | 2517 if (FLAG_use_gvn) { |
| 2518 HPhase phase("H Global value numbering", graph()); | 2518 HPhase phase("H_Global value numbering", graph()); |
| 2519 HGlobalValueNumberer gvn(graph(), info()); | 2519 HGlobalValueNumberer gvn(graph(), info()); |
| 2520 bool removed_side_effects = gvn.Analyze(); | 2520 bool removed_side_effects = gvn.Analyze(); |
| 2521 // Trigger a second analysis pass to further eliminate duplicate values that | 2521 // Trigger a second analysis pass to further eliminate duplicate values that |
| 2522 // could only be discovered by removing side-effect-generating instructions | 2522 // could only be discovered by removing side-effect-generating instructions |
| 2523 // during the first pass. | 2523 // during the first pass. |
| 2524 if (FLAG_smi_only_arrays && removed_side_effects) { | 2524 if (FLAG_smi_only_arrays && removed_side_effects) { |
| 2525 removed_side_effects = gvn.Analyze(); | 2525 removed_side_effects = gvn.Analyze(); |
| 2526 ASSERT(!removed_side_effects); | 2526 ASSERT(!removed_side_effects); |
| 2527 } | 2527 } |
| 2528 } | 2528 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2541 // result is used. This is safe now, since we don't do code motion after this | 2541 // result is used. This is safe now, since we don't do code motion after this |
| 2542 // point. It enables better register allocation since the value produced by | 2542 // point. It enables better register allocation since the value produced by |
| 2543 // check instructions is really a copy of the original value. | 2543 // check instructions is really a copy of the original value. |
| 2544 graph()->ReplaceCheckedValues(); | 2544 graph()->ReplaceCheckedValues(); |
| 2545 | 2545 |
| 2546 return graph(); | 2546 return graph(); |
| 2547 } | 2547 } |
| 2548 | 2548 |
| 2549 | 2549 |
| 2550 void HGraph::ReplaceCheckedValues() { | 2550 void HGraph::ReplaceCheckedValues() { |
| 2551 HPhase phase("H Replace checked values", this); | 2551 HPhase phase("H_Replace checked values", this); |
| 2552 for (int i = 0; i < blocks()->length(); ++i) { | 2552 for (int i = 0; i < blocks()->length(); ++i) { |
| 2553 HInstruction* instr = blocks()->at(i)->first(); | 2553 HInstruction* instr = blocks()->at(i)->first(); |
| 2554 while (instr != NULL) { | 2554 while (instr != NULL) { |
| 2555 if (instr->IsBoundsCheck()) { | 2555 if (instr->IsBoundsCheck()) { |
| 2556 // Replace all uses of the checked value with the original input. | 2556 // Replace all uses of the checked value with the original input. |
| 2557 ASSERT(instr->UseCount() > 0); | 2557 ASSERT(instr->UseCount() > 0); |
| 2558 instr->ReplaceAllUsesWith(HBoundsCheck::cast(instr)->index()); | 2558 instr->ReplaceAllUsesWith(HBoundsCheck::cast(instr)->index()); |
| 2559 } | 2559 } |
| 2560 instr = instr->next(); | 2560 instr = instr->next(); |
| 2561 } | 2561 } |
| (...skipping 5483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8045 } | 8045 } |
| 8046 } | 8046 } |
| 8047 | 8047 |
| 8048 #ifdef DEBUG | 8048 #ifdef DEBUG |
| 8049 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8049 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 8050 if (allocator_ != NULL) allocator_->Verify(); | 8050 if (allocator_ != NULL) allocator_->Verify(); |
| 8051 #endif | 8051 #endif |
| 8052 } | 8052 } |
| 8053 | 8053 |
| 8054 } } // namespace v8::internal | 8054 } } // namespace v8::internal |
| OLD | NEW |