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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2512023002: Add types for map literal construction with kernel code. (Closed)
Patch Set: implicitInstantiations Created 4 years, 1 month 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 | « no previous file | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 '../common.dart'; 7 import '../common.dart';
8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
9 import '../common/names.dart'; 9 import '../common/names.dart';
10 import '../common/tasks.dart' show CompilerTask; 10 import '../common/tasks.dart' show CompilerTask;
(...skipping 11 matching lines...) Expand all
22 import '../universe/selector.dart'; 22 import '../universe/selector.dart';
23 import '../universe/use.dart' show TypeUse; 23 import '../universe/use.dart' show TypeUse;
24 import 'graph_builder.dart'; 24 import 'graph_builder.dart';
25 import 'kernel_ast_adapter.dart'; 25 import 'kernel_ast_adapter.dart';
26 import 'kernel_string_builder.dart'; 26 import 'kernel_string_builder.dart';
27 import 'locals_handler.dart'; 27 import 'locals_handler.dart';
28 import 'loop_handler.dart'; 28 import 'loop_handler.dart';
29 import 'nodes.dart'; 29 import 'nodes.dart';
30 import 'ssa_branch_builder.dart'; 30 import 'ssa_branch_builder.dart';
31 import 'type_builder.dart'; 31 import 'type_builder.dart';
32 import 'types.dart' show TypeMaskFactory;
32 33
33 class SsaKernelBuilderTask extends CompilerTask { 34 class SsaKernelBuilderTask extends CompilerTask {
34 final JavaScriptBackend backend; 35 final JavaScriptBackend backend;
35 final SourceInformationStrategy sourceInformationFactory; 36 final SourceInformationStrategy sourceInformationFactory;
36 37
37 String get name => 'SSA kernel builder'; 38 String get name => 'SSA kernel builder';
38 39
39 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) 40 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
40 : backend = backend, 41 : backend = backend,
41 super(backend.compiler.measurer); 42 super(backend.compiler.measurer);
42 43
43 HGraph build(CodegenWorkItem work) { 44 HGraph build(CodegenWorkItem work) {
44 return measure(() { 45 return measure(() {
45 AstElement element = work.element.implementation; 46 AstElement element = work.element.implementation;
46 Kernel kernel = backend.kernelTask.kernel; 47 Kernel kernel = backend.kernelTask.kernel;
47 KernelSsaBuilder builder = new KernelSsaBuilder(element, work.resolvedAst, 48 KernelSsaBuilder builder = new KernelSsaBuilder(element, work.resolvedAst,
48 backend.compiler, work.registry, sourceInformationFactory, kernel); 49 backend.compiler, work.registry, sourceInformationFactory, kernel);
49 return builder.build(); 50 return builder.build();
50 }); 51 });
51 } 52 }
52 } 53 }
53 54
54 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { 55 class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
55 ir.Node target; 56 ir.Node target;
56 final AstElement targetElement; 57 final AstElement targetElement;
57 final ResolvedAst resolvedAst; 58 final ResolvedAst resolvedAst;
58 final CodegenRegistry registry; 59 final CodegenRegistry registry;
59 60
61 /// A stack of [DartType]s that have been seen during inlining of factory
62 /// constructors. These types are preserved in [HInvokeStatic]s and
63 /// [HCreate]s inside the inline code and registered during code generation
64 /// for these nodes.
65 // TODO(karlklose): consider removing this and keeping the (substituted) types
66 // of the type variables in an environment (like the [LocalsHandler]).
67 final List<DartType> currentImplicitInstantiations = <DartType>[];
68
60 @override 69 @override
61 JavaScriptBackend get backend => compiler.backend; 70 JavaScriptBackend get backend => compiler.backend;
62 71
63 @override 72 @override
64 TreeElements get elements => resolvedAst.elements; 73 TreeElements get elements => resolvedAst.elements;
65 74
66 SourceInformationBuilder sourceInformationBuilder; 75 SourceInformationBuilder sourceInformationBuilder;
67 KernelAstAdapter astAdapter; 76 KernelAstAdapter astAdapter;
68 LoopHandler<ir.Node> loopHandler; 77 LoopHandler<ir.Node> loopHandler;
69 TypeBuilder typeBuilder; 78 TypeBuilder typeBuilder;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 type, kind, original.instructionType, reifiedType, original); 322 type, kind, original.instructionType, reifiedType, original);
314 } 323 }
315 324
316 /// Builds a SSA graph for [procedure]. 325 /// Builds a SSA graph for [procedure].
317 void buildProcedure(ir.Procedure procedure) { 326 void buildProcedure(ir.Procedure procedure) {
318 openFunction(); 327 openFunction();
319 procedure.function.body.accept(this); 328 procedure.function.body.accept(this);
320 closeFunction(); 329 closeFunction();
321 } 330 }
322 331
332 void addImplicitInstantiation(DartType type) {
333 if (type != null) {
334 currentImplicitInstantiations.add(type);
335 }
336 }
337
338 void removeImplicitInstantiation(DartType type) {
339 if (type != null) {
340 currentImplicitInstantiations.removeLast();
341 }
342 }
343
323 void openFunction() { 344 void openFunction() {
324 HBasicBlock block = graph.addNewBlock(); 345 HBasicBlock block = graph.addNewBlock();
325 open(graph.entry); 346 open(graph.entry);
326 347
327 Node function; 348 Node function;
328 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 349 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
329 function = resolvedAst.node; 350 function = resolvedAst.node;
330 } 351 }
331 localsHandler.startFunction(targetElement, function); 352 localsHandler.startFunction(targetElement, function);
332 close(new HGoto()).addSuccessor(block); 353 close(new HGoto()).addSuccessor(block);
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 stack.add(graph.addConstant( 729 stack.add(graph.addConstant(
709 astAdapter.getConstantForSymbol(symbolLiteral), compiler)); 730 astAdapter.getConstantForSymbol(symbolLiteral), compiler));
710 registry?.registerConstSymbol(symbolLiteral.value); 731 registry?.registerConstSymbol(symbolLiteral.value);
711 } 732 }
712 733
713 @override 734 @override
714 void visitNullLiteral(ir.NullLiteral nullLiteral) { 735 void visitNullLiteral(ir.NullLiteral nullLiteral) {
715 stack.add(graph.addConstantNull(compiler)); 736 stack.add(graph.addConstantNull(compiler));
716 } 737 }
717 738
718 HInstruction setRtiIfNeeded(HInstruction object, ir.ListLiteral listLiteral) { 739 /// Set the runtime type information if necessary.
740 HInstruction setListRuntimeTypeInfoIfNeeded(
741 HInstruction object, ir.ListLiteral listLiteral) {
719 InterfaceType type = localsHandler 742 InterfaceType type = localsHandler
720 .substInContext(elements.getType(astAdapter.getNode(listLiteral))); 743 .substInContext(elements.getType(astAdapter.getNode(listLiteral)));
721 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 744 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
722 return object; 745 return object;
723 } 746 }
724 List<HInstruction> arguments = <HInstruction>[]; 747 List<HInstruction> arguments = <HInstruction>[];
725 for (DartType argument in type.typeArguments) { 748 for (DartType argument in type.typeArguments) {
726 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 749 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
727 } 750 }
728 // TODO(15489): Register at codegen. 751 // TODO(15489): Register at codegen.
729 registry?.registerInstantiation(type); 752 registry?.registerInstantiation(type);
730 return callSetRuntimeTypeInfoWithTypeArguments(type, arguments, object); 753 return callSetRuntimeTypeInfoWithTypeArguments(type, arguments, object);
731 } 754 }
732 755
733 @override 756 @override
734 void visitListLiteral(ir.ListLiteral listLiteral) { 757 void visitListLiteral(ir.ListLiteral listLiteral) {
735 HInstruction listInstruction; 758 HInstruction listInstruction;
736 if (listLiteral.isConst) { 759 if (listLiteral.isConst) {
737 listInstruction = 760 listInstruction =
738 graph.addConstant(astAdapter.getConstantFor(listLiteral), compiler); 761 graph.addConstant(astAdapter.getConstantFor(listLiteral), compiler);
739 } else { 762 } else {
740 List<HInstruction> elements = <HInstruction>[]; 763 List<HInstruction> elements = <HInstruction>[];
741 for (ir.Expression element in listLiteral.expressions) { 764 for (ir.Expression element in listLiteral.expressions) {
742 element.accept(this); 765 element.accept(this);
743 elements.add(pop()); 766 elements.add(pop());
744 } 767 }
745 listInstruction = new HLiteralList(elements, backend.extendableArrayType); 768 listInstruction = new HLiteralList(elements, backend.extendableArrayType);
746 add(listInstruction); 769 add(listInstruction);
747 listInstruction = setRtiIfNeeded(listInstruction, listLiteral); 770 listInstruction =
771 setListRuntimeTypeInfoIfNeeded(listInstruction, listLiteral);
748 } 772 }
749 773
750 TypeMask type = astAdapter.typeOfNewList(targetElement, listLiteral); 774 TypeMask type = astAdapter.typeOfNewList(targetElement, listLiteral);
751 if (!type.containsAll(compiler.closedWorld)) { 775 if (!type.containsAll(compiler.closedWorld)) {
752 listInstruction.instructionType = type; 776 listInstruction.instructionType = type;
753 } 777 }
754 stack.add(listInstruction); 778 stack.add(listInstruction);
755 } 779 }
756 780
757 @override 781 @override
(...skipping 18 matching lines...) Expand all
776 if (constructorArgs.isEmpty) { 800 if (constructorArgs.isEmpty) {
777 constructor = astAdapter.mapLiteralConstructorEmpty; 801 constructor = astAdapter.mapLiteralConstructorEmpty;
778 } else { 802 } else {
779 constructor = astAdapter.mapLiteralConstructor; 803 constructor = astAdapter.mapLiteralConstructor;
780 HLiteralList argList = 804 HLiteralList argList =
781 new HLiteralList(constructorArgs, backend.extendableArrayType); 805 new HLiteralList(constructorArgs, backend.extendableArrayType);
782 add(argList); 806 add(argList);
783 inputs.add(argList); 807 inputs.add(argList);
784 } 808 }
785 809
786 // TODO(het): Add type information 810 assert(constructor.kind == ir.ProcedureKind.Factory);
787 _pushStaticInvocation(constructor, inputs, backend.dynamicType); 811
812 InterfaceType type = localsHandler
813 .substInContext(elements.getType(astAdapter.getNode(mapLiteral)));
814
815 ir.Class cls = constructor.enclosingClass;
816
817 if (backend.classNeedsRti(astAdapter.getElement(cls))) {
818 List<HInstruction> typeInputs = <HInstruction>[];
819 type.typeArguments.forEach((DartType argument) {
820 typeInputs
821 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
822 });
823
824 // We lift this common call pattern into a helper function to save space
825 // in the output.
826 if (typeInputs.every((HInstruction input) => input.isNull())) {
827 if (constructorArgs.isEmpty) {
828 constructor = astAdapter.mapLiteralUntypedEmptyMaker;
829 } else {
830 constructor = astAdapter.mapLiteralUntypedMaker;
831 }
832 } else {
833 inputs.addAll(typeInputs);
834 }
835 }
836
837 // If runtime type information is needed and the map literal has no type
838 // parameters, 'constructor' is a static function that forwards the call to
839 // the factory constructor without type parameters.
840 assert(constructor.kind == ir.ProcedureKind.Factory);
841
842 // The instruction type will always be a subtype of the mapLiteralClass, but
843 // type inference might discover a more specific type, or find nothing (in
844 // dart2js unit tests).
845 TypeMask mapType = new TypeMask.nonNullSubtype(
846 astAdapter.getElement(astAdapter.mapLiteralClass),
847 compiler.closedWorld);
848 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
849 astAdapter.getElement(constructor), compiler);
850 TypeMask instructionType =
851 mapType.intersection(returnTypeMask, compiler.closedWorld);
852
853 addImplicitInstantiation(type);
854 _pushStaticInvocation(constructor, inputs, instructionType);
855 removeImplicitInstantiation(type);
788 } 856 }
789 857
790 @override 858 @override
791 void visitMapEntry(ir.MapEntry mapEntry) { 859 void visitMapEntry(ir.MapEntry mapEntry) {
792 // Visit value before the key because each will push an expression to the 860 // Visit value before the key because each will push an expression to the
793 // stack, so when we pop them off, the key is popped first, then the value. 861 // stack, so when we pop them off, the key is popped first, then the value.
794 mapEntry.value.accept(this); 862 mapEntry.value.accept(this);
795 mapEntry.key.accept(this); 863 mapEntry.key.accept(this);
796 } 864 }
797 865
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 List<HInstruction> arguments = _visitArguments(invocation.arguments); 978 List<HInstruction> arguments = _visitArguments(invocation.arguments);
911 979
912 _pushStaticInvocation(target, arguments, typeMask); 980 _pushStaticInvocation(target, arguments, typeMask);
913 } 981 }
914 982
915 void _pushStaticInvocation( 983 void _pushStaticInvocation(
916 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) { 984 ir.Node target, List<HInstruction> arguments, TypeMask typeMask) {
917 HInstruction instruction = new HInvokeStatic( 985 HInstruction instruction = new HInvokeStatic(
918 astAdapter.getMember(target), arguments, typeMask, 986 astAdapter.getMember(target), arguments, typeMask,
919 targetCanThrow: astAdapter.getCanThrow(target)); 987 targetCanThrow: astAdapter.getCanThrow(target));
988 if (currentImplicitInstantiations.isNotEmpty) {
989 instruction.instantiatedTypes =
990 new List<DartType>.from(currentImplicitInstantiations);
991 }
920 instruction.sideEffects = astAdapter.getSideEffects(target); 992 instruction.sideEffects = astAdapter.getSideEffects(target);
921 993
922 push(instruction); 994 push(instruction);
923 } 995 }
924 996
925 void _pushDynamicInvocation( 997 void _pushDynamicInvocation(
926 ir.Node node, TypeMask mask, List<HInstruction> arguments, 998 ir.Node node, TypeMask mask, List<HInstruction> arguments,
927 {Selector selector}) { 999 {Selector selector}) {
928 HInstruction receiver = arguments.first; 1000 HInstruction receiver = arguments.first;
929 List<HInstruction> inputs = <HInstruction>[]; 1001 List<HInstruction> inputs = <HInstruction>[];
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 push(new HNot(popBoolified(), backend.boolType)); 1123 push(new HNot(popBoolified(), backend.boolType));
1052 } 1124 }
1053 1125
1054 @override 1126 @override
1055 void visitStringConcatenation(ir.StringConcatenation stringConcat) { 1127 void visitStringConcatenation(ir.StringConcatenation stringConcat) {
1056 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); 1128 KernelStringBuilder stringBuilder = new KernelStringBuilder(this);
1057 stringConcat.accept(stringBuilder); 1129 stringConcat.accept(stringBuilder);
1058 stack.add(stringBuilder.result); 1130 stack.add(stringBuilder.result);
1059 } 1131 }
1060 } 1132 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698