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 |