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

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

Issue 10140027: 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: Change copyright year. 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
296 HInstruction visitEquals(HEquals node) { 333 HInstruction visitEquals(HEquals node) {
297 HInstruction left = node.left; 334 HInstruction left = node.left;
298 HInstruction right = node.right; 335 HInstruction right = node.right;
299 336
300 if (left.isConstant() && right.isConstant()) { 337 if (left.isConstant() && right.isConstant()) {
301 return visitInvokeBinary(node); 338 return super.visitEquals(node);
302 } 339 }
303 340
304 if (left.isNonPrimitive()) { 341 if (left.isNonPrimitive()) {
305 HNonPrimitiveType type = left.propagatedType; 342 HNonPrimitiveType type = left.propagatedType;
306 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); 343 Element element = type.lookupMember(Namer.OPERATOR_EQUALS);
307 if (element !== null) { 344 if (element !== null) {
308 // If the left-hand side is guaranteed to be a non-primitive 345 // 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 346 // type and and it defines operator==, we emit a call to that
310 // operator. 347 // operator.
311 return visitInvokeBinary(node); 348 return super.visitEquals(node);
312 } else if (right.isConstantNull()) { 349 } else if (right.isConstantNull()) {
313 return graph.addConstantBool(false); 350 return graph.addConstantBool(false);
314 } else { 351 } else {
315 // We can just emit an identity check because the type does 352 // We can just emit an identity check because the type does
316 // not implement operator=. 353 // not implement operator=.
317 // TODO(floitsch): cache interceptors. 354 // TODO(floitsch): cache interceptors.
318 HStatic target = new HStatic( 355 HStatic target = new HStatic(
319 compiler.builder.interceptors.getTripleEqualsInterceptor()); 356 compiler.builder.interceptors.getTripleEqualsInterceptor());
320 node.block.addBefore(node, target); 357 node.block.addBefore(node, target);
321 return new HIdentity(target, left, right); 358 return new HIdentity(target, left, right);
322 } 359 }
323 } 360 }
324 361
325 362
326 if (right.isConstantNull()) { 363 if (right.isConstantNull()) {
327 if (left.propagatedType.isUseful()) { 364 if (left.propagatedType.isUseful()) {
328 return graph.addConstantBool(false); 365 return graph.addConstantBool(false);
329 } else { 366 } else {
330 // TODO(floitsch): cache interceptors. 367 // TODO(floitsch): cache interceptors.
331 HStatic target = new HStatic( 368 Interceptors interceptors = compiler.builder.interceptors;
332 compiler.builder.interceptors.getEqualsNullInterceptor()); 369 Element targetElement = interceptors.getEqualsNullInterceptor();
370 bool onlyUsedInBoolify = allUsersAreBoolifies(node);
371 if (onlyUsedInBoolify) {
372 targetElement = interceptors.getBoolifiedVersionOf(targetElement);
373 }
374 HStatic target = new HStatic(targetElement);
333 node.block.addBefore(node, target); 375 node.block.addBefore(node, target);
334 return new HEquals(target, node.left, node.right); 376 HEquals result = new HEquals(target, node.left, node.right);
377 if (onlyUsedInBoolify) {
378 result.usesBoolifiedInterceptor = true;
379 result.propagatedType = HType.BOOLEAN;
380 }
381 return result;
335 } 382 }
336 } 383 }
337 384
338 // All other cases are dealt with by the [visitInvokeBinary]. 385 // All other cases are dealt with by the [visitRelational] and
339 return visitInvokeBinary(node); 386 // [visitInvokeBinary], which are visited by invoking the [super]'s
387 // visit method.
388 return super.visitEquals(node);
340 } 389 }
341 390
342 HInstruction visitTypeGuard(HTypeGuard node) { 391 HInstruction visitTypeGuard(HTypeGuard node) {
343 HInstruction value = node.guarded; 392 HInstruction value = node.guarded;
344 HType combinedType = value.propagatedType.combine(node.guardedType); 393 HType combinedType = value.propagatedType.combine(node.guardedType);
345 return (combinedType == value.propagatedType) ? value : node; 394 return (combinedType == value.propagatedType) ? value : node;
346 } 395 }
347 396
348 HInstruction visitIs(HIs node) { 397 HInstruction visitIs(HIs node) {
349 Type type = node.typeName; 398 Type type = node.typeName;
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 } 912 }
864 } 913 }
865 if (!canBeMoved) continue; 914 if (!canBeMoved) continue;
866 915
867 // This is safe because we are running after GVN. 916 // This is safe because we are running after GVN.
868 // TODO(ngeoffray): ensure GVN has been run. 917 // TODO(ngeoffray): ensure GVN has been run.
869 set_.add(current); 918 set_.add(current);
870 } 919 }
871 } 920 }
872 } 921 }
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