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

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

Issue 2258523002: Dummy receiver optimization for super calls (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Use receiver type - synthesized type was invalid for abstract superclass Created 4 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 | « no previous file | no next file » | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 '../compiler.dart' show Compiler; 5 import '../compiler.dart' show Compiler;
6 import '../constants/values.dart'; 6 import '../constants/values.dart';
7 import '../elements/elements.dart'; 7 import '../elements/elements.dart';
8 import '../js_backend/js_backend.dart'; 8 import '../js_backend/js_backend.dart';
9 import '../types/types.dart'; 9 import '../types/types.dart';
10 import '../universe/selector.dart' show Selector; 10 import '../universe/selector.dart' show Selector;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 (left.isPrimitive(compiler) && leftType == rightType)) { 89 (left.isPrimitive(compiler) && leftType == rightType)) {
90 return '=='; 90 return '==';
91 } 91 }
92 return null; 92 return null;
93 } 93 }
94 return '==='; 94 return '===';
95 } 95 }
96 96
97 HInstruction visitInvokeDynamic(HInvokeDynamic node) { 97 HInstruction visitInvokeDynamic(HInvokeDynamic node) {
98 if (node.isInterceptedCall) { 98 if (node.isInterceptedCall) {
99 // Calls of the form 99 tryReplaceInterceptorWithDummy(node, node.selector, node.mask);
100 //
101 // a.foo$1(a, x)
102 //
103 // where the interceptor calling convention is used come from recognizing
104 // that 'a' is a 'self-interceptor'. If the selector matches only methods
105 // that ignore the explicit receiver parameter, replace occurences of the
106 // receiver argument with a dummy receiver '0':
107 //
108 // a.foo$1(a, x) ---> a.foo$1(0, x)
109 //
110 // This often reduces the number of references to 'a' to one, allowing 'a'
111 // to be generated at use to avoid a temporary, e.g.
112 //
113 // t1 = b.get$thing();
114 // t1.foo$1(t1, x)
115 // --->
116 // b.get$thing().foo$1(0, x)
117 //
118 Selector selector = node.selector;
119 TypeMask mask = node.mask;
120 if (backend.isInterceptedSelector(selector) &&
121 !backend.isInterceptedMixinSelector(selector, mask)) {
122 HInstruction interceptor = node.inputs[0];
123 HInstruction receiverArgument = node.inputs[1];
124
125 if (interceptor.nonCheck() == receiverArgument.nonCheck()) {
126 // TODO(15933): Make automatically generated property extraction
127 // closures work with the dummy receiver optimization.
128 if (!selector.isGetter) {
129 ConstantValue constant = new SyntheticConstantValue(
130 SyntheticConstantKind.DUMMY_INTERCEPTOR,
131 receiverArgument.instructionType);
132 HConstant dummy = graph.addConstant(constant, compiler);
133 receiverArgument.usedBy.remove(node);
134 node.inputs[1] = dummy;
135 dummy.usedBy.add(node);
136 }
137 }
138 }
139 } 100 }
140
141 return node; 101 return node;
142 } 102 }
143 103
104 HInstruction visitInvokeSuper(HInvokeSuper node) {
105 if (node.isInterceptedCall) {
106 TypeMask mask = node.getDartReceiver(compiler).instructionType;
107 tryReplaceInterceptorWithDummy(node, node.selector, mask);
108 }
109 return node;
110 }
111
112 void tryReplaceInterceptorWithDummy(
113 HInvoke node, Selector selector, TypeMask mask) {
114 // Calls of the form
115 //
116 // a.foo$1(a, x)
117 //
118 // where the interceptor calling convention is used come from recognizing
119 // that 'a' is a 'self-interceptor'. If the selector matches only methods
120 // that ignore the explicit receiver parameter, replace occurences of the
121 // receiver argument with a dummy receiver '0':
122 //
123 // a.foo$1(a, x) ---> a.foo$1(0, x)
124 //
125 // This often reduces the number of references to 'a' to one, allowing 'a'
126 // to be generated at use to avoid a temporary, e.g.
127 //
128 // t1 = b.get$thing();
129 // t1.foo$1(t1, x)
130 // --->
131 // b.get$thing().foo$1(0, x)
132 //
133
134 // TODO(15933): Make automatically generated property extraction closures
135 // work with the dummy receiver optimization.
136 if (selector.isGetter) return;
137
138 // This assignment of inputs is uniform for HInvokeDynamic and HInvokeSuper.
139 HInstruction interceptor = node.inputs[0];
140 HInstruction receiverArgument = node.inputs[1];
141
142 if (interceptor.nonCheck() == receiverArgument.nonCheck()) {
143 if (backend.isInterceptedSelector(selector) &&
144 !backend.isInterceptedMixinSelector(selector, mask)) {
145 ConstantValue constant = new SyntheticConstantValue(
146 SyntheticConstantKind.DUMMY_INTERCEPTOR,
147 receiverArgument.instructionType);
148 HConstant dummy = graph.addConstant(constant, compiler);
149 receiverArgument.usedBy.remove(node);
150 node.inputs[1] = dummy;
151 dummy.usedBy.add(node);
152 }
153 }
154 }
155
144 HInstruction visitFieldSet(HFieldSet setter) { 156 HInstruction visitFieldSet(HFieldSet setter) {
145 // Pattern match 157 // Pattern match
146 // t1 = x.f; t2 = t1 + 1; x.f = t2; use(t2) --> ++x.f 158 // t1 = x.f; t2 = t1 + 1; x.f = t2; use(t2) --> ++x.f
147 // t1 = x.f; t2 = t1 op y; x.f = t2; use(t2) --> x.f op= y 159 // t1 = x.f; t2 = t1 op y; x.f = t2; use(t2) --> x.f op= y
148 // t1 = x.f; t2 = t1 + 1; x.f = t2; use(t1) --> x.f++ 160 // t1 = x.f; t2 = t1 + 1; x.f = t2; use(t1) --> x.f++
149 HBasicBlock block = setter.block; 161 HBasicBlock block = setter.block;
150 HInstruction op = setter.value; 162 HInstruction op = setter.value;
151 HInstruction receiver = setter.receiver; 163 HInstruction receiver = setter.receiver;
152 164
153 bool isMatchingRead(HInstruction candidate) { 165 bool isMatchingRead(HInstruction candidate) {
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 } 788 }
777 789
778 // If [thenInput] is defined in the first predecessor, then it is only used 790 // If [thenInput] is defined in the first predecessor, then it is only used
779 // by [phi] and can be generated at use site. 791 // by [phi] and can be generated at use site.
780 if (identical(thenInput.block, end.predecessors[0])) { 792 if (identical(thenInput.block, end.predecessors[0])) {
781 assert(thenInput.usedBy.length == 1); 793 assert(thenInput.usedBy.length == 1);
782 markAsGenerateAtUseSite(thenInput); 794 markAsGenerateAtUseSite(thenInput);
783 } 795 }
784 } 796 }
785 } 797 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698