// Copyright (c) 2012, 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.

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

#include <vector>

#include "platform/text_buffer.h"
#include "platform/utils.h"
#include "vm/compiler/backend/block_builder.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/backend/type_propagator.h"
#include "vm/unit_test.h"

namespace dart {

#if defined(TARGET_ARCH_IS_64_BIT)
ISOLATE_UNIT_TEST_CASE(FlowGraph_UnboxInt64Phi) {
  using compiler::BlockBuilder;

  CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);

  FlowGraphBuilderHelper H(/*num_parameters=*/1);
  H.AddVariable("v0", AbstractType::ZoneHandle(Type::IntType()),
                new CompileType(CompileType::Int()));

  auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
  auto loop_header = H.JoinEntry();
  auto loop_body = H.TargetEntry();
  auto loop_exit = H.TargetEntry();

  Definition* v0;
  PhiInstr* loop_var;
  Definition* add1;

  {
    BlockBuilder builder(H.flow_graph(), normal_entry);
    v0 = builder.AddParameter(0, 0, /*with_frame=*/true, kTagged);
    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), loop_header);
    loop_var = H.Phi(loop_header, {{normal_entry, v0}, {loop_body, &add1}});
    builder.AddPhi(loop_var);
    builder.AddBranch(new RelationalOpInstr(
                          InstructionSource(), Token::kLT, new Value(loop_var),
                          new Value(H.IntConstant(50)), kMintCid,
                          S.GetNextDeoptId(), Instruction::kNotSpeculative),
                      loop_body, loop_exit);
  }

  {
    BlockBuilder builder(H.flow_graph(), loop_body);
    add1 = builder.AddDefinition(new BinaryInt64OpInstr(
        Token::kADD, new Value(loop_var), new Value(H.IntConstant(1)),
        S.GetNextDeoptId(), Instruction::kNotSpeculative));
    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), loop_exit);
    builder.AddReturn(new Value(loop_var));
  }

  H.FinishGraph();

  FlowGraphTypePropagator::Propagate(H.flow_graph());
  H.flow_graph()->SelectRepresentations();

  EXPECT_PROPERTY(loop_var, it.representation() == kUnboxedInt64);
}
#endif  // defined(TARGET_ARCH_IS_64_BIT)

ISOLATE_UNIT_TEST_CASE(FlowGraph_LateVariablePhiUnboxing) {
  using compiler::BlockBuilder;

  CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);
  FlowGraphBuilderHelper H;

  auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
  auto loop_header = H.JoinEntry();
  auto loop_body = H.TargetEntry();
  auto loop_exit = H.TargetEntry();

  ConstantInstr* sentinel = H.flow_graph()->GetConstant(Object::sentinel());

  PhiInstr* loop_var;
  PhiInstr* late_var;
  Definition* add1;

  {
    BlockBuilder builder(H.flow_graph(), normal_entry);
    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), loop_header);
    loop_var = H.Phi(loop_header,
                     {{normal_entry, H.IntConstant(0)}, {loop_body, &add1}});
    builder.AddPhi(loop_var);
    loop_var->UpdateType(CompileType::Int());
    loop_var->UpdateType(CompileType::FromAbstractType(
        Type::ZoneHandle(Type::IntType()), CompileType::kCannotBeNull,
        CompileType::kCanBeSentinel));
    late_var =
        H.Phi(loop_header, {{normal_entry, sentinel}, {loop_body, &add1}});
    builder.AddPhi(late_var);
    builder.AddBranch(new RelationalOpInstr(
                          InstructionSource(), Token::kLT, new Value(loop_var),
                          new Value(H.IntConstant(10)), kMintCid,
                          S.GetNextDeoptId(), Instruction::kNotSpeculative),
                      loop_body, loop_exit);
  }

  {
    BlockBuilder builder(H.flow_graph(), loop_body);
    add1 = builder.AddDefinition(new BinaryInt64OpInstr(
        Token::kADD, new Value(loop_var), new Value(H.IntConstant(1)),
        S.GetNextDeoptId(), Instruction::kNotSpeculative));
    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), loop_exit);
    builder.AddReturn(new Value(late_var));
  }

  H.FinishGraph();

  FlowGraphTypePropagator::Propagate(H.flow_graph());
  H.flow_graph()->SelectRepresentations();

#if defined(TARGET_ARCH_IS_64_BIT)
  EXPECT_PROPERTY(loop_var, it.representation() == kUnboxedInt64);
#endif
  EXPECT_PROPERTY(late_var, it.representation() == kTagged);
}

void TestLargeFrame(const char* type,
                    const char* zero,
                    const char* one,
                    const char* main) {
  SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 1000);
  TextBuffer printer(256 * KB);

  intptr_t num_locals = 2000;
  printer.Printf("import 'dart:typed_data';\n");
  printer.Printf("@pragma('vm:never-inline')\n");
  printer.Printf("%s one() { return %s; }\n", type, one);
  printer.Printf("@pragma('vm:never-inline')\n");
  printer.Printf("%s largeFrame(int n) {\n", type);
  for (intptr_t i = 0; i < num_locals; i++) {
    printer.Printf("  %s local%" Pd " = %s;\n", type, i, zero);
  }
  printer.Printf("  for (int i = 0; i < n; i++) {\n");
  for (intptr_t i = 0; i < num_locals; i++) {
    printer.Printf("    local%" Pd " += one();\n", i);
  }
  printer.Printf("  }\n");
  printer.Printf("  %s sum = %s;\n", type, zero);
  for (intptr_t i = 0; i < num_locals; i++) {
    printer.Printf("    sum += local%" Pd ";\n", i);
  }
  printer.Printf("  return sum;\n");
  printer.Printf("}\n");

  printer.AddString(main);

  const auto& root_library = Library::Handle(LoadTestScript(printer.buffer()));
  Invoke(root_library, "main");
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Int) {
  TestLargeFrame("int", "0", "1",
                 "main() {\n"
                 "  for (var i = 0; i < 100; i++) {\n"
                 "    var r = largeFrame(1);\n"
                 "    if (r != 2000) throw r;\n"
                 "  }\n"
                 "  return 'Okay';\n"
                 "}\n");
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Double) {
  TestLargeFrame("double", "0.0", "1.0",
                 "main() {\n"
                 "  for (var i = 0; i < 100; i++) {\n"
                 "    var r = largeFrame(1);\n"
                 "    if (r != 2000.0) throw r;\n"
                 "  }\n"
                 "  return 'Okay';\n"
                 "}\n");
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Int32x4) {
  TestLargeFrame("Int32x4", "Int32x4(0, 0, 0, 0)", "Int32x4(1, 2, 3, 4)",
                 "main() {\n"
                 "  for (var i = 0; i < 100; i++) {\n"
                 "    var r = largeFrame(1);\n"
                 "    if (r.x != 2000) throw r;\n"
                 "    if (r.y != 4000) throw r;\n"
                 "    if (r.z != 6000) throw r;\n"
                 "    if (r.w != 8000) throw r;\n"
                 "  }\n"
                 "  return 'Okay';\n"
                 "}\n");
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Float32x4) {
  TestLargeFrame("Float32x4", "Float32x4(0.0, 0.0, 0.0, 0.0)",
                 "Float32x4(1.0, 2.0, 3.0, 4.0)",
                 "main() {\n"
                 "  for (var i = 0; i < 100; i++) {\n"
                 "    var r = largeFrame(1);\n"
                 "    if (r.x != 2000.0) throw r;\n"
                 "    if (r.y != 4000.0) throw r;\n"
                 "    if (r.z != 6000.0) throw r;\n"
                 "    if (r.w != 8000.0) throw r;\n"
                 "  }\n"
                 "  return 'Okay';\n"
                 "}\n");
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_LargeFrame_Float64x2) {
  TestLargeFrame("Float64x2", "Float64x2(0.0, 0.0)", "Float64x2(1.0, 2.0)",
                 "main() {\n"
                 "  for (var i = 0; i < 100; i++) {\n"
                 "    var r = largeFrame(1);\n"
                 "    if (r.x != 2000.0) throw r;\n"
                 "    if (r.y != 4000.0) throw r;\n"
                 "  }\n"
                 "  return 'Okay';\n"
                 "}\n");
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Double) {
  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
    return;
  }

  const char* kScript = R"(
    double foo(double sum, int n) {
       if (sum == null) return 0.0;
       for (int i = 0; i < n; i++) {
          sum += 1.0;
       }
       return sum;
    }
    main() {
      foo(0.0, 10);
    }
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "foo"));

  Invoke(root_library, "main");

  TestPipeline pipeline(function, CompilerPass::kJIT);
  FlowGraph* flow_graph = pipeline.RunPasses({});

  auto entry = flow_graph->graph_entry()->normal_entry();
  ILMatcher cursor(flow_graph, entry, /*trace=*/true,
                   ParallelMovesHandling::kSkip);

  RELEASE_ASSERT(cursor.TryMatch({
      kMatchAndMoveFunctionEntry,
  }));
  if (FLAG_sound_null_safety != kNullSafetyOptionStrong) {
    RELEASE_ASSERT(cursor.TryMatch({
        kMatchAndMoveBranchFalse,
        kMatchAndMoveTargetEntry,
    }));
  }
  RELEASE_ASSERT(cursor.TryMatch({
      kMatchAndMoveUnbox,  // outside of loop
      kMatchAndMoveCheckSmi,
      kMoveGlob,

      // Loop header
      kMatchAndMoveJoinEntry,
      kMatchAndMoveCheckStackOverflow,
      kMatchAndMoveBranchTrue,

      // Loop body
      kMatchAndMoveTargetEntry,
      kMatchAndMoveBinaryDoubleOp,
      kMatchAndMoveBinarySmiOp,
      kMatchAndMoveGoto,

      // Loop header, again
      kMatchAndMoveJoinEntry,
      kMatchAndMoveCheckStackOverflow,
      kMatchAndMoveBranchFalse,

      // After loop
      kMatchAndMoveTargetEntry,
      kMatchAndMoveBox,
      kMatchReturn,
  }));
}

static void TestPhiUnboxingHeuristicSimd(const char* script) {
  if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {
    return;
  }

  const auto& root_library = Library::Handle(LoadTestScript(script));
  const auto& function = Function::Handle(GetFunction(root_library, "foo"));

  Invoke(root_library, "main");

  TestPipeline pipeline(function, CompilerPass::kJIT);
  FlowGraph* flow_graph = pipeline.RunPasses({});

  auto entry = flow_graph->graph_entry()->normal_entry();
  ILMatcher cursor(flow_graph, entry, /*trace=*/true,
                   ParallelMovesHandling::kSkip);

  RELEASE_ASSERT(cursor.TryMatch({
      kMatchAndMoveFunctionEntry,
  }));
  if (FLAG_sound_null_safety != kNullSafetyOptionStrong) {
    RELEASE_ASSERT(cursor.TryMatch({
        kMatchAndMoveBranchFalse,
        kMatchAndMoveTargetEntry,
    }));
  }
  RELEASE_ASSERT(cursor.TryMatch({
      kMatchAndMoveUnbox,  // outside of loop
      kMatchAndMoveCheckSmi,
      kMoveGlob,

      // Loop header
      kMatchAndMoveJoinEntry,
      kMatchAndMoveCheckStackOverflow,
      kMatchAndMoveBranchTrue,

      // Loop body
      kMatchAndMoveTargetEntry,
      kMatchAndMoveSimdOp,
      kMatchAndMoveBinarySmiOp,
      kMatchAndMoveGoto,

      // Loop header, again
      kMatchAndMoveJoinEntry,
      kMatchAndMoveCheckStackOverflow,
      kMatchAndMoveBranchFalse,

      // After loop
      kMatchAndMoveTargetEntry,
      kMatchAndMoveBox,
      kMatchReturn,
  }));
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Float32x4) {
  const char* kScript = R"(
    import 'dart:typed_data';
    Float32x4 foo(Float32x4 sum, int n) {
       if (sum == null) return Float32x4(0.0, 0.0, 0.0, 0.0);
       for (int i = 0; i < n; i++) {
          sum += Float32x4(1.0, 2.0, 3.0, 4.0);
       }
       return sum;
    }
    main() {
      foo(Float32x4(0.0, 0.0, 0.0, 0.0), 10);
    }
  )";
  TestPhiUnboxingHeuristicSimd(kScript);
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Float64x2) {
  const char* kScript = R"(
    import 'dart:typed_data';
    Float64x2 foo(Float64x2 sum, int n) {
       if (sum == null) return Float64x2(0.0, 0.0);
       for (int i = 0; i < n; i++) {
          sum += Float64x2(1.0, 2.0);
       }
       return sum;
    }
    main() {
      foo(Float64x2(0.0, 0.0), 10);
    }
  )";
  TestPhiUnboxingHeuristicSimd(kScript);
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Int32x4) {
  const char* kScript = R"(
    import 'dart:typed_data';
    Int32x4 foo(Int32x4 sum, int n) {
       if (sum == null) return Int32x4(0, 0, 0, 0);
       for (int i = 0; i < n; i++) {
          sum += Int32x4(1, 2, 3, 4);
       }
       return sum;
    }
    main() {
      foo(Int32x4(0, 0, 0, 0), 10);
    }
  )";
  TestPhiUnboxingHeuristicSimd(kScript);
}

}  // namespace dart
