// 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.

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

#include "vm/compiler/aot/aot_call_specializer.h"
#include "vm/compiler/backend/block_scheduler.h"
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/inliner.h"
#include "vm/compiler/call_specializer.h"
#include "vm/compiler/compiler_pass.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/compiler/jit/jit_call_specializer.h"
#include "vm/dart_api_impl.h"
#include "vm/parser.h"
#include "vm/unit_test.h"

namespace dart {

LibraryPtr LoadTestScript(const char* script,
                          Dart_NativeEntryResolver resolver,
                          const char* lib_uri) {
  Dart_Handle api_lib;
  {
    TransitionVMToNative transition(Thread::Current());
    api_lib = TestCase::LoadTestScript(script, resolver, lib_uri);
    EXPECT_VALID(api_lib);
  }
  auto& lib = Library::Handle();
  lib ^= Api::UnwrapHandle(api_lib);
  EXPECT(!lib.IsNull());
  return lib.ptr();
}

#if !defined(PRODUCT)
LibraryPtr ReloadTestScript(const char* script) {
  Dart_Handle api_lib;
  {
    TransitionVMToNative transition(Thread::Current());
    api_lib = TestCase::ReloadTestScript(script);
    EXPECT_VALID(api_lib);
  }
  auto& lib = Library::Handle();
  lib ^= Api::UnwrapHandle(api_lib);
  EXPECT(!lib.IsNull());
  return lib.ptr();
}
#endif

FunctionPtr GetFunction(const Library& lib, const char* name) {
  Thread* thread = Thread::Current();
  const auto& func = Function::Handle(lib.LookupFunctionAllowPrivate(
      String::Handle(Symbols::New(thread, name))));
  EXPECT(!func.IsNull());
  return func.ptr();
}

ClassPtr GetClass(const Library& lib, const char* name) {
  Thread* thread = Thread::Current();
  const auto& cls = Class::Handle(
      lib.LookupClassAllowPrivate(String::Handle(Symbols::New(thread, name))));
  EXPECT(!cls.IsNull());
  return cls.ptr();
}

TypeParameterPtr GetClassTypeParameter(const Class& klass, intptr_t index) {
  const auto& param = TypeParameter::Handle(klass.TypeParameterAt(index));
  EXPECT(!param.IsNull());
  return param.ptr();
}

TypeParameterPtr GetFunctionTypeParameter(const Function& fun, intptr_t index) {
  const auto& param = TypeParameter::Handle(fun.TypeParameterAt(index));
  EXPECT(!param.IsNull());
  return param.ptr();
}

ObjectPtr Invoke(const Library& lib, const char* name) {
  Thread* thread = Thread::Current();
  Dart_Handle api_lib = Api::NewHandle(thread, lib.ptr());
  Dart_Handle result;
  {
    TransitionVMToNative transition(thread);
    result =
        Dart_Invoke(api_lib, NewString(name), /*argc=*/0, /*argv=*/nullptr);
    EXPECT_VALID(result);
  }
  return Api::UnwrapHandle(result);
}

FlowGraph* TestPipeline::RunPasses(
    std::initializer_list<CompilerPass::Id> passes) {
  auto thread = Thread::Current();
  auto zone = thread->zone();
  const bool optimized = true;
  const intptr_t osr_id = Compiler::kNoOSRDeoptId;

  auto pipeline = CompilationPipeline::New(zone, function_);

  parsed_function_ = new (zone)
      ParsedFunction(thread, Function::ZoneHandle(zone, function_.ptr()));
  pipeline->ParseFunction(parsed_function_);

  // Extract type feedback before the graph is built, as the graph
  // builder uses it to attach it to nodes.
  ic_data_array_ = new (zone) ZoneGrowableArray<const ICData*>();
  if (mode_ == CompilerPass::kJIT) {
    function_.RestoreICDataMap(ic_data_array_, /*clone_ic_data=*/false);
  }

  flow_graph_ = pipeline->BuildFlowGraph(zone, parsed_function_, ic_data_array_,
                                         osr_id, optimized);

  if (mode_ == CompilerPass::kAOT) {
    flow_graph_->PopulateWithICData(function_);
  }

  const bool reorder_blocks =
      FlowGraph::ShouldReorderBlocks(function_, optimized);
  if (mode_ == CompilerPass::kJIT && reorder_blocks) {
    BlockScheduler::AssignEdgeWeights(flow_graph_);
  }

  SpeculativeInliningPolicy speculative_policy(/*enable_suppression=*/false);
  pass_state_ = new CompilerPassState(thread, flow_graph_, &speculative_policy);
  pass_state_->reorder_blocks = reorder_blocks;

  if (optimized) {
    JitCallSpecializer jit_call_specializer(flow_graph_, &speculative_policy);
    AotCallSpecializer aot_call_specializer(/*precompiler=*/nullptr,
                                            flow_graph_, &speculative_policy);
    if (mode_ == CompilerPass::kAOT) {
      pass_state_->call_specializer = &aot_call_specializer;
    } else {
      pass_state_->call_specializer = &jit_call_specializer;
    }

    if (passes.size() > 0) {
      flow_graph_ = CompilerPass::RunPipelineWithPasses(pass_state_, passes);
    } else {
      flow_graph_ = CompilerPass::RunPipeline(mode_, pass_state_);
    }
  }

  return flow_graph_;
}

void TestPipeline::CompileGraphAndAttachFunction() {
  Zone* zone = thread_->zone();
  const bool optimized = true;

  SpeculativeInliningPolicy speculative_policy(/*enable_suppression=*/false);

#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32)
  const intptr_t far_branch_level = 0;
#else
  const intptr_t far_branch_level = 1;
#endif

  ASSERT(pass_state_->inline_id_to_function.length() ==
         pass_state_->caller_inline_id.length());
  compiler::ObjectPoolBuilder object_pool_builder;
  compiler::Assembler assembler(&object_pool_builder, far_branch_level);
  FlowGraphCompiler graph_compiler(
      &assembler, flow_graph_, *parsed_function_, optimized,
      &speculative_policy, pass_state_->inline_id_to_function,
      pass_state_->inline_id_to_token_pos, pass_state_->caller_inline_id,
      ic_data_array_);

  graph_compiler.CompileGraph();

  const auto& deopt_info_array =
      Array::Handle(zone, graph_compiler.CreateDeoptInfo(&assembler));
  const auto pool_attachment = Code::PoolAttachment::kAttachPool;
  Code& code = Code::Handle();
  {
    SafepointWriteRwLocker ml(thread_,
                              thread_->isolate_group()->program_lock());
    code ^= Code::FinalizeCode(&graph_compiler, &assembler, pool_attachment,
                               optimized, nullptr);
  }
  code.set_is_optimized(optimized);
  code.set_owner(function_);

  graph_compiler.FinalizePcDescriptors(code);
  code.set_deopt_info_array(deopt_info_array);

  graph_compiler.FinalizeStackMaps(code);
  graph_compiler.FinalizeVarDescriptors(code);
  graph_compiler.FinalizeExceptionHandlers(code);
  graph_compiler.FinalizeCatchEntryMovesMap(code);
  graph_compiler.FinalizeStaticCallTargetsTable(code);
  graph_compiler.FinalizeCodeSourceMap(code);

  {
    SafepointWriteRwLocker ml(thread_,
                              thread_->isolate_group()->program_lock());
    if (optimized) {
      function_.InstallOptimizedCode(code);
    } else {
      function_.set_unoptimized_code(code);
      function_.AttachCode(code);
    }
  }

  // We expect there to be no deoptimizations.
  if (mode_ == CompilerPass::kAOT) {
    EXPECT(deopt_info_array.IsNull() || deopt_info_array.Length() == 0);
  }
}

bool ILMatcher::TryMatch(std::initializer_list<MatchCode> match_codes,
                         MatchOpCode insert_before) {
  std::vector<MatchCode> qcodes = match_codes;

  if (insert_before != kInvalidMatchOpCode) {
    for (auto pos = qcodes.begin(); pos < qcodes.end(); pos++) {
      pos = qcodes.insert(pos, insert_before) + 1;
    }
  }

  if (trace_) {
    OS::PrintErr("ILMatcher: Matching the following graph\n");
    FlowGraphPrinter::PrintGraph("ILMatcher", flow_graph_);
    OS::PrintErr("ILMatcher: Starting match at %s:\n", cursor_->ToCString());
  }

  Instruction* cursor = cursor_;
  for (size_t i = 0; i < qcodes.size(); ++i) {
    Instruction** capture = qcodes[i].capture_;
    if (parallel_moves_handling_ == ParallelMovesHandling::kSkip) {
      while (cursor->IsParallelMove()) {
        cursor = cursor->next();
      }
    }
    if (trace_) {
      OS::PrintErr("  matching %30s @ %s\n",
                   MatchOpCodeToCString(qcodes[i].opcode()),
                   cursor->ToCString());
    }

    auto next = MatchInternal(qcodes, i, cursor);
    if (next == nullptr) {
      if (trace_) {
        OS::PrintErr("  -> Match failed\n");
      }
      cursor = next;
      break;
    }
    if (capture != nullptr) {
      *capture = cursor;
    }
    cursor = next;
  }
  if (cursor != nullptr) {
    cursor_ = cursor;
    return true;
  }
  return false;
}

Instruction* ILMatcher::MatchInternal(std::vector<MatchCode> match_codes,
                                      size_t i,
                                      Instruction* cursor) {
  const MatchOpCode opcode = match_codes[i].opcode();
  if (opcode == kMatchAndMoveBranchTrue) {
    auto branch = cursor->AsBranch();
    if (branch == nullptr) return nullptr;
    return branch->true_successor();
  }
  if (opcode == kMatchAndMoveBranchFalse) {
    auto branch = cursor->AsBranch();
    if (branch == nullptr) return nullptr;
    return branch->false_successor();
  }
  if (opcode == kNop) {
    return cursor;
  }
  if (opcode == kMoveAny) {
    return cursor->next();
  }
  if (opcode == kMoveParallelMoves) {
    while (cursor != nullptr && cursor->IsParallelMove()) {
      cursor = cursor->next();
    }
    return cursor;
  }

  if (opcode == kMoveGlob) {
    ASSERT((i + 1) < match_codes.size());
    while (true) {
      if (cursor == nullptr) return nullptr;
      if (MatchInternal(match_codes, i + 1, cursor) != nullptr) {
        return cursor;
      }
      if (auto as_goto = cursor->AsGoto()) {
        cursor = as_goto->successor();
      } else {
        cursor = cursor->next();
      }
    }
  }

  if (opcode == kMoveDebugStepChecks) {
    while (cursor != nullptr && cursor->IsDebugStepCheck()) {
      cursor = cursor->next();
    }
    return cursor;
  }

  if (opcode == kMatchAndMoveGoto) {
    if (auto goto_instr = cursor->AsGoto()) {
      return goto_instr->successor();
    }
  }

  switch (opcode) {
#define EMIT_CASE(Instruction, _)                                              \
  case kMatch##Instruction: {                                                  \
    if (cursor->Is##Instruction()) {                                           \
      return cursor;                                                           \
    }                                                                          \
    return nullptr;                                                            \
  }                                                                            \
  case kMatchAndMove##Instruction: {                                           \
    if (cursor->Is##Instruction()) {                                           \
      return cursor->next();                                                   \
    }                                                                          \
    return nullptr;                                                            \
  }                                                                            \
  case kMatchAndMoveOptional##Instruction: {                                   \
    if (cursor->Is##Instruction()) {                                           \
      return cursor->next();                                                   \
    }                                                                          \
    return cursor;                                                             \
  }
    FOR_EACH_INSTRUCTION(EMIT_CASE)
#undef EMIT_CASE
    default:
      UNREACHABLE();
  }

  UNREACHABLE();
  return nullptr;
}

const char* ILMatcher::MatchOpCodeToCString(MatchOpCode opcode) {
  if (opcode == kMatchAndMoveBranchTrue) {
    return "kMatchAndMoveBranchTrue";
  }
  if (opcode == kMatchAndMoveBranchFalse) {
    return "kMatchAndMoveBranchFalse";
  }
  if (opcode == kNop) {
    return "kNop";
  }
  if (opcode == kMoveAny) {
    return "kMoveAny";
  }
  if (opcode == kMoveParallelMoves) {
    return "kMoveParallelMoves";
  }
  if (opcode == kMoveGlob) {
    return "kMoveGlob";
  }
  if (opcode == kMoveDebugStepChecks) {
    return "kMoveDebugStepChecks";
  }

  switch (opcode) {
#define EMIT_CASE(Instruction, _)                                              \
  case kMatch##Instruction:                                                    \
    return "kMatch" #Instruction;                                              \
  case kMatchAndMove##Instruction:                                             \
    return "kMatchAndMove" #Instruction;                                       \
  case kMatchAndMoveOptional##Instruction:                                     \
    return "kMatchAndMoveOptional" #Instruction;
    FOR_EACH_INSTRUCTION(EMIT_CASE)
#undef EMIT_CASE
    default:
      UNREACHABLE();
  }

  UNREACHABLE();
  return nullptr;
}

}  // namespace dart
