//===- llvm/tools/gollvm/unittests/BackendCore/BackendTreeIntegrity.cpp -===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//

#include "TestUtils.h"
#include "go-llvm-backend.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace goBackendUnitTests;

namespace {

class BackendTreeIntegrity
    : public testing::TestWithParam<llvm::CallingConv::ID> {};

INSTANTIATE_TEST_CASE_P(
    UnitTest, BackendTreeIntegrity,
    goBackendUnitTests::CConvs,
    [](const testing::TestParamInfo<BackendTreeIntegrity::ParamType> &info) {
      std::string name = goBackendUnitTests::ccName(info.param);
      return name;
    });

TEST_P(BackendTreeIntegrity, CheckTreeIntegrity1) {
  auto cc = GetParam();
  FcnTestHarness h(cc, "foo");
  Llvm_backend *be = h.be();
  Bfunction *func = h.func();
  Location loc;

  // So that we can test the checker itself
  be->disableIntegrityChecks();

  // Create "2 + x"
  Btype *bi64t = be->integer_type(false, 64);
  Bvariable *xv = h.mkLocal("x", bi64t);
  Bexpression *vex = be->var_expression(xv, loc);
  Bexpression *bl1 = mkInt64Const(be, 2);
  Bexpression *badd1 = be->binary_expression(OPERATOR_PLUS, bl1, vex, loc);
  Bstatement *es = be->expression_statement(func, badd1);
  h.addStmt(es);

  // Grab pointer to the add expr above, post-materialization.
  badd1 = es->children()[0]->castToBexpression();

  // Create "4"
  Bexpression *b4 = mkInt64Const(be, 4);
  Bstatement *es2 = be->expression_statement(func, b4);
  h.addStmt(es2);

  // Mangle the IR so that we have a some instructions
  // parented by more than one Bexpression. Warning to our viewers at
  // home -- don't do this.
  for (auto inst : badd1->instructions())
    b4->appendInstruction(inst);

  TreeIntegCtl control(NoDumpPointers, ReportRepairableSharing, BatchMode);
  std::pair<bool, std::string> result =
      be->checkTreeIntegrity(h.block(), control);
  EXPECT_FALSE(result.first);
  EXPECT_TRUE(containstokens(result.second,
                             "instruction has multiple parents"));

  // Undo the mangling to avoid asserts later on
  b4->clear();

  h.finish(PreserveDebugInfo);
}

TEST_P(BackendTreeIntegrity, CheckTreeIntegrity2) {

  // Add the same Expression to more than one statement
  LLVMContext C;
  auto cc = GetParam();
  std::unique_ptr<Llvm_backend> be(
      new Llvm_backend(C, nullptr, nullptr, 0, cc));
  be->disableIntegrityChecks();

  Location loc;
  Bfunction *func = mkFunci32o64(be.get(), "foo");
  Btype *bi64t = be->integer_type(false, 64);
  Bvariable *loc1 = be->local_variable(func, "loc1", bi64t, nullptr, true, loc);
  Bvariable *loc2 = be->local_variable(func, "loc2", bi64t, nullptr, true, loc);

  // Create "loc1" varexpr, then supply to more than one statement
  Bexpression *ve = be->var_expression(loc1, loc);
  Bstatement *es1 = be->expression_statement(func, ve);
  Bblock *block = mkBlockFromStmt(be.get(), func, es1);
  Bstatement *es2 = be->expression_statement(func, ve);
  addStmtToBlock(be.get(), block, es2);

  TreeIntegCtl control(NoDumpPointers, ReportRepairableSharing, BatchMode);
  std::pair<bool, std::string> result = be->checkTreeIntegrity(block, control);
  EXPECT_FALSE(result.first);
  EXPECT_TRUE(containstokens(result.second, "expr has multiple parents"));

  be->nodeBuilder().destroy(block, DelBoth);

  Bexpression *ve3 = be->var_expression(loc2, loc);
  Bstatement *es3 = be->expression_statement(func, ve3);
  Bblock *block2 = mkBlockFromStmt(be.get(), func, es3);

  be->disableDebugMetaDataGeneration();

  be->function_set_body(func, block2);
}

TEST_P(BackendTreeIntegrity, CheckTreeIntegrity3) {

  // Same statement with more than one parent.
  LLVMContext C;
  auto cc = GetParam();
  std::unique_ptr<Llvm_backend> be(
      new Llvm_backend(C, nullptr, nullptr, 0, cc));
  be->disableIntegrityChecks();
  Location loc;
  Bfunction *func = mkFunci32o64(be.get(), "foo");

  // Create expr stmt, add to block more than once
  Bexpression *b2 = mkInt64Const(be.get(), 2);
  Bstatement *es = be->expression_statement(func, b2);
  Bblock *block = mkBlockFromStmt(be.get(), func, es);
  addStmtToBlock(be.get(), block, es);

  TreeIntegCtl control(NoDumpPointers, ReportRepairableSharing, BatchMode);
  std::pair<bool, std::string> result = be->checkTreeIntegrity(block, control);
  EXPECT_FALSE(result.first);
  EXPECT_TRUE(containstokens(result.second, "stmt has multiple parents"));

  Bexpression *b3 = mkInt64Const(be.get(), 3);
  Bstatement *es2 = be->expression_statement(func, b3);
  Bblock *block2 = mkBlockFromStmt(be.get(), func, es2);

  be->disableDebugMetaDataGeneration();

  be->function_set_body(func, block2);
}

TEST_P(BackendTreeIntegrity, CheckTreeIntegrityRepairableSubtree) {
  auto cc = GetParam();
  FcnTestHarness h(cc);
  Llvm_backend *be = h.be();
  Btype *bi32t = be->integer_type(false, 32);
  Btype *bpi32t = be->pointer_type(bi32t);
  BFunctionType *befty = mkFuncTyp(be, L_PARM, bpi32t, L_END);
  Bfunction *func = h.mkFunction("x", befty);
  Location loc;

  TreeIntegCtl ctl(NoDumpPointers, ReportRepairableSharing, BatchMode);
  IntegrityVisitor ivis(be, ctl);

  // *p0 + 2
  Bvariable *p0v = func->getNthParamVar(0);
  Bexpression *vex0 = be->var_expression(p0v, loc);
  Bexpression *deref = be->indirect_expression(bi32t, vex0, false, loc);
  Bexpression *add =
      be->binary_expression(OPERATOR_PLUS, mkInt32Const(be, 2), deref, loc);
  EXPECT_TRUE(ivis.repairableSubTree(vex0));
  EXPECT_TRUE(ivis.repairableSubTree(deref));
  EXPECT_TRUE(ivis.repairableSubTree(add));

  // p0 == nil ? 1 : *p0
  Bexpression *vex2 = be->var_expression(p0v, loc);
  Bexpression *npe = be->nil_pointer_expression();
  Bexpression *cmp = be->binary_expression(OPERATOR_EQEQ, npe, vex2, loc);
  Bexpression *der2 = be->indirect_expression(bi32t, vex2, false, loc);
  Bexpression *const1 = mkInt32Const(be, 1);
  Bexpression *condex = be->conditional_expression(func, bi32t, cmp, const1,
                                                   der2, loc);
  EXPECT_TRUE(ivis.repairableSubTree(cmp));
  EXPECT_TRUE(ivis.repairableSubTree(condex));

  // Not legal to share calls (in general)
  Bexpression *vex3 = be->var_expression(p0v, loc);
  Bexpression *call2 = h.mkCallExpr(be, func, vex3, nullptr);
  EXPECT_FALSE(ivis.repairableSubTree(call2));

  // Create runtime error function.
  const char *rtename = "runtime.panicmem";
  BFunctionType *bfterr = mkFuncTyp(be, L_END);
  unsigned fflags = (Backend::function_is_visible |
                     Backend::function_is_inlinable |
                     Backend::function_does_not_return |
                     Backend::function_is_declaration);
  Bfunction *rtefcn = be->function(bfterr, rtename, rtename, fflags, loc);

  // p0 != nil ? *p0 + 3 : runtime.panicmem()
  Bexpression *cmp2 = be->binary_expression(OPERATOR_NOTEQ, vex3, npe, loc);
  Bexpression *der3 = be->indirect_expression(bi32t, vex3, false, loc);
  Bexpression *add2 = be->binary_expression(OPERATOR_PLUS, mkInt32Const(be, 3), der3, loc);
  Bexpression *call3 = h.mkCallExpr(be, rtefcn, nullptr);
  Bexpression *condex2 = be->conditional_expression(func, bi32t, cmp2, add2,
                                                   call3, loc);

  // Runtime error calls are ok to unshare/duplicate.
  EXPECT_TRUE(ivis.repairableSubTree(call3));
  EXPECT_TRUE(ivis.repairableSubTree(condex2));

  h.mkExprStmt(call2);
  h.mkExprStmt(condex);
  h.mkExprStmt(condex2);
  h.mkExprStmt(add);

  bool broken = h.finish(StripDebugInfo);
  EXPECT_FALSE(broken && "Module failed to verify.");
}

} // namespace
