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

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

Issue 10238003: Reapply "Avoid "=== true" inside code by calling a function that does this for us." (Closed) Base URL: https://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
« no previous file with comments | « lib/compiler/implementation/ssa/nodes.dart ('k') | tests/language/src/Operator5Test.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) 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 bool allUsersAreBoolifies(HInstruction instruction) {
297 List<HInstruction> users = instruction.usedBy;
298 int length = users.length;
299 for (int i = 0; i < length; i++) {
300 if (users[i] is! HBoolify) return false;
301 }
302 return true;
303 }
304
305 HInstruction visitRelational(HRelational node) {
306 if (allUsersAreBoolifies(node)) {
307 Interceptors interceptors = compiler.builder.interceptors;
308 HStatic oldTarget = node.target;
309 Element boolifiedInterceptor =
310 interceptors.getBoolifiedVersionOf(oldTarget.element);
311 if (boolifiedInterceptor !== null) {
312 HStatic boolifiedTarget = new HStatic(boolifiedInterceptor);
313 // We don't remove the [oldTarget] in case it is used by other
314 // instructions. If it is unused it will be treated as dead code and
315 // discarded.
316 oldTarget.block.addAfter(oldTarget, boolifiedTarget);
317 // Remove us as user from the [oldTarget].
318 HBasicBlock.removeUser(oldTarget, node);
319 // Replace old target with boolified target.
320 assert(node.target == node.inputs[0]);
321 node.inputs[0] = boolifiedTarget;
322 boolifiedTarget.usedBy.add(node);
323 node.usesBoolifiedInterceptor = true;
324 node.propagatedType = HType.BOOLEAN;
325 }
326 // This node stays the same, but the Boolify node will go away.
327 }
328 // Note that we still have to call [super] to make sure that we end up
329 // in the remaining optimizations.
330 return super.visitRelational(node);
331 }
332
296 HInstruction handleIdentityCheck(HInvokeBinary node) { 333 HInstruction handleIdentityCheck(HInvokeBinary node) {
297 HInstruction left = node.left; 334 HInstruction left = node.left;
298 HInstruction right = node.right; 335 HInstruction right = node.right;
299 HType leftType = left.propagatedType; 336 HType leftType = left.propagatedType;
300 HType rightType = right.propagatedType; 337 HType rightType = right.propagatedType;
301 assert(!leftType.isConflicting() && !rightType.isConflicting()); 338 assert(!leftType.isConflicting() && !rightType.isConflicting());
302 339
303 // We don't optimize on numbers to preserve the runtime semantics. 340 // We don't optimize on numbers to preserve the runtime semantics.
304 if (!(left.isNumber() && right.isNumber()) && 341 if (!(left.isNumber() && right.isNumber()) &&
305 leftType.intersection(rightType).isConflicting()) { 342 leftType.intersection(rightType).isConflicting()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 384
348 HInstruction visitEquals(HEquals node) { 385 HInstruction visitEquals(HEquals node) {
349 HInstruction left = node.left; 386 HInstruction left = node.left;
350 HInstruction right = node.right; 387 HInstruction right = node.right;
351 388
352 if (node.builtin) { 389 if (node.builtin) {
353 return foldBuiltinEqualsCheck(node); 390 return foldBuiltinEqualsCheck(node);
354 } 391 }
355 392
356 if (left.isConstant() && right.isConstant()) { 393 if (left.isConstant() && right.isConstant()) {
357 return visitInvokeBinary(node); 394 return super.visitEquals(node);
358 } 395 }
359 396
360 if (left.isNonPrimitive()) { 397 if (left.isNonPrimitive()) {
361 HNonPrimitiveType type = left.propagatedType; 398 HNonPrimitiveType type = left.propagatedType;
362 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); 399 Element element = type.lookupMember(Namer.OPERATOR_EQUALS);
363 if (element !== null) { 400 if (element !== null) {
364 // If the left-hand side is guaranteed to be a non-primitive 401 // If the left-hand side is guaranteed to be a non-primitive
365 // type and and it defines operator==, we emit a call to that 402 // type and and it defines operator==, we emit a call to that
366 // operator. 403 // operator.
367 return visitInvokeBinary(node); 404 return super.visitEquals(node);
368 } else if (right.isConstantNull()) { 405 } else if (right.isConstantNull()) {
369 return graph.addConstantBool(false); 406 return graph.addConstantBool(false);
370 } else { 407 } else {
371 // We can just emit an identity check because the type does 408 // We can just emit an identity check because the type does
372 // not implement operator=. 409 // not implement operator=.
373 return foldBuiltinEqualsCheck(node); 410 return foldBuiltinEqualsCheck(node);
374 } 411 }
375 } 412 }
376 413
377 if (right.isConstantNull()) { 414 if (right.isConstantNull()) {
378 if (left.propagatedType.isUseful()) { 415 if (left.propagatedType.isUseful()) {
379 return graph.addConstantBool(false); 416 return graph.addConstantBool(false);
380 } else { 417 } else {
381 // TODO(floitsch): cache interceptors. 418 // TODO(floitsch): cache interceptors.
382 HStatic target = new HStatic( 419 Interceptors interceptors = compiler.builder.interceptors;
383 compiler.builder.interceptors.getEqualsNullInterceptor()); 420 Element targetElement = interceptors.getEqualsNullInterceptor();
421 bool onlyUsedInBoolify = allUsersAreBoolifies(node);
422 if (onlyUsedInBoolify) {
423 targetElement = interceptors.getBoolifiedVersionOf(targetElement);
424 }
425 HStatic target = new HStatic(targetElement);
384 node.block.addBefore(node, target); 426 node.block.addBefore(node, target);
385 return new HEquals(target, node.left, node.right); 427 HEquals result = new HEquals(target, node.left, node.right);
428 if (onlyUsedInBoolify) {
429 result.usesBoolifiedInterceptor = true;
430 result.propagatedType = HType.BOOLEAN;
431 }
432 return result;
386 } 433 }
387 } 434 }
388 435
389 // All other cases are dealt with by the [visitInvokeBinary]. 436 // All other cases are dealt with by the [visitRelational] and
390 return visitInvokeBinary(node); 437 // [visitInvokeBinary], which are visited by invoking the [super]'s
438 // visit method.
439 return super.visitEquals(node);
391 } 440 }
392 441
393 HInstruction visitTypeGuard(HTypeGuard node) { 442 HInstruction visitTypeGuard(HTypeGuard node) {
394 HInstruction value = node.guarded; 443 HInstruction value = node.guarded;
395 // If the union of the types is still the guarded type than the incoming 444 // If the union of the types is still the guarded type than the incoming
396 // type was a subtype of the guarded type, and no check is required. 445 // type was a subtype of the guarded type, and no check is required.
397 HType combinedType = value.propagatedType.union(node.guardedType); 446 HType combinedType = value.propagatedType.union(node.guardedType);
398 return (combinedType == value.propagatedType) ? value : node; 447 return (combinedType == value.propagatedType) ? value : node;
399 } 448 }
400 449
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 } 965 }
917 } 966 }
918 if (!canBeMoved) continue; 967 if (!canBeMoved) continue;
919 968
920 // This is safe because we are running after GVN. 969 // This is safe because we are running after GVN.
921 // TODO(ngeoffray): ensure GVN has been run. 970 // TODO(ngeoffray): ensure GVN has been run.
922 set_.add(current); 971 set_.add(current);
923 } 972 }
924 } 973 }
925 } 974 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/nodes.dart ('k') | tests/language/src/Operator5Test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698