//===- 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_SUITE_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, llvm::Triple(), 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, llvm::Triple(), 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
