//===- PHITransAddr.cpp - PHI Translation for Addresses -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the PHITransAddr class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

static cl::opt<bool> EnableAddPhiTranslation(
    "gvn-add-phi-translation", cl::init(false), cl::Hidden,
    cl::desc("Enable phi-translation of add instructions"));

static bool canPHITrans(Instruction *Inst) {
  if (isa<PHINode>(Inst) || isa<GetElementPtrInst>(Inst) || isa<CastInst>(Inst))
    return true;

  if (Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1)))
    return true;

  return false;
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void PHITransAddr::dump() const {
  if (!Addr) {
    dbgs() << "PHITransAddr: null\n";
    return;
  }
  dbgs() << "PHITransAddr: " << *Addr << "\n";
  for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
    dbgs() << "  Input #" << i << " is " << *InstInputs[i] << "\n";
}
#endif

static bool verifySubExpr(Value *Expr,
                          SmallVectorImpl<Instruction *> &InstInputs) {
  // If this is a non-instruction value, there is nothing to do.
  Instruction *I = dyn_cast<Instruction>(Expr);
  if (!I) return true;

  // If it's an instruction, it is either in Tmp or its operands recursively
  // are.
  if (auto Entry = find(InstInputs, I); Entry != InstInputs.end()) {
    InstInputs.erase(Entry);
    return true;
  }

  // If it isn't in the InstInputs list it is a subexpr incorporated into the
  // address.  Validate that it is phi translatable.
  if (!canPHITrans(I)) {
    errs() << "Instruction in PHITransAddr is not phi-translatable:\n";
    errs() << *I << '\n';
    llvm_unreachable("Either something is missing from InstInputs or "
                     "canPHITrans is wrong.");
  }

  // Validate the operands of the instruction.
  return all_of(I->operands(),
                [&](Value *Op) { return verifySubExpr(Op, InstInputs); });
}

/// verify - Check internal consistency of this data structure.  If the
/// structure is valid, it returns true.  If invalid, it prints errors and
/// returns false.
bool PHITransAddr::verify() const {
  if (!Addr) return true;

  SmallVector<Instruction*, 8> Tmp(InstInputs.begin(), InstInputs.end());

  if (!verifySubExpr(Addr, Tmp))
    return false;

  if (!Tmp.empty()) {
    errs() << "PHITransAddr contains extra instructions:\n";
    for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
      errs() << "  InstInput #" << i << " is " << *InstInputs[i] << "\n";
    llvm_unreachable("This is unexpected.");
  }

  // a-ok.
  return true;
}

/// isPotentiallyPHITranslatable - If this needs PHI translation, return true
/// if we have some hope of doing it.  This should be used as a filter to
/// avoid calling PHITranslateValue in hopeless situations.
bool PHITransAddr::isPotentiallyPHITranslatable() const {
  // If the input value is not an instruction, or if it is not defined in CurBB,
  // then we don't need to phi translate it.
  Instruction *Inst = dyn_cast<Instruction>(Addr);
  return !Inst || canPHITrans(Inst);
}

static void RemoveInstInputs(Value *V,
                             SmallVectorImpl<Instruction*> &InstInputs) {
  Instruction *I = dyn_cast<Instruction>(V);
  if (!I) return;

  // If the instruction is in the InstInputs list, remove it.
  if (auto Entry = find(InstInputs, I); Entry != InstInputs.end()) {
    InstInputs.erase(Entry);
    return;
  }

  assert(!isa<PHINode>(I) && "Error, removing something that isn't an input");

  // Otherwise, it must have instruction inputs itself.  Zap them recursively.
  for (Value *Op : I->operands())
    if (Instruction *OpInst = dyn_cast<Instruction>(Op))
      RemoveInstInputs(OpInst, InstInputs);
}

Value *PHITransAddr::translateSubExpr(Value *V, BasicBlock *CurBB,
                                      BasicBlock *PredBB,
                                      const DominatorTree *DT, Value *Cond,
                                      bool CondVal) {
  // If this is a non-instruction value, it can't require PHI translation.
  Instruction *Inst = dyn_cast<Instruction>(V);
  if (!Inst) return V;

  // Determine whether 'Inst' is an input to our PHI translatable expression.
  bool isInput = is_contained(InstInputs, Inst);

  // Handle inputs instructions if needed.
  if (isInput) {
    if (Inst->getParent() != CurBB) {
      // If it is an input defined in a different block, then it remains an
      // input.
      return Inst;
    }

    // If 'Inst' is defined in this block and is an input that needs to be phi
    // translated, we need to incorporate the value into the expression or fail.

    // In either case, the instruction itself isn't an input any longer.
    InstInputs.erase(find(InstInputs, Inst));

    // If this is a PHI, go ahead and translate it.
    if (PHINode *PN = dyn_cast<PHINode>(Inst)) {
      Value *Incoming = PN->getIncomingValueForBlock(PredBB);
      // If the incoming value on this edge is a select on the condition we are
      // resolving, fold it to the requested side. This is what lets us obtain
      // the two distinct addresses referenced by a select-dependent load along
      // a backedge (e.g. min/max idioms).
      if (Cond)
        if (auto *SI = dyn_cast<SelectInst>(Incoming))
          if (SI->getCondition() == Cond)
            return addAsInput(CondVal ? SI->getTrueValue()
                                      : SI->getFalseValue());
      return addAsInput(Incoming);
    }

    // If this is a non-phi value, and it is analyzable, we can incorporate it
    // into the expression by making all instruction operands be inputs.
    if (!canPHITrans(Inst))
      return nullptr;

    // All instruction operands are now inputs (and of course, they may also be
    // defined in this block, so they may need to be phi translated themselves.
    for (Value *Op : Inst->operands())
      addAsInput(Op);
  }

  // Ok, it must be an intermediate result (either because it started that way
  // or because we just incorporated it into the expression).  See if its
  // operands need to be phi translated, and if so, reconstruct it.

  if (CastInst *Cast = dyn_cast<CastInst>(Inst)) {
    Value *PHIIn =
        translateSubExpr(Cast->getOperand(0), CurBB, PredBB, DT, Cond, CondVal);
    if (!PHIIn) return nullptr;
    if (PHIIn == Cast->getOperand(0))
      return Cast;

    // Find an available version of this cast.

    // Try to simplify cast first.
    if (Value *V = simplifyCastInst(Cast->getOpcode(), PHIIn, Cast->getType(),
                                    {DL, TLI, DT, AC})) {
      RemoveInstInputs(PHIIn, InstInputs);
      return addAsInput(V);
    }

    // Otherwise we have to see if a casted version of the incoming pointer
    // is available.  If so, we can use it, otherwise we have to fail.  Don't
    // scan the use list of a constant: ConstantData has no use list, and
    // other constants may be used from different functions, whose blocks are
    // not in this function's DominatorTree.
    if (!isa<Constant>(PHIIn)) {
      for (User *U : PHIIn->users()) {
        if (CastInst *CastI = dyn_cast<CastInst>(U))
          if (CastI->getOpcode() == Cast->getOpcode() &&
              CastI->getType() == Cast->getType() &&
              (!DT || DT->dominates(CastI->getParent(), PredBB)))
            return CastI;
      }
    }
    return nullptr;
  }

  // Handle getelementptr with at least one PHI translatable operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
    SmallVector<Value*, 8> GEPOps;
    bool AnyChanged = false;
    for (Value *Op : GEP->operands()) {
      Value *GEPOp = translateSubExpr(Op, CurBB, PredBB, DT, Cond, CondVal);
      if (!GEPOp) return nullptr;

      AnyChanged |= GEPOp != Op;
      GEPOps.push_back(GEPOp);
    }

    if (!AnyChanged)
      return GEP;

    // Simplify the GEP to handle 'gep x, 0' -> x etc.
    if (Value *V = simplifyGEPInst(GEP->getSourceElementType(), GEPOps[0],
                                   ArrayRef<Value *>(GEPOps).slice(1),
                                   GEP->getNoWrapFlags(), {DL, TLI, DT, AC})) {
      for (Value *Op : GEPOps)
        RemoveInstInputs(Op, InstInputs);

      return addAsInput(V);
    }

    // Scan to see if we have this GEP available.
    Value *APHIOp = GEPOps[0];
    if (isa<ConstantData>(APHIOp))
      return nullptr;

    for (User *U : APHIOp->users()) {
      if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(U))
        if (GEPI->getType() == GEP->getType() &&
            GEPI->getSourceElementType() == GEP->getSourceElementType() &&
            GEPI->getNumOperands() == GEPOps.size() &&
            GEPI->getParent()->getParent() == CurBB->getParent() &&
            (!DT || DT->dominates(GEPI->getParent(), PredBB))) {
          if (std::equal(GEPOps.begin(), GEPOps.end(), GEPI->op_begin()))
            return GEPI;
        }
    }
    return nullptr;
  }

  // Handle add with a constant RHS.
  if (Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1))) {
    // PHI translate the LHS.
    Constant *RHS = cast<ConstantInt>(Inst->getOperand(1));
    bool isNSW = cast<BinaryOperator>(Inst)->hasNoSignedWrap();
    bool isNUW = cast<BinaryOperator>(Inst)->hasNoUnsignedWrap();

    Value *LHS =
        translateSubExpr(Inst->getOperand(0), CurBB, PredBB, DT, Cond, CondVal);
    if (!LHS) return nullptr;

    // If the PHI translated LHS is an add of a constant, fold the immediates.
    if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(LHS))
      if (BOp->getOpcode() == Instruction::Add)
        if (ConstantInt *CI = dyn_cast<ConstantInt>(BOp->getOperand(1))) {
          LHS = BOp->getOperand(0);
          RHS = ConstantExpr::getAdd(RHS, CI);
          isNSW = isNUW = false;

          // If the old 'LHS' was an input, add the new 'LHS' as an input.
          if (is_contained(InstInputs, BOp)) {
            RemoveInstInputs(BOp, InstInputs);
            addAsInput(LHS);
          }
        }

    // See if the add simplifies away.
    if (Value *Res = simplifyAddInst(LHS, RHS, isNSW, isNUW, {DL, TLI, DT, AC})) {
      // If we simplified the operands, the LHS is no longer an input, but Res
      // is.
      RemoveInstInputs(LHS, InstInputs);
      return addAsInput(Res);
    }

    // If we didn't modify the add, just return it.
    if (LHS == Inst->getOperand(0) && RHS == Inst->getOperand(1))
      return Inst;

    // Otherwise, see if we have this add available somewhere.
    for (User *U : LHS->users()) {
      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U))
        if (BO->getOpcode() == Instruction::Add &&
            BO->getOperand(0) == LHS && BO->getOperand(1) == RHS &&
            BO->getParent()->getParent() == CurBB->getParent() &&
            (!DT || DT->dominates(BO->getParent(), PredBB)))
          return BO;
    }

    return nullptr;
  }

  // Otherwise, we failed.
  return nullptr;
}

/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state to reflect any needed changes.  If
/// 'MustDominate' is true, the translated value must dominate PredBB.
Value *PHITransAddr::translateValue(BasicBlock *CurBB, BasicBlock *PredBB,
                                    const DominatorTree *DT,
                                    bool MustDominate) {
  assert(DT || !MustDominate);
  assert(verify() && "Invalid PHITransAddr!");
  if (DT && DT->isReachableFromEntry(PredBB))
    Addr = translateSubExpr(Addr, CurBB, PredBB, DT);
  else
    Addr = nullptr;
  assert(verify() && "Invalid PHITransAddr!");

  if (MustDominate)
    // Make sure the value is live in the predecessor.
    if (Instruction *Inst = dyn_cast_or_null<Instruction>(Addr))
      if (!DT->dominates(Inst->getParent(), PredBB))
        Addr = nullptr;

  return Addr;
}

SelectAddr::SelectAddrs PHITransAddr::translateValue(BasicBlock *CurBB,
                                                     BasicBlock *PredBB,
                                                     const DominatorTree *DT,
                                                     Value *Cond) {
  assert(Cond && "expected a non-null select condition");
  assert(verify() && "Invalid PHITransAddr!");

  if (!DT || !DT->isReachableFromEntry(PredBB))
    return {nullptr, nullptr};

  auto TranslateSide = [&](bool CondVal) -> Value * {
    // Work on a copy so that the original address state is preserved and the
    // other side can be translated independently.
    PHITransAddr Tmp(*this);
    return Tmp.translateSubExpr(Tmp.Addr, CurBB, PredBB, DT, Cond, CondVal);
  };

  return {TranslateSide(/*CondVal=*/true), TranslateSide(/*CondVal=*/false)};
}

Value *PHITransAddr::getSelectCondition() const {
  for (Instruction *I : InstInputs)
    if (auto *SI = dyn_cast<SelectInst>(I))
      return SI->getCondition();
  return nullptr;
}

/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
///
/// All newly created instructions are added to the NewInsts list.  This
/// returns null on failure.
///
Value *
PHITransAddr::translateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
                                     const DominatorTree &DT,
                                     SmallVectorImpl<Instruction *> &NewInsts) {
  unsigned NISize = NewInsts.size();

  // Attempt to PHI translate with insertion.
  Addr = insertTranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts);

  // If successful, return the new value.
  if (Addr) return Addr;

  // If not, destroy any intermediate instructions inserted.
  while (NewInsts.size() != NISize)
    NewInsts.pop_back_val()->eraseFromParent();
  return nullptr;
}

/// insertTranslatedSubExpr - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block.  All newly created instructions are added to the NewInsts list.
/// This returns null on failure.
///
Value *PHITransAddr::insertTranslatedSubExpr(
    Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB,
    const DominatorTree &DT, SmallVectorImpl<Instruction *> &NewInsts) {
  // See if we have a version of this value already available and dominating
  // PredBB.  If so, there is no need to insert a new instance of it.
  PHITransAddr Tmp(InVal, DL, AC);
  if (Value *Addr =
          Tmp.translateValue(CurBB, PredBB, &DT, /*MustDominate=*/true))
    return Addr;

  // We don't need to PHI translate values which aren't instructions.
  auto *Inst = dyn_cast<Instruction>(InVal);
  if (!Inst)
    return nullptr;

  // Handle cast of PHI translatable value.
  if (CastInst *Cast = dyn_cast<CastInst>(Inst)) {
    Value *OpVal = insertTranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB,
                                           DT, NewInsts);
    if (!OpVal) return nullptr;

    // Otherwise insert a cast at the end of PredBB.
    CastInst *New = CastInst::Create(Cast->getOpcode(), OpVal, InVal->getType(),
                                     InVal->getName() + ".phi.trans.insert",
                                     PredBB->getTerminator()->getIterator());
    New->setDebugLoc(Inst->getDebugLoc());
    NewInsts.push_back(New);
    return New;
  }

  // Handle getelementptr with at least one PHI operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
    SmallVector<Value*, 8> GEPOps;
    BasicBlock *CurBB = GEP->getParent();
    for (Value *Op : GEP->operands()) {
      Value *OpVal = insertTranslatedSubExpr(Op, CurBB, PredBB, DT, NewInsts);
      if (!OpVal) return nullptr;
      GEPOps.push_back(OpVal);
    }

    GetElementPtrInst *Result = GetElementPtrInst::Create(
        GEP->getSourceElementType(), GEPOps[0], ArrayRef(GEPOps).slice(1),
        InVal->getName() + ".phi.trans.insert",
        PredBB->getTerminator()->getIterator());
    Result->setDebugLoc(Inst->getDebugLoc());
    Result->setNoWrapFlags(GEP->getNoWrapFlags());
    NewInsts.push_back(Result);
    return Result;
  }

  // Handle add with a constant RHS.
  if (EnableAddPhiTranslation && Inst->getOpcode() == Instruction::Add &&
      isa<ConstantInt>(Inst->getOperand(1))) {

    // FIXME: This code works, but it is unclear that we actually want to insert
    // a big chain of computation in order to make a value available in a block.
    // This needs to be evaluated carefully to consider its cost trade offs.

    // PHI translate the LHS.
    Value *OpVal = insertTranslatedSubExpr(Inst->getOperand(0), CurBB, PredBB,
                                           DT, NewInsts);
    if (OpVal == nullptr)
      return nullptr;

    BinaryOperator *Res = BinaryOperator::CreateAdd(
        OpVal, Inst->getOperand(1), InVal->getName() + ".phi.trans.insert",
        PredBB->getTerminator()->getIterator());
    Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap());
    Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap());
    NewInsts.push_back(Res);
    return Res;
  }

  return nullptr;
}
