//===-- go-llvm-tree-integrity.cpp - tree integrity utils impl ------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
//
// Methods for class IntegrityVisitor.
//
//===----------------------------------------------------------------------===//

#include "go-llvm-bexpression.h"
#include "go-llvm-bstatement.h"
#include "go-llvm-tree-integrity.h"
#include "go-llvm.h"

#include "llvm/IR/Instruction.h"

IntegrityVisitor::IntegrityVisitor(Llvm_backend *be,
                                   TreeIntegCtl control)
    : be_(be), ss_(str_), control_(control),
      instShareCount_(0), stmtShareCount_(0), exprShareCount_(0)
{
  acceptableNodes_.insert(N_Const);
  acceptableNodes_.insert(N_Call); // subject to acceptable target
  acceptableNodes_.insert(N_FcnAddress);
  acceptableNodes_.insert(N_Conditional);
  acceptableNodes_.insert(N_Var);
  acceptableNodes_.insert(N_Conversion);
  acceptableNodes_.insert(N_Deref);
  acceptableNodes_.insert(N_StructField);
  acceptableNodes_.insert(N_BinaryOp); // subject to acceptableOpcodes
  acceptableOpcodes_.insert(OPERATOR_PLUS);
  acceptableOpcodes_.insert(OPERATOR_MINUS);
  acceptableOpcodes_.insert(OPERATOR_EQEQ);
  acceptableOpcodes_.insert(OPERATOR_NOTEQ);
}

void IntegrityVisitor::dumpTag(const char *tag, void *ptr) {
  ss_ << tag << ": ";
  if (includePointers() == DumpPointers)
    ss_ << ptr;
  ss_ << "\n";
}

void IntegrityVisitor::dump(Bnode *node) {
  dumpTag(node->isStmt() ? "stmt" : "expr", (void*) node);
  node->osdump(ss_, 0, be_->linemap(), false);
}

void IntegrityVisitor::dump(llvm::Instruction *inst) {
  dumpTag("inst", (void*) inst);
  inst->print(ss_);
  ss_ << "\n";
}

bool IntegrityVisitor::shouldBeTracked(Bnode *child)
{
  Bexpression *expr = child->castToBexpression();
  if (expr && expr->value() &&
      be_->moduleScopeValue(expr->value(), expr->btype()))
    return false;
  return true;
}

void IntegrityVisitor::deletePending(Bnode *node)
{
  assert(shouldBeTracked(node));
  auto it = nparent_.find(node);
  if (it == nparent_.end())
    return;
  nparent_.erase(it);
}

// This helper routine is invoked in situations where the node
// builder wants to "reparent" the children of a node, e.g. it has
// a "foo" node with children X and Y, and it wants to convert it
// into a "bar" node with the same children. Ex:
//
//     foo               bar
//    .  .       =>     .   .
//   .    .            .     .
//  X      Y          X       Y
//
// In this situation we need to update "nparent_" to reflect the fact
// that X and Y are no longer parented by foo. A complication can crop
// up if sharing has already been established at the point where this
// routine is called. For example, suppose that there is some other
// node "baz" that has also installed "X" as a child:
//
//        baz    foo
//       .  .   .   .
//      .    . .     .
//     W      X       Y
//
// If this situation arises, we need to preserve the existing nparent_
// mapping, so as to be able to repair the sharing later on.

void IntegrityVisitor::unsetParent(Bnode *child, Bnode *parent, unsigned slot)
{
  if (! shouldBeTracked(child))
    return;
  auto it = nparent_.find(child);
  if (it == nparent_.end())
    return;
  parslot pps = it->second;
  Bnode *prevParent = pps.first;
  unsigned prevSlot = pps.second;
  if (prevParent == parent || prevSlot == slot)
    nparent_.erase(it);
}

void IntegrityVisitor::unsetParent(llvm::Instruction *inst,
                                   Bexpression *exprParent,
                                   unsigned slot)
{
  auto it = iparent_.find(inst);
  if (it == iparent_.end())
    return;
  parslot pps = it->second;
  Bnode *prevParent = pps.first;
  unsigned prevSlot = pps.second;
  if (prevParent == exprParent || prevSlot == slot)
    iparent_.erase(it);
}

void IntegrityVisitor::setParent(Bnode *child, Bnode *parent, unsigned slot)
{
  if (! shouldBeTracked(child))
    return;
  auto it = nparent_.find(child);
  if (it != nparent_.end()) {
    parslot pps = it->second;
    Bnode *prevParent = pps.first;
    unsigned prevSlot = pps.second;
    if (prevParent == parent && prevSlot == slot)
      return;
    if (child->flavor() == N_Error)
      return;

    // Was this instance of sharing recorded previously?
    parslot ps = std::make_pair(parent, slot);
    auto it = sharing_.find(ps);
    if (it != sharing_.end())
      return;

    // Keep track of this location for future use in repair operations.
    sharing_.insert(ps);

    // If the sharing at this subtree is repairable, don't
    // log an error, since the sharing will be undone later on.
    Bexpression *expr = child->castToBexpression();
    if (expr != nullptr &&
        doRepairs() == DontReportRepairableSharing &&
        repairableSubTree(expr))
      return;

    const char *wh = nullptr;
    if (child->isStmt()) {
      stmtShareCount_ += 1;
      wh = "stmt";
    } else {
      exprShareCount_ += 1;
      wh = "expr";
    }

    // capture a description of the error
    ss_ << "error: " << wh << " has multiple parents"
        << " [ID=" << child->id() << "]\n";
    ss_ << "child " << wh << ":\n";
    dump(child);
    ss_ << "parent 1: [ID=" << prevParent->id() << "]\n";
    dump(prevParent);
    ss_ << "parent 2: [ID=" << parent->id() << "]\n";
    dump(parent);
    return;
  }
  nparent_[child] = std::make_pair(parent, slot);
}

void IntegrityVisitor::setParent(llvm::Instruction *inst,
                                 Bexpression *exprParent,
                                 unsigned slot)
{
  auto it = iparent_.find(inst);
  if (it != iparent_.end()) {
    parslot ps = it->second;
    Bnode *prevParent = ps.first;
    unsigned prevSlot = ps.second;
    if (prevParent == exprParent && prevSlot == slot)
      return;
    instShareCount_ += 1;
    ss_ << "error: instruction has multiple parents\n";
    dump(inst);
    ss_ << "parent 1:\n";
    dump(prevParent);
    ss_ << "parent 2:\n";
    dump(exprParent);
  } else {
    iparent_[inst] = std::make_pair(exprParent, slot);
  }
}

bool IntegrityVisitor::repairableSubTree(Bexpression *root)
{
  std::set<Bexpression *> visited;
  visited.insert(root);
  std::vector<Bexpression *> workList;
  workList.push_back(root);

  while (! workList.empty()) {
    Bexpression *e = workList.back();
    workList.pop_back();
    if (acceptableNodes_.find(e->flavor()) == acceptableNodes_.end())
      return false;
    if (e->flavor() == N_Call) {
      // ok to duplicate runtime error calls, but not other calls
      Bfunction *target = e->getCallTarget();
      if (!target || target->name().compare(0, 13, "runtime.panic") != 0)
        return false;
    }
    if (e->flavor() == N_BinaryOp &&
        acceptableOpcodes_.find(e->op()) == acceptableOpcodes_.end())
      return false;
    for (auto &c : e->children()) {
      Bexpression *ce = c->castToBexpression();
      assert(ce);
      if (visited.find(ce) == visited.end()) {
        visited.insert(ce);
        workList.push_back(ce);
      }
    }
  }
  return true;
}

class ScopedIntegrityCheckDisabler {
 public:
  ScopedIntegrityCheckDisabler(Llvm_backend *be)
      : be_(be), val_(be->nodeBuilder().integrityChecksEnabled()) {
    be_->nodeBuilder().setIntegrityChecks(false);
  }
  ~ScopedIntegrityCheckDisabler() {
    be_->nodeBuilder().setIntegrityChecks(val_);
  }
 private:
  Llvm_backend *be_;
  bool val_;
};

bool IntegrityVisitor::repair(Bnode *node)
{
  ScopedIntegrityCheckDisabler disabler(be_);
  std::set<Bexpression *> visited;
  for (auto &ps : sharing_) {
    Bnode *parent = ps.first;
    unsigned slot = ps.second;
    const std::vector<Bnode *> &pkids = parent->children();
    Bexpression *child = pkids[slot]->castToBexpression();
    assert(child);

    if (visited.find(child) == visited.end()) {
      // Repairable?
      if (!repairableSubTree(child))
        return false;
      visited.insert(child);
    }
    Bexpression *childClone = be_->nodeBuilder().cloneSubtree(child);
    parent->replaceChild(slot, childClone);
  }
  sharing_.clear();
  exprShareCount_ = 0;
  return true;
}

void IntegrityVisitor::visit(Bnode *node)
{
  unsigned idx = 0;
  for (auto &child : node->children()) {
    if (visitMode() == BatchMode)
      visit(child);
    setParent(child, node, idx++);
  }
  Bexpression *expr = node->castToBexpression();
  if (expr) {
    idx = 0;
    for (auto inst : expr->instructions())
      setParent(inst, expr, idx++);
  }
}

bool IntegrityVisitor::examine(Bnode *node)
{
  // Visit node (and possibly entire subtree at node, mode depending)
  visit(node);

  // Inst sharing and statement sharing are not repairable.
  if (instShareCount_ != 0 || stmtShareCount_ != 0)
    return false;

  if (exprShareCount_ != 0)
    return false;

  // If the checker is in incremental mode, don't attempt repairs
  // (those will be done later on).
  if (visitMode() == IncrementalMode) {
    sharing_.clear();
    return true;
  }

  // Batch mode: return now if no sharing.
  if (sharing_.empty())
    return true;

  // Batch mode: perform repairs.
  if (repair(node))
    return true;

  // Repair failed -- return failure
  return false;
}
