Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: runtime/vm/flow_graph_type_propagator.cc

Issue 3004463002: [vm] Use strong mode types to calculate CompileType (Closed)
Patch Set: Address review comments Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/flag_list.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/flow_graph_type_propagator.h" 5 #include "vm/flow_graph_type_propagator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
11 #include "vm/regexp_assembler.h" 11 #include "vm/regexp_assembler.h"
12 #include "vm/resolver.h" 12 #include "vm/resolver.h"
13 #include "vm/timeline.h" 13 #include "vm/timeline.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 DEFINE_FLAG(bool, 17 DEFINE_FLAG(bool,
18 trace_type_propagation, 18 trace_type_propagation,
19 false, 19 false,
20 "Trace flow graph type propagation"); 20 "Trace flow graph type propagation");
21 21
22 DECLARE_FLAG(bool, propagate_types); 22 DECLARE_FLAG(bool, propagate_types);
23 23
24 static void TraceStrongModeType(const Instruction* instr,
25 const AbstractType& type) {
26 if (FLAG_trace_experimental_strong_mode) {
27 THR_Print("[Strong mode] Type of %s - %s\n", instr->ToCString(),
28 type.ToCString());
29 }
30 }
31
32 static void TraceStrongModeType(const Instruction* instr,
33 CompileType* compileType) {
34 if (FLAG_trace_experimental_strong_mode) {
35 const AbstractType* type = compileType->ToAbstractType();
36 if ((type != NULL) && !type->IsDynamicType()) {
37 TraceStrongModeType(instr, *type);
38 }
39 }
40 }
41
24 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) { 42 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
25 #ifndef PRODUCT 43 #ifndef PRODUCT
26 Thread* thread = flow_graph->thread(); 44 Thread* thread = flow_graph->thread();
27 TimelineStream* compiler_timeline = Timeline::GetCompilerStream(); 45 TimelineStream* compiler_timeline = Timeline::GetCompilerStream();
28 TimelineDurationScope tds2(thread, compiler_timeline, 46 TimelineDurationScope tds2(thread, compiler_timeline,
29 "FlowGraphTypePropagator"); 47 "FlowGraphTypePropagator");
30 #endif // !PRODUCT 48 #endif // !PRODUCT
31 FlowGraphTypePropagator propagator(flow_graph); 49 FlowGraphTypePropagator propagator(flow_graph);
32 propagator.Propagate(); 50 propagator.Propagate();
33 } 51 }
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 839 }
822 cid = type_class.id(); 840 cid = type_class.id();
823 } 841 }
824 } 842 }
825 } 843 }
826 } 844 }
827 845
828 return CompileType(CompileType::kNonNullable, cid, &type); 846 return CompileType(CompileType::kNonNullable, cid, &type);
829 } 847 }
830 848
849 if (FLAG_experimental_strong_mode && block_->IsGraphEntry()) {
850 LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
851 const AbstractType& param_type = scope->VariableAt(index())->type();
852 TraceStrongModeType(this, param_type);
853 return CompileType::FromAbstractType(param_type);
854 }
855
831 return CompileType::Dynamic(); 856 return CompileType::Dynamic();
832 } 857 }
833 858
834 CompileType PushArgumentInstr::ComputeType() const { 859 CompileType PushArgumentInstr::ComputeType() const {
835 return CompileType::Dynamic(); 860 return CompileType::Dynamic();
836 } 861 }
837 862
838 CompileType ConstantInstr::ComputeType() const { 863 CompileType ConstantInstr::ComputeType() const {
839 if (value().IsNull()) { 864 if (value().IsNull()) {
840 return CompileType::Null(); 865 return CompileType::Null();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 CompileType AllocateContextInstr::ComputeType() const { 946 CompileType AllocateContextInstr::ComputeType() const {
922 return CompileType(CompileType::kNonNullable, kContextCid, 947 return CompileType(CompileType::kNonNullable, kContextCid,
923 &Object::dynamic_type()); 948 &Object::dynamic_type());
924 } 949 }
925 950
926 CompileType AllocateUninitializedContextInstr::ComputeType() const { 951 CompileType AllocateUninitializedContextInstr::ComputeType() const {
927 return CompileType(CompileType::kNonNullable, kContextCid, 952 return CompileType(CompileType::kNonNullable, kContextCid,
928 &Object::dynamic_type()); 953 &Object::dynamic_type());
929 } 954 }
930 955
956 CompileType InstanceCallInstr::ComputeType() const {
957 if (FLAG_experimental_strong_mode) {
958 const Function& target = interface_target();
959 if (!target.IsNull()) {
960 // TODO(alexmarkov): instantiate generic result_type
961 const AbstractType& result_type =
962 AbstractType::ZoneHandle(target.result_type());
963 TraceStrongModeType(this, result_type);
964 return CompileType::FromAbstractType(result_type);
965 }
966 }
967
968 return CompileType::Dynamic();
969 }
970
931 CompileType PolymorphicInstanceCallInstr::ComputeType() const { 971 CompileType PolymorphicInstanceCallInstr::ComputeType() const {
932 if (!IsSureToCallSingleRecognizedTarget()) return CompileType::Dynamic(); 972 if (IsSureToCallSingleRecognizedTarget()) {
933 const Function& target = *targets_.TargetAt(0)->target; 973 const Function& target = *targets_.TargetAt(0)->target;
934 return (target.recognized_kind() != MethodRecognizer::kUnknown) 974 if (target.recognized_kind() != MethodRecognizer::kUnknown) {
935 ? CompileType::FromCid(MethodRecognizer::ResultCid(target)) 975 return CompileType::FromCid(MethodRecognizer::ResultCid(target));
936 : CompileType::Dynamic(); 976 }
977 }
978
979 if (FLAG_experimental_strong_mode) {
980 CompileType* type = instance_call()->Type();
981 TraceStrongModeType(this, type);
982 return *type;
983 }
984
985 return CompileType::Dynamic();
937 } 986 }
938 987
939 CompileType StaticCallInstr::ComputeType() const { 988 CompileType StaticCallInstr::ComputeType() const {
940 if (result_cid_ != kDynamicCid) { 989 if (result_cid_ != kDynamicCid) {
941 return CompileType::FromCid(result_cid_); 990 return CompileType::FromCid(result_cid_);
942 } 991 }
943 992
944 if (Isolate::Current()->type_checks()) { 993 if (function_.recognized_kind() != MethodRecognizer::kUnknown) {
994 return CompileType::FromCid(MethodRecognizer::ResultCid(function_));
995 }
996
997 if (FLAG_experimental_strong_mode || Isolate::Current()->type_checks()) {
945 const AbstractType& result_type = 998 const AbstractType& result_type =
946 AbstractType::ZoneHandle(function().result_type()); 999 AbstractType::ZoneHandle(function().result_type());
1000 TraceStrongModeType(this, result_type);
947 return CompileType::FromAbstractType(result_type); 1001 return CompileType::FromAbstractType(result_type);
948 } 1002 }
949 1003
950 return (function_.recognized_kind() != MethodRecognizer::kUnknown) 1004 return CompileType::Dynamic();
951 ? CompileType::FromCid(MethodRecognizer::ResultCid(function_))
952 : CompileType::Dynamic();
953 } 1005 }
954 1006
955 CompileType LoadLocalInstr::ComputeType() const { 1007 CompileType LoadLocalInstr::ComputeType() const {
956 if (Isolate::Current()->type_checks()) { 1008 if (FLAG_experimental_strong_mode || Isolate::Current()->type_checks()) {
957 return CompileType::FromAbstractType(local().type()); 1009 const AbstractType& local_type = local().type();
1010 TraceStrongModeType(this, local_type);
1011 return CompileType::FromAbstractType(local_type);
958 } 1012 }
959 return CompileType::Dynamic(); 1013 return CompileType::Dynamic();
960 } 1014 }
961 1015
962 CompileType DropTempsInstr::ComputeType() const { 1016 CompileType DropTempsInstr::ComputeType() const {
963 return *value()->Type(); 1017 return *value()->Type();
964 } 1018 }
965 1019
966 CompileType StoreLocalInstr::ComputeType() const { 1020 CompileType StoreLocalInstr::ComputeType() const {
967 // Returns stored value. 1021 // Returns stored value.
(...skipping 11 matching lines...) Expand all
979 CompileType StringInterpolateInstr::ComputeType() const { 1033 CompileType StringInterpolateInstr::ComputeType() const {
980 // TODO(srdjan): Do better and determine if it is a one or two byte string. 1034 // TODO(srdjan): Do better and determine if it is a one or two byte string.
981 return CompileType::String(); 1035 return CompileType::String();
982 } 1036 }
983 1037
984 CompileType LoadStaticFieldInstr::ComputeType() const { 1038 CompileType LoadStaticFieldInstr::ComputeType() const {
985 bool is_nullable = CompileType::kNullable; 1039 bool is_nullable = CompileType::kNullable;
986 intptr_t cid = kDynamicCid; 1040 intptr_t cid = kDynamicCid;
987 AbstractType* abstract_type = NULL; 1041 AbstractType* abstract_type = NULL;
988 const Field& field = this->StaticField(); 1042 const Field& field = this->StaticField();
989 if (Isolate::Current()->type_checks()) { 1043 if (FLAG_experimental_strong_mode || Isolate::Current()->type_checks()) {
990 cid = kIllegalCid; 1044 cid = kIllegalCid;
991 abstract_type = &AbstractType::ZoneHandle(field.type()); 1045 abstract_type = &AbstractType::ZoneHandle(field.type());
1046 TraceStrongModeType(this, *abstract_type);
992 } 1047 }
993 ASSERT(field.is_static()); 1048 ASSERT(field.is_static());
994 if (field.is_final()) { 1049 if (field.is_final()) {
995 if (!FLAG_fields_may_be_reset) { 1050 if (!FLAG_fields_may_be_reset) {
996 const Instance& obj = Instance::Handle(field.StaticValue()); 1051 const Instance& obj = Instance::Handle(field.StaticValue());
997 if ((obj.raw() != Object::sentinel().raw()) && 1052 if ((obj.raw() != Object::sentinel().raw()) &&
998 (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) { 1053 (obj.raw() != Object::transition_sentinel().raw()) && !obj.IsNull()) {
999 is_nullable = CompileType::kNonNullable; 1054 is_nullable = CompileType::kNonNullable;
1000 cid = obj.GetClassId(); 1055 cid = obj.GetClassId();
1001 } 1056 }
(...skipping 30 matching lines...) Expand all
1032 1087
1033 CompileType LoadFieldInstr::ComputeType() const { 1088 CompileType LoadFieldInstr::ComputeType() const {
1034 // Type may be null if the field is a VM field, e.g. context parent. 1089 // Type may be null if the field is a VM field, e.g. context parent.
1035 // Keep it as null for debug purposes and do not return dynamic in production 1090 // Keep it as null for debug purposes and do not return dynamic in production
1036 // mode, since misuse of the type would remain undetected. 1091 // mode, since misuse of the type would remain undetected.
1037 if (type().IsNull()) { 1092 if (type().IsNull()) {
1038 return CompileType::Dynamic(); 1093 return CompileType::Dynamic();
1039 } 1094 }
1040 1095
1041 const AbstractType* abstract_type = NULL; 1096 const AbstractType* abstract_type = NULL;
1042 if (Isolate::Current()->type_checks() && 1097 if (FLAG_experimental_strong_mode ||
1043 (type().IsFunctionType() || type().HasResolvedTypeClass())) { 1098 (Isolate::Current()->type_checks() &&
1099 (type().IsFunctionType() || type().HasResolvedTypeClass()))) {
1044 abstract_type = &type(); 1100 abstract_type = &type();
1101 TraceStrongModeType(this, *abstract_type);
1045 } 1102 }
1046 1103
1047 if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) { 1104 if ((field_ != NULL) && (field_->guarded_cid() != kIllegalCid)) {
1048 bool is_nullable = field_->is_nullable(); 1105 bool is_nullable = field_->is_nullable();
1049 intptr_t field_cid = field_->guarded_cid(); 1106 intptr_t field_cid = field_->guarded_cid();
1050 return CompileType(is_nullable, field_cid, abstract_type); 1107 return CompileType(is_nullable, field_cid, abstract_type);
1051 } 1108 }
1052 1109
1053 return CompileType::Create(result_cid_, *abstract_type); 1110 return CompileType::Create(result_cid_, *abstract_type);
1054 } 1111 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 } 1156 }
1100 1157
1101 CompileType ShiftInt64OpInstr::ComputeType() const { 1158 CompileType ShiftInt64OpInstr::ComputeType() const {
1102 return CompileType::Int(); 1159 return CompileType::Int();
1103 } 1160 }
1104 1161
1105 CompileType UnaryInt64OpInstr::ComputeType() const { 1162 CompileType UnaryInt64OpInstr::ComputeType() const {
1106 return CompileType::Int(); 1163 return CompileType::Int();
1107 } 1164 }
1108 1165
1166 CompileType CheckedSmiOpInstr::ComputeType() const {
1167 if (FLAG_experimental_strong_mode) {
1168 CompileType* type = call()->Type();
1169 TraceStrongModeType(this, type);
1170 return *type;
1171 }
1172 return CompileType::Dynamic();
1173 }
1174
1175 CompileType CheckedSmiComparisonInstr::ComputeType() const {
1176 if (FLAG_experimental_strong_mode) {
1177 CompileType* type = call()->Type();
1178 TraceStrongModeType(this, type);
1179 return *type;
1180 }
1181 return CompileType::Dynamic();
1182 }
1183
1109 CompileType BoxIntegerInstr::ComputeType() const { 1184 CompileType BoxIntegerInstr::ComputeType() const {
1110 return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int(); 1185 return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int();
1111 } 1186 }
1112 1187
1113 bool BoxIntegerInstr::RecomputeType() { 1188 bool BoxIntegerInstr::RecomputeType() {
1114 return UpdateType(ComputeType()); 1189 return UpdateType(ComputeType());
1115 } 1190 }
1116 1191
1117 CompileType UnboxIntegerInstr::ComputeType() const { 1192 CompileType UnboxIntegerInstr::ComputeType() const {
1118 return CompileType::Int(); 1193 return CompileType::Int();
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1362 1437
1363 CompileType TruncDivModInstr::ComputeType() const { 1438 CompileType TruncDivModInstr::ComputeType() const {
1364 return CompileType::Dynamic(); 1439 return CompileType::Dynamic();
1365 } 1440 }
1366 1441
1367 CompileType ExtractNthOutputInstr::ComputeType() const { 1442 CompileType ExtractNthOutputInstr::ComputeType() const {
1368 return CompileType::FromCid(definition_cid_); 1443 return CompileType::FromCid(definition_cid_);
1369 } 1444 }
1370 1445
1371 } // namespace dart 1446 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flag_list.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698