sdk
sdk copied to clipboard
Simplify branch conditions based on ranges & simplify control flow afterwards if condition turns out to be constant
This
import 'dart:typed_data';
import 'package:benchmark_harness/benchmark_harness.dart';
void main() {
Foo().report();
if (int.parse('1') == 1) print(sink);
}
final XX = Uint8List.fromList([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
final class Foo extends BenchmarkBase {
Foo() : super('Uint8List.fromList');
@override
@pragma('vm:never-inline')
void run() {
sink = Uint8List.fromList(XX);
}
}
var sink;
currently generates this code
*** BEGIN CFG
After GenerateCode
0: B0[graph]:0 {
v0 <- Constant(#null) T{Null?}
v17 <- Constant(#0) [0, 0] T{_Smi}
v176 <- Constant(#1048576) [1048576, 1048576] T{_Smi}
v203 <- UnboxedConstant(#0) [0, 0] int64
}
2: B1[function entry]:2 {
v2 <- Parameter(0 @rdi) T{Foo}
}
4: CheckStackOverflow:8(stack=0, loop=0)
6: v7 <- LoadStaticField:4(XX, CallsInitializer) T{_Uint8List}
7: ParallelMove rcx <- rax
8: ParallelMove fp[-2] <- rcx
8: v22 <- LoadField(v7 T{_Uint8List} . TypedDataBase.length {final}) [0, 4611686018427387903] T{_Smi}
9: ParallelMove rax <- rdx, fp[-1] <- rdx
10: v28 <- AllocateTypedData:10(v22 T{_Smi}) T{_Uint8List}
12: ParallelMove rcx <- fp[-1], fp[-4] <- rax
12: v201 <- UnboxInt64([non-speculative], v22 T{_Smi}) [0, 4611686018427387903] int64
13: ParallelMove fp[-3] <- rcx
14: Branch if RelationalOp(>, v203 T{_Smi}, v201 T{_Smi}) T{bool} goto (28, 25)
16: B28[target]:48
18: ParallelMove goto:50 B26
20: B25[target]:40
22: Branch if RelationalOp(>, v201 T{_Smi}, v201 T{_Smi}) T{bool} goto (29, 30)
24: B29[target]:52
26: ParallelMove goto:54 B26
28: B26[join]:42 pred(B28, B29)
29: ParallelMove rdi <- C, rsi <- fp[-1], rdx <- rcx
30: StaticCall:58( checkValidRange<0> v203 T{_Smi}, v22 T{_Smi}, v201 T{_Smi}) int64
32: ParallelMove goto:64 B35
34: B30[target]:60
36: ParallelMove goto:66 B35
38: B35[join]:62 pred(B26, B30) ParallelMove rdx <- fp[-3]
40: Branch if RelationalOp(<, v201 T{_Smi}, v201 T{_Smi}) T{bool} goto (36, 37)
84: B36[target]:126
86: v82 <- StaticCall:128( tooFew<0> ) T{StateError}
88: Throw:130(v82)
42: B37[target]:132
44: Branch if EqualityCompare(v201 T{_Smi} == v203 T{_Smi}) T{bool} goto (38, 39)
46: B38[target]:142
48: ParallelMove r12 <- fp[-4] goto:146 B43
50: B39[target]:148 ParallelMove rcx <- fp[-1]
52: Branch if RelationalOp:12(<, v22 T{_Smi}, v176 T{_Smi}) T{bool} goto (59, 60)
54: B59[target]:18 ParallelMove rax <- fp[-2], r12 <- fp[-4]
56: MemoryCopy(v7 T{_Uint8List}, v28 T{_Uint8List}, v17 T{_Smi}, v17 T{_Smi}, v22 T{_Smi}, dest_cid=_Int8List (111), src_cid=_Int8List (111), can_overlap)
58: ParallelMove goto:12 B58
60: B60[target]:20 ParallelMove rax <- fp[-2], r12 <- fp[-4]
62: v165 <- LoadField(v28 T{_Uint8List} . PointerBase.data, MayLoadInnerPointer) untagged
64: v168 <- LoadField(v7 T{_Uint8List} . PointerBase.data, MayLoadInnerPointer) untagged
66: v170 <- LoadThread() untagged
68: v171 <- LoadUntagged(v170, 1536) untagged
69: ParallelMove rdi <- rdi, rsi <- rsi, rdx <- rdx, rax <- rcx
70: LeafRuntimeCall(target_address=v171, v165 T{Object}, v168 T{Object}, v201 T{int}) untagged
72: ParallelMove goto:12 B58
74: B58[join]:10 pred(B59, B60)
76: ParallelMove goto:154 B43
78: B43[join]:33 pred(B38, B58)
79: ParallelMove rax <- r12
80: StoreStaticField(sink, v28 T{_Uint8List})
81: ParallelMove rax <- C
82: DartReturn:18(v0)
*** END CFG
This can be optimized, e.g. the following branch can be eliminated:
*** BEGIN CFG
After GenerateCode
B0[graph]:0 {
v203 <- UnboxedConstant(#0) [0, 0] int64
}
v201 <- UnboxInt64([non-speculative], v22 T{_Smi}) [0, 4611686018427387903] int64
Branch if RelationalOp(>, v203 T{_Smi}, v201 T{_Smi}) T{bool} goto (28, 25)
/cc @mraleph