Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| 11 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
| 12 #include "vm/flow_graph_optimizer.h" | 12 #include "vm/flow_graph_optimizer.h" |
| 13 #include "vm/locations.h" | 13 #include "vm/locations.h" |
| 14 #include "vm/object.h" | 14 #include "vm/object.h" |
| 15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 16 #include "vm/os.h" | 16 #include "vm/os.h" |
| 17 #include "vm/scopes.h" | 17 #include "vm/scopes.h" |
| 18 #include "vm/stub_code.h" | 18 #include "vm/stub_code.h" |
| 19 #include "vm/symbols.h" | 19 #include "vm/symbols.h" |
| 20 | 20 |
| 21 #include "vm/il_printer.h" | |
|
Florian Schneider
2012/09/21 08:56:44
Why this include?
Kevin Millikin (Google)
2012/09/21 08:59:33
Is there any reason to split this out from all the
Vyacheslav Egorov (Google)
2012/09/21 20:08:07
Debugging leftover. Removing.
| |
| 22 | |
| 21 namespace dart { | 23 namespace dart { |
| 22 | 24 |
| 23 DECLARE_FLAG(bool, enable_type_checks); | 25 DECLARE_FLAG(bool, enable_type_checks); |
| 24 | 26 |
| 25 | 27 |
| 26 Definition::Definition() | 28 Definition::Definition() |
| 27 : temp_index_(-1), | 29 : temp_index_(-1), |
| 28 ssa_temp_index_(-1), | 30 ssa_temp_index_(-1), |
| 29 propagated_type_(AbstractType::Handle()), | 31 propagated_type_(AbstractType::Handle()), |
| 30 propagated_cid_(kIllegalCid), | 32 propagated_cid_(kIllegalCid), |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 definition()->set_input_use_list(this); | 565 definition()->set_input_use_list(this); |
| 564 } | 566 } |
| 565 | 567 |
| 566 | 568 |
| 567 void Value::AddToEnvUseList() { | 569 void Value::AddToEnvUseList() { |
| 568 set_next_use(definition()->env_use_list()); | 570 set_next_use(definition()->env_use_list()); |
| 569 definition()->set_env_use_list(this); | 571 definition()->set_env_use_list(this); |
| 570 } | 572 } |
| 571 | 573 |
| 572 | 574 |
| 575 void Value::RemoveFromInputUseList() { | |
| 576 if (definition_->input_use_list() == this) { | |
| 577 definition_->set_input_use_list(next_use_); | |
| 578 return; | |
| 579 } | |
| 580 | |
| 581 Value* prev = definition_->input_use_list(); | |
| 582 while (prev->next_use_ != this) { | |
| 583 prev = prev->next_use_; | |
| 584 } | |
| 585 prev->next_use_ = next_use_; | |
| 586 definition_ = NULL; | |
| 587 } | |
| 588 | |
| 589 | |
| 573 void Definition::ReplaceUsesWith(Definition* other) { | 590 void Definition::ReplaceUsesWith(Definition* other) { |
| 574 ASSERT(other != NULL); | 591 ASSERT(other != NULL); |
| 575 ASSERT(this != other); | 592 ASSERT(this != other); |
| 576 while (input_use_list_ != NULL) { | 593 while (input_use_list_ != NULL) { |
| 577 Value* current = input_use_list_; | 594 Value* current = input_use_list_; |
| 578 input_use_list_ = input_use_list_->next_use(); | 595 input_use_list_ = input_use_list_->next_use(); |
| 579 current->set_definition(other); | 596 current->set_definition(other); |
| 580 current->AddToInputUseList(); | 597 current->AddToInputUseList(); |
| 581 } | 598 } |
| 582 while (env_use_list_ != NULL) { | 599 while (env_use_list_ != NULL) { |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1204 } | 1221 } |
| 1205 | 1222 |
| 1206 | 1223 |
| 1207 bool BinarySmiOpInstr::CanDeoptimize() const { | 1224 bool BinarySmiOpInstr::CanDeoptimize() const { |
| 1208 switch (op_kind()) { | 1225 switch (op_kind()) { |
| 1209 case Token::kBIT_AND: | 1226 case Token::kBIT_AND: |
| 1210 case Token::kBIT_OR: | 1227 case Token::kBIT_OR: |
| 1211 case Token::kBIT_XOR: | 1228 case Token::kBIT_XOR: |
| 1212 return false; | 1229 return false; |
| 1213 default: | 1230 default: |
| 1214 return true; | 1231 return overflow_; |
| 1215 } | 1232 } |
| 1216 } | 1233 } |
| 1217 | 1234 |
| 1218 | 1235 |
| 1219 RawAbstractType* BinaryMintOpInstr::CompileType() const { | 1236 RawAbstractType* BinaryMintOpInstr::CompileType() const { |
| 1220 return Type::MintType(); | 1237 return Type::MintType(); |
| 1221 } | 1238 } |
| 1222 | 1239 |
| 1223 | 1240 |
| 1224 intptr_t BinaryMintOpInstr::ResultCid() const { | 1241 intptr_t BinaryMintOpInstr::ResultCid() const { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1429 LocationSummary* ParallelMoveInstr::MakeLocationSummary() const { | 1446 LocationSummary* ParallelMoveInstr::MakeLocationSummary() const { |
| 1430 return NULL; | 1447 return NULL; |
| 1431 } | 1448 } |
| 1432 | 1449 |
| 1433 | 1450 |
| 1434 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1451 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1435 UNREACHABLE(); | 1452 UNREACHABLE(); |
| 1436 } | 1453 } |
| 1437 | 1454 |
| 1438 | 1455 |
| 1456 LocationSummary* ConstraintInstr::MakeLocationSummary() const { | |
| 1457 UNREACHABLE(); | |
| 1458 return NULL; | |
| 1459 } | |
| 1460 | |
| 1461 | |
| 1462 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 1463 UNREACHABLE(); | |
| 1464 } | |
| 1465 | |
| 1439 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 1466 LocationSummary* ThrowInstr::MakeLocationSummary() const { |
| 1440 return new LocationSummary(0, 0, LocationSummary::kCall); | 1467 return new LocationSummary(0, 0, LocationSummary::kCall); |
| 1441 } | 1468 } |
| 1442 | 1469 |
| 1443 | 1470 |
| 1444 | 1471 |
| 1445 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1472 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1446 compiler->GenerateCallRuntime(token_pos(), | 1473 compiler->GenerateCallRuntime(token_pos(), |
| 1447 kThrowRuntimeEntry, | 1474 kThrowRuntimeEntry, |
| 1448 locs()); | 1475 locs()); |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1836 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { | 1863 for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) { |
| 1837 Value* value = it.CurrentValue(); | 1864 Value* value = it.CurrentValue(); |
| 1838 value->set_instruction(instr); | 1865 value->set_instruction(instr); |
| 1839 value->set_use_index(use_index++); | 1866 value->set_use_index(use_index++); |
| 1840 value->AddToEnvUseList(); | 1867 value->AddToEnvUseList(); |
| 1841 } | 1868 } |
| 1842 instr->env()->outer_ = copy; | 1869 instr->env()->outer_ = copy; |
| 1843 } | 1870 } |
| 1844 | 1871 |
| 1845 | 1872 |
| 1873 Range* Instruction::range() { | |
| 1874 if (range_ == NULL) { | |
| 1875 range_ = Range::Unknown(); | |
| 1876 } | |
| 1877 return range_; | |
| 1878 } | |
| 1879 | |
| 1880 | |
| 1881 RangeBoundary RangeBoundary::LowerBound() const { | |
| 1882 if (IsConstant()) return *this; | |
| 1883 if (symbol()->range() == NULL) return MinSmi(); | |
| 1884 return Add(symbol()->range()->min().LowerBound(), | |
| 1885 RangeBoundary::FromConstant(offs_), | |
| 1886 MinSmi()); | |
| 1887 } | |
| 1888 | |
| 1889 | |
| 1890 RangeBoundary RangeBoundary::UpperBound() const { | |
| 1891 if (IsConstant()) return *this; | |
| 1892 if (symbol()->range() == NULL) return MaxSmi(); | |
| 1893 return Add(symbol()->range()->max().UpperBound(), | |
| 1894 RangeBoundary::FromConstant(offs_), | |
| 1895 MaxSmi()); | |
| 1896 } | |
| 1897 | |
| 1898 | |
| 1899 bool ConstraintInstr::InferRange() { | |
| 1900 Range* value_range = value()->definition()->range(); | |
| 1901 | |
| 1902 // Compute intersection of constraint and value ranges. | |
| 1903 return Range::Update(&range_, | |
| 1904 RangeBoundary::Max(Range::ConstantMin(value_range), | |
| 1905 Range::ConstantMin(constraint())), | |
| 1906 RangeBoundary::Min(Range::ConstantMax(value_range), | |
| 1907 Range::ConstantMax(constraint()))); | |
| 1908 } | |
| 1909 | |
| 1910 | |
| 1911 bool PhiInstr::InferRange() { | |
| 1912 RangeBoundary new_min; | |
| 1913 RangeBoundary new_max; | |
| 1914 | |
| 1915 bool has_unranged_inputs = false; | |
| 1916 for (intptr_t i = 0; i < InputCount(); i++) { | |
| 1917 Range* input_range = InputAt(i)->definition()->range(); | |
| 1918 if (input_range == NULL) { | |
| 1919 has_unranged_inputs = true; | |
| 1920 continue; | |
| 1921 } | |
| 1922 | |
| 1923 if (new_min.IsUnknown()) { | |
| 1924 new_min = Range::ConstantMin(input_range); | |
| 1925 } else { | |
| 1926 new_min = RangeBoundary::Min(new_min, Range::ConstantMin(input_range)); | |
| 1927 } | |
| 1928 | |
| 1929 if (new_max.IsUnknown()) { | |
| 1930 new_max = Range::ConstantMax(input_range); | |
| 1931 } else { | |
| 1932 new_max = RangeBoundary::Max(new_max, Range::ConstantMax(input_range)); | |
| 1933 } | |
| 1934 } | |
| 1935 | |
| 1936 ASSERT(new_min.IsUnknown() == new_max.IsUnknown()); | |
| 1937 if (new_min.IsUnknown()) { | |
| 1938 ASSERT(range_ == NULL); | |
| 1939 return false; | |
| 1940 } | |
| 1941 | |
| 1942 bool had_unranged_inputs = has_unranged_inputs_; | |
|
Kevin Millikin (Google)
2012/09/21 08:59:33
Simpler to test the old value before changing it:
Vyacheslav Egorov (Google)
2012/09/21 20:08:07
Agreed. The control flow in this function was prev
| |
| 1943 if (!has_unranged_inputs) has_unranged_inputs_ = false; | |
| 1944 | |
| 1945 if ((range_ != NULL) && !had_unranged_inputs) { | |
| 1946 // If phi's range is growing widen it in the direction of growth to | |
| 1947 // speedup convergence. | |
| 1948 new_min = RangeBoundary::WidenMin(range_->min(), new_min); | |
| 1949 new_max = RangeBoundary::WidenMax(range_->max(), new_max); | |
| 1950 } | |
| 1951 | |
| 1952 return Range::Update(&range_, new_min, new_max); | |
| 1953 } | |
| 1954 | |
| 1955 | |
| 1956 bool BinarySmiOpInstr::InferRange() { | |
| 1957 Range* lrange = left()->definition()->range(); | |
|
Florian Schneider
2012/09/21 08:56:44
lrange and rrange are easy to confuse. How about j
Vyacheslav Egorov (Google)
2012/09/21 20:08:07
Done.
| |
| 1958 Range* rrange = right()->definition()->range(); | |
| 1959 | |
| 1960 if ((lrange == NULL) || (rrange == NULL)) { | |
| 1961 return Range::Update(&range_, | |
| 1962 RangeBoundary::MinSmi(), | |
| 1963 RangeBoundary::MaxSmi()); | |
| 1964 } | |
| 1965 | |
| 1966 RangeBoundary new_min; | |
| 1967 RangeBoundary new_max; | |
| 1968 switch (op_kind()) { | |
| 1969 case Token::kADD: | |
| 1970 new_min = | |
| 1971 RangeBoundary::Add(Range::ConstantMin(lrange), | |
| 1972 Range::ConstantMin(rrange), | |
| 1973 RangeBoundary::OverflowedMinSmi()); | |
| 1974 new_max = | |
| 1975 RangeBoundary::Add(Range::ConstantMax(lrange), | |
| 1976 Range::ConstantMax(rrange), | |
| 1977 RangeBoundary::OverflowedMaxSmi()); | |
| 1978 break; | |
| 1979 | |
| 1980 case Token::kSUB: | |
| 1981 new_min = | |
| 1982 RangeBoundary::Sub(Range::ConstantMin(lrange), | |
| 1983 Range::ConstantMax(rrange), | |
| 1984 RangeBoundary::OverflowedMinSmi()); | |
| 1985 new_max = | |
| 1986 RangeBoundary::Sub(Range::ConstantMax(lrange), | |
| 1987 Range::ConstantMin(rrange), | |
| 1988 RangeBoundary::OverflowedMaxSmi()); | |
| 1989 break; | |
| 1990 | |
| 1991 default: | |
| 1992 if (range_ == NULL) { | |
| 1993 range_ = Range::Unknown(); | |
| 1994 return true; | |
| 1995 } | |
| 1996 return false; | |
| 1997 } | |
| 1998 | |
| 1999 ASSERT(!new_min.IsUnknown() && !new_max.IsUnknown()); | |
| 2000 set_overflow(new_min.Overflowed() || new_max.Overflowed()); | |
| 2001 return Range::Update(&range_, new_min, new_max); | |
| 2002 } | |
| 2003 | |
| 2004 | |
| 1846 #undef __ | 2005 #undef __ |
| 1847 | 2006 |
| 1848 } // namespace dart | 2007 } // namespace dart |
| OLD | NEW |