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

Side by Side Diff: pkg/compiler/lib/src/inferrer/inferrer_engine.dart

Issue 3004713002: Remove use of Compiler in inferrer engines. (Closed)
Patch Set: 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
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../../compiler_new.dart';
7 import '../common.dart'; 8 import '../common.dart';
8 import '../common/names.dart'; 9 import '../common/names.dart';
9 import '../compiler.dart'; 10 import '../compiler.dart';
10 import '../common_elements.dart'; 11 import '../common_elements.dart';
11 import '../constants/values.dart'; 12 import '../constants/values.dart';
12 import '../elements/elements.dart' 13 import '../elements/elements.dart'
13 show 14 show
14 ClassElement, 15 ClassElement,
15 ConstructorElement, 16 ConstructorElement,
16 Elements, 17 Elements,
17 MemberElement, 18 MemberElement,
18 ParameterElement; 19 ParameterElement;
19 import '../elements/entities.dart'; 20 import '../elements/entities.dart';
20 import '../elements/names.dart'; 21 import '../elements/names.dart';
21 import '../js_backend/annotations.dart'; 22 import '../js_backend/annotations.dart';
22 import '../js_backend/js_backend.dart'; 23 import '../js_backend/mirrors_data.dart';
24 import '../js_backend/no_such_method_registry.dart';
23 import '../native/behavior.dart' as native; 25 import '../native/behavior.dart' as native;
26 import '../options.dart';
24 import '../types/constants.dart'; 27 import '../types/constants.dart';
25 import '../types/types.dart'; 28 import '../types/types.dart';
26 import '../universe/call_structure.dart'; 29 import '../universe/call_structure.dart';
27 import '../universe/selector.dart'; 30 import '../universe/selector.dart';
28 import '../universe/side_effects.dart'; 31 import '../universe/side_effects.dart';
29 import '../util/setlet.dart'; 32 import '../util/setlet.dart';
30 import '../world.dart'; 33 import '../world.dart';
31 import 'closure_tracer.dart'; 34 import 'closure_tracer.dart';
32 import 'debug.dart' as debug; 35 import 'debug.dart' as debug;
33 import 'locals_handler.dart'; 36 import 'locals_handler.dart';
(...skipping 16 matching lines...) Expand all
50 new Selector.getter(const PublicName('first')), 53 new Selector.getter(const PublicName('first')),
51 new Selector.getter(const PublicName('last')), 54 new Selector.getter(const PublicName('last')),
52 new Selector.getter(const PublicName('single')), 55 new Selector.getter(const PublicName('single')),
53 new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG), 56 new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG),
54 new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG), 57 new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG),
55 new Selector.index(), 58 new Selector.index(),
56 new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG), 59 new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG),
57 new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS) 60 new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS)
58 ]); 61 ]);
59 62
60 Compiler get compiler; 63 CompilerOptions get options;
61 ClosedWorld get closedWorld; 64 ClosedWorld get closedWorld;
62 ClosedWorldRefiner get closedWorldRefiner; 65 ClosedWorldRefiner get closedWorldRefiner;
63 JavaScriptBackend get backend => compiler.backend; 66 OptimizerHintsForTests get optimizerHints;
64 OptimizerHintsForTests get optimizerHints => backend.optimizerHints; 67 DiagnosticReporter get reporter;
65 DiagnosticReporter get reporter => compiler.reporter;
66 CommonMasks get commonMasks => closedWorld.commonMasks; 68 CommonMasks get commonMasks => closedWorld.commonMasks;
67 CommonElements get commonElements => closedWorld.commonElements; 69 CommonElements get commonElements => closedWorld.commonElements;
68 70
71 // TODO(johnniwinther): This should be part of [ClosedWorld] or
72 // [ClosureWorldRefiner].
73 NoSuchMethodRegistry get noSuchMethodRegistry;
74
69 TypeSystem<T> get types; 75 TypeSystem<T> get types;
70 Map<T, TypeInformation> get concreteTypes; 76 Map<T, TypeInformation> get concreteTypes;
71 77
72 FunctionEntity get mainElement; 78 FunctionEntity get mainElement;
73 79
74 void runOverAllElements(); 80 void runOverAllElements();
75 81
76 void analyze(MemberEntity member, T node, ArgumentsTypes arguments); 82 void analyze(MemberEntity member, T node, ArgumentsTypes arguments);
77 void analyzeListAndEnqueue(ListTypeInformation info); 83 void analyzeListAndEnqueue(ListTypeInformation info);
78 void analyzeMapAndEnqueue(MapTypeInformation info); 84 void analyzeMapAndEnqueue(MapTypeInformation info);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 222
217 /// Returns the type for [nativeBehavior]. See documentation on 223 /// Returns the type for [nativeBehavior]. See documentation on
218 /// [native.NativeBehavior]. 224 /// [native.NativeBehavior].
219 TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior); 225 TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior);
220 226
221 bool returnsListElementType(Selector selector, TypeMask mask); 227 bool returnsListElementType(Selector selector, TypeMask mask);
222 228
223 bool returnsMapValueType(Selector selector, TypeMask mask); 229 bool returnsMapValueType(Selector selector, TypeMask mask);
224 230
225 void clear(); 231 void clear();
232
233 /// Returns true if global optimizations such as type inferencing can apply to
234 /// the field [element].
235 ///
236 /// One category of elements that do not apply is runtime helpers that the
237 /// backend calls, but the optimizations don't see those calls.
238 bool canFieldBeUsedForGlobalOptimizations(FieldEntity element);
239
240 /// Returns true if global optimizations such as type inferencing can apply to
241 /// the parameter [element].
242 ///
243 /// One category of elements that do not apply is runtime helpers that the
244 /// backend calls, but the optimizations don't see those calls.
245 bool canFunctionParametersBeUsedForGlobalOptimizations(
246 FunctionEntity function);
226 } 247 }
227 248
228 abstract class InferrerEngineImpl<T> extends InferrerEngine<T> { 249 abstract class InferrerEngineImpl<T> extends InferrerEngine<T> {
229 final Map<Local, TypeInformation> defaultTypeOfParameter = 250 final Map<Local, TypeInformation> defaultTypeOfParameter =
230 new Map<Local, TypeInformation>(); 251 new Map<Local, TypeInformation>();
231 final WorkQueue workQueue = new WorkQueue(); 252 final WorkQueue workQueue = new WorkQueue();
232 final FunctionEntity mainElement; 253 final FunctionEntity mainElement;
233 final Set<MemberEntity> analyzedElements = new Set<MemberEntity>(); 254 final Set<MemberEntity> analyzedElements = new Set<MemberEntity>();
234 255
235 /// The maximum number of times we allow a node in the graph to 256 /// The maximum number of times we allow a node in the graph to
236 /// change types. If a node reaches that limit, we give up 257 /// change types. If a node reaches that limit, we give up
237 /// inferencing on it and give it the dynamic type. 258 /// inferencing on it and give it the dynamic type.
238 final int MAX_CHANGE_COUNT = 6; 259 final int MAX_CHANGE_COUNT = 6;
239 260
240 int overallRefineCount = 0; 261 int overallRefineCount = 0;
241 int addedInGraph = 0; 262 int addedInGraph = 0;
242 263
243 final Compiler compiler; 264 final CompilerOptions options;
265 final Progress progress;
266 final DiagnosticReporter reporter;
267 final CompilerOutput _compilerOutput;
268 final OptimizerHintsForTests optimizerHints;
244 269
245 /// The [ClosedWorld] on which inference reasoning is based. 270 /// The [ClosedWorld] on which inference reasoning is based.
246 final ClosedWorld closedWorld; 271 final ClosedWorld closedWorld;
247 272
248 final ClosedWorldRefiner closedWorldRefiner; 273 final ClosedWorldRefiner closedWorldRefiner;
249 final TypeSystem<T> types; 274 final TypeSystem<T> types;
250 final Map<T, TypeInformation> concreteTypes = new Map<T, TypeInformation>(); 275 final Map<T, TypeInformation> concreteTypes = new Map<T, TypeInformation>();
251 276
252 final Map<ir.Node, TypeInformation> concreteKernelTypes = 277 final Map<ir.Node, TypeInformation> concreteKernelTypes =
253 new Map<ir.Node, TypeInformation>(); 278 new Map<ir.Node, TypeInformation>();
254 final Set<ConstructorEntity> generativeConstructorsExposingThis = 279 final Set<ConstructorEntity> generativeConstructorsExposingThis =
255 new Set<ConstructorEntity>(); 280 new Set<ConstructorEntity>();
256 281
257 /// Data computed internally within elements, like the type-mask of a send a 282 /// Data computed internally within elements, like the type-mask of a send a
258 /// list allocation, or a for-in loop. 283 /// list allocation, or a for-in loop.
259 final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData = 284 final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData =
260 new Map<MemberEntity, GlobalTypeInferenceElementData>(); 285 new Map<MemberEntity, GlobalTypeInferenceElementData>();
261 286
287 // TODO(johnniwinther): This should be accessible throught [closedWorld].
288 final MirrorsData mirrorsData;
289
290 final NoSuchMethodRegistry noSuchMethodRegistry;
291
262 InferrerEngineImpl( 292 InferrerEngineImpl(
263 this.compiler, 293 this.options,
264 ClosedWorld closedWorld, 294 this.progress,
295 this.reporter,
296 this._compilerOutput,
297 this.optimizerHints,
298 this.closedWorld,
265 this.closedWorldRefiner, 299 this.closedWorldRefiner,
300 this.mirrorsData,
301 this.noSuchMethodRegistry,
266 this.mainElement, 302 this.mainElement,
267 TypeSystemStrategy<T> typeSystemStrategy) 303 TypeSystemStrategy<T> typeSystemStrategy)
268 : this.types = new TypeSystem<T>(closedWorld, typeSystemStrategy), 304 : this.types = new TypeSystem<T>(closedWorld, typeSystemStrategy);
269 this.closedWorld = closedWorld;
270 305
271 void forEachElementMatching( 306 void forEachElementMatching(
272 Selector selector, TypeMask mask, bool f(MemberEntity element)) { 307 Selector selector, TypeMask mask, bool f(MemberEntity element)) {
273 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask); 308 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask);
274 for (MemberEntity e in elements) { 309 for (MemberEntity e in elements) {
275 if (!f(e)) return; 310 if (!f(e)) return;
276 } 311 }
277 } 312 }
278 313
279 GlobalTypeInferenceElementData<T> createElementData(); 314 GlobalTypeInferenceElementData<T> createElementData();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 } 485 }
451 486
452 info.markAsInferred(); 487 info.markAsInferred();
453 workQueue.add(info.keyType); 488 workQueue.add(info.keyType);
454 workQueue.add(info.valueType); 489 workQueue.add(info.valueType);
455 workQueue.addAll(info.typeInfoMap.values); 490 workQueue.addAll(info.typeInfoMap.values);
456 workQueue.add(info); 491 workQueue.add(info);
457 } 492 }
458 493
459 void runOverAllElements() { 494 void runOverAllElements() {
460 if (compiler.disableTypeInference) return; 495 progress.startPhase();
461 if (compiler.options.verbose) { 496
462 compiler.progress.reset();
463 }
464 analyzeAllElements(); 497 analyzeAllElements();
465 498
466 TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null; 499 TypeGraphDump dump =
500 debug.PRINT_GRAPH ? new TypeGraphDump(_compilerOutput, this) : null;
467 501
468 dump?.beforeAnalysis(); 502 dump?.beforeAnalysis();
469 buildWorkQueue(); 503 buildWorkQueue();
470 refine(); 504 refine();
471 505
472 // Try to infer element types of lists and compute their escape information. 506 // Try to infer element types of lists and compute their escape information.
473 types.allocatedLists.values.forEach((TypeInformation info) { 507 types.allocatedLists.values.forEach((TypeInformation info) {
474 analyzeListAndEnqueue(info); 508 analyzeListAndEnqueue(info);
475 }); 509 });
476 510
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 657
624 reporter.log('Inferred $overallRefineCount types.'); 658 reporter.log('Inferred $overallRefineCount types.');
625 659
626 processLoopInformation(); 660 processLoopInformation();
627 } 661 }
628 662
629 /// Call [analyze] for all live members. 663 /// Call [analyze] for all live members.
630 void analyzeAllElements() { 664 void analyzeAllElements() {
631 sortMembers(closedWorld.processedMembers, computeMemberSize) 665 sortMembers(closedWorld.processedMembers, computeMemberSize)
632 .forEach((MemberEntity member) { 666 .forEach((MemberEntity member) {
633 if (compiler.shouldPrintProgress) { 667 progress.showProgress(
634 reporter.log('Added $addedInGraph elements in inferencing graph.'); 668 'Added ', addedInGraph, ' elements in inferencing graph.');
635 compiler.progress.reset();
636 }
637 // This also forces the creation of the [ElementTypeInformation] to ensure 669 // This also forces the creation of the [ElementTypeInformation] to ensure
638 // it is in the graph. 670 // it is in the graph.
639 T body = computeMemberBody(member); 671 T body = computeMemberBody(member);
640 types.withMember(member, () => analyze(member, body, null)); 672 types.withMember(member, () => analyze(member, body, null));
641 }); 673 });
642 reporter.log('Added $addedInGraph elements in inferencing graph.'); 674 reporter.log('Added $addedInGraph elements in inferencing graph.');
643 } 675 }
644 676
645 /// Compute a 'size' of [member] used for sorting member for the type 677 /// Compute a 'size' of [member] used for sorting member for the type
646 /// inference work-queue. Smallest members are processed first. 678 /// inference work-queue. Smallest members are processed first.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 // on the code bloat. 772 // on the code bloat.
741 info.targets.forEach((MemberEntity element) { 773 info.targets.forEach((MemberEntity element) {
742 closedWorldRefiner.addFunctionCalledInLoop(element); 774 closedWorldRefiner.addFunctionCalledInLoop(element);
743 }); 775 });
744 } 776 }
745 }); 777 });
746 } 778 }
747 779
748 void refine() { 780 void refine() {
749 while (!workQueue.isEmpty) { 781 while (!workQueue.isEmpty) {
750 if (compiler.shouldPrintProgress) { 782 progress.showProgress('Inferred ', overallRefineCount, ' types.');
751 reporter.log('Inferred $overallRefineCount types.');
752 compiler.progress.reset();
753 }
754 TypeInformation info = workQueue.remove(); 783 TypeInformation info = workQueue.remove();
755 TypeMask oldType = info.type; 784 TypeMask oldType = info.type;
756 TypeMask newType = info.refine(this); 785 TypeMask newType = info.refine(this);
757 // Check that refinement has not accidentally changed the type. 786 // Check that refinement has not accidentally changed the type.
758 assert(oldType == info.type); 787 assert(oldType == info.type);
759 if (info.abandonInferencing) info.doNotEnqueue = true; 788 if (info.abandonInferencing) info.doNotEnqueue = true;
760 if ((info.type = newType) != oldType) { 789 if ((info.type = newType) != oldType) {
761 overallRefineCount++; 790 overallRefineCount++;
762 info.refineCount++; 791 info.refineCount++;
763 if (info.refineCount > MAX_CHANGE_COUNT) { 792 if (info.refineCount > MAX_CHANGE_COUNT) {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 types.allocatedClosures.clear(); 1093 types.allocatedClosures.clear();
1065 1094
1066 analyzedElements.clear(); 1095 analyzedElements.clear();
1067 generativeConstructorsExposingThis.clear(); 1096 generativeConstructorsExposingThis.clear();
1068 1097
1069 types.allocatedMaps.values.forEach(cleanup); 1098 types.allocatedMaps.values.forEach(cleanup);
1070 types.allocatedLists.values.forEach(cleanup); 1099 types.allocatedLists.values.forEach(cleanup);
1071 } 1100 }
1072 1101
1073 Iterable<MemberEntity> getCallersOf(MemberEntity element) { 1102 Iterable<MemberEntity> getCallersOf(MemberEntity element) {
1074 if (compiler.disableTypeInference) {
1075 throw new UnsupportedError(
1076 "Cannot query the type inferrer when type inference is disabled.");
1077 }
1078 MemberTypeInformation info = types.getInferredTypeOfMember(element); 1103 MemberTypeInformation info = types.getInferredTypeOfMember(element);
1079 return info.callers; 1104 return info.callers;
1080 } 1105 }
1081 1106
1082 TypeInformation typeOfMemberWithSelector( 1107 TypeInformation typeOfMemberWithSelector(
1083 covariant MemberElement element, Selector selector) { 1108 covariant MemberElement element, Selector selector) {
1084 if (element.name == Identifiers.noSuchMethod_ && 1109 if (element.name == Identifiers.noSuchMethod_ &&
1085 selector.name != element.name) { 1110 selector.name != element.name) {
1086 // An invocation can resolve to a [noSuchMethod], in which case 1111 // An invocation can resolve to a [noSuchMethod], in which case
1087 // we get the return type of [noSuchMethod]. 1112 // we get the return type of [noSuchMethod].
(...skipping 13 matching lines...) Expand all
1101 return returnTypeOfMember(element); 1126 return returnTypeOfMember(element);
1102 } 1127 }
1103 } else if (element.isGetter || element.isField) { 1128 } else if (element.isGetter || element.isField) {
1104 assert(selector.isCall || selector.isSetter); 1129 assert(selector.isCall || selector.isSetter);
1105 return types.dynamicType; 1130 return types.dynamicType;
1106 } else { 1131 } else {
1107 return returnTypeOfMember(element); 1132 return returnTypeOfMember(element);
1108 } 1133 }
1109 } 1134 }
1110 1135
1136 /// Returns true if global optimizations such as type inferencing can apply to
1137 /// the field [element].
1138 ///
1139 /// One category of elements that do not apply is runtime helpers that the
1140 /// backend calls, but the optimizations don't see those calls.
1141 bool canFieldBeUsedForGlobalOptimizations(FieldEntity element) {
1142 if (closedWorld.backendUsage.isFieldUsedByBackend(element)) {
1143 return false;
1144 }
1145 if ((element.isTopLevel || element.isStatic) && !element.isAssignable) {
1146 return true;
1147 }
1148 return !mirrorsData.isMemberAccessibleByReflection(element);
1149 }
1150
1151 /// Returns true if global optimizations such as type inferencing can apply to
1152 /// the parameter [element].
1153 ///
1154 /// One category of elements that do not apply is runtime helpers that the
1155 /// backend calls, but the optimizations don't see those calls.
1156 bool canFunctionParametersBeUsedForGlobalOptimizations(
1157 FunctionEntity function) {
1158 return !closedWorld.backendUsage.isFunctionUsedByBackend(function) &&
1159 !mirrorsData.isMemberAccessibleByReflection(function);
1160 }
1161
1111 // Sorts the resolved elements by size. We do this for this inferrer 1162 // Sorts the resolved elements by size. We do this for this inferrer
1112 // to get the same results for [ListTracer] compared to the 1163 // to get the same results for [ListTracer] compared to the
1113 // [SimpleTypesInferrer]. 1164 // [SimpleTypesInferrer].
1114 static Iterable<MemberEntity> sortMembers( 1165 static Iterable<MemberEntity> sortMembers(
1115 Iterable<MemberEntity> members, int computeSize(MemberEntity member)) { 1166 Iterable<MemberEntity> members, int computeSize(MemberEntity member)) {
1116 Map<int, Set<MemberEntity>> methodSizes = 1167 Map<int, Set<MemberEntity>> methodSizes =
1117 groupMembers(members, computeSize); 1168 groupMembers(members, computeSize);
1118 int max = methodSizes.keys.fold(0, (a, b) => a > b ? a : b); 1169 int max = methodSizes.keys.fold(0, (a, b) => a > b ? a : b);
1119 List<MemberEntity> result = <MemberEntity>[]; 1170 List<MemberEntity> result = <MemberEntity>[];
1120 for (int i = 0; i <= max; i++) { 1171 for (int i = 0; i <= max; i++) {
(...skipping 11 matching lines...) Expand all
1132 // Put the other operators in buckets by size, later to be added in 1183 // Put the other operators in buckets by size, later to be added in
1133 // size order. 1184 // size order.
1134 int size = computeSize(element); 1185 int size = computeSize(element);
1135 Set<MemberEntity> set = 1186 Set<MemberEntity> set =
1136 methodSizes.putIfAbsent(size, () => new Setlet<MemberEntity>()); 1187 methodSizes.putIfAbsent(size, () => new Setlet<MemberEntity>());
1137 set.add(element); 1188 set.add(element);
1138 }); 1189 });
1139 return methodSizes; 1190 return methodSizes;
1140 } 1191 }
1141 } 1192 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart ('k') | pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698