//===- 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, 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
