//===- ThreadSafetyTIL.cpp ------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT in the llvm repository for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Basic/LLVM.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstddef>

using namespace clang;
using namespace threadSafety;
using namespace til;

StringRef til::getUnaryOpcodeString(TIL_UnaryOpcode Op) {
  switch (Op) {
    case UOP_Minus:    return "-";
    case UOP_BitNot:   return "~";
    case UOP_LogicNot: return "!";
  }
  return {};
}

StringRef til::getBinaryOpcodeString(TIL_BinaryOpcode Op) {
  switch (Op) {
    case BOP_Mul:      return "*";
    case BOP_Div:      return "/";
    case BOP_Rem:      return "%";
    case BOP_Add:      return "+";
    case BOP_Sub:      return "-";
    case BOP_Shl:      return "<<";
    case BOP_Shr:      return ">>";
    case BOP_BitAnd:   return "&";
    case BOP_BitXor:   return "^";
    case BOP_BitOr:    return "|";
    case BOP_Eq:       return "==";
    case BOP_Neq:      return "!=";
    case BOP_Lt:       return "<";
    case BOP_Leq:      return "<=";
    case BOP_Cmp:      return "<=>";
    case BOP_LogicAnd: return "&&";
    case BOP_LogicOr:  return "||";
  }
  return {};
}

SExpr* Future::force() {
  Status = FS_evaluating;
  Result = compute();
  Status = FS_done;
  return Result;
}

unsigned BasicBlock::addPredecessor(BasicBlock *Pred) {
  unsigned Idx = Predecessors.size();
  Predecessors.reserveCheck(1, Arena);
  Predecessors.push_back(Pred);
  for (auto *E : Args) {
    if (auto *Ph = dyn_cast<Phi>(E)) {
      Ph->values().reserveCheck(1, Arena);
      Ph->values().push_back(nullptr);
    }
  }
  return Idx;
}

void BasicBlock::reservePredecessors(unsigned NumPreds) {
  Predecessors.reserve(NumPreds, Arena);
  for (auto *E : Args) {
    if (auto *Ph = dyn_cast<Phi>(E)) {
      Ph->values().reserve(NumPreds, Arena);
    }
  }
}

// If E is a variable, then trace back through any aliases or redundant
// Phi nodes to find the canonical definition.
const SExpr *til::getCanonicalVal(const SExpr *E) {
  while (true) {
    if (const auto *V = dyn_cast<Variable>(E)) {
      if (V->kind() == Variable::VK_Let) {
        E = V->definition();
        continue;
      }
    }
    if (const auto *Ph = dyn_cast<Phi>(E)) {
      if (Ph->status() == Phi::PH_SingleVal) {
        E = Ph->values()[0];
        continue;
      }
    }
    break;
  }
  return E;
}

// If E is a variable, then trace back through any aliases or redundant
// Phi nodes to find the canonical definition.
// The non-const version will simplify incomplete Phi nodes.
SExpr *til::simplifyToCanonicalVal(SExpr *E) {
  while (true) {
    if (auto *V = dyn_cast<Variable>(E)) {
      if (V->kind() != Variable::VK_Let)
        return V;
      // Eliminate redundant variables, e.g. x = y, or x = 5,
      // but keep anything more complicated.
      if (til::ThreadSafetyTIL::isTrivial(V->definition())) {
        E = V->definition();
        continue;
      }
      return V;
    }
    if (auto *Ph = dyn_cast<Phi>(E)) {
      if (Ph->status() == Phi::PH_Incomplete)
        simplifyIncompleteArg(Ph);
      // Eliminate redundant Phi nodes.
      if (Ph->status() == Phi::PH_SingleVal) {
        E = Ph->values()[0];
        continue;
      }
    }
    return E;
  }
}

// Trace the arguments of an incomplete Phi node to see if they have the same
// canonical definition.  If so, mark the Phi node as redundant.
// getCanonicalVal() will recursively call simplifyIncompletePhi().
void til::simplifyIncompleteArg(til::Phi *Ph) {
  assert(Ph && Ph->status() == Phi::PH_Incomplete);

  // eliminate infinite recursion -- assume that this node is not redundant.
  Ph->setStatus(Phi::PH_MultiVal);

  SExpr *E0 = simplifyToCanonicalVal(Ph->values()[0]);
  for (unsigned i = 1, n = Ph->values().size(); i < n; ++i) {
    SExpr *Ei = simplifyToCanonicalVal(Ph->values()[i]);
    if (Ei == Ph)
      continue;  // Recursive reference to itself.  Don't count.
    if (Ei != E0) {
      return;    // Status is already set to MultiVal.
    }
  }
  Ph->setStatus(Phi::PH_SingleVal);
}

// Renumbers the arguments and instructions to have unique, sequential IDs.
int BasicBlock::renumberInstrs(int ID) {
  for (auto *Arg : Args)
    Arg->setID(this, ID++);
  for (auto *Instr : Instrs)
    Instr->setID(this, ID++);
  TermInstr->setID(this, ID++);
  return ID;
}

// Sorts the CFGs blocks using a reverse post-order depth-first traversal.
// Each block will be written into the Blocks array in order, and its BlockID
// will be set to the index in the array.  Sorting should start from the entry
// block, and ID should be the total number of blocks.
int BasicBlock::topologicalSort(SimpleArray<BasicBlock *> &Blocks, int ID) {
  if (Visited) return ID;
  Visited = true;
  for (auto *Block : successors())
    ID = Block->topologicalSort(Blocks, ID);
  // set ID and update block array in place.
  // We may lose pointers to unreachable blocks.
  assert(ID > 0);
  BlockID = --ID;
  Blocks[BlockID] = this;
  return ID;
}

// Performs a reverse topological traversal, starting from the exit block and
// following back-edges.  The dominator is serialized before any predecessors,
// which guarantees that all blocks are serialized after their dominator and
// before their post-dominator (because it's a reverse topological traversal).
// ID should be initially set to 0.
//
// This sort assumes that (1) dominators have been computed, (2) there are no
// critical edges, and (3) the entry block is reachable from the exit block
// and no blocks are accessible via traversal of back-edges from the exit that
// weren't accessible via forward edges from the entry.
int BasicBlock::topologicalFinalSort(SimpleArray<BasicBlock*>& Blocks, int ID) {
  // Visited is assumed to have been set by the topologicalSort.  This pass
  // assumes !Visited means that we've visited this node before.
  if (!Visited) return ID;
  Visited = false;
  if (DominatorNode.Parent)
    ID = DominatorNode.Parent->topologicalFinalSort(Blocks, ID);
  for (auto *Pred : Predecessors)
    ID = Pred->topologicalFinalSort(Blocks, ID);
  assert(static_cast<size_t>(ID) < Blocks.size());
  BlockID = ID++;
  Blocks[BlockID] = this;
  return ID;
}

// Computes the immediate dominator of the current block.  Assumes that all of
// its predecessors have already computed their dominators.  This is achieved
// by visiting the nodes in topological order.
void BasicBlock::computeDominator() {
  BasicBlock *Candidate = nullptr;
  // Walk backwards from each predecessor to find the common dominator node.
  for (auto *Pred : Predecessors) {
    // Skip back-edges
    if (Pred->BlockID >= BlockID) continue;
    // If we don't yet have a candidate for dominator yet, take this one.
    if (Candidate == nullptr) {
      Candidate = Pred;
      continue;
    }
    // Walk the alternate and current candidate back to find a common ancestor.
    auto *Alternate = Pred;
    while (Alternate != Candidate) {
      if (Candidate->BlockID > Alternate->BlockID)
        Candidate = Candidate->DominatorNode.Parent;
      else
        Alternate = Alternate->DominatorNode.Parent;
    }
  }
  DominatorNode.Parent = Candidate;
  DominatorNode.SizeOfSubTree = 1;
}

// Computes the immediate post-dominator of the current block.  Assumes that all
// of its successors have already computed their post-dominators.  This is
// achieved visiting the nodes in reverse topological order.
void BasicBlock::computePostDominator() {
  BasicBlock *Candidate = nullptr;
  // Walk back from each predecessor to find the common post-dominator node.
  for (auto *Succ : successors()) {
    // Skip back-edges
    if (Succ->BlockID <= BlockID) continue;
    // If we don't yet have a candidate for post-dominator yet, take this one.
    if (Candidate == nullptr) {
      Candidate = Succ;
      continue;
    }
    // Walk the alternate and current candidate back to find a common ancestor.
    auto *Alternate = Succ;
    while (Alternate != Candidate) {
      if (Candidate->BlockID < Alternate->BlockID)
        Candidate = Candidate->PostDominatorNode.Parent;
      else
        Alternate = Alternate->PostDominatorNode.Parent;
    }
  }
  PostDominatorNode.Parent = Candidate;
  PostDominatorNode.SizeOfSubTree = 1;
}

// Renumber instructions in all blocks
void SCFG::renumberInstrs() {
  int InstrID = 0;
  for (auto *Block : Blocks)
    InstrID = Block->renumberInstrs(InstrID);
}

static inline void computeNodeSize(BasicBlock *B,
                                   BasicBlock::TopologyNode BasicBlock::*TN) {
  BasicBlock::TopologyNode *N = &(B->*TN);
  if (N->Parent) {
    BasicBlock::TopologyNode *P = &(N->Parent->*TN);
    // Initially set ID relative to the (as yet uncomputed) parent ID
    N->NodeID = P->SizeOfSubTree;
    P->SizeOfSubTree += N->SizeOfSubTree;
  }
}

static inline void computeNodeID(BasicBlock *B,
                                 BasicBlock::TopologyNode BasicBlock::*TN) {
  BasicBlock::TopologyNode *N = &(B->*TN);
  if (N->Parent) {
    BasicBlock::TopologyNode *P = &(N->Parent->*TN);
    N->NodeID += P->NodeID;    // Fix NodeIDs relative to starting node.
  }
}

// Normalizes a CFG.  Normalization has a few major components:
// 1) Removing unreachable blocks.
// 2) Computing dominators and post-dominators
// 3) Topologically sorting the blocks into the "Blocks" array.
void SCFG::computeNormalForm() {
  // Topologically sort the blocks starting from the entry block.
  int NumUnreachableBlocks = Entry->topologicalSort(Blocks, Blocks.size());
  if (NumUnreachableBlocks > 0) {
    // If there were unreachable blocks shift everything down, and delete them.
    for (size_t I = NumUnreachableBlocks, E = Blocks.size(); I < E; ++I) {
      size_t NI = I - NumUnreachableBlocks;
      Blocks[NI] = Blocks[I];
      Blocks[NI]->BlockID = NI;
      // FIXME: clean up predecessor pointers to unreachable blocks?
    }
    Blocks.drop(NumUnreachableBlocks);
  }

  // Compute dominators.
  for (auto *Block : Blocks)
    Block->computeDominator();

  // Once dominators have been computed, the final sort may be performed.
  int NumBlocks = Exit->topologicalFinalSort(Blocks, 0);
  assert(static_cast<size_t>(NumBlocks) == Blocks.size());
  (void) NumBlocks;

  // Renumber the instructions now that we have a final sort.
  renumberInstrs();

  // Compute post-dominators and compute the sizes of each node in the
  // dominator tree.
  for (auto *Block : Blocks.reverse()) {
    Block->computePostDominator();
    computeNodeSize(Block, &BasicBlock::DominatorNode);
  }
  // Compute the sizes of each node in the post-dominator tree and assign IDs in
  // the dominator tree.
  for (auto *Block : Blocks) {
    computeNodeID(Block, &BasicBlock::DominatorNode);
    computeNodeSize(Block, &BasicBlock::PostDominatorNode);
  }
  // Assign IDs in the post-dominator tree.
  for (auto *Block : Blocks.reverse()) {
    computeNodeID(Block, &BasicBlock::PostDominatorNode);
  }
}
