//===- ValueNumbering.cpp - Value #'ing Implementation ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the non-abstract Value Numbering methods as well as a
// default implementation for the analysis group.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ValueNumbering.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Type.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;

char ValueNumbering::ID = 0;
// Register the ValueNumbering interface, providing a nice name to refer to.
static RegisterAnalysisGroup<ValueNumbering> X("Value Numbering");

/// ValueNumbering destructor: DO NOT move this to the header file for
/// ValueNumbering or else clients of the ValueNumbering class may not depend on
/// the ValueNumbering.o file in the current .a file, causing alias analysis
/// support to not be included in the tool correctly!
///
ValueNumbering::~ValueNumbering() {}

//===----------------------------------------------------------------------===//
// Basic ValueNumbering Pass Implementation
//===----------------------------------------------------------------------===//
//
// Because of the way .a files work, the implementation of the BasicVN class
// MUST be in the ValueNumbering file itself, or else we run the risk of
// ValueNumbering being used, but the default implementation not being linked
// into the tool that uses it.  As such, we register and implement the class
// here.
//

namespace {
  /// BasicVN - This class is the default implementation of the ValueNumbering
  /// interface.  It walks the SSA def-use chains to trivially identify
  /// lexically identical expressions.  This does not require any ahead of time
  /// analysis, so it is a very fast default implementation.
  ///
  struct VISIBILITY_HIDDEN BasicVN 
      : public ImmutablePass, public ValueNumbering {
    static char ID; // Class identification, replacement for typeinfo
    BasicVN() : ImmutablePass((intptr_t)&ID) {}

    /// getEqualNumberNodes - Return nodes with the same value number as the
    /// specified Value.  This fills in the argument vector with any equal
    /// values.
    ///
    /// This is where our implementation is.
    ///
    virtual void getEqualNumberNodes(Value *V1,
                                     std::vector<Value*> &RetVals) const;
  };

  char BasicVN::ID = 0;
  // Register this pass...
  RegisterPass<BasicVN>
  X("basicvn", "Basic Value Numbering (default GVN impl)");

  // Declare that we implement the ValueNumbering interface
  RegisterAnalysisGroup<ValueNumbering, true> Y(X);

  /// BVNImpl - Implement BasicVN in terms of a visitor class that
  /// handles the different types of instructions as appropriate.
  ///
  struct VISIBILITY_HIDDEN BVNImpl : public InstVisitor<BVNImpl> {
    std::vector<Value*> &RetVals;
    explicit BVNImpl(std::vector<Value*> &RV) : RetVals(RV) {}

    void visitCastInst(CastInst &I);
    void visitGetElementPtrInst(GetElementPtrInst &I);
    void visitCmpInst(CmpInst &I);

    void handleBinaryInst(Instruction &I);
    void visitBinaryOperator(Instruction &I)     { handleBinaryInst(I); }
    void visitShiftInst(Instruction &I)          { handleBinaryInst(I); }
    void visitExtractElementInst(Instruction &I) { handleBinaryInst(I); }

    void handleTernaryInst(Instruction &I);
    void visitSelectInst(Instruction &I)         { handleTernaryInst(I); }
    void visitInsertElementInst(Instruction &I)  { handleTernaryInst(I); }
    void visitShuffleVectorInst(Instruction &I)  { handleTernaryInst(I); }
    void visitInstruction(Instruction &) {
      // Cannot value number calls or terminator instructions.
    }
  };
}

ImmutablePass *llvm::createBasicVNPass() { return new BasicVN(); }

// getEqualNumberNodes - Return nodes with the same value number as the
// specified Value.  This fills in the argument vector with any equal values.
//
void BasicVN::getEqualNumberNodes(Value *V, std::vector<Value*> &RetVals) const{
  assert(V->getType() != Type::VoidTy &&
         "Can only value number non-void values!");
  // We can only handle the case where I is an instruction!
  if (Instruction *I = dyn_cast<Instruction>(V))
    BVNImpl(RetVals).visit(I);
}

void BVNImpl::visitCastInst(CastInst &CI) {
  Instruction &I = (Instruction&)CI;
  Value *Op = I.getOperand(0);
  Function *F = I.getParent()->getParent();

  for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
       UI != UE; ++UI)
    if (CastInst *Other = dyn_cast<CastInst>(*UI))
      // Check that the opcode is the same
      if (Other->getOpcode() == Instruction::CastOps(I.getOpcode()) &&
          // Check that the destination types are the same
          Other->getType() == I.getType() &&
          // Is it embedded in the same function?  (This could be false if LHS
          // is a constant or global!)
          Other->getParent()->getParent() == F &&
          // Check to see if this new cast is not I.
          Other != &I) {
        // These instructions are identical.  Add to list...
        RetVals.push_back(Other);
      }
}

void  BVNImpl::visitCmpInst(CmpInst &CI1) {
  Value *LHS = CI1.getOperand(0);
  for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end();
       UI != UE; ++UI)
    if (CmpInst *CI2 = dyn_cast<CmpInst>(*UI))
      // Check to see if this compare instruction is not CI, but same opcode,
      // same predicate, and in the same function.
      if (CI2 != &CI1 && CI2->getOpcode() == CI1.getOpcode() &&
          CI2->getPredicate() == CI1.getPredicate() &&
          CI2->getParent()->getParent() == CI1.getParent()->getParent())
        // If the operands are the same
        if ((CI2->getOperand(0) == CI1.getOperand(0) &&
            CI2->getOperand(1) == CI1.getOperand(1)) ||
            // Or the compare is commutative and the operands are reversed 
            (CI1.isCommutative() && 
             CI2->getOperand(0) == CI1.getOperand(1) &&
             CI2->getOperand(1) == CI1.getOperand(0)))
          // Then the instructiosn are identical, add to list.
          RetVals.push_back(CI2);
}



// isIdenticalBinaryInst - Return true if the two binary instructions are
// identical.
//
static inline bool isIdenticalBinaryInst(const Instruction &I1,
                                         const Instruction *I2) {
  // Is it embedded in the same function?  (This could be false if LHS
  // is a constant or global!)
  if (I1.getOpcode() != I2->getOpcode() ||
      I1.getParent()->getParent() != I2->getParent()->getParent())
    return false;

  // If they are CmpInst instructions, check their predicates
  if (CmpInst *CI1 = dyn_cast<CmpInst>(&const_cast<Instruction&>(I1)))
    if (CI1->getPredicate() != cast<CmpInst>(I2)->getPredicate())
      return false;

  // They are identical if both operands are the same!
  if (I1.getOperand(0) == I2->getOperand(0) &&
      I1.getOperand(1) == I2->getOperand(1))
    return true;

  // If the instruction is commutative, the instruction can match if the
  // operands are swapped!
  //
  if ((I1.getOperand(0) == I2->getOperand(1) &&
       I1.getOperand(1) == I2->getOperand(0)) &&
      I1.isCommutative())
    return true;

  return false;
}

// isIdenticalTernaryInst - Return true if the two ternary instructions are
// identical.
//
static inline bool isIdenticalTernaryInst(const Instruction &I1,
                                          const Instruction *I2) {
  // Is it embedded in the same function?  (This could be false if LHS
  // is a constant or global!)
  if (I1.getParent()->getParent() != I2->getParent()->getParent())
    return false;
  
  // They are identical if all operands are the same!
  return I1.getOperand(0) == I2->getOperand(0) &&
         I1.getOperand(1) == I2->getOperand(1) &&
         I1.getOperand(2) == I2->getOperand(2);
}



void BVNImpl::handleBinaryInst(Instruction &I) {
  Value *LHS = I.getOperand(0);

  for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end();
       UI != UE; ++UI)
    if (Instruction *Other = dyn_cast<Instruction>(*UI))
      // Check to see if this new binary operator is not I, but same operand...
      if (Other != &I && isIdenticalBinaryInst(I, Other)) {
        // These instructions are identical.  Handle the situation.
        RetVals.push_back(Other);
      }
}

// IdenticalComplexInst - Return true if the two instructions are the same, by
// using a brute force comparison.  This is useful for instructions with an
// arbitrary number of arguments.
//
static inline bool IdenticalComplexInst(const Instruction *I1,
                                        const Instruction *I2) {
  assert(I1->getOpcode() == I2->getOpcode());
  // Equal if they are in the same function...
  return I1->getParent()->getParent() == I2->getParent()->getParent() &&
    // And return the same type...
    I1->getType() == I2->getType() &&
    // And have the same number of operands...
    I1->getNumOperands() == I2->getNumOperands() &&
    // And all of the operands are equal.
    std::equal(I1->op_begin(), I1->op_end(), I2->op_begin());
}

void BVNImpl::visitGetElementPtrInst(GetElementPtrInst &I) {
  Value *Op = I.getOperand(0);

  // Try to pick a local operand if possible instead of a constant or a global
  // that might have a lot of uses.
  for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
    if (isa<Instruction>(I.getOperand(i)) || isa<Argument>(I.getOperand(i))) {
      Op = I.getOperand(i);
      break;
    }

  for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
       UI != UE; ++UI)
    if (GetElementPtrInst *Other = dyn_cast<GetElementPtrInst>(*UI))
      // Check to see if this new getelementptr is not I, but same operand...
      if (Other != &I && IdenticalComplexInst(&I, Other)) {
        // These instructions are identical.  Handle the situation.
        RetVals.push_back(Other);
      }
}

void BVNImpl::handleTernaryInst(Instruction &I) {
  Value *Op0 = I.getOperand(0);
  Instruction *OtherInst;
  
  for (Value::use_iterator UI = Op0->use_begin(), UE = Op0->use_end();
       UI != UE; ++UI)
    if ((OtherInst = dyn_cast<Instruction>(*UI)) && 
        OtherInst->getOpcode() == I.getOpcode()) {
      // Check to see if this new select is not I, but has the same operands.
      if (OtherInst != &I && isIdenticalTernaryInst(I, OtherInst)) {
        // These instructions are identical.  Handle the situation.
        RetVals.push_back(OtherInst);
      }
        
    }
}


// Ensure that users of ValueNumbering.h will link with this file
DEFINING_FILE_FOR(BasicValueNumbering)
