OLD | NEW |
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 1832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1843 } else { | 1843 } else { |
1844 next = HInstruction::cast(use_value); | 1844 next = HInstruction::cast(use_value); |
1845 } | 1845 } |
1846 | 1846 |
1847 // For constants we try to make the representation change at compile | 1847 // For constants we try to make the representation change at compile |
1848 // time. When a representation change is not possible without loss of | 1848 // time. When a representation change is not possible without loss of |
1849 // information we treat constants like normal instructions and insert the | 1849 // information we treat constants like normal instructions and insert the |
1850 // change instructions for them. | 1850 // change instructions for them. |
1851 HInstruction* new_value = NULL; | 1851 HInstruction* new_value = NULL; |
1852 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 1852 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
| 1853 bool deoptimize_on_undefined = |
| 1854 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); |
1853 if (value->IsConstant()) { | 1855 if (value->IsConstant()) { |
1854 HConstant* constant = HConstant::cast(value); | 1856 HConstant* constant = HConstant::cast(value); |
1855 // Try to create a new copy of the constant with the new representation. | 1857 // Try to create a new copy of the constant with the new representation. |
1856 new_value = is_truncating | 1858 new_value = is_truncating |
1857 ? constant->CopyToTruncatedInt32() | 1859 ? constant->CopyToTruncatedInt32() |
1858 : constant->CopyToRepresentation(to); | 1860 : constant->CopyToRepresentation(to); |
1859 } | 1861 } |
1860 | 1862 |
1861 if (new_value == NULL) { | 1863 if (new_value == NULL) { |
1862 new_value = | 1864 new_value = new(zone()) HChange(value, value->representation(), to, |
1863 new(zone()) HChange(value, value->representation(), to, is_truncating); | 1865 is_truncating, deoptimize_on_undefined); |
1864 } | 1866 } |
1865 | 1867 |
1866 new_value->InsertBefore(next); | 1868 new_value->InsertBefore(next); |
1867 use_value->SetOperandAt(use_index, new_value); | 1869 use_value->SetOperandAt(use_index, new_value); |
1868 } | 1870 } |
1869 | 1871 |
1870 | 1872 |
1871 void HGraph::InsertRepresentationChangesForValue(HValue* value) { | 1873 void HGraph::InsertRepresentationChangesForValue(HValue* value) { |
1872 Representation r = value->representation(); | 1874 Representation r = value->representation(); |
1873 if (r.IsNone()) return; | 1875 if (r.IsNone()) return; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 // Process normal instructions. | 1937 // Process normal instructions. |
1936 HInstruction* current = blocks_[i]->first(); | 1938 HInstruction* current = blocks_[i]->first(); |
1937 while (current != NULL) { | 1939 while (current != NULL) { |
1938 InsertRepresentationChangesForValue(current); | 1940 InsertRepresentationChangesForValue(current); |
1939 current = current->next(); | 1941 current = current->next(); |
1940 } | 1942 } |
1941 } | 1943 } |
1942 } | 1944 } |
1943 | 1945 |
1944 | 1946 |
| 1947 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { |
| 1948 if (phi->CheckFlag(HValue::kDeoptimizeOnUndefined)) return; |
| 1949 phi->SetFlag(HValue::kDeoptimizeOnUndefined); |
| 1950 for (int i = 0; i < phi->OperandCount(); ++i) { |
| 1951 HValue* input = phi->OperandAt(i); |
| 1952 if (input->IsPhi()) { |
| 1953 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
| 1954 } |
| 1955 } |
| 1956 } |
| 1957 |
| 1958 |
| 1959 void HGraph::MarkDeoptimizeOnUndefined() { |
| 1960 HPhase phase("MarkDeoptimizeOnUndefined", this); |
| 1961 // Compute DeoptimizeOnUndefined flag for phis. |
| 1962 // Any phi that can reach a use with DeoptimizeOnUndefined set must |
| 1963 // have DeoptimizeOnUndefined set. Currently only HCompare, with |
| 1964 // double input representation, has this flag set. |
| 1965 // The flag is used by HChange tagged->double, which must deoptimize |
| 1966 // if one of its uses has this flag set. |
| 1967 for (int i = 0; i < phi_list()->length(); i++) { |
| 1968 HPhi* phi = phi_list()->at(i); |
| 1969 if (phi->representation().IsDouble()) { |
| 1970 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
| 1971 if (it.value()->CheckFlag(HValue::kDeoptimizeOnUndefined)) { |
| 1972 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); |
| 1973 break; |
| 1974 } |
| 1975 } |
| 1976 } |
| 1977 } |
| 1978 } |
| 1979 |
| 1980 |
1945 void HGraph::ComputeMinusZeroChecks() { | 1981 void HGraph::ComputeMinusZeroChecks() { |
1946 BitVector visited(GetMaximumValueID()); | 1982 BitVector visited(GetMaximumValueID()); |
1947 for (int i = 0; i < blocks_.length(); ++i) { | 1983 for (int i = 0; i < blocks_.length(); ++i) { |
1948 for (HInstruction* current = blocks_[i]->first(); | 1984 for (HInstruction* current = blocks_[i]->first(); |
1949 current != NULL; | 1985 current != NULL; |
1950 current = current->next()) { | 1986 current = current->next()) { |
1951 if (current->IsChange()) { | 1987 if (current->IsChange()) { |
1952 HChange* change = HChange::cast(current); | 1988 HChange* change = HChange::cast(current); |
1953 // Propagate flags for negative zero checks upwards from conversions | 1989 // Propagate flags for negative zero checks upwards from conversions |
1954 // int32-to-tagged and int32-to-double. | 1990 // int32-to-tagged and int32-to-double. |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2241 HInferRepresentation rep(graph()); | 2277 HInferRepresentation rep(graph()); |
2242 rep.Analyze(); | 2278 rep.Analyze(); |
2243 | 2279 |
2244 if (FLAG_use_range) { | 2280 if (FLAG_use_range) { |
2245 HRangeAnalysis rangeAnalysis(graph()); | 2281 HRangeAnalysis rangeAnalysis(graph()); |
2246 rangeAnalysis.Analyze(); | 2282 rangeAnalysis.Analyze(); |
2247 } | 2283 } |
2248 | 2284 |
2249 graph()->InitializeInferredTypes(); | 2285 graph()->InitializeInferredTypes(); |
2250 graph()->Canonicalize(); | 2286 graph()->Canonicalize(); |
| 2287 graph()->MarkDeoptimizeOnUndefined(); |
2251 graph()->InsertRepresentationChanges(); | 2288 graph()->InsertRepresentationChanges(); |
2252 graph()->ComputeMinusZeroChecks(); | 2289 graph()->ComputeMinusZeroChecks(); |
2253 | 2290 |
2254 // Eliminate redundant stack checks on backwards branches. | 2291 // Eliminate redundant stack checks on backwards branches. |
2255 HStackCheckEliminator sce(graph()); | 2292 HStackCheckEliminator sce(graph()); |
2256 sce.Process(); | 2293 sce.Process(); |
2257 | 2294 |
2258 // Perform common subexpression elimination and loop-invariant code motion. | 2295 // Perform common subexpression elimination and loop-invariant code motion. |
2259 if (FLAG_use_gvn) { | 2296 if (FLAG_use_gvn) { |
2260 HPhase phase("Global value numbering", graph()); | 2297 HPhase phase("Global value numbering", graph()); |
(...skipping 4107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6368 } | 6405 } |
6369 } | 6406 } |
6370 | 6407 |
6371 #ifdef DEBUG | 6408 #ifdef DEBUG |
6372 if (graph_ != NULL) graph_->Verify(); | 6409 if (graph_ != NULL) graph_->Verify(); |
6373 if (allocator_ != NULL) allocator_->Verify(); | 6410 if (allocator_ != NULL) allocator_->Verify(); |
6374 #endif | 6411 #endif |
6375 } | 6412 } |
6376 | 6413 |
6377 } } // namespace v8::internal | 6414 } } // namespace v8::internal |
OLD | NEW |