// Copyright (c) 2019, 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.
//
// Unit tests specific to BCE (bounds check elimination),
// which runs as part of range analysis optimizations.

#include "vm/compiler/backend/range_analysis.h"

#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/object.h"
#include "vm/unit_test.h"

namespace dart {

// Helper method to count number of bounds checks.
static intptr_t CountBoundChecks(FlowGraph* flow_graph) {
  intptr_t count = 0;
  for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
       !block_it.Done(); block_it.Advance()) {
    for (ForwardInstructionIterator it(block_it.Current()); !it.Done();
         it.Advance()) {
      if (it.Current()->IsCheckBoundBase()) {
        count++;
      }
    }
  }
  return count;
}

// Helper method to build CFG, run BCE, and count number of
// before/after bounds checks.
static std::pair<intptr_t, intptr_t> ApplyBCE(const char* script_chars,
                                              CompilerPass::PipelineMode mode) {
  // Load the script and exercise the code once
  // while exercising the given compiler passes.
  const auto& root_library = Library::Handle(LoadTestScript(script_chars));
  Invoke(root_library, "main");
  std::initializer_list<CompilerPass::Id> passes = {
      CompilerPass::kComputeSSA,
      CompilerPass::kTypePropagation,
      CompilerPass::kApplyICData,
      CompilerPass::kInlining,
      CompilerPass::kTypePropagation,
      CompilerPass::kApplyICData,
      CompilerPass::kSelectRepresentations,
      CompilerPass::kCanonicalize,
      CompilerPass::kConstantPropagation,
      CompilerPass::kCSE,
      CompilerPass::kLICM,
  };
  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
  TestPipeline pipeline(function, mode);
  FlowGraph* flow_graph = pipeline.RunPasses(passes);
  // Count the number of before/after bounds checks.
  const intptr_t num_bc_before = CountBoundChecks(flow_graph);
  RangeAnalysis range_analysis(flow_graph);
  range_analysis.Analyze();
  const intptr_t num_bc_after = CountBoundChecks(flow_graph);
  return {num_bc_before, num_bc_after};
}

static void TestScriptJIT(const char* script_chars,
                          intptr_t expected_before,
                          intptr_t expected_after) {
  auto jit_result = ApplyBCE(script_chars, CompilerPass::kJIT);
  EXPECT_EQ(expected_before, jit_result.first);
  EXPECT_EQ(expected_after, jit_result.second);
}

//
// BCE (bounds-check-elimination) tests.
//

ISOLATE_UNIT_TEST_CASE(BCECannotRemove) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        return l[0];
      }
      main() {
        foo(new Float64List(1));
      }
    )";
  TestScriptJIT(kScriptChars, 1, 1);
}

ISOLATE_UNIT_TEST_CASE(BCERemoveOne) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        return l[1] + l[0];
      }
      main() {
        foo(new Float64List(2));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 1);
}

ISOLATE_UNIT_TEST_CASE(BCESimpleLoops) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        for (int i = 0; i < l.length; i++) {
          l[i] = 0;
        }
        for (int i = 10; i <= l.length - 5; i++) {
          l[i] = 1;
        }
      }
      main() {
        foo(new Float64List(100));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCESimpleLoopsDown) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        for (int i = l.length - 1; i >= 0; i--) {
          l[i] = 0;
        }
        for (int i = l.length - 5; i >= 10; i--) {
          l[i] = 1;
        }
      }
      main() {
        foo(new Float64List(100));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCEModulo) {
  const char* kScriptChars =
      R"(
      foo(int i) {
        var l = List<int>.filled(3, 0);
        return l[i % 3] ?? l[i % (-3)];
      }
      main() {
        foo(0);
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCELowerTriangular) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        for (int i = 0; i < l.length; i++) {
          for (int j = 0; j <= i; j++) {
            l[i] += l[j];
          }
        }
      }
      main() {
        foo(new Float64List(100));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCEUpperTriangular) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        for (int i = 0; i < l.length; i++) {
          for (int j = i; j < l.length; j++) {
            l[i] += l[j];
          }
        }
      }
      main() {
        foo(new Float64List(100));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCETriangularDown) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List l) {
        for (int i = l.length - 1; i >= 0; i--) {
          for (int j = i; j >= 0; j--) {
            l[i] += l[j];
          }
        }
      }
      main() {
        foo(new Float64List(100));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCENamedLength) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      Int8List foo(int count) {
        var x = new Int8List(count);
        for (int i = 0; i < count; i++) {
          x[i] = 0;
        }
        return x;
      }
      main() {
        foo(100);
      }
    )";
  TestScriptJIT(kScriptChars, 1, 0);
}

ISOLATE_UNIT_TEST_CASE(BCEBubbleSort) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      foo(Float64List a) {
        int len = a.length;
        for (int i = len - 2; i >= 0; i--) {
          for (int j = 0; j <= i; j++) {
            var c = a[j];
            var n = a[j + 1];
            if (c > n) {
              a[j] = n;
              a[j + 1] = c;
            }
          }
        }
      }
      main() {
        foo(new Float64List(100));
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

ISOLATE_UNIT_TEST_CASE(BCEArithmeticWrapAround) {
  const char* kScriptChars =
      R"(
      import 'dart:typed_data';
      const kMax = 0x7fffffffffffffff;
      foo(Float64List a) {
        for (int i = kMax - 10; i < kMax; i++) {
          for (int j = i + 10; j < a.length; j++) {
            // Don't be fooled: j in [-minint, len).
            a[j] = 1;
          }
        }
      }
      main() {
        try {
          foo(new Float64List(100));
        }  catch (e) {
        }
      }
    )";
  TestScriptJIT(kScriptChars, 1, 1);
}

ISOLATE_UNIT_TEST_CASE(BCEListNamedAndPlainLength) {
  const char* kScriptChars =
      R"(
      List<int> foo(int count) {
        var x = new List<int>.filled(count, 42);
        for (int i = 0; i < count; i++) {
          x[i] = 0;
        }
        for (int i = 0; i < x.length; i++) {
          x[i] = 0;
        }
        return x;
      }
      main() {
        foo(100);
      }
    )";
  TestScriptJIT(kScriptChars, 2, 0);
}

}  // namespace dart
