| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 '../compiler.dart' show Compiler; | 5 import '../compiler.dart' show Compiler; |
| 6 import '../constants/constant_system.dart'; | 6 import '../constants/constant_system.dart'; |
| 7 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
| 8 import '../elements/elements.dart' show Name; | 8 import '../elements/elements.dart' show Name; |
| 9 import '../elements/entities.dart'; | 9 import '../elements/entities.dart'; |
| 10 import '../js_backend/js_backend.dart'; | 10 import '../js_backend/js_backend.dart'; |
| 11 import '../js_backend/backend_helpers.dart'; |
| 12 import '../options.dart'; |
| 11 import '../types/types.dart'; | 13 import '../types/types.dart'; |
| 12 import '../universe/call_structure.dart'; | 14 import '../universe/call_structure.dart'; |
| 13 import '../universe/selector.dart'; | 15 import '../universe/selector.dart'; |
| 14 import '../world.dart' show ClosedWorld; | 16 import '../world.dart' show ClosedWorld; |
| 15 import 'nodes.dart'; | 17 import 'nodes.dart'; |
| 16 import 'types.dart'; | 18 import 'types.dart'; |
| 17 | 19 |
| 18 /** | 20 /** |
| 19 * [InvokeDynamicSpecializer] and its subclasses are helpers to | 21 * [InvokeDynamicSpecializer] and its subclasses are helpers to |
| 20 * optimize intercepted dynamic calls. It knows what input types | 22 * optimize intercepted dynamic calls. It knows what input types |
| 21 * would be beneficial for performance, and how to change a invoke | 23 * would be beneficial for performance, and how to change a invoke |
| 22 * dynamic to a builtin instruction (e.g. HIndex, HBitNot). | 24 * dynamic to a builtin instruction (e.g. HIndex, HBitNot). |
| 23 */ | 25 */ |
| 24 class InvokeDynamicSpecializer { | 26 class InvokeDynamicSpecializer { |
| 25 const InvokeDynamicSpecializer(); | 27 const InvokeDynamicSpecializer(); |
| 26 | 28 |
| 27 TypeMask computeTypeFromInputTypes( | 29 TypeMask computeTypeFromInputTypes( |
| 28 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 30 HInvokeDynamic instruction, |
| 29 return TypeMaskFactory.inferredTypeForSelector(instruction.selector, | 31 GlobalTypeInferenceResults results, |
| 30 instruction.mask, compiler.globalInference.results); | 32 CompilerOptions options, |
| 33 BackendHelpers helpers, |
| 34 ClosedWorld closedWorld) { |
| 35 return TypeMaskFactory.inferredTypeForSelector( |
| 36 instruction.selector, instruction.mask, results); |
| 31 } | 37 } |
| 32 | 38 |
| 33 HInstruction tryConvertToBuiltin( | 39 HInstruction tryConvertToBuiltin( |
| 34 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 40 HInvokeDynamic instruction, |
| 41 GlobalTypeInferenceResults results, |
| 42 CompilerOptions options, |
| 43 BackendHelpers helpers, |
| 44 ClosedWorld closedWorld) { |
| 35 return null; | 45 return null; |
| 36 } | 46 } |
| 37 | 47 |
| 38 void clearAllSideEffects(HInstruction instruction) { | 48 void clearAllSideEffects(HInstruction instruction) { |
| 39 instruction.sideEffects.clearAllSideEffects(); | 49 instruction.sideEffects.clearAllSideEffects(); |
| 40 instruction.sideEffects.clearAllDependencies(); | 50 instruction.sideEffects.clearAllDependencies(); |
| 41 instruction.setUseGvn(); | 51 instruction.setUseGvn(); |
| 42 } | 52 } |
| 43 | 53 |
| 44 Selector renameToOptimizedSelector( | 54 Selector renameToOptimizedSelector( |
| 45 String name, Selector selector, Compiler compiler) { | 55 String name, Selector selector, BackendHelpers helpers) { |
| 46 if (selector.name == name) return selector; | 56 if (selector.name == name) return selector; |
| 47 JavaScriptBackend backend = compiler.backend; | 57 return new Selector.call(new Name(name, helpers.interceptorsLibrary), |
| 48 return new Selector.call( | |
| 49 new Name(name, backend.helpers.interceptorsLibrary), | |
| 50 new CallStructure(selector.argumentCount)); | 58 new CallStructure(selector.argumentCount)); |
| 51 } | 59 } |
| 52 | 60 |
| 53 Operation operation(ConstantSystem constantSystem) => null; | 61 Operation operation(ConstantSystem constantSystem) => null; |
| 54 | 62 |
| 55 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { | 63 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { |
| 56 if (selector.isIndex) return const IndexSpecializer(); | 64 if (selector.isIndex) return const IndexSpecializer(); |
| 57 if (selector.isIndexSet) return const IndexAssignSpecializer(); | 65 if (selector.isIndexSet) return const IndexAssignSpecializer(); |
| 58 String name = selector.name; | 66 String name = selector.name; |
| 59 if (selector.isOperator) { | 67 if (selector.isOperator) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 109 } |
| 102 } | 110 } |
| 103 return const InvokeDynamicSpecializer(); | 111 return const InvokeDynamicSpecializer(); |
| 104 } | 112 } |
| 105 } | 113 } |
| 106 | 114 |
| 107 class IndexAssignSpecializer extends InvokeDynamicSpecializer { | 115 class IndexAssignSpecializer extends InvokeDynamicSpecializer { |
| 108 const IndexAssignSpecializer(); | 116 const IndexAssignSpecializer(); |
| 109 | 117 |
| 110 HInstruction tryConvertToBuiltin( | 118 HInstruction tryConvertToBuiltin( |
| 111 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 119 HInvokeDynamic instruction, |
| 120 GlobalTypeInferenceResults results, |
| 121 CompilerOptions options, |
| 122 BackendHelpers helpers, |
| 123 ClosedWorld closedWorld) { |
| 112 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { | 124 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { |
| 113 if (!instruction.inputs[2].isInteger(closedWorld) && | 125 if (!instruction.inputs[2].isInteger(closedWorld) && |
| 114 compiler.options.enableTypeAssertions) { | 126 options.enableTypeAssertions) { |
| 115 // We want the right checked mode error. | 127 // We want the right checked mode error. |
| 116 return null; | 128 return null; |
| 117 } | 129 } |
| 118 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], | 130 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], |
| 119 instruction.inputs[3], instruction.selector); | 131 instruction.inputs[3], instruction.selector); |
| 120 } | 132 } |
| 121 return null; | 133 return null; |
| 122 } | 134 } |
| 123 } | 135 } |
| 124 | 136 |
| 125 class IndexSpecializer extends InvokeDynamicSpecializer { | 137 class IndexSpecializer extends InvokeDynamicSpecializer { |
| 126 const IndexSpecializer(); | 138 const IndexSpecializer(); |
| 127 | 139 |
| 128 HInstruction tryConvertToBuiltin( | 140 HInstruction tryConvertToBuiltin( |
| 129 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 141 HInvokeDynamic instruction, |
| 142 GlobalTypeInferenceResults results, |
| 143 CompilerOptions options, |
| 144 BackendHelpers helpers, |
| 145 ClosedWorld closedWorld) { |
| 130 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; | 146 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; |
| 131 if (!instruction.inputs[2].isInteger(closedWorld) && | 147 if (!instruction.inputs[2].isInteger(closedWorld) && |
| 132 compiler.options.enableTypeAssertions) { | 148 options.enableTypeAssertions) { |
| 133 // We want the right checked mode error. | 149 // We want the right checked mode error. |
| 134 return null; | 150 return null; |
| 135 } | 151 } |
| 136 TypeMask receiverType = | 152 TypeMask receiverType = |
| 137 instruction.getDartReceiver(closedWorld).instructionType; | 153 instruction.getDartReceiver(closedWorld).instructionType; |
| 138 TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 154 TypeMask type = TypeMaskFactory.inferredTypeForSelector( |
| 139 instruction.selector, receiverType, compiler.globalInference.results); | 155 instruction.selector, receiverType, results); |
| 140 return new HIndex(instruction.inputs[1], instruction.inputs[2], | 156 return new HIndex(instruction.inputs[1], instruction.inputs[2], |
| 141 instruction.selector, type); | 157 instruction.selector, type); |
| 142 } | 158 } |
| 143 } | 159 } |
| 144 | 160 |
| 145 class BitNotSpecializer extends InvokeDynamicSpecializer { | 161 class BitNotSpecializer extends InvokeDynamicSpecializer { |
| 146 const BitNotSpecializer(); | 162 const BitNotSpecializer(); |
| 147 | 163 |
| 148 UnaryOperation operation(ConstantSystem constantSystem) { | 164 UnaryOperation operation(ConstantSystem constantSystem) { |
| 149 return constantSystem.bitNot; | 165 return constantSystem.bitNot; |
| 150 } | 166 } |
| 151 | 167 |
| 152 TypeMask computeTypeFromInputTypes( | 168 TypeMask computeTypeFromInputTypes( |
| 153 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 169 HInvokeDynamic instruction, |
| 170 GlobalTypeInferenceResults results, |
| 171 CompilerOptions options, |
| 172 BackendHelpers helpers, |
| 173 ClosedWorld closedWorld) { |
| 154 // All bitwise operations on primitive types either produce an | 174 // All bitwise operations on primitive types either produce an |
| 155 // integer or throw an error. | 175 // integer or throw an error. |
| 156 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { | 176 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { |
| 157 return closedWorld.commonMasks.uint32Type; | 177 return closedWorld.commonMasks.uint32Type; |
| 158 } | 178 } |
| 159 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 179 return super.computeTypeFromInputTypes( |
| 180 instruction, results, options, helpers, closedWorld); |
| 160 } | 181 } |
| 161 | 182 |
| 162 HInstruction tryConvertToBuiltin( | 183 HInstruction tryConvertToBuiltin( |
| 163 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 184 HInvokeDynamic instruction, |
| 185 GlobalTypeInferenceResults results, |
| 186 CompilerOptions options, |
| 187 BackendHelpers helpers, |
| 188 ClosedWorld closedWorld) { |
| 164 HInstruction input = instruction.inputs[1]; | 189 HInstruction input = instruction.inputs[1]; |
| 165 if (input.isNumber(closedWorld)) { | 190 if (input.isNumber(closedWorld)) { |
| 166 return new HBitNot(input, instruction.selector, | 191 return new HBitNot( |
| 167 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 192 input, |
| 193 instruction.selector, |
| 194 computeTypeFromInputTypes( |
| 195 instruction, results, options, helpers, closedWorld)); |
| 168 } | 196 } |
| 169 return null; | 197 return null; |
| 170 } | 198 } |
| 171 } | 199 } |
| 172 | 200 |
| 173 class UnaryNegateSpecializer extends InvokeDynamicSpecializer { | 201 class UnaryNegateSpecializer extends InvokeDynamicSpecializer { |
| 174 const UnaryNegateSpecializer(); | 202 const UnaryNegateSpecializer(); |
| 175 | 203 |
| 176 UnaryOperation operation(ConstantSystem constantSystem) { | 204 UnaryOperation operation(ConstantSystem constantSystem) { |
| 177 return constantSystem.negate; | 205 return constantSystem.negate; |
| 178 } | 206 } |
| 179 | 207 |
| 180 TypeMask computeTypeFromInputTypes( | 208 TypeMask computeTypeFromInputTypes( |
| 181 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 209 HInvokeDynamic instruction, |
| 210 GlobalTypeInferenceResults results, |
| 211 CompilerOptions options, |
| 212 BackendHelpers helpers, |
| 213 ClosedWorld closedWorld) { |
| 182 TypeMask operandType = instruction.inputs[1].instructionType; | 214 TypeMask operandType = instruction.inputs[1].instructionType; |
| 183 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; | 215 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; |
| 184 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 216 return super.computeTypeFromInputTypes( |
| 217 instruction, results, options, helpers, closedWorld); |
| 185 } | 218 } |
| 186 | 219 |
| 187 HInstruction tryConvertToBuiltin( | 220 HInstruction tryConvertToBuiltin( |
| 188 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 221 HInvokeDynamic instruction, |
| 222 GlobalTypeInferenceResults results, |
| 223 CompilerOptions options, |
| 224 BackendHelpers helpers, |
| 225 ClosedWorld closedWorld) { |
| 189 HInstruction input = instruction.inputs[1]; | 226 HInstruction input = instruction.inputs[1]; |
| 190 if (input.isNumber(closedWorld)) { | 227 if (input.isNumber(closedWorld)) { |
| 191 return new HNegate(input, instruction.selector, input.instructionType); | 228 return new HNegate(input, instruction.selector, input.instructionType); |
| 192 } | 229 } |
| 193 return null; | 230 return null; |
| 194 } | 231 } |
| 195 } | 232 } |
| 196 | 233 |
| 197 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer { | 234 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer { |
| 198 const BinaryArithmeticSpecializer(); | 235 const BinaryArithmeticSpecializer(); |
| 199 | 236 |
| 200 TypeMask computeTypeFromInputTypes( | 237 TypeMask computeTypeFromInputTypes( |
| 201 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 238 HInvokeDynamic instruction, |
| 239 GlobalTypeInferenceResults results, |
| 240 CompilerOptions options, |
| 241 BackendHelpers helpers, |
| 242 ClosedWorld closedWorld) { |
| 202 HInstruction left = instruction.inputs[1]; | 243 HInstruction left = instruction.inputs[1]; |
| 203 HInstruction right = instruction.inputs[2]; | 244 HInstruction right = instruction.inputs[2]; |
| 204 if (left.isIntegerOrNull(closedWorld) && | 245 if (left.isIntegerOrNull(closedWorld) && |
| 205 right.isIntegerOrNull(closedWorld)) { | 246 right.isIntegerOrNull(closedWorld)) { |
| 206 return closedWorld.commonMasks.intType; | 247 return closedWorld.commonMasks.intType; |
| 207 } | 248 } |
| 208 if (left.isNumberOrNull(closedWorld)) { | 249 if (left.isNumberOrNull(closedWorld)) { |
| 209 if (left.isDoubleOrNull(closedWorld) || | 250 if (left.isDoubleOrNull(closedWorld) || |
| 210 right.isDoubleOrNull(closedWorld)) { | 251 right.isDoubleOrNull(closedWorld)) { |
| 211 return closedWorld.commonMasks.doubleType; | 252 return closedWorld.commonMasks.doubleType; |
| 212 } | 253 } |
| 213 return closedWorld.commonMasks.numType; | 254 return closedWorld.commonMasks.numType; |
| 214 } | 255 } |
| 215 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 256 return super.computeTypeFromInputTypes( |
| 257 instruction, results, options, helpers, closedWorld); |
| 216 } | 258 } |
| 217 | 259 |
| 218 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { | 260 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { |
| 219 return instruction.inputs[1].isNumber(closedWorld) && | 261 return instruction.inputs[1].isNumber(closedWorld) && |
| 220 instruction.inputs[2].isNumber(closedWorld); | 262 instruction.inputs[2].isNumber(closedWorld); |
| 221 } | 263 } |
| 222 | 264 |
| 223 HInstruction tryConvertToBuiltin( | 265 HInstruction tryConvertToBuiltin( |
| 224 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 266 HInvokeDynamic instruction, |
| 267 GlobalTypeInferenceResults results, |
| 268 CompilerOptions options, |
| 269 BackendHelpers helpers, |
| 270 ClosedWorld closedWorld) { |
| 225 if (isBuiltin(instruction, closedWorld)) { | 271 if (isBuiltin(instruction, closedWorld)) { |
| 226 HInstruction builtin = | 272 HInstruction builtin = newBuiltinVariant( |
| 227 newBuiltinVariant(instruction, compiler, closedWorld); | 273 instruction, results, options, helpers, closedWorld); |
| 228 if (builtin != null) return builtin; | 274 if (builtin != null) return builtin; |
| 229 // Even if there is no builtin equivalent instruction, we know | 275 // Even if there is no builtin equivalent instruction, we know |
| 230 // the instruction does not have any side effect, and that it | 276 // the instruction does not have any side effect, and that it |
| 231 // can be GVN'ed. | 277 // can be GVN'ed. |
| 232 clearAllSideEffects(instruction); | 278 clearAllSideEffects(instruction); |
| 233 } | 279 } |
| 234 return null; | 280 return null; |
| 235 } | 281 } |
| 236 | 282 |
| 237 bool inputsArePositiveIntegers( | 283 bool inputsArePositiveIntegers( |
| 238 HInstruction instruction, ClosedWorld closedWorld) { | 284 HInstruction instruction, ClosedWorld closedWorld) { |
| 239 HInstruction left = instruction.inputs[1]; | 285 HInstruction left = instruction.inputs[1]; |
| 240 HInstruction right = instruction.inputs[2]; | 286 HInstruction right = instruction.inputs[2]; |
| 241 return left.isPositiveIntegerOrNull(closedWorld) && | 287 return left.isPositiveIntegerOrNull(closedWorld) && |
| 242 right.isPositiveIntegerOrNull(closedWorld); | 288 right.isPositiveIntegerOrNull(closedWorld); |
| 243 } | 289 } |
| 244 | 290 |
| 245 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { | 291 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { |
| 246 HInstruction left = instruction.inputs[1]; | 292 HInstruction left = instruction.inputs[1]; |
| 247 HInstruction right = instruction.inputs[2]; | 293 HInstruction right = instruction.inputs[2]; |
| 248 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); | 294 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); |
| 249 } | 295 } |
| 250 | 296 |
| 251 HInstruction newBuiltinVariant( | 297 HInstruction newBuiltinVariant( |
| 252 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld); | 298 HInvokeDynamic instruction, |
| 299 GlobalTypeInferenceResults results, |
| 300 CompilerOptions options, |
| 301 BackendHelpers helpers, |
| 302 ClosedWorld closedWorld); |
| 253 } | 303 } |
| 254 | 304 |
| 255 class AddSpecializer extends BinaryArithmeticSpecializer { | 305 class AddSpecializer extends BinaryArithmeticSpecializer { |
| 256 const AddSpecializer(); | 306 const AddSpecializer(); |
| 257 | 307 |
| 258 TypeMask computeTypeFromInputTypes( | 308 TypeMask computeTypeFromInputTypes( |
| 259 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 309 HInvokeDynamic instruction, |
| 310 GlobalTypeInferenceResults results, |
| 311 CompilerOptions options, |
| 312 BackendHelpers helpers, |
| 313 ClosedWorld closedWorld) { |
| 260 if (inputsAreUInt31(instruction, closedWorld)) { | 314 if (inputsAreUInt31(instruction, closedWorld)) { |
| 261 return closedWorld.commonMasks.uint32Type; | 315 return closedWorld.commonMasks.uint32Type; |
| 262 } | 316 } |
| 263 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 317 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
| 264 return closedWorld.commonMasks.positiveIntType; | 318 return closedWorld.commonMasks.positiveIntType; |
| 265 } | 319 } |
| 266 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 320 return super.computeTypeFromInputTypes( |
| 321 instruction, results, options, helpers, closedWorld); |
| 267 } | 322 } |
| 268 | 323 |
| 269 BinaryOperation operation(ConstantSystem constantSystem) { | 324 BinaryOperation operation(ConstantSystem constantSystem) { |
| 270 return constantSystem.add; | 325 return constantSystem.add; |
| 271 } | 326 } |
| 272 | 327 |
| 273 HInstruction newBuiltinVariant( | 328 HInstruction newBuiltinVariant( |
| 274 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 329 HInvokeDynamic instruction, |
| 330 GlobalTypeInferenceResults results, |
| 331 CompilerOptions options, |
| 332 BackendHelpers helpers, |
| 333 ClosedWorld closedWorld) { |
| 275 return new HAdd( | 334 return new HAdd( |
| 276 instruction.inputs[1], | 335 instruction.inputs[1], |
| 277 instruction.inputs[2], | 336 instruction.inputs[2], |
| 278 instruction.selector, | 337 instruction.selector, |
| 279 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 338 computeTypeFromInputTypes( |
| 339 instruction, results, options, helpers, closedWorld)); |
| 280 } | 340 } |
| 281 } | 341 } |
| 282 | 342 |
| 283 class DivideSpecializer extends BinaryArithmeticSpecializer { | 343 class DivideSpecializer extends BinaryArithmeticSpecializer { |
| 284 const DivideSpecializer(); | 344 const DivideSpecializer(); |
| 285 | 345 |
| 286 BinaryOperation operation(ConstantSystem constantSystem) { | 346 BinaryOperation operation(ConstantSystem constantSystem) { |
| 287 return constantSystem.divide; | 347 return constantSystem.divide; |
| 288 } | 348 } |
| 289 | 349 |
| 290 TypeMask computeTypeFromInputTypes( | 350 TypeMask computeTypeFromInputTypes( |
| 291 HInstruction instruction, Compiler compiler, ClosedWorld closedWorld) { | 351 HInstruction instruction, |
| 352 GlobalTypeInferenceResults results, |
| 353 CompilerOptions options, |
| 354 BackendHelpers helpers, |
| 355 ClosedWorld closedWorld) { |
| 292 HInstruction left = instruction.inputs[1]; | 356 HInstruction left = instruction.inputs[1]; |
| 293 if (left.isNumberOrNull(closedWorld)) { | 357 if (left.isNumberOrNull(closedWorld)) { |
| 294 return closedWorld.commonMasks.doubleType; | 358 return closedWorld.commonMasks.doubleType; |
| 295 } | 359 } |
| 296 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 360 return super.computeTypeFromInputTypes( |
| 361 instruction, results, options, helpers, closedWorld); |
| 297 } | 362 } |
| 298 | 363 |
| 299 HInstruction newBuiltinVariant( | 364 HInstruction newBuiltinVariant( |
| 300 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 365 HInvokeDynamic instruction, |
| 366 GlobalTypeInferenceResults results, |
| 367 CompilerOptions options, |
| 368 BackendHelpers helpers, |
| 369 ClosedWorld closedWorld) { |
| 301 return new HDivide(instruction.inputs[1], instruction.inputs[2], | 370 return new HDivide(instruction.inputs[1], instruction.inputs[2], |
| 302 instruction.selector, closedWorld.commonMasks.doubleType); | 371 instruction.selector, closedWorld.commonMasks.doubleType); |
| 303 } | 372 } |
| 304 } | 373 } |
| 305 | 374 |
| 306 class ModuloSpecializer extends BinaryArithmeticSpecializer { | 375 class ModuloSpecializer extends BinaryArithmeticSpecializer { |
| 307 const ModuloSpecializer(); | 376 const ModuloSpecializer(); |
| 308 | 377 |
| 309 TypeMask computeTypeFromInputTypes( | 378 TypeMask computeTypeFromInputTypes( |
| 310 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 379 HInvokeDynamic instruction, |
| 380 GlobalTypeInferenceResults results, |
| 381 CompilerOptions options, |
| 382 BackendHelpers helpers, |
| 383 ClosedWorld closedWorld) { |
| 311 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 384 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
| 312 return closedWorld.commonMasks.positiveIntType; | 385 return closedWorld.commonMasks.positiveIntType; |
| 313 } | 386 } |
| 314 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 387 return super.computeTypeFromInputTypes( |
| 388 instruction, results, options, helpers, closedWorld); |
| 315 } | 389 } |
| 316 | 390 |
| 317 BinaryOperation operation(ConstantSystem constantSystem) { | 391 BinaryOperation operation(ConstantSystem constantSystem) { |
| 318 return constantSystem.modulo; | 392 return constantSystem.modulo; |
| 319 } | 393 } |
| 320 | 394 |
| 321 HInstruction newBuiltinVariant( | 395 HInstruction newBuiltinVariant( |
| 322 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 396 HInvokeDynamic instruction, |
| 397 GlobalTypeInferenceResults results, |
| 398 CompilerOptions options, |
| 399 BackendHelpers helpers, |
| 400 ClosedWorld closedWorld) { |
| 323 // Modulo cannot be mapped to the native operator (different semantics). | 401 // Modulo cannot be mapped to the native operator (different semantics). |
| 324 | 402 |
| 325 // We can use HRemainder if both inputs are non-negative and the receiver | 403 // We can use HRemainder if both inputs are non-negative and the receiver |
| 326 // cannot be -0.0. Note that -0.0 is considered to be an int, so until we | 404 // cannot be -0.0. Note that -0.0 is considered to be an int, so until we |
| 327 // track -0.0 precisely, we have to syntatically filter inputs that cannot | 405 // track -0.0 precisely, we have to syntatically filter inputs that cannot |
| 328 // generate -0.0. | 406 // generate -0.0. |
| 329 bool canBePositiveZero(HInstruction input) { | 407 bool canBePositiveZero(HInstruction input) { |
| 330 if (input is HConstant) { | 408 if (input is HConstant) { |
| 331 ConstantValue value = input.constant; | 409 ConstantValue value = input.constant; |
| 332 if (value is DoubleConstantValue && value.isZero) return true; | 410 if (value is DoubleConstantValue && value.isZero) return true; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 359 } | 437 } |
| 360 return true; | 438 return true; |
| 361 } | 439 } |
| 362 | 440 |
| 363 if (inputsArePositiveIntegers(instruction, closedWorld) && | 441 if (inputsArePositiveIntegers(instruction, closedWorld) && |
| 364 !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) { | 442 !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) { |
| 365 return new HRemainder( | 443 return new HRemainder( |
| 366 instruction.inputs[1], | 444 instruction.inputs[1], |
| 367 instruction.inputs[2], | 445 instruction.inputs[2], |
| 368 instruction.selector, | 446 instruction.selector, |
| 369 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 447 computeTypeFromInputTypes( |
| 448 instruction, results, options, helpers, closedWorld)); |
| 370 } | 449 } |
| 371 // TODO(sra): | 450 // TODO(sra): |
| 372 // a % N --> a & (N-1), N=2^k, where a>=0, does not have -0.0 problem. | 451 // a % N --> a & (N-1), N=2^k, where a>=0, does not have -0.0 problem. |
| 373 | 452 |
| 374 // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x + | 453 // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x + |
| 375 // 0) % y, but we would have to fix HAdd optimizations. | 454 // 0) % y, but we would have to fix HAdd optimizations. |
| 376 | 455 |
| 377 // TODO(sra): We could replace $mod with HRemainder when we don't care about | 456 // TODO(sra): We could replace $mod with HRemainder when we don't care about |
| 378 // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we | 457 // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we |
| 379 // don't want to ruin GVN opportunities. | 458 // don't want to ruin GVN opportunities. |
| 380 return null; | 459 return null; |
| 381 } | 460 } |
| 382 } | 461 } |
| 383 | 462 |
| 384 class RemainderSpecializer extends BinaryArithmeticSpecializer { | 463 class RemainderSpecializer extends BinaryArithmeticSpecializer { |
| 385 const RemainderSpecializer(); | 464 const RemainderSpecializer(); |
| 386 | 465 |
| 387 TypeMask computeTypeFromInputTypes( | 466 TypeMask computeTypeFromInputTypes( |
| 388 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 467 HInvokeDynamic instruction, |
| 468 GlobalTypeInferenceResults results, |
| 469 CompilerOptions options, |
| 470 BackendHelpers helpers, |
| 471 ClosedWorld closedWorld) { |
| 389 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 472 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
| 390 return closedWorld.commonMasks.positiveIntType; | 473 return closedWorld.commonMasks.positiveIntType; |
| 391 } | 474 } |
| 392 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 475 return super.computeTypeFromInputTypes( |
| 476 instruction, results, options, helpers, closedWorld); |
| 393 } | 477 } |
| 394 | 478 |
| 395 BinaryOperation operation(ConstantSystem constantSystem) { | 479 BinaryOperation operation(ConstantSystem constantSystem) { |
| 396 return constantSystem.remainder; | 480 return constantSystem.remainder; |
| 397 } | 481 } |
| 398 | 482 |
| 399 HInstruction newBuiltinVariant( | 483 HInstruction newBuiltinVariant( |
| 400 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 484 HInvokeDynamic instruction, |
| 485 GlobalTypeInferenceResults results, |
| 486 CompilerOptions options, |
| 487 BackendHelpers helpers, |
| 488 ClosedWorld closedWorld) { |
| 401 return new HRemainder( | 489 return new HRemainder( |
| 402 instruction.inputs[1], | 490 instruction.inputs[1], |
| 403 instruction.inputs[2], | 491 instruction.inputs[2], |
| 404 instruction.selector, | 492 instruction.selector, |
| 405 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 493 computeTypeFromInputTypes( |
| 494 instruction, results, options, helpers, closedWorld)); |
| 406 } | 495 } |
| 407 } | 496 } |
| 408 | 497 |
| 409 class MultiplySpecializer extends BinaryArithmeticSpecializer { | 498 class MultiplySpecializer extends BinaryArithmeticSpecializer { |
| 410 const MultiplySpecializer(); | 499 const MultiplySpecializer(); |
| 411 | 500 |
| 412 BinaryOperation operation(ConstantSystem constantSystem) { | 501 BinaryOperation operation(ConstantSystem constantSystem) { |
| 413 return constantSystem.multiply; | 502 return constantSystem.multiply; |
| 414 } | 503 } |
| 415 | 504 |
| 416 TypeMask computeTypeFromInputTypes( | 505 TypeMask computeTypeFromInputTypes( |
| 417 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 506 HInvokeDynamic instruction, |
| 507 GlobalTypeInferenceResults results, |
| 508 CompilerOptions options, |
| 509 BackendHelpers helpers, |
| 510 ClosedWorld closedWorld) { |
| 418 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 511 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
| 419 return closedWorld.commonMasks.positiveIntType; | 512 return closedWorld.commonMasks.positiveIntType; |
| 420 } | 513 } |
| 421 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 514 return super.computeTypeFromInputTypes( |
| 515 instruction, results, options, helpers, closedWorld); |
| 422 } | 516 } |
| 423 | 517 |
| 424 HInstruction newBuiltinVariant( | 518 HInstruction newBuiltinVariant( |
| 425 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 519 HInvokeDynamic instruction, |
| 520 GlobalTypeInferenceResults results, |
| 521 CompilerOptions options, |
| 522 BackendHelpers helpers, |
| 523 ClosedWorld closedWorld) { |
| 426 return new HMultiply( | 524 return new HMultiply( |
| 427 instruction.inputs[1], | 525 instruction.inputs[1], |
| 428 instruction.inputs[2], | 526 instruction.inputs[2], |
| 429 instruction.selector, | 527 instruction.selector, |
| 430 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 528 computeTypeFromInputTypes( |
| 529 instruction, results, options, helpers, closedWorld)); |
| 431 } | 530 } |
| 432 } | 531 } |
| 433 | 532 |
| 434 class SubtractSpecializer extends BinaryArithmeticSpecializer { | 533 class SubtractSpecializer extends BinaryArithmeticSpecializer { |
| 435 const SubtractSpecializer(); | 534 const SubtractSpecializer(); |
| 436 | 535 |
| 437 BinaryOperation operation(ConstantSystem constantSystem) { | 536 BinaryOperation operation(ConstantSystem constantSystem) { |
| 438 return constantSystem.subtract; | 537 return constantSystem.subtract; |
| 439 } | 538 } |
| 440 | 539 |
| 441 HInstruction newBuiltinVariant( | 540 HInstruction newBuiltinVariant( |
| 442 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 541 HInvokeDynamic instruction, |
| 542 GlobalTypeInferenceResults results, |
| 543 CompilerOptions options, |
| 544 BackendHelpers helpers, |
| 545 ClosedWorld closedWorld) { |
| 443 return new HSubtract( | 546 return new HSubtract( |
| 444 instruction.inputs[1], | 547 instruction.inputs[1], |
| 445 instruction.inputs[2], | 548 instruction.inputs[2], |
| 446 instruction.selector, | 549 instruction.selector, |
| 447 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 550 computeTypeFromInputTypes( |
| 551 instruction, results, options, helpers, closedWorld)); |
| 448 } | 552 } |
| 449 } | 553 } |
| 450 | 554 |
| 451 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { | 555 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { |
| 452 const TruncatingDivideSpecializer(); | 556 const TruncatingDivideSpecializer(); |
| 453 | 557 |
| 454 BinaryOperation operation(ConstantSystem constantSystem) { | 558 BinaryOperation operation(ConstantSystem constantSystem) { |
| 455 return constantSystem.truncatingDivide; | 559 return constantSystem.truncatingDivide; |
| 456 } | 560 } |
| 457 | 561 |
| 458 TypeMask computeTypeFromInputTypes( | 562 TypeMask computeTypeFromInputTypes( |
| 459 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 563 HInvokeDynamic instruction, |
| 564 GlobalTypeInferenceResults results, |
| 565 CompilerOptions options, |
| 566 BackendHelpers helpers, |
| 567 ClosedWorld closedWorld) { |
| 460 if (hasUint31Result(instruction, closedWorld)) { | 568 if (hasUint31Result(instruction, closedWorld)) { |
| 461 return closedWorld.commonMasks.uint31Type; | 569 return closedWorld.commonMasks.uint31Type; |
| 462 } | 570 } |
| 463 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 571 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
| 464 return closedWorld.commonMasks.positiveIntType; | 572 return closedWorld.commonMasks.positiveIntType; |
| 465 } | 573 } |
| 466 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 574 return super.computeTypeFromInputTypes( |
| 575 instruction, results, options, helpers, closedWorld); |
| 467 } | 576 } |
| 468 | 577 |
| 469 bool isNotZero(HInstruction instruction) { | 578 bool isNotZero(HInstruction instruction) { |
| 470 if (!instruction.isConstantInteger()) return false; | 579 if (!instruction.isConstantInteger()) return false; |
| 471 HConstant rightConstant = instruction; | 580 HConstant rightConstant = instruction; |
| 472 IntConstantValue intConstant = rightConstant.constant; | 581 IntConstantValue intConstant = rightConstant.constant; |
| 473 int count = intConstant.primitiveValue; | 582 int count = intConstant.primitiveValue; |
| 474 return count != 0; | 583 return count != 0; |
| 475 } | 584 } |
| 476 | 585 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 490 return true; | 599 return true; |
| 491 } | 600 } |
| 492 if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) { | 601 if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) { |
| 493 return true; | 602 return true; |
| 494 } | 603 } |
| 495 } | 604 } |
| 496 return false; | 605 return false; |
| 497 } | 606 } |
| 498 | 607 |
| 499 HInstruction tryConvertToBuiltin( | 608 HInstruction tryConvertToBuiltin( |
| 500 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 609 HInvokeDynamic instruction, |
| 610 GlobalTypeInferenceResults results, |
| 611 CompilerOptions options, |
| 612 BackendHelpers helpers, |
| 613 ClosedWorld closedWorld) { |
| 501 HInstruction right = instruction.inputs[2]; | 614 HInstruction right = instruction.inputs[2]; |
| 502 if (isBuiltin(instruction, closedWorld)) { | 615 if (isBuiltin(instruction, closedWorld)) { |
| 503 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { | 616 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { |
| 504 if (hasUint31Result(instruction, closedWorld)) { | 617 if (hasUint31Result(instruction, closedWorld)) { |
| 505 return newBuiltinVariant(instruction, compiler, closedWorld); | 618 return newBuiltinVariant( |
| 619 instruction, results, options, helpers, closedWorld); |
| 506 } | 620 } |
| 507 // We can call _tdivFast because the rhs is a 32bit integer | 621 // We can call _tdivFast because the rhs is a 32bit integer |
| 508 // and not 0, nor -1. | 622 // and not 0, nor -1. |
| 509 instruction.selector = renameToOptimizedSelector( | 623 instruction.selector = renameToOptimizedSelector( |
| 510 '_tdivFast', instruction.selector, compiler); | 624 '_tdivFast', instruction.selector, helpers); |
| 511 } | 625 } |
| 512 clearAllSideEffects(instruction); | 626 clearAllSideEffects(instruction); |
| 513 } | 627 } |
| 514 return null; | 628 return null; |
| 515 } | 629 } |
| 516 | 630 |
| 517 HInstruction newBuiltinVariant( | 631 HInstruction newBuiltinVariant( |
| 518 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 632 HInvokeDynamic instruction, |
| 633 GlobalTypeInferenceResults results, |
| 634 CompilerOptions options, |
| 635 BackendHelpers helpers, |
| 636 ClosedWorld closedWorld) { |
| 519 return new HTruncatingDivide( | 637 return new HTruncatingDivide( |
| 520 instruction.inputs[1], | 638 instruction.inputs[1], |
| 521 instruction.inputs[2], | 639 instruction.inputs[2], |
| 522 instruction.selector, | 640 instruction.selector, |
| 523 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 641 computeTypeFromInputTypes( |
| 642 instruction, results, options, helpers, closedWorld)); |
| 524 } | 643 } |
| 525 } | 644 } |
| 526 | 645 |
| 527 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 646 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
| 528 const BinaryBitOpSpecializer(); | 647 const BinaryBitOpSpecializer(); |
| 529 | 648 |
| 530 TypeMask computeTypeFromInputTypes( | 649 TypeMask computeTypeFromInputTypes( |
| 531 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 650 HInvokeDynamic instruction, |
| 651 GlobalTypeInferenceResults results, |
| 652 CompilerOptions options, |
| 653 BackendHelpers helpers, |
| 654 ClosedWorld closedWorld) { |
| 532 // All bitwise operations on primitive types either produce an | 655 // All bitwise operations on primitive types either produce an |
| 533 // integer or throw an error. | 656 // integer or throw an error. |
| 534 HInstruction left = instruction.inputs[1]; | 657 HInstruction left = instruction.inputs[1]; |
| 535 if (left.isPrimitiveOrNull(closedWorld)) { | 658 if (left.isPrimitiveOrNull(closedWorld)) { |
| 536 return closedWorld.commonMasks.uint32Type; | 659 return closedWorld.commonMasks.uint32Type; |
| 537 } | 660 } |
| 538 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 661 return super.computeTypeFromInputTypes( |
| 662 instruction, results, options, helpers, closedWorld); |
| 539 } | 663 } |
| 540 | 664 |
| 541 bool argumentLessThan32(HInstruction instruction) { | 665 bool argumentLessThan32(HInstruction instruction) { |
| 542 return argumentInRange(instruction, 0, 31); | 666 return argumentInRange(instruction, 0, 31); |
| 543 } | 667 } |
| 544 | 668 |
| 545 bool argumentInRange(HInstruction instruction, int low, int high) { | 669 bool argumentInRange(HInstruction instruction, int low, int high) { |
| 546 if (instruction.isConstantInteger()) { | 670 if (instruction.isConstantInteger()) { |
| 547 HConstant rightConstant = instruction; | 671 HConstant rightConstant = instruction; |
| 548 IntConstantValue intConstant = rightConstant.constant; | 672 IntConstantValue intConstant = rightConstant.constant; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 566 } | 690 } |
| 567 | 691 |
| 568 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { | 692 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { |
| 569 const ShiftLeftSpecializer(); | 693 const ShiftLeftSpecializer(); |
| 570 | 694 |
| 571 BinaryOperation operation(ConstantSystem constantSystem) { | 695 BinaryOperation operation(ConstantSystem constantSystem) { |
| 572 return constantSystem.shiftLeft; | 696 return constantSystem.shiftLeft; |
| 573 } | 697 } |
| 574 | 698 |
| 575 HInstruction tryConvertToBuiltin( | 699 HInstruction tryConvertToBuiltin( |
| 576 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 700 HInvokeDynamic instruction, |
| 701 GlobalTypeInferenceResults results, |
| 702 CompilerOptions options, |
| 703 BackendHelpers helpers, |
| 704 ClosedWorld closedWorld) { |
| 577 HInstruction left = instruction.inputs[1]; | 705 HInstruction left = instruction.inputs[1]; |
| 578 HInstruction right = instruction.inputs[2]; | 706 HInstruction right = instruction.inputs[2]; |
| 579 if (left.isNumber(closedWorld)) { | 707 if (left.isNumber(closedWorld)) { |
| 580 if (argumentLessThan32(right)) { | 708 if (argumentLessThan32(right)) { |
| 581 return newBuiltinVariant(instruction, compiler, closedWorld); | 709 return newBuiltinVariant( |
| 710 instruction, results, options, helpers, closedWorld); |
| 582 } | 711 } |
| 583 // Even if there is no builtin equivalent instruction, we know | 712 // Even if there is no builtin equivalent instruction, we know |
| 584 // the instruction does not have any side effect, and that it | 713 // the instruction does not have any side effect, and that it |
| 585 // can be GVN'ed. | 714 // can be GVN'ed. |
| 586 clearAllSideEffects(instruction); | 715 clearAllSideEffects(instruction); |
| 587 if (isPositive(right, closedWorld)) { | 716 if (isPositive(right, closedWorld)) { |
| 588 instruction.selector = renameToOptimizedSelector( | 717 instruction.selector = renameToOptimizedSelector( |
| 589 '_shlPositive', instruction.selector, compiler); | 718 '_shlPositive', instruction.selector, helpers); |
| 590 } | 719 } |
| 591 } | 720 } |
| 592 return null; | 721 return null; |
| 593 } | 722 } |
| 594 | 723 |
| 595 HInstruction newBuiltinVariant( | 724 HInstruction newBuiltinVariant( |
| 596 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 725 HInvokeDynamic instruction, |
| 726 GlobalTypeInferenceResults results, |
| 727 CompilerOptions options, |
| 728 BackendHelpers helpers, |
| 729 ClosedWorld closedWorld) { |
| 597 return new HShiftLeft( | 730 return new HShiftLeft( |
| 598 instruction.inputs[1], | 731 instruction.inputs[1], |
| 599 instruction.inputs[2], | 732 instruction.inputs[2], |
| 600 instruction.selector, | 733 instruction.selector, |
| 601 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 734 computeTypeFromInputTypes( |
| 735 instruction, results, options, helpers, closedWorld)); |
| 602 } | 736 } |
| 603 } | 737 } |
| 604 | 738 |
| 605 class ShiftRightSpecializer extends BinaryBitOpSpecializer { | 739 class ShiftRightSpecializer extends BinaryBitOpSpecializer { |
| 606 const ShiftRightSpecializer(); | 740 const ShiftRightSpecializer(); |
| 607 | 741 |
| 608 TypeMask computeTypeFromInputTypes( | 742 TypeMask computeTypeFromInputTypes( |
| 609 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 743 HInvokeDynamic instruction, |
| 744 GlobalTypeInferenceResults results, |
| 745 CompilerOptions options, |
| 746 BackendHelpers helpers, |
| 747 ClosedWorld closedWorld) { |
| 610 HInstruction left = instruction.inputs[1]; | 748 HInstruction left = instruction.inputs[1]; |
| 611 if (left.isUInt32(closedWorld)) return left.instructionType; | 749 if (left.isUInt32(closedWorld)) return left.instructionType; |
| 612 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 750 return super.computeTypeFromInputTypes( |
| 751 instruction, results, options, helpers, closedWorld); |
| 613 } | 752 } |
| 614 | 753 |
| 615 HInstruction tryConvertToBuiltin( | 754 HInstruction tryConvertToBuiltin( |
| 616 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 755 HInvokeDynamic instruction, |
| 756 GlobalTypeInferenceResults results, |
| 757 CompilerOptions options, |
| 758 BackendHelpers helpers, |
| 759 ClosedWorld closedWorld) { |
| 617 HInstruction left = instruction.inputs[1]; | 760 HInstruction left = instruction.inputs[1]; |
| 618 HInstruction right = instruction.inputs[2]; | 761 HInstruction right = instruction.inputs[2]; |
| 619 if (left.isNumber(closedWorld)) { | 762 if (left.isNumber(closedWorld)) { |
| 620 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { | 763 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { |
| 621 return newBuiltinVariant(instruction, compiler, closedWorld); | 764 return newBuiltinVariant( |
| 765 instruction, results, options, helpers, closedWorld); |
| 622 } | 766 } |
| 623 // Even if there is no builtin equivalent instruction, we know | 767 // Even if there is no builtin equivalent instruction, we know |
| 624 // the instruction does not have any side effect, and that it | 768 // the instruction does not have any side effect, and that it |
| 625 // can be GVN'ed. | 769 // can be GVN'ed. |
| 626 clearAllSideEffects(instruction); | 770 clearAllSideEffects(instruction); |
| 627 if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) { | 771 if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) { |
| 628 instruction.selector = renameToOptimizedSelector( | 772 instruction.selector = renameToOptimizedSelector( |
| 629 '_shrBothPositive', instruction.selector, compiler); | 773 '_shrBothPositive', instruction.selector, helpers); |
| 630 } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) { | 774 } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) { |
| 631 instruction.selector = renameToOptimizedSelector( | 775 instruction.selector = renameToOptimizedSelector( |
| 632 '_shrReceiverPositive', instruction.selector, compiler); | 776 '_shrReceiverPositive', instruction.selector, helpers); |
| 633 } else if (isPositive(right, closedWorld)) { | 777 } else if (isPositive(right, closedWorld)) { |
| 634 instruction.selector = renameToOptimizedSelector( | 778 instruction.selector = renameToOptimizedSelector( |
| 635 '_shrOtherPositive', instruction.selector, compiler); | 779 '_shrOtherPositive', instruction.selector, helpers); |
| 636 } | 780 } |
| 637 } | 781 } |
| 638 return null; | 782 return null; |
| 639 } | 783 } |
| 640 | 784 |
| 641 HInstruction newBuiltinVariant( | 785 HInstruction newBuiltinVariant( |
| 642 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 786 HInvokeDynamic instruction, |
| 787 GlobalTypeInferenceResults results, |
| 788 CompilerOptions options, |
| 789 BackendHelpers helpers, |
| 790 ClosedWorld closedWorld) { |
| 643 return new HShiftRight( | 791 return new HShiftRight( |
| 644 instruction.inputs[1], | 792 instruction.inputs[1], |
| 645 instruction.inputs[2], | 793 instruction.inputs[2], |
| 646 instruction.selector, | 794 instruction.selector, |
| 647 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 795 computeTypeFromInputTypes( |
| 796 instruction, results, options, helpers, closedWorld)); |
| 648 } | 797 } |
| 649 | 798 |
| 650 BinaryOperation operation(ConstantSystem constantSystem) { | 799 BinaryOperation operation(ConstantSystem constantSystem) { |
| 651 return constantSystem.shiftRight; | 800 return constantSystem.shiftRight; |
| 652 } | 801 } |
| 653 } | 802 } |
| 654 | 803 |
| 655 class BitOrSpecializer extends BinaryBitOpSpecializer { | 804 class BitOrSpecializer extends BinaryBitOpSpecializer { |
| 656 const BitOrSpecializer(); | 805 const BitOrSpecializer(); |
| 657 | 806 |
| 658 BinaryOperation operation(ConstantSystem constantSystem) { | 807 BinaryOperation operation(ConstantSystem constantSystem) { |
| 659 return constantSystem.bitOr; | 808 return constantSystem.bitOr; |
| 660 } | 809 } |
| 661 | 810 |
| 662 TypeMask computeTypeFromInputTypes( | 811 TypeMask computeTypeFromInputTypes( |
| 663 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 812 HInvokeDynamic instruction, |
| 813 GlobalTypeInferenceResults results, |
| 814 CompilerOptions options, |
| 815 BackendHelpers helpers, |
| 816 ClosedWorld closedWorld) { |
| 664 HInstruction left = instruction.inputs[1]; | 817 HInstruction left = instruction.inputs[1]; |
| 665 HInstruction right = instruction.inputs[2]; | 818 HInstruction right = instruction.inputs[2]; |
| 666 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { | 819 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { |
| 667 return closedWorld.commonMasks.uint31Type; | 820 return closedWorld.commonMasks.uint31Type; |
| 668 } | 821 } |
| 669 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 822 return super.computeTypeFromInputTypes( |
| 823 instruction, results, options, helpers, closedWorld); |
| 670 } | 824 } |
| 671 | 825 |
| 672 HInstruction newBuiltinVariant( | 826 HInstruction newBuiltinVariant( |
| 673 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 827 HInvokeDynamic instruction, |
| 828 GlobalTypeInferenceResults results, |
| 829 CompilerOptions options, |
| 830 BackendHelpers helpers, |
| 831 ClosedWorld closedWorld) { |
| 674 return new HBitOr( | 832 return new HBitOr( |
| 675 instruction.inputs[1], | 833 instruction.inputs[1], |
| 676 instruction.inputs[2], | 834 instruction.inputs[2], |
| 677 instruction.selector, | 835 instruction.selector, |
| 678 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 836 computeTypeFromInputTypes( |
| 837 instruction, results, options, helpers, closedWorld)); |
| 679 } | 838 } |
| 680 } | 839 } |
| 681 | 840 |
| 682 class BitAndSpecializer extends BinaryBitOpSpecializer { | 841 class BitAndSpecializer extends BinaryBitOpSpecializer { |
| 683 const BitAndSpecializer(); | 842 const BitAndSpecializer(); |
| 684 | 843 |
| 685 BinaryOperation operation(ConstantSystem constantSystem) { | 844 BinaryOperation operation(ConstantSystem constantSystem) { |
| 686 return constantSystem.bitAnd; | 845 return constantSystem.bitAnd; |
| 687 } | 846 } |
| 688 | 847 |
| 689 TypeMask computeTypeFromInputTypes( | 848 TypeMask computeTypeFromInputTypes( |
| 690 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 849 HInvokeDynamic instruction, |
| 850 GlobalTypeInferenceResults results, |
| 851 CompilerOptions options, |
| 852 BackendHelpers helpers, |
| 853 ClosedWorld closedWorld) { |
| 691 HInstruction left = instruction.inputs[1]; | 854 HInstruction left = instruction.inputs[1]; |
| 692 HInstruction right = instruction.inputs[2]; | 855 HInstruction right = instruction.inputs[2]; |
| 693 if (left.isPrimitiveOrNull(closedWorld) && | 856 if (left.isPrimitiveOrNull(closedWorld) && |
| 694 (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) { | 857 (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) { |
| 695 return closedWorld.commonMasks.uint31Type; | 858 return closedWorld.commonMasks.uint31Type; |
| 696 } | 859 } |
| 697 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 860 return super.computeTypeFromInputTypes( |
| 861 instruction, results, options, helpers, closedWorld); |
| 698 } | 862 } |
| 699 | 863 |
| 700 HInstruction newBuiltinVariant( | 864 HInstruction newBuiltinVariant( |
| 701 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 865 HInvokeDynamic instruction, |
| 866 GlobalTypeInferenceResults results, |
| 867 CompilerOptions options, |
| 868 BackendHelpers helpers, |
| 869 ClosedWorld closedWorld) { |
| 702 return new HBitAnd( | 870 return new HBitAnd( |
| 703 instruction.inputs[1], | 871 instruction.inputs[1], |
| 704 instruction.inputs[2], | 872 instruction.inputs[2], |
| 705 instruction.selector, | 873 instruction.selector, |
| 706 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 874 computeTypeFromInputTypes( |
| 875 instruction, results, options, helpers, closedWorld)); |
| 707 } | 876 } |
| 708 } | 877 } |
| 709 | 878 |
| 710 class BitXorSpecializer extends BinaryBitOpSpecializer { | 879 class BitXorSpecializer extends BinaryBitOpSpecializer { |
| 711 const BitXorSpecializer(); | 880 const BitXorSpecializer(); |
| 712 | 881 |
| 713 BinaryOperation operation(ConstantSystem constantSystem) { | 882 BinaryOperation operation(ConstantSystem constantSystem) { |
| 714 return constantSystem.bitXor; | 883 return constantSystem.bitXor; |
| 715 } | 884 } |
| 716 | 885 |
| 717 TypeMask computeTypeFromInputTypes( | 886 TypeMask computeTypeFromInputTypes( |
| 718 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 887 HInvokeDynamic instruction, |
| 888 GlobalTypeInferenceResults results, |
| 889 CompilerOptions options, |
| 890 BackendHelpers helpers, |
| 891 ClosedWorld closedWorld) { |
| 719 HInstruction left = instruction.inputs[1]; | 892 HInstruction left = instruction.inputs[1]; |
| 720 HInstruction right = instruction.inputs[2]; | 893 HInstruction right = instruction.inputs[2]; |
| 721 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { | 894 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { |
| 722 return closedWorld.commonMasks.uint31Type; | 895 return closedWorld.commonMasks.uint31Type; |
| 723 } | 896 } |
| 724 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 897 return super.computeTypeFromInputTypes( |
| 898 instruction, results, options, helpers, closedWorld); |
| 725 } | 899 } |
| 726 | 900 |
| 727 HInstruction newBuiltinVariant( | 901 HInstruction newBuiltinVariant( |
| 728 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 902 HInvokeDynamic instruction, |
| 903 GlobalTypeInferenceResults results, |
| 904 CompilerOptions options, |
| 905 BackendHelpers helpers, |
| 906 ClosedWorld closedWorld) { |
| 729 return new HBitXor( | 907 return new HBitXor( |
| 730 instruction.inputs[1], | 908 instruction.inputs[1], |
| 731 instruction.inputs[2], | 909 instruction.inputs[2], |
| 732 instruction.selector, | 910 instruction.selector, |
| 733 computeTypeFromInputTypes(instruction, compiler, closedWorld)); | 911 computeTypeFromInputTypes( |
| 912 instruction, results, options, helpers, closedWorld)); |
| 734 } | 913 } |
| 735 } | 914 } |
| 736 | 915 |
| 737 abstract class RelationalSpecializer extends InvokeDynamicSpecializer { | 916 abstract class RelationalSpecializer extends InvokeDynamicSpecializer { |
| 738 const RelationalSpecializer(); | 917 const RelationalSpecializer(); |
| 739 | 918 |
| 740 TypeMask computeTypeFromInputTypes( | 919 TypeMask computeTypeFromInputTypes( |
| 741 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 920 HInvokeDynamic instruction, |
| 921 GlobalTypeInferenceResults results, |
| 922 CompilerOptions options, |
| 923 BackendHelpers helpers, |
| 924 ClosedWorld closedWorld) { |
| 742 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { | 925 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { |
| 743 return closedWorld.commonMasks.boolType; | 926 return closedWorld.commonMasks.boolType; |
| 744 } | 927 } |
| 745 return super.computeTypeFromInputTypes(instruction, compiler, closedWorld); | 928 return super.computeTypeFromInputTypes( |
| 929 instruction, results, options, helpers, closedWorld); |
| 746 } | 930 } |
| 747 | 931 |
| 748 HInstruction tryConvertToBuiltin( | 932 HInstruction tryConvertToBuiltin( |
| 749 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 933 HInvokeDynamic instruction, |
| 934 GlobalTypeInferenceResults results, |
| 935 CompilerOptions options, |
| 936 BackendHelpers helpers, |
| 937 ClosedWorld closedWorld) { |
| 750 HInstruction left = instruction.inputs[1]; | 938 HInstruction left = instruction.inputs[1]; |
| 751 HInstruction right = instruction.inputs[2]; | 939 HInstruction right = instruction.inputs[2]; |
| 752 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { | 940 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { |
| 753 return newBuiltinVariant(instruction, closedWorld); | 941 return newBuiltinVariant(instruction, closedWorld); |
| 754 } | 942 } |
| 755 return null; | 943 return null; |
| 756 } | 944 } |
| 757 | 945 |
| 758 HInstruction newBuiltinVariant( | 946 HInstruction newBuiltinVariant( |
| 759 HInvokeDynamic instruction, ClosedWorld closedWorld); | 947 HInvokeDynamic instruction, ClosedWorld closedWorld); |
| 760 } | 948 } |
| 761 | 949 |
| 762 class EqualsSpecializer extends RelationalSpecializer { | 950 class EqualsSpecializer extends RelationalSpecializer { |
| 763 const EqualsSpecializer(); | 951 const EqualsSpecializer(); |
| 764 | 952 |
| 765 HInstruction tryConvertToBuiltin( | 953 HInstruction tryConvertToBuiltin( |
| 766 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 954 HInvokeDynamic instruction, |
| 955 GlobalTypeInferenceResults results, |
| 956 CompilerOptions options, |
| 957 BackendHelpers helpers, |
| 958 ClosedWorld closedWorld) { |
| 767 HInstruction left = instruction.inputs[1]; | 959 HInstruction left = instruction.inputs[1]; |
| 768 HInstruction right = instruction.inputs[2]; | 960 HInstruction right = instruction.inputs[2]; |
| 769 TypeMask instructionType = left.instructionType; | 961 TypeMask instructionType = left.instructionType; |
| 770 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { | 962 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { |
| 771 return newBuiltinVariant(instruction, closedWorld); | 963 return newBuiltinVariant(instruction, closedWorld); |
| 772 } | 964 } |
| 773 Iterable<MemberEntity> matches = | 965 Iterable<MemberEntity> matches = |
| 774 closedWorld.allFunctions.filter(instruction.selector, instructionType); | 966 closedWorld.allFunctions.filter(instruction.selector, instructionType); |
| 775 // This test relies the on `Object.==` and `Interceptor.==` always being | 967 // This test relies the on `Object.==` and `Interceptor.==` always being |
| 776 // implemented because if the selector matches by subtype, it still will be | 968 // implemented because if the selector matches by subtype, it still will be |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 } | 1042 } |
| 851 | 1043 |
| 852 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer { | 1044 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer { |
| 853 const CodeUnitAtSpecializer(); | 1045 const CodeUnitAtSpecializer(); |
| 854 | 1046 |
| 855 BinaryOperation operation(ConstantSystem constantSystem) { | 1047 BinaryOperation operation(ConstantSystem constantSystem) { |
| 856 return constantSystem.codeUnitAt; | 1048 return constantSystem.codeUnitAt; |
| 857 } | 1049 } |
| 858 | 1050 |
| 859 HInstruction tryConvertToBuiltin( | 1051 HInstruction tryConvertToBuiltin( |
| 860 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 1052 HInvokeDynamic instruction, |
| 1053 GlobalTypeInferenceResults results, |
| 1054 CompilerOptions options, |
| 1055 BackendHelpers helpers, |
| 1056 ClosedWorld closedWorld) { |
| 861 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index | 1057 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index |
| 862 // bounds checking optimizations as for HIndex. | 1058 // bounds checking optimizations as for HIndex. |
| 863 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1059 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 864 if (receiver.isStringOrNull(closedWorld)) { | 1060 if (receiver.isStringOrNull(closedWorld)) { |
| 865 // Even if there is no builtin equivalent instruction, we know | 1061 // Even if there is no builtin equivalent instruction, we know |
| 866 // String.codeUnitAt does not have any side effect (other than throwing), | 1062 // String.codeUnitAt does not have any side effect (other than throwing), |
| 867 // and that it can be GVN'ed. | 1063 // and that it can be GVN'ed. |
| 868 clearAllSideEffects(instruction); | 1064 clearAllSideEffects(instruction); |
| 869 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { | 1065 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { |
| 870 instruction.selector = renameToOptimizedSelector( | 1066 instruction.selector = renameToOptimizedSelector( |
| 871 '_codeUnitAt', instruction.selector, compiler); | 1067 '_codeUnitAt', instruction.selector, helpers); |
| 872 } | 1068 } |
| 873 } | 1069 } |
| 874 return null; | 1070 return null; |
| 875 } | 1071 } |
| 876 } | 1072 } |
| 877 | 1073 |
| 878 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { | 1074 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { |
| 879 const IdempotentStringOperationSpecializer(); | 1075 const IdempotentStringOperationSpecializer(); |
| 880 | 1076 |
| 881 HInstruction tryConvertToBuiltin( | 1077 HInstruction tryConvertToBuiltin( |
| 882 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 1078 HInvokeDynamic instruction, |
| 1079 GlobalTypeInferenceResults results, |
| 1080 CompilerOptions options, |
| 1081 BackendHelpers helpers, |
| 1082 ClosedWorld closedWorld) { |
| 883 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1083 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 884 if (receiver.isStringOrNull(closedWorld)) { | 1084 if (receiver.isStringOrNull(closedWorld)) { |
| 885 // String.xxx does not have any side effect (other than throwing), and it | 1085 // String.xxx does not have any side effect (other than throwing), and it |
| 886 // can be GVN'ed. | 1086 // can be GVN'ed. |
| 887 clearAllSideEffects(instruction); | 1087 clearAllSideEffects(instruction); |
| 888 } | 1088 } |
| 889 return null; | 1089 return null; |
| 890 } | 1090 } |
| 891 } | 1091 } |
| 892 | 1092 |
| 893 class SubstringSpecializer extends IdempotentStringOperationSpecializer { | 1093 class SubstringSpecializer extends IdempotentStringOperationSpecializer { |
| 894 const SubstringSpecializer(); | 1094 const SubstringSpecializer(); |
| 895 } | 1095 } |
| 896 | 1096 |
| 897 class TrimSpecializer extends IdempotentStringOperationSpecializer { | 1097 class TrimSpecializer extends IdempotentStringOperationSpecializer { |
| 898 const TrimSpecializer(); | 1098 const TrimSpecializer(); |
| 899 } | 1099 } |
| 900 | 1100 |
| 901 class PatternMatchSpecializer extends InvokeDynamicSpecializer { | 1101 class PatternMatchSpecializer extends InvokeDynamicSpecializer { |
| 902 const PatternMatchSpecializer(); | 1102 const PatternMatchSpecializer(); |
| 903 | 1103 |
| 904 HInstruction tryConvertToBuiltin( | 1104 HInstruction tryConvertToBuiltin( |
| 905 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 1105 HInvokeDynamic instruction, |
| 1106 GlobalTypeInferenceResults results, |
| 1107 CompilerOptions options, |
| 1108 BackendHelpers helpers, |
| 1109 ClosedWorld closedWorld) { |
| 906 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1110 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 907 HInstruction pattern = instruction.inputs[2]; | 1111 HInstruction pattern = instruction.inputs[2]; |
| 908 if (receiver.isStringOrNull(closedWorld) && | 1112 if (receiver.isStringOrNull(closedWorld) && |
| 909 pattern.isStringOrNull(closedWorld)) { | 1113 pattern.isStringOrNull(closedWorld)) { |
| 910 // String.contains(String s) does not have any side effect (other than | 1114 // String.contains(String s) does not have any side effect (other than |
| 911 // throwing), and it can be GVN'ed. | 1115 // throwing), and it can be GVN'ed. |
| 912 clearAllSideEffects(instruction); | 1116 clearAllSideEffects(instruction); |
| 913 } | 1117 } |
| 914 return null; | 1118 return null; |
| 915 } | 1119 } |
| 916 } | 1120 } |
| 917 | 1121 |
| 918 class RoundSpecializer extends InvokeDynamicSpecializer { | 1122 class RoundSpecializer extends InvokeDynamicSpecializer { |
| 919 const RoundSpecializer(); | 1123 const RoundSpecializer(); |
| 920 | 1124 |
| 921 UnaryOperation operation(ConstantSystem constantSystem) { | 1125 UnaryOperation operation(ConstantSystem constantSystem) { |
| 922 return constantSystem.round; | 1126 return constantSystem.round; |
| 923 } | 1127 } |
| 924 | 1128 |
| 925 HInstruction tryConvertToBuiltin( | 1129 HInstruction tryConvertToBuiltin( |
| 926 HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) { | 1130 HInvokeDynamic instruction, |
| 1131 GlobalTypeInferenceResults results, |
| 1132 CompilerOptions options, |
| 1133 BackendHelpers helpers, |
| 1134 ClosedWorld closedWorld) { |
| 927 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1135 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
| 928 if (receiver.isNumberOrNull(closedWorld)) { | 1136 if (receiver.isNumberOrNull(closedWorld)) { |
| 929 // Even if there is no builtin equivalent instruction, we know the | 1137 // Even if there is no builtin equivalent instruction, we know the |
| 930 // instruction does not have any side effect, and that it can be GVN'ed. | 1138 // instruction does not have any side effect, and that it can be GVN'ed. |
| 931 clearAllSideEffects(instruction); | 1139 clearAllSideEffects(instruction); |
| 932 } | 1140 } |
| 933 return null; | 1141 return null; |
| 934 } | 1142 } |
| 935 } | 1143 } |
| OLD | NEW |