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

Side by Side Diff: lib/compiler/implementation/ssa/optimize.dart

Issue 10174040: Better constant fold identity checks. (100 bytes saved on swarm, yeah! :)) (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 interface OptimizationPhase { 5 interface OptimizationPhase {
6 String get name(); 6 String get name();
7 void visitGraph(HGraph graph); 7 void visitGraph(HGraph graph);
8 } 8 }
9 9
10 class SsaOptimizerTask extends CompilerTask { 10 class SsaOptimizerTask extends CompilerTask {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 286 }
287 287
288 if (left.isNonPrimitive() && node.operation.isUserDefinable()) { 288 if (left.isNonPrimitive() && node.operation.isUserDefinable()) {
289 SourceString methodName = Elements.constructOperatorName( 289 SourceString methodName = Elements.constructOperatorName(
290 const SourceString('operator'), node.operation.name); 290 const SourceString('operator'), node.operation.name);
291 return fromInterceptorToDynamicInvocation(node, methodName); 291 return fromInterceptorToDynamicInvocation(node, methodName);
292 } 292 }
293 return node; 293 return node;
294 } 294 }
295 295
296 HInstruction handleIdentityCheck(HInvokeBinary node) {
297 HInstruction left = node.left;
298 HInstruction right = node.right;
299 HType leftType = left.propagatedType;
300 HType rightType = right.propagatedType;
301 assert(!leftType.isConflicting() && !rightType.isConflicting());
302
303 // We don't optimize on numbers to preserve the runtime semantics.
304 if (!(left.isNumber() && right.isNumber()) &&
305 leftType.intersection(rightType).isConflicting()) {
306 return graph.addConstantBool(false);
307 }
308
309 if (left.isConstantBoolean() && right.isBoolean()) {
310 HConstant constant = left;
311 if (constant.constant.isTrue()) {
312 return right;
313 } else {
314 return new HNot(right);
315 }
316 }
317
318 if (right.isConstantBoolean() && left.isBoolean()) {
319 HConstant constant = right;
320 if (constant.constant.isTrue()) {
321 return left;
322 } else {
323 return new HNot(left);
324 }
325 }
326
327 return null;
328 }
329
330 HInstruction visitIdentity(HIdentity node) {
331 HInstruction newInstruction = handleIdentityCheck(node);
332 return newInstruction === null ? super.visitIdentity(node) : newInstruction;
333 }
334
335 HInstruction foldBuiltinEqualsCheck(HEquals node) {
336 // TODO(floitsch): cache interceptors.
337 HInstruction newInstruction = handleIdentityCheck(node);
338 if (newInstruction === null) {
339 HStatic target = new HStatic(
340 compiler.builder.interceptors.getTripleEqualsInterceptor());
341 node.block.addBefore(node, target);
342 return new HIdentity(target, node.left, node.right);
343 } else {
344 return newInstruction;
345 }
346 }
347
296 HInstruction visitEquals(HEquals node) { 348 HInstruction visitEquals(HEquals node) {
297 HInstruction left = node.left; 349 HInstruction left = node.left;
298 HInstruction right = node.right; 350 HInstruction right = node.right;
299 351
352 if (node.builtin) {
353 return foldBuiltinEqualsCheck(node);
354 }
355
300 if (left.isConstant() && right.isConstant()) { 356 if (left.isConstant() && right.isConstant()) {
301 return visitInvokeBinary(node); 357 return visitInvokeBinary(node);
302 } 358 }
303 359
304 if (left.isNonPrimitive()) { 360 if (left.isNonPrimitive()) {
305 HNonPrimitiveType type = left.propagatedType; 361 HNonPrimitiveType type = left.propagatedType;
306 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); 362 Element element = type.lookupMember(Namer.OPERATOR_EQUALS);
307 if (element !== null) { 363 if (element !== null) {
308 // If the left-hand side is guaranteed to be a non-primitive 364 // If the left-hand side is guaranteed to be a non-primitive
309 // type and and it defines operator==, we emit a call to that 365 // type and and it defines operator==, we emit a call to that
310 // operator. 366 // operator.
311 return visitInvokeBinary(node); 367 return visitInvokeBinary(node);
312 } else if (right.isConstantNull()) { 368 } else if (right.isConstantNull()) {
313 return graph.addConstantBool(false); 369 return graph.addConstantBool(false);
314 } else { 370 } else {
315 // We can just emit an identity check because the type does 371 // We can just emit an identity check because the type does
316 // not implement operator=. 372 // not implement operator=.
317 // TODO(floitsch): cache interceptors. 373 return foldBuiltinEqualsCheck(node);
318 HStatic target = new HStatic(
319 compiler.builder.interceptors.getTripleEqualsInterceptor());
320 node.block.addBefore(node, target);
321 return new HIdentity(target, left, right);
322 } 374 }
323 } 375 }
324 376
325
326 if (right.isConstantNull()) { 377 if (right.isConstantNull()) {
327 if (left.propagatedType.isUseful()) { 378 if (left.propagatedType.isUseful()) {
328 return graph.addConstantBool(false); 379 return graph.addConstantBool(false);
329 } else { 380 } else {
330 // TODO(floitsch): cache interceptors. 381 // TODO(floitsch): cache interceptors.
331 HStatic target = new HStatic( 382 HStatic target = new HStatic(
332 compiler.builder.interceptors.getEqualsNullInterceptor()); 383 compiler.builder.interceptors.getEqualsNullInterceptor());
333 node.block.addBefore(node, target); 384 node.block.addBefore(node, target);
334 return new HEquals(target, node.left, node.right); 385 return new HEquals(target, node.left, node.right);
335 } 386 }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 } 916 }
866 } 917 }
867 if (!canBeMoved) continue; 918 if (!canBeMoved) continue;
868 919
869 // This is safe because we are running after GVN. 920 // This is safe because we are running after GVN.
870 // TODO(ngeoffray): ensure GVN has been run. 921 // TODO(ngeoffray): ensure GVN has been run.
871 set_.add(current); 922 set_.add(current);
872 } 923 }
873 } 924 }
874 } 925 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/nodes.dart ('k') | tests/language/src/ConstantFoldEqualsTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698