// Copyright (c) 2024, 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 `Pointer` are not allocated before being passed into a load.

import 'dart:ffi';

import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';
import 'package:vm/testing/il_matchers.dart';

void main() async {
  using((arena) {
    const length = 100;
    final pointer = arena<Int8>(100);
    for (int i = 0; i < length; i++) {
      pointer[i] = i;
    }
    Expect.equals(
      10,
      testOffset(pointer),
    );
    Expect.equals(
      10,
      testAllocate(pointer),
    );
    Expect.equals(
      45,
      testHoist(pointer),
    );
    print(globalVar);
  });
}

@pragma('vm:never-inline')
@pragma('vm:testing:print-flow-graph')
int testOffset(Pointer<Int8> pointer) {
  // `pointer2` is not allocated.
  final pointer2 = pointer + 10;
  return pointer2.value;
}

void matchIL$testOffset(FlowGraph graph) {
  graph.dump();
  graph.match([
    match.block('Graph', [
      'int 10' << match.UnboxedConstant(value: 10),
      'int 0' << match.UnboxedConstant(value: 0),
    ]),
    match.block('Function', [
      'pointer' <<
          match.Parameter(
            index: 0,
          ),
      'pointer.address untagged' <<
          match.LoadField(
            'pointer',
            slot: 'PointerBase.data',
          ),
      ...convertUntaggedAddressToInt64('pointer'),
      'pointer2.address int64' <<
          match.BinaryInt64Op(
            'pointer.address int64',
            'int 10',
          ),
      // `pointer2` is not allocated.
      ...convertInt64AddressToUntagged('pointer2'),
      ...loadIndexedValueAsInt64('pointer2', 'int 0'),
      match.DartReturn('pointer2.value int64'),
    ]),
  ]);
}

class A {
  final int i;

  A(this.i);
}

A? globalVar;

@pragma('vm:never-inline')
@pragma('vm:testing:print-flow-graph')
int testAllocate(Pointer<Int8> pointer) {
  final pointer2 = pointer + 10;
  globalVar = A(10);
  return pointer2.value;
}

void matchIL$testAllocate(FlowGraph graph) {
  graph.dump();
  graph.match([
    match.block('Graph', [
      'int 10' << match.UnboxedConstant(value: 10),
      'int 0' << match.UnboxedConstant(value: 0),
    ]),
    match.block('Function', [
      'pointer' <<
          match.Parameter(
            index: 0,
          ),
      'pointer.address untagged' <<
          match.LoadField(
            'pointer',
            slot: 'PointerBase.data',
          ),
      ...convertUntaggedAddressToInt64('pointer'),
      'pointer2.address int64' <<
          match.BinaryInt64Op(
            'pointer.address int64',
            'int 10',
          ),
      ...convertInt64AddressToUntagged('pointer2'),
      // The untagged pointer2.address can live through an allocation
      // even though it is marked `InnerPointerAccess::kMayBeInnerPointer`
      // because its cid is a Pointer cid.
      match.AllocateObject(),
      match.StoreStaticField(match.any),
      ...loadIndexedValueAsInt64('pointer2', 'int 0'),
      match.DartReturn('pointer2.value int64'),
    ]),
  ]);
}

@pragma('vm:never-inline')
@pragma('vm:testing:print-flow-graph')
int testHoist(Pointer<Int8> pointer) {
  int result = 0;
  for (int i = 0; i < 10; i++) {
    globalVar = A(10);
    // The address load is hoisted out of the loop.
    // The indexed load is _not_ hoisted out of the loop.
    result += pointer[i];
  }
  return result;
}

void matchIL$testHoist(FlowGraph graph) {
  graph.dump();
  final indexRep = is32BitConfiguration ? 'int32' : 'int64';
  graph.match([
    match.block('Graph', [
      'int 0' << match.UnboxedConstant(value: 0),
      'int 10' << match.UnboxedConstant(value: 10),
      'int 1' << match.UnboxedConstant(value: 1),
    ]),
    match.block('Function', [
      'pointer' <<
          match.Parameter(
            index: 0,
          ),
      'pointer[i].address untagged' <<
          match.LoadField(
            'pointer',
            slot: 'PointerBase.data',
          ),
      match.Goto('B1'),
    ]),
    'B1' <<
        match.block('Join', [
          'result int64' << match.Phi('int 0', 'result'),
          'i int64' << match.Phi('int 0', 'i'),
          match.CheckStackOverflow(),
          match.Branch(match.RelationalOp(match.any, match.any, kind: '<'),
              ifTrue: 'B2', ifFalse: 'B3'),
        ]),
    'B2' <<
        match.block('Target', [
          // Do some allocation.
          match.AllocateObject(),
          match.StoreStaticField(match.any),
          if (is32BitConfiguration) ...[
            'i $indexRep' <<
                match.IntConverter(
                  'i int64',
                  from: 'int64',
                  to: indexRep,
                ),
          ],
          // Do a load indexed with the untagged pointer.address that is
          // hoisted out of the loop.
          ...loadIndexedValueAsInt64('pointer[i]', 'i $indexRep'),
          'result' <<
              match.BinaryInt64Op(
                match.any,
                'pointer[i].value int64',
              ),
          'i' <<
              match.BinaryInt64Op(
                match.any,
                match.any,
              ),
          match.Goto('B1'),
        ]),
    'B3' <<
        match.block('Target', [
          match.DartReturn(match.any),
        ]),
  ]);
}

final addressRep = is32BitConfiguration ? 'uint32' : 'int64';
final valueRep = is32BitConfiguration ? 'int32' : 'int64';

List<Matcher> convertUntaggedAddressToInt64(String name) {
  return [
    '$name.address $addressRep' <<
        match.IntConverter(
          '$name.address untagged',
          from: 'untagged',
          to: addressRep,
        ),
    if (is32BitConfiguration) ...[
      '$name.address int64' <<
          match.IntConverter(
            '$name.address $addressRep',
            from: addressRep,
            to: 'int64',
          ),
    ],
  ];
}

List<Matcher> convertInt64AddressToUntagged(String name) {
  return [
    if (is32BitConfiguration) ...[
      '$name.address $addressRep' <<
          match.IntConverter(
            '$name.address int64',
            from: 'int64',
            to: addressRep,
          ),
    ],
    // `pointer2` is not allocated.
    '$name.address untagged' <<
        match.IntConverter(
          '$name.address $addressRep',
          from: addressRep,
          to: 'untagged',
        ),
  ];
}

List<Matcher> loadIndexedValueAsInt64(String name, String index) {
  return [
    '$name.value $valueRep' <<
        match.LoadIndexed(
          '$name.address untagged',
          index,
        ),
    if (is32BitConfiguration) ...[
      '$name.value int64' <<
          match.IntConverter(
            '$name.value $valueRep',
            from: valueRep,
            to: 'int64',
          ),
    ],
  ];
}
