Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/constant_propagator.h" | 5 #include "vm/constant_propagator.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/flow_graph_range_analysis.h" | 10 #include "vm/flow_graph_range_analysis.h" |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 756 ((rep == kUnboxedMint) && (value_cid == kMintCid))); | 756 ((rep == kUnboxedMint) && (value_cid == kMintCid))); |
| 757 // The representation guarantees the type check to be true. | 757 // The representation guarantees the type check to be true. |
| 758 SetValue(instr, Bool::True()); | 758 SetValue(instr, Bool::True()); |
| 759 } else { | 759 } else { |
| 760 SetValue(instr, non_constant_); | 760 SetValue(instr, non_constant_); |
| 761 } | 761 } |
| 762 } else if (IsConstant(value)) { | 762 } else if (IsConstant(value)) { |
| 763 if (value.IsInstance()) { | 763 if (value.IsInstance()) { |
| 764 const Instance& instance = Instance::Cast(value); | 764 const Instance& instance = Instance::Cast(value); |
| 765 const AbstractType& checked_type = instr->type(); | 765 const AbstractType& checked_type = instr->type(); |
| 766 if (instr->instantiator_type_arguments()->BindsToConstantNull()) { | 766 if (instr->instantiator_type_arguments()->BindsToConstantNull() && |
| 767 instr->function_type_arguments()->BindsToConstantNull() && | |
| 768 checked_type.IsInstantiated(kParentFunctions)) { | |
| 767 Error& bound_error = Error::Handle(); | 769 Error& bound_error = Error::Handle(); |
| 768 bool is_instance = instance.IsInstanceOf( | 770 bool is_instance = |
| 769 checked_type, Object::null_type_arguments(), &bound_error); | 771 instance.IsInstanceOf(checked_type, Object::null_type_arguments(), |
| 772 Object::null_type_arguments(), &bound_error); | |
| 770 // Can only have bound error with generics. | 773 // Can only have bound error with generics. |
| 771 ASSERT(bound_error.IsNull()); | 774 ASSERT(bound_error.IsNull()); |
| 772 SetValue(instr, Bool::Get(is_instance)); | 775 SetValue(instr, Bool::Get(is_instance)); |
| 773 return; | 776 return; |
| 774 } | 777 } |
| 775 } | 778 } |
| 776 SetValue(instr, non_constant_); | 779 SetValue(instr, non_constant_); |
| 777 } | 780 } |
| 778 } | 781 } |
| 779 | 782 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 } | 856 } |
| 854 } | 857 } |
| 855 } | 858 } |
| 856 SetValue(instr, non_constant_); | 859 SetValue(instr, non_constant_); |
| 857 } | 860 } |
| 858 | 861 |
| 859 | 862 |
| 860 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { | 863 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { |
| 861 const Object& object = | 864 const Object& object = |
| 862 instr->instantiator_type_arguments()->definition()->constant_value(); | 865 instr->instantiator_type_arguments()->definition()->constant_value(); |
| 863 // TODO(regis): Check function type arguments. | |
| 864 if (IsNonConstant(object)) { | 866 if (IsNonConstant(object)) { |
| 865 SetValue(instr, non_constant_); | 867 SetValue(instr, non_constant_); |
| 866 return; | 868 return; |
| 867 } | 869 } |
| 868 if (IsConstant(object)) { | 870 if (IsConstant(object)) { |
| 869 if (instr->type().IsTypeParameter()) { | 871 if (instr->type().IsTypeParameter() && |
| 872 TypeParameter::Cast(instr->type()).IsClassTypeParameter()) { | |
| 870 if (object.IsNull()) { | 873 if (object.IsNull()) { |
| 871 SetValue(instr, Object::dynamic_type()); | 874 SetValue(instr, Object::dynamic_type()); |
| 872 return; | 875 return; |
| 873 } | 876 } |
| 874 // We could try to instantiate the type parameter and return it if no | 877 // We could try to instantiate the type parameter and return it if no |
| 875 // malformed error is reported. | 878 // malformed error is reported. |
| 876 } | 879 } |
| 877 SetValue(instr, non_constant_); | 880 SetValue(instr, non_constant_); |
| 878 } | 881 } |
| 882 // TODO(regis): We can do the same as above for a function type parameter. | |
| 883 // Better: If both instantiator type arguments and function type arguments are | |
| 884 // constant, instantiate the type if no bound error is reported. | |
| 879 } | 885 } |
| 880 | 886 |
| 881 | 887 |
| 882 void ConstantPropagator::VisitInstantiateTypeArguments( | 888 void ConstantPropagator::VisitInstantiateTypeArguments( |
| 883 InstantiateTypeArgumentsInstr* instr) { | 889 InstantiateTypeArgumentsInstr* instr) { |
| 884 const Object& object = | 890 const Object& instantiator_type_args = |
| 885 instr->instantiator_type_arguments()->definition()->constant_value(); | 891 instr->instantiator_type_arguments()->definition()->constant_value(); |
| 886 // TODO(regis): Check function type arguments. | 892 const Object& function_type_args = |
| 887 if (IsNonConstant(object)) { | 893 instr->function_type_arguments()->definition()->constant_value(); |
| 894 if (IsNonConstant(instantiator_type_args) || | |
| 895 IsNonConstant(function_type_args)) { | |
| 888 SetValue(instr, non_constant_); | 896 SetValue(instr, non_constant_); |
| 889 return; | 897 return; |
| 890 } | 898 } |
| 891 if (IsConstant(object)) { | 899 if (IsConstant(instantiator_type_args) && IsConstant(function_type_args)) { |
| 892 const intptr_t len = instr->type_arguments().Length(); | 900 if (instantiator_type_args.IsNull() && function_type_args.IsNull()) { |
| 893 if (instr->type_arguments().IsRawInstantiatedRaw(len) && object.IsNull()) { | 901 const intptr_t len = instr->type_arguments().Length(); |
| 894 SetValue(instr, object); | 902 if (instr->type_arguments().IsRawInstantiatedRaw(len)) { |
| 895 return; | 903 SetValue(instr, instantiator_type_args); |
| 904 return; | |
| 905 } | |
| 896 } | 906 } |
| 897 if (instr->type_arguments().IsUninstantiatedIdentity() || | 907 if (instr->type_arguments().IsUninstantiatedIdentity() || |
| 898 instr->type_arguments().CanShareInstantiatorTypeArguments( | 908 instr->type_arguments().CanShareInstantiatorTypeArguments( |
| 899 instr->instantiator_class())) { | 909 instr->instantiator_class())) { |
| 900 SetValue(instr, object); | 910 SetValue(instr, instantiator_type_args); |
| 901 return; | 911 return; |
| 902 } | 912 } |
| 903 SetValue(instr, non_constant_); | 913 SetValue(instr, non_constant_); |
| 904 } | 914 } |
| 915 // TODO(regis): If both instantiator type arguments and function type | |
| 916 // arguments are constant, instantiate the type arguments if no bound error | |
| 917 // is reported. | |
| 918 // TODO(regis): If either instantiator type arguments or function type | |
| 919 // arguments are constant null, check if the type arguments is | |
| 920 // IsRawInstantiatedRaw separately for each genericity. | |
|
zra
2017/04/07 17:36:29
'IsRawInstantiatedRaw' is this a typo?
regis
2017/04/11 04:23:07
No :-)
It is used on line 902 if both instantiator
| |
| 905 } | 921 } |
| 906 | 922 |
| 907 | 923 |
| 908 void ConstantPropagator::VisitAllocateContext(AllocateContextInstr* instr) { | 924 void ConstantPropagator::VisitAllocateContext(AllocateContextInstr* instr) { |
| 909 SetValue(instr, non_constant_); | 925 SetValue(instr, non_constant_); |
| 910 } | 926 } |
| 911 | 927 |
| 912 | 928 |
| 913 void ConstantPropagator::VisitAllocateUninitializedContext( | 929 void ConstantPropagator::VisitAllocateUninitializedContext( |
| 914 AllocateUninitializedContextInstr* instr) { | 930 AllocateUninitializedContextInstr* instr) { |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1715 GrowableArray<BitVector*> dominance_frontier; | 1731 GrowableArray<BitVector*> dominance_frontier; |
| 1716 graph_->ComputeDominators(&dominance_frontier); | 1732 graph_->ComputeDominators(&dominance_frontier); |
| 1717 | 1733 |
| 1718 if (FLAG_trace_constant_propagation && | 1734 if (FLAG_trace_constant_propagation && |
| 1719 FlowGraphPrinter::ShouldPrint(graph_->function())) { | 1735 FlowGraphPrinter::ShouldPrint(graph_->function())) { |
| 1720 FlowGraphPrinter::PrintGraph("After CP", graph_); | 1736 FlowGraphPrinter::PrintGraph("After CP", graph_); |
| 1721 } | 1737 } |
| 1722 } | 1738 } |
| 1723 | 1739 |
| 1724 } // namespace dart | 1740 } // namespace dart |
| OLD | NEW |