blob: 5e6ffef532f2388dd3c9fa0477c9b9f5c151168a [file] [log] [blame]
// Copyright (c) 2022, 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.
// Check that inliner can also specialize calls between rounds of inlining.
//
// In the [test] function below we would only be able to fully eliminate
// abstractions and inline [TestIterable.elementAt] if inliner devirtualizes
// it during inlining.
import 'dart:collection';
import 'package:vm/testing/il_matchers.dart';
@pragma('vm:never-inline')
void myprint(Object? obj) {
print(obj);
}
class TestIterable extends IterableBase<int> {
@pragma('vm:prefer-inline')
TestIterator get iterator => TestIterator(this);
@override
int get length => 10;
@pragma('vm:prefer-inline')
int elementAt(int index) {
return index;
}
}
class TestIterator implements Iterator<int> {
final Iterable<int> iterable;
int current = 0;
int index = 0;
TestIterator(this.iterable);
@pragma('vm:prefer-inline')
bool moveNext() {
if (index >= iterable.length) {
return false;
}
current = iterable.elementAt(index++);
return true;
}
List<int> toList() => [for (; moveNext();) current];
}
@pragma('vm:never-inline')
@pragma('vm:testing:print-flow-graph')
void test(TestIterable obj) {
for (var el in obj) {
myprint(el);
}
}
void matchIL$test(FlowGraph graph) {
graph.match([
match.block('Graph'),
match.block('Function', [
'obj' << match.Parameter(index: 0),
match.CheckStackOverflow(),
match.Goto('LoopHeader'),
]),
'LoopHeader' <<
match.block('Join', [
'index' << match.Phi(match.any, 'inc'),
match.CheckStackOverflow(),
match.Branch(
match.RelationalOp('index', match.any, kind: '>='),
ifTrue: 'LoopExit',
ifFalse: 'LoopBody',
),
]),
'LoopExit' << match.block('Target', [match.DartReturn()]),
'LoopBody' <<
match.block('Target', [
'inc' << match.BinaryInt64Op('index', match.any),
'boxed_index' << match.BoxInt64('index'),
match.StaticCall('boxed_index'),
match.Goto('LoopHeader'),
]),
]);
}
void main() {
myprint(TestIterator([0, 1, 2, 3, 4]).toList());
myprint(TestIterator(const [0, 1, 2, 3, 4]).toList());
test(TestIterable());
}