// 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);
}

ISOLATE_UNIT_TEST_CASE(FlowGraph_UnboxedFloatPhi) {
  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 then_body = H.TargetEntry();
  auto else_body = H.TargetEntry();
  auto join_exit = H.JoinEntry();

  PhiInstr* phi;
  Definition* double_to_float_1;
  Definition* double_to_float_2;

  {
    BlockBuilder builder(H.flow_graph(), normal_entry);
    builder.AddBranch(
        new StrictCompareInstr(
            InstructionSource(), Token::kEQ_STRICT, new Value(H.IntConstant(1)),
            new Value(H.IntConstant(1)),
            /*needs_number_check=*/false, S.GetNextDeoptId()),
        then_body, else_body);
  }

  {
    BlockBuilder builder(H.flow_graph(), then_body);
    double_to_float_1 = builder.AddDefinition(new DoubleToFloatInstr(
        new Value(H.DoubleConstant(1)), S.GetNextDeoptId(),
        Instruction::kNotSpeculative));
    builder.AddInstruction(new GotoInstr(join_exit, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), else_body);
    double_to_float_2 = builder.AddDefinition(new DoubleToFloatInstr(
        new Value(H.DoubleConstant(2)), S.GetNextDeoptId(),
        Instruction::kNotSpeculative));
    builder.AddInstruction(new GotoInstr(join_exit, S.GetNextDeoptId()));
  }

  {
    BlockBuilder builder(H.flow_graph(), join_exit);
    phi = new PhiInstr(join_exit, 3);
    phi->SetInputAt(0, new Value(double_to_float_1));
    phi->SetInputAt(1, new Value(double_to_float_2));
    phi->SetInputAt(2, new Value(phi));
    builder.AddPhi(phi);
    builder.AddReturn(new Value(phi));
  }
  H.FinishGraph();

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

  EXPECT_PROPERTY(phi, it.representation() == kUnboxedFloat);
}

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) {
    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) {
    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
