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

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

Issue 10558022: Better bitwise and binary arithmetic when the left operand is known to be a number. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Cleanup HTypeConversion usage. Created 8 years, 6 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) 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 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 final JavaScriptBackend backend; 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend) 7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend, 8 : this.backend = backend,
9 super(backend.compiler); 9 super(backend.compiler);
10 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 use(node.right, operatorPrecedences.right); 1122 use(node.right, operatorPrecedences.right);
1123 endExpression(operatorPrecedences.precedence); 1123 endExpression(operatorPrecedences.precedence);
1124 } else { 1124 } else {
1125 visitInvokeStatic(node); 1125 visitInvokeStatic(node);
1126 } 1126 }
1127 } 1127 }
1128 1128
1129 // We want the outcome of bit-operations to be positive. We use the unsigned 1129 // We want the outcome of bit-operations to be positive. We use the unsigned
1130 // shift operator to achieve this. 1130 // shift operator to achieve this.
1131 visitBitInvokeBinary(HBinaryBitOp node, String op) { 1131 visitBitInvokeBinary(HBinaryBitOp node, String op) {
1132 if (node.builtin){ 1132 if (node.builtin) {
1133 beginExpression(unsignedShiftPrecedences.precedence); 1133 beginExpression(unsignedShiftPrecedences.precedence);
1134 int oldPrecedence = this.expectedPrecedence; 1134 int oldPrecedence = this.expectedPrecedence;
1135 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE; 1135 this.expectedPrecedence = JSPrecedence.SHIFT_PRECEDENCE;
1136 visitInvokeBinary(node, op); 1136 visitInvokeBinary(node, op);
1137 buffer.add(' >>> 0'); 1137 buffer.add(' >>> 0');
1138 this.expectedPrecedence = oldPrecedence; 1138 this.expectedPrecedence = oldPrecedence;
1139 endExpression(unsignedShiftPrecedences.precedence); 1139 endExpression(unsignedShiftPrecedences.precedence);
1140 } else { 1140 } else {
1141 visitInvokeBinary(node, op); 1141 visitInvokeBinary(node, op);
1142 } 1142 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 visitSubtract(HSubtract node) => visitInvokeBinary(node, '-'); 1195 visitSubtract(HSubtract node) => visitInvokeBinary(node, '-');
1196 // Truncating divide does not have a JS equivalent. 1196 // Truncating divide does not have a JS equivalent.
1197 visitTruncatingDivide(HTruncatingDivide node) => visitInvokeStatic(node); 1197 visitTruncatingDivide(HTruncatingDivide node) => visitInvokeStatic(node);
1198 // Modulo cannot be mapped to the native operator (different semantics). 1198 // Modulo cannot be mapped to the native operator (different semantics).
1199 visitModulo(HModulo node) => visitInvokeStatic(node); 1199 visitModulo(HModulo node) => visitInvokeStatic(node);
1200 1200
1201 visitBitAnd(HBitAnd node) => visitBitInvokeBinary(node, '&'); 1201 visitBitAnd(HBitAnd node) => visitBitInvokeBinary(node, '&');
1202 visitBitNot(HBitNot node) => visitBitInvokeUnary(node, '~'); 1202 visitBitNot(HBitNot node) => visitBitInvokeUnary(node, '~');
1203 visitBitOr(HBitOr node) => visitBitInvokeBinary(node, '|'); 1203 visitBitOr(HBitOr node) => visitBitInvokeBinary(node, '|');
1204 visitBitXor(HBitXor node) => visitBitInvokeBinary(node, '^'); 1204 visitBitXor(HBitXor node) => visitBitInvokeBinary(node, '^');
1205 1205 visitShiftRight(HShiftRight node) => visitBitInvokeBinary(node, '>>');
1206 // We need to check if the left operand is negative in order to use 1206 visitShiftLeft(HShiftLeft node) => visitBitInvokeBinary(node, '<<');
1207 // the native operator.
1208 visitShiftRight(HShiftRight node) => visitInvokeStatic(node);
1209
1210 // Shift left cannot be mapped to the native operator (different semantics).
1211 visitShiftLeft(HShiftLeft node) => visitInvokeStatic(node);
1212 1207
1213 visitNegate(HNegate node) => visitInvokeUnary(node, '-'); 1208 visitNegate(HNegate node) => visitInvokeUnary(node, '-');
1214 1209
1215 visitIdentity(HIdentity node) => visitInvokeBinary(node, '==='); 1210 visitIdentity(HIdentity node) => visitInvokeBinary(node, '===');
1216 visitLess(HLess node) => visitInvokeBinary(node, '<'); 1211 visitLess(HLess node) => visitInvokeBinary(node, '<');
1217 visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<='); 1212 visitLessEqual(HLessEqual node) => visitInvokeBinary(node, '<=');
1218 visitGreater(HGreater node) => visitInvokeBinary(node, '>'); 1213 visitGreater(HGreater node) => visitInvokeBinary(node, '>');
1219 visitGreaterEqual(HGreaterEqual node) => visitInvokeBinary(node, '>='); 1214 visitGreaterEqual(HGreaterEqual node) => visitInvokeBinary(node, '>=');
1220 1215
1221 visitBoolify(HBoolify node) { 1216 visitBoolify(HBoolify node) {
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 buffer.add(' >= '); 1996 buffer.add(' >= ');
2002 use(node.length, JSPrecedence.SHIFT_PRECEDENCE); 1997 use(node.length, JSPrecedence.SHIFT_PRECEDENCE);
2003 buffer.add(") "); 1998 buffer.add(") ");
2004 } 1999 }
2005 generateThrowWithHelper('ioore', node.index); 2000 generateThrowWithHelper('ioore', node.index);
2006 } 2001 }
2007 2002
2008 visitIntegerCheck(HIntegerCheck node) { 2003 visitIntegerCheck(HIntegerCheck node) {
2009 if (!node.alwaysFalse) { 2004 if (!node.alwaysFalse) {
2010 buffer.add('if ('); 2005 buffer.add('if (');
2011 use(node.value, JSPrecedence.EQUALITY_PRECEDENCE); 2006 checkInt(node.value, '!==');
2012 buffer.add(' !== ('); 2007 buffer.add(') ');
2013 use(node.value, JSPrecedence.BITWISE_OR_PRECEDENCE);
2014 buffer.add(" | 0)) ");
2015 } 2008 }
2016 generateThrowWithHelper('iae', node.value); 2009 generateThrowWithHelper('iae', node.value);
2017 } 2010 }
2018 2011
2019 void generateThrowWithHelper(String helperName, HInstruction argument) { 2012 void generateThrowWithHelper(String helperName, HInstruction argument) {
2020 Element helper = compiler.findHelper(new SourceString(helperName)); 2013 Element helper = compiler.findHelper(new SourceString(helperName));
2021 world.registerStaticUse(helper); 2014 world.registerStaticUse(helper);
2022 buffer.add('throw '); 2015 buffer.add('throw ');
2023 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE); 2016 beginExpression(JSPrecedence.EXPRESSION_PRECEDENCE);
2024 beginExpression(JSPrecedence.CALL_PRECEDENCE); 2017 beginExpression(JSPrecedence.CALL_PRECEDENCE);
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
2408 buffer.add(".${name.slowToString()} === '${arguments.head}'"); 2401 buffer.add(".${name.slowToString()} === '${arguments.head}'");
2409 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2402 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2410 }); 2403 });
2411 } 2404 }
2412 if (node.nullOk) { 2405 if (node.nullOk) {
2413 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2406 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2414 } 2407 }
2415 } 2408 }
2416 2409
2417 void visitTypeConversion(HTypeConversion node) { 2410 void visitTypeConversion(HTypeConversion node) {
2418 if (node.checked) { 2411 if (node.isChecked()) {
2419 Element element = node.type.computeType(compiler).element; 2412 Element element = node.type.computeType(compiler).element;
2420 world.registerIsCheck(element); 2413 world.registerIsCheck(element);
2421 SourceString helper; 2414 SourceString helper;
2422 String additionalArgument; 2415 String additionalArgument;
2423 bool nativeCheck = 2416 bool nativeCheck =
2424 backend.emitter.nativeEmitter.requiresNativeIsCheck(element); 2417 backend.emitter.nativeEmitter.requiresNativeIsCheck(element);
2425 beginExpression(JSPrecedence.CALL_PRECEDENCE); 2418 beginExpression(JSPrecedence.CALL_PRECEDENCE);
2426 2419
2420 if (node.isArgumentTypeCheck()) {
2421 buffer.add('if (');
2422 if (element == compiler.intClass) {
2423 checkInt(node.checkedInput, '!==');
2424 } else {
2425 assert(element == compiler.numClass);
2426 checkNum(node.checkedInput, '!==');
2427 }
2428 buffer.add(') ');
2429 generateThrowWithHelper('iae', node.checkedInput);
2430 return;
2431 }
2432
2433 assert(node.isCheckedModeCheck());
2427 if (element == compiler.stringClass) { 2434 if (element == compiler.stringClass) {
2428 helper = const SourceString('stringTypeCheck'); 2435 helper = const SourceString('stringTypeCheck');
2429 } else if (element == compiler.doubleClass) { 2436 } else if (element == compiler.doubleClass) {
2430 helper = const SourceString('doubleTypeCheck'); 2437 helper = const SourceString('doubleTypeCheck');
2431 } else if (element == compiler.numClass) { 2438 } else if (element == compiler.numClass) {
2432 helper = const SourceString('numTypeCheck'); 2439 helper = const SourceString('numTypeCheck');
2433 } else if (element == compiler.boolClass) { 2440 } else if (element == compiler.boolClass) {
2434 helper = const SourceString('boolTypeCheck'); 2441 helper = const SourceString('boolTypeCheck');
2435 } else if (element == compiler.functionClass || element.isTypedef()) { 2442 } else if (element == compiler.functionClass || element.isTypedef()) {
2436 helper = const SourceString('functionTypeCheck'); 2443 helper = const SourceString('functionTypeCheck');
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
2908 startBailoutSwitch(); 2915 startBailoutSwitch();
2909 } 2916 }
2910 } 2917 }
2911 2918
2912 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2919 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2913 if (labeledBlockInfo.body.start.hasGuards()) { 2920 if (labeledBlockInfo.body.start.hasGuards()) {
2914 endBailoutSwitch(); 2921 endBailoutSwitch();
2915 } 2922 }
2916 } 2923 }
2917 } 2924 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698