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

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

Issue 10236007: Revert "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, 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 | « 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
333 HInstruction handleIdentityCheck(HInvokeBinary node) { 296 HInstruction handleIdentityCheck(HInvokeBinary node) {
334 HInstruction left = node.left; 297 HInstruction left = node.left;
335 HInstruction right = node.right; 298 HInstruction right = node.right;
336 HType leftType = left.propagatedType; 299 HType leftType = left.propagatedType;
337 HType rightType = right.propagatedType; 300 HType rightType = right.propagatedType;
338 assert(!leftType.isConflicting() && !rightType.isConflicting()); 301 assert(!leftType.isConflicting() && !rightType.isConflicting());
339 302
340 // We don't optimize on numbers to preserve the runtime semantics. 303 // We don't optimize on numbers to preserve the runtime semantics.
341 if (!(left.isNumber() && right.isNumber()) && 304 if (!(left.isNumber() && right.isNumber()) &&
342 leftType.intersection(rightType).isConflicting()) { 305 leftType.intersection(rightType).isConflicting()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 347
385 HInstruction visitEquals(HEquals node) { 348 HInstruction visitEquals(HEquals node) {
386 HInstruction left = node.left; 349 HInstruction left = node.left;
387 HInstruction right = node.right; 350 HInstruction right = node.right;
388 351
389 if (node.builtin) { 352 if (node.builtin) {
390 return foldBuiltinEqualsCheck(node); 353 return foldBuiltinEqualsCheck(node);
391 } 354 }
392 355
393 if (left.isConstant() && right.isConstant()) { 356 if (left.isConstant() && right.isConstant()) {
394 return super.visitEquals(node); 357 return visitInvokeBinary(node);
395 } 358 }
396 359
397 if (left.isNonPrimitive()) { 360 if (left.isNonPrimitive()) {
398 HNonPrimitiveType type = left.propagatedType; 361 HNonPrimitiveType type = left.propagatedType;
399 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); 362 Element element = type.lookupMember(Namer.OPERATOR_EQUALS);
400 if (element !== null) { 363 if (element !== null) {
401 // 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
402 // 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
403 // operator. 366 // operator.
404 return super.visitEquals(node); 367 return visitInvokeBinary(node);
405 } else if (right.isConstantNull()) { 368 } else if (right.isConstantNull()) {
406 return graph.addConstantBool(false); 369 return graph.addConstantBool(false);
407 } else { 370 } else {
408 // We can just emit an identity check because the type does 371 // We can just emit an identity check because the type does
409 // not implement operator=. 372 // not implement operator=.
410 return foldBuiltinEqualsCheck(node); 373 return foldBuiltinEqualsCheck(node);
411 } 374 }
412 } 375 }
413 376
414 if (right.isConstantNull()) { 377 if (right.isConstantNull()) {
415 if (left.propagatedType.isUseful()) { 378 if (left.propagatedType.isUseful()) {
416 return graph.addConstantBool(false); 379 return graph.addConstantBool(false);
417 } else { 380 } else {
418 // TODO(floitsch): cache interceptors. 381 // TODO(floitsch): cache interceptors.
419 Interceptors interceptors = compiler.builder.interceptors; 382 HStatic target = new HStatic(
420 Element targetElement = interceptors.getEqualsNullInterceptor(); 383 compiler.builder.interceptors.getEqualsNullInterceptor());
421 bool onlyUsedInBoolify = allUsersAreBoolifies(node);
422 if (onlyUsedInBoolify) {
423 targetElement = interceptors.getBoolifiedVersionOf(targetElement);
424 }
425 HStatic target = new HStatic(targetElement);
426 node.block.addBefore(node, target); 384 node.block.addBefore(node, target);
427 HEquals result = new HEquals(target, node.left, node.right); 385 return new HEquals(target, node.left, node.right);
428 if (onlyUsedInBoolify) {
429 result.usesBoolifiedInterceptor = true;
430 result.propagatedType = HType.BOOLEAN;
431 }
432 return result;
433 } 386 }
434 } 387 }
435 388
436 // All other cases are dealt with by the [visitRelational] and 389 // All other cases are dealt with by the [visitInvokeBinary].
437 // [visitInvokeBinary], which are visited by invoking the [super]'s 390 return visitInvokeBinary(node);
438 // visit method.
439 return super.visitEquals(node);
440 } 391 }
441 392
442 HInstruction visitTypeGuard(HTypeGuard node) { 393 HInstruction visitTypeGuard(HTypeGuard node) {
443 HInstruction value = node.guarded; 394 HInstruction value = node.guarded;
444 // If the union of the types is still the guarded type than the incoming 395 // If the union of the types is still the guarded type than the incoming
445 // type was a subtype of the guarded type, and no check is required. 396 // type was a subtype of the guarded type, and no check is required.
446 HType combinedType = value.propagatedType.union(node.guardedType); 397 HType combinedType = value.propagatedType.union(node.guardedType);
447 return (combinedType == value.propagatedType) ? value : node; 398 return (combinedType == value.propagatedType) ? value : node;
448 } 399 }
449 400
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 } 916 }
966 } 917 }
967 if (!canBeMoved) continue; 918 if (!canBeMoved) continue;
968 919
969 // This is safe because we are running after GVN. 920 // This is safe because we are running after GVN.
970 // TODO(ngeoffray): ensure GVN has been run. 921 // TODO(ngeoffray): ensure GVN has been run.
971 set_.add(current); 922 set_.add(current);
972 } 923 }
973 } 924 }
974 } 925 }
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