| OLD | NEW |
| 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 import 'dart:math' as math; | |
| 6 import '../common.dart'; | 5 import '../common.dart'; |
| 7 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 8 import '../common/tasks.dart' show CompilerTask; | 7 import '../common/tasks.dart' show CompilerTask; |
| 9 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 10 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
| 11 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| 12 import '../core_types.dart' show CoreClasses; | 11 import '../core_types.dart' show CoreClasses; |
| 13 import '../dart_types.dart'; | 12 import '../dart_types.dart'; |
| 14 import '../elements/elements.dart'; | 13 import '../elements/elements.dart'; |
| 15 import '../elements/entities.dart'; | 14 import '../elements/entities.dart'; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 phiSet.add(user); | 203 phiSet.add(user); |
| 205 if (hasNonBitOpUser(user, phiSet)) return true; | 204 if (hasNonBitOpUser(user, phiSet)) return true; |
| 206 } | 205 } |
| 207 } else if (user is! HBitNot && user is! HBinaryBitOp) { | 206 } else if (user is! HBitNot && user is! HBinaryBitOp) { |
| 208 return true; | 207 return true; |
| 209 } | 208 } |
| 210 } | 209 } |
| 211 return false; | 210 return false; |
| 212 } | 211 } |
| 213 | 212 |
| 214 // Returns the number of bits occupied by the value computed by [instruction]. | |
| 215 // Returns `32` if the value is negative or does not fit in a smaller number | |
| 216 // of bits. | |
| 217 int bitWidth(HInstruction instruction) { | |
| 218 const int MAX = 32; | |
| 219 int constant(HInstruction insn) { | |
| 220 if (insn.isConstantInteger()) { | |
| 221 IntConstantValue constant = insn.constant; | |
| 222 return constant.primitiveValue; | |
| 223 } | |
| 224 return null; | |
| 225 } | |
| 226 | |
| 227 if (instruction.isConstantInteger()) { | |
| 228 int value = constant(instruction); | |
| 229 if (value < 0) return MAX; | |
| 230 if (value > ((1 << 31) - 1)) return MAX; | |
| 231 return value.bitLength; | |
| 232 } | |
| 233 if (instruction is HBitAnd) { | |
| 234 return math.min(bitWidth(instruction.left), bitWidth(instruction.right)); | |
| 235 } | |
| 236 if (instruction is HBitOr || instruction is HBitXor) { | |
| 237 int leftWidth = bitWidth(instruction.left); | |
| 238 if (leftWidth == MAX) return MAX; | |
| 239 return math.max(leftWidth, bitWidth(instruction.right)); | |
| 240 } | |
| 241 if (instruction is HShiftLeft) { | |
| 242 int shiftCount = constant(instruction.right); | |
| 243 if (shiftCount == null || shiftCount < 0 || shiftCount > 31) return MAX; | |
| 244 int leftWidth = bitWidth(instruction.left); | |
| 245 int width = leftWidth + shiftCount; | |
| 246 return math.min(width, MAX); | |
| 247 } | |
| 248 if (instruction is HShiftRight) { | |
| 249 int shiftCount = constant(instruction.right); | |
| 250 if (shiftCount == null || shiftCount < 0 || shiftCount > 31) return MAX; | |
| 251 int leftWidth = bitWidth(instruction.left); | |
| 252 if (leftWidth >= MAX) return MAX; | |
| 253 return math.max(leftWidth - shiftCount, 0); | |
| 254 } | |
| 255 if (instruction is HAdd) { | |
| 256 return math.min( | |
| 257 1 + math.max(bitWidth(instruction.left), bitWidth(instruction.right)), | |
| 258 MAX); | |
| 259 } | |
| 260 return MAX; | |
| 261 } | |
| 262 | |
| 263 bool requiresUintConversion(instruction) { | 213 bool requiresUintConversion(instruction) { |
| 264 if (instruction.isUInt31(compiler)) return false; | 214 if (instruction.isUInt31(compiler)) return false; |
| 265 if (bitWidth(instruction) <= 31) return false; | |
| 266 // If the result of a bit-operation is only used by other bit | 215 // If the result of a bit-operation is only used by other bit |
| 267 // operations, we do not have to convert to an unsigned integer. | 216 // operations, we do not have to convert to an unsigned integer. |
| 268 return hasNonBitOpUser(instruction, new Set<HPhi>()); | 217 return hasNonBitOpUser(instruction, new Set<HPhi>()); |
| 269 } | 218 } |
| 270 | 219 |
| 271 /** | 220 /** |
| 272 * If the [instruction] is not `null` it will be used to attach the position | 221 * If the [instruction] is not `null` it will be used to attach the position |
| 273 * to the [statement]. | 222 * to the [statement]. |
| 274 */ | 223 */ |
| 275 void pushStatement(js.Statement statement) { | 224 void pushStatement(js.Statement statement) { |
| (...skipping 2819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3095 registry.registerStaticUse(new StaticUse.staticInvoke( | 3044 registry.registerStaticUse(new StaticUse.staticInvoke( |
| 3096 helper, new CallStructure.unnamed(argumentCount))); | 3045 helper, new CallStructure.unnamed(argumentCount))); |
| 3097 return backend.emitter.staticFunctionAccess(helper); | 3046 return backend.emitter.staticFunctionAccess(helper); |
| 3098 } | 3047 } |
| 3099 | 3048 |
| 3100 @override | 3049 @override |
| 3101 void visitRef(HRef node) { | 3050 void visitRef(HRef node) { |
| 3102 visit(node.value); | 3051 visit(node.value); |
| 3103 } | 3052 } |
| 3104 } | 3053 } |
| OLD | NEW |