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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 15834006: Remove last inlining restrictions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/js_backend/backend.dart ('k') | 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 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 LocalsHandler newLocalsHandler = new LocalsHandler(this); 1179 LocalsHandler newLocalsHandler = new LocalsHandler(this);
1180 newLocalsHandler.closureData = 1180 newLocalsHandler.closureData =
1181 compiler.closureToClassMapper.computeClosureToClassMapping( 1181 compiler.closureToClassMapper.computeClosureToClassMapping(
1182 function, function.parseNode(compiler), elements); 1182 function, function.parseNode(compiler), elements);
1183 int argumentIndex = 0; 1183 int argumentIndex = 0;
1184 if (isInstanceMember) { 1184 if (isInstanceMember) {
1185 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement, 1185 newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement,
1186 compiledArguments[argumentIndex++]); 1186 compiledArguments[argumentIndex++]);
1187 } 1187 }
1188 1188
1189 FunctionSignature signature = function.computeSignature(compiler);
1190 signature.orderedForEachParameter((Element parameter) {
1191 HInstruction argument = compiledArguments[argumentIndex++];
1192 newLocalsHandler.updateLocal(parameter, argument);
1193 });
1194
1189 ClassElement enclosing = function.getEnclosingClass(); 1195 ClassElement enclosing = function.getEnclosingClass();
1190 FunctionSignature signature = function.computeSignature(compiler);
1191 int parameterCount = signature.parameterCount;
1192 // If [function] is a generative constructor body, we need to add
1193 // 1 for the new instance.
1194 int typeArgumentIndex = parameterCount + (isInstanceMember ? 1 : 0);
1195 if ((function.isConstructor() || function.isGenerativeConstructorBody()) 1196 if ((function.isConstructor() || function.isGenerativeConstructorBody())
1196 && backend.needsRti(enclosing)) { 1197 && backend.needsRti(enclosing)) {
1197 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { 1198 enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
1198 HInstruction argument = compiledArguments[typeArgumentIndex++]; 1199 HInstruction argument = compiledArguments[argumentIndex++];
1199 newLocalsHandler.updateLocal(typeVariable.element, argument); 1200 newLocalsHandler.updateLocal(typeVariable.element, argument);
1200 }); 1201 });
1201 } 1202 }
1202 assert(typeArgumentIndex == compiledArguments.length); 1203 assert(argumentIndex == compiledArguments.length);
1203
1204 // Check the type of the arguments. This must be done after setting up the
1205 // type variables in the [localsHandler] because the checked types may
1206 // contain type variables.
1207 signature.orderedForEachParameter((Element parameter) {
1208 HInstruction argument = compiledArguments[argumentIndex++];
1209 newLocalsHandler.updateLocal(parameter, argument);
1210 potentiallyCheckType(argument, parameter.computeType(compiler));
1211 });
1212 assert(argumentIndex == parameterCount + (isInstanceMember ? 1 : 0));
1213 1204
1214 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here. 1205 // TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
1215 returnElement = new ElementX(const SourceString("result"), 1206 returnElement = new ElementX(const SourceString("result"),
1216 ElementKind.VARIABLE, 1207 ElementKind.VARIABLE,
1217 function); 1208 function);
1218 newLocalsHandler.updateLocal(returnElement, 1209 newLocalsHandler.updateLocal(returnElement,
1219 graph.addConstantNull(constantSystem)); 1210 graph.addConstantNull(constantSystem));
1220 elements = compiler.enqueuer.resolution.getCachedElements(function); 1211 elements = compiler.enqueuer.resolution.getCachedElements(function);
1221 assert(elements != null); 1212 assert(elements != null);
1222 returnType = signature.returnType; 1213 returnType = signature.returnType;
(...skipping 27 matching lines...) Expand all
1250 Node currentNode) { 1241 Node currentNode) {
1251 // We cannot inline a method from a deferred library into a method 1242 // We cannot inline a method from a deferred library into a method
1252 // which isn't deferred. 1243 // which isn't deferred.
1253 // TODO(ahe): But we should still inline into the same 1244 // TODO(ahe): But we should still inline into the same
1254 // connected-component of the deferred library. 1245 // connected-component of the deferred library.
1255 if (compiler.deferredLoadTask.isDeferred(element)) return false; 1246 if (compiler.deferredLoadTask.isDeferred(element)) return false;
1256 1247
1257 if (compiler.disableInlining) return false; 1248 if (compiler.disableInlining) return false;
1258 // Ensure that [element] is an implementation element. 1249 // Ensure that [element] is an implementation element.
1259 element = element.implementation; 1250 element = element.implementation;
1260 // TODO(floitsch): we should be able to inline inside lazy initializers.
1261 if (currentElement.isField()) return false;
1262 // TODO(floitsch): find a cleaner way to know if the element is a function 1251 // TODO(floitsch): find a cleaner way to know if the element is a function
1263 // containing nodes. 1252 // containing nodes.
1264 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s. 1253 // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s.
1265 if (element is !PartialFunctionElement 1254 if (element is !PartialFunctionElement
1266 && !element.isGenerativeConstructorBody()) { 1255 && !element.isGenerativeConstructorBody()) {
1267 return false; 1256 return false;
1268 } 1257 }
1269 if (inliningStack.length > MAX_INLINING_DEPTH) return false; 1258 if (inliningStack.length > MAX_INLINING_DEPTH) return false;
1270 // Don't inline recursive calls. We use the same elements for the inlined 1259 // Don't inline recursive calls. We use the same elements for the inlined
1271 // functions and would thus clobber our local variables. 1260 // functions and would thus clobber our local variables.
(...skipping 25 matching lines...) Expand all
1297 if (newElements == null) { 1286 if (newElements == null) {
1298 compiler.internalError("Element not resolved: $function"); 1287 compiler.internalError("Element not resolved: $function");
1299 } 1288 }
1300 1289
1301 if (canBeInlined == null) { 1290 if (canBeInlined == null) {
1302 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements); 1291 canBeInlined = InlineWeeder.canBeInlined(functionExpression, newElements);
1303 backend.canBeInlined[function] = canBeInlined; 1292 backend.canBeInlined[function] = canBeInlined;
1304 if (!canBeInlined) return false; 1293 if (!canBeInlined) return false;
1305 } 1294 }
1306 1295
1307 // We cannot inline methods with type variables in the signature in checked
1308 // mode, because we currently do not have access to the type variables
1309 // through the locals.
1310 // TODO(karlklose): remove this and enable inlining of these methods.
1311 if (compiler.enableTypeAssertions
1312 && !element.isGenerativeConstructorBody()
1313 && element.computeType(compiler).containsTypeVariables) {
1314 return false;
1315 }
1316
1317 assert(canBeInlined); 1296 assert(canBeInlined);
1318 // Add an explicit null check on the receiver before doing the 1297 // Add an explicit null check on the receiver before doing the
1319 // inlining. We use [element] to get the same name in the NoSuchMethodError 1298 // inlining. We use [element] to get the same name in the NoSuchMethodError
1320 // message as if we had called it. 1299 // message as if we had called it.
1321 if (element.isInstanceMember() 1300 if (element.isInstanceMember()
1322 && !element.isGenerativeConstructorBody() 1301 && !element.isGenerativeConstructorBody()
1323 && (selector.mask == null || selector.mask.isNullable)) { 1302 && (selector.mask == null || selector.mask.isNullable)) {
1324 addWithPosition( 1303 addWithPosition(
1325 new HFieldGet(element, providedArguments[0]), currentNode); 1304 new HFieldGet(element, providedArguments[0]), currentNode);
1326 } 1305 }
1327 InliningState state = enterInlinedMethod( 1306 InliningState state = enterInlinedMethod(
1328 function, selector, argumentsNodes, providedArguments, currentNode); 1307 function, selector, argumentsNodes, providedArguments, currentNode);
1308
1329 inlinedFrom(element, () { 1309 inlinedFrom(element, () {
1310 FunctionSignature signature = element.computeSignature(compiler);
1311 signature.orderedForEachParameter((Element parameter) {
1312 HInstruction argument = localsHandler.readLocal(parameter);
1313 potentiallyCheckType(argument, parameter.computeType(compiler));
1314 });
1330 element.isGenerativeConstructor() 1315 element.isGenerativeConstructor()
1331 ? buildFactory(element) 1316 ? buildFactory(element)
1332 : functionExpression.body.accept(this); 1317 : functionExpression.body.accept(this);
1333 }); 1318 });
1319
1334 leaveInlinedMethod(state); 1320 leaveInlinedMethod(state);
1335 return true; 1321 return true;
1336 } 1322 }
1337 1323
1338 inlinedFrom(Element element, f()) { 1324 inlinedFrom(Element element, f()) {
1339 assert(element is FunctionElement || element is VariableElement); 1325 assert(element is FunctionElement || element is VariableElement);
1340 return compiler.withCurrentElement(element, () { 1326 return compiler.withCurrentElement(element, () {
1341 sourceElementStack.add(element); 1327 sourceElementStack.add(element);
1342 var result = f(); 1328 var result = f();
1343 sourceElementStack.removeLast(); 1329 sourceElementStack.removeLast();
(...skipping 4051 matching lines...) Expand 10 before | Expand all | Expand 10 after
5395 new HSubGraphBlockInformation(elseBranch.graph)); 5381 new HSubGraphBlockInformation(elseBranch.graph));
5396 5382
5397 HBasicBlock conditionStartBlock = conditionBranch.block; 5383 HBasicBlock conditionStartBlock = conditionBranch.block;
5398 conditionStartBlock.setBlockFlow(info, joinBlock); 5384 conditionStartBlock.setBlockFlow(info, joinBlock);
5399 SubGraph conditionGraph = conditionBranch.graph; 5385 SubGraph conditionGraph = conditionBranch.graph;
5400 HIf branch = conditionGraph.end.last; 5386 HIf branch = conditionGraph.end.last;
5401 assert(branch is HIf); 5387 assert(branch is HIf);
5402 branch.blockInformation = conditionStartBlock.blockFlow; 5388 branch.blockInformation = conditionStartBlock.blockFlow;
5403 } 5389 }
5404 } 5390 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/js_backend/backend.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698