| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| library shru_test; | |
| import 'dart:async'; | |
| import 'package:expect/async_helper.dart'; | |
| import '../helpers/compiler_helper.dart'; | |
| const COMMON = r""" | |
| int g1 = 0, g2 = 0; | |
| int sink1 = 0, sink2 = 0; | |
| main() { | |
| for (int i = 0; i < 0x100000000; i = i + (i >> 4) + 1) { | |
| g1 = g2 = i; | |
| sink1 = callFoo(i, 1 - i, i); | |
| sink2 = callFoo(2 - i, i, 3 - i); | |
| } | |
| } | |
| """; | |
| const tests = [ | |
| r""" | |
| // constant-fold positive | |
| int foo(int param) { | |
| int a = 100; | |
| int b = 2; | |
| return a >>> b; | |
| // present: 'return 25;' | |
| } | |
| """, | |
| r""" | |
| // constant-fold negative | |
| int foo(int param) { | |
| int a = -1; | |
| int b = 30; | |
| return a >>> b; | |
| // present: 'return 3;' | |
| } | |
| """, | |
| r""" | |
| // base case | |
| int foo(int value, int shift) { | |
| return value >>> shift; | |
| // Default code pattern: | |
| // present: 'JSInt_methods.$shru(value, shift);' | |
| } | |
| int callFoo(int a, int b, int c) => foo(a, b); | |
| """, | |
| r""" | |
| // shift by zero | |
| int foo(int param) { | |
| return param >>> 0; | |
| // present: 'return param >>> 0;' | |
| } | |
| """, | |
| r""" | |
| // shift by one | |
| int foo(int param) { | |
| return param >>> 1; | |
| // present: 'return param >>> 1;' | |
| } | |
| """, | |
| r""" | |
| // shift masked into safe range | |
| int foo(int value, int shift) { | |
| return value >>> (shift & 31); | |
| // present: 'return value >>> (shift & 31);' | |
| } | |
| int callFoo(int a, int b, int c) => foo(a, b); | |
| """, | |
| r""" | |
| // idempotent shift by zero | |
| int foo(int param) { | |
| return param >>> 0 >>> 0 >>> 0; | |
| // present: 'return param >>> 0;' | |
| } | |
| """, | |
| r""" | |
| // idempotent shift by zero #2 | |
| int foo(int param) { | |
| return (param & 15) >>> 0; | |
| // present: 'return param & 15;' | |
| } | |
| """, | |
| // TODO(sra): shift-shift reduction. | |
| // r""" | |
| //// shift-shift-reduction | |
| //int foo(int param) { | |
| // return param >>> 1 >>> 2; | |
| // // present: 'return param >>> 3' | |
| //} | |
| //""", | |
| r""" | |
| // mask-shift to shift-mask reduction | |
| int foo(int param) { | |
| return (param & 0xF0) >>> 4; | |
| // present: 'return param >>> 4 & 15' | |
| } | |
| """, | |
| r""" | |
| // mask-shift to shift-mask reduction enabling mask reduction | |
| int foo(int param) { | |
| return (param & 0x7FFFFFFF) >>> 31; | |
| // present: 'return 0;' | |
| } | |
| """, | |
| ]; | |
| main() { | |
| runTests() async { | |
| Future check(String test) { | |
| String program = COMMON + '\n\n' + test; | |
| if (!test.contains('callFoo')) { | |
| program += 'int callFoo(int a, int b, int c) => foo(a);\n'; | |
| } | |
| return compile( | |
| program, | |
| entry: 'main', | |
| methodName: 'foo', | |
| disableTypeInference: false, | |
| check: checkerForAbsentPresent(test), | |
| ); | |
| } | |
| for (final test in tests) { | |
| String name = 'unnamed'; | |
| if (test.startsWith('//')) { | |
| final comment = test.split('\n').first.replaceFirst('//', '').trim(); | |
| if (comment.isNotEmpty) name = comment; | |
| } | |
| print('-- $name'); | |
| await check(test); | |
| } | |
| } | |
| asyncTest(() async { | |
| print('--test from kernel------------------------------------------------'); | |
| await runTests(); | |
| }); | |
| } |