//===- NaryReassociate.h - Reassociate n-ary expressions --------*- C++ -*-===//
//
// 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 pass reassociates n-ary add expressions and eliminates the redundancy
// exposed by the reassociation.
//
// A motivating example:
//
//   void foo(int a, int b) {
//     bar(a + b);
//     bar((a + 2) + b);
//   }
//
// An ideal compiler should reassociate (a + 2) + b to (a + b) + 2 and simplify
// the above code to
//
//   int t = a + b;
//   bar(t);
//   bar(t + 2);
//
// However, the Reassociate pass is unable to do that because it processes each
// instruction individually and believes (a + 2) + b is the best form according
// to its rank system.
//
// To address this limitation, NaryReassociate reassociates an expression in a
// form that reuses existing instructions. As a result, NaryReassociate can
// reassociate (a + 2) + b in the example to (a + b) + 2 because it detects that
// (a + b) is computed before.
//
// NaryReassociate works as follows. For every instruction in the form of (a +
// b) + c, it checks whether a + c or b + c is already computed by a dominating
// instruction. If so, it then reassociates (a + b) + c into (a + c) + b or (b +
// c) + a and removes the redundancy accordingly. To efficiently look up whether
// an expression is computed before, we store each instruction seen and its SCEV
// into an SCEV-to-instruction map.
//
// Although the algorithm pattern-matches only ternary additions, it
// automatically handles many >3-ary expressions by walking through the function
// in the depth-first order. For example, given
//
//   (a + c) + d
//   ((a + b) + c) + d
//
// NaryReassociate first rewrites (a + b) + c to (a + c) + b, and then rewrites
// ((a + c) + b) + d into ((a + c) + d) + b.
//
// Finally, the above dominator-based algorithm may need to be run multiple
// iterations before emitting optimal code. One source of this need is that we
// only split an operand when it is used only once. The above algorithm can
// eliminate an instruction and decrease the usage count of its operands. As a
// result, an instruction that previously had multiple uses may become a
// single-use instruction and thus eligible for split consideration. For
// example,
//
//   ac = a + c
//   ab = a + b
//   abc = ab + c
//   ab2 = ab + b
//   ab2c = ab2 + c
//
// In the first iteration, we cannot reassociate abc to ac+b because ab is used
// twice. However, we can reassociate ab2c to abc+b in the first iteration. As a
// result, ab2 becomes dead and ab will be used only once in the second
// iteration.
//
// Limitations and TODO items:
//
// 1) We only considers n-ary adds and muls for now. This should be extended
// and generalized.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H
#define LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"

namespace llvm {

class AssumptionCache;
class BinaryOperator;
class DataLayout;
class DominatorTree;
class Function;
class GetElementPtrInst;
class Instruction;
class ScalarEvolution;
class SCEV;
class TargetLibraryInfo;
class TargetTransformInfo;
class Type;
class Value;

class NaryReassociatePass : public PassInfoMixin<NaryReassociatePass> {
public:
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);

  // Glue for old PM.
  bool runImpl(Function &F, AssumptionCache *AC_, DominatorTree *DT_,
               ScalarEvolution *SE_, TargetLibraryInfo *TLI_,
               TargetTransformInfo *TTI_);

private:
  // Runs only one iteration of the dominator-based algorithm. See the header
  // comments for why we need multiple iterations.
  bool doOneIteration(Function &F);

  // Reassociates I for better CSE.
  Instruction *tryReassociate(Instruction *I, const SCEV *&OrigSCEV);

  // Reassociate GEP for better CSE.
  Instruction *tryReassociateGEP(GetElementPtrInst *GEP);

  // Try splitting GEP at the I-th index and see whether either part can be
  // CSE'ed. This is a helper function for tryReassociateGEP.
  //
  // \p IndexedType The element type indexed by GEP's I-th index. This is
  //                equivalent to
  //                  GEP->getIndexedType(GEP->getPointerOperand(), 0-th index,
  //                                      ..., i-th index).
  GetElementPtrInst *tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
                                              unsigned I, Type *IndexedType);

  // Given GEP's I-th index = LHS + RHS, see whether &Base[..][LHS][..] or
  // &Base[..][RHS][..] can be CSE'ed and rewrite GEP accordingly.
  GetElementPtrInst *tryReassociateGEPAtIndex(GetElementPtrInst *GEP,
                                              unsigned I, Value *LHS,
                                              Value *RHS, Type *IndexedType);

  // Reassociate binary operators for better CSE.
  Instruction *tryReassociateBinaryOp(BinaryOperator *I);

  // A helper function for tryReassociateBinaryOp. LHS and RHS are explicitly
  // passed.
  Instruction *tryReassociateBinaryOp(Value *LHS, Value *RHS,
                                      BinaryOperator *I);
  // Rewrites I to (LHS op RHS) if LHS is computed already.
  Instruction *tryReassociatedBinaryOp(const SCEV *LHS, Value *RHS,
                                       BinaryOperator *I);

  // Tries to match Op1 and Op2 by using V.
  bool matchTernaryOp(BinaryOperator *I, Value *V, Value *&Op1, Value *&Op2);

  // Gets SCEV for (LHS op RHS).
  const SCEV *getBinarySCEV(BinaryOperator *I, const SCEV *LHS,
                            const SCEV *RHS);

  // Returns the closest dominator of \c Dominatee that computes
  // \c CandidateExpr. Returns null if not found.
  Instruction *findClosestMatchingDominator(const SCEV *CandidateExpr,
                                            Instruction *Dominatee);

  // Try to match \p I as signed/unsigned Min/Max and reassociate it. \p
  // OrigSCEV is set if \I matches Min/Max regardless whether resassociation is
  // done or not. If reassociation was successful newly generated instruction is
  // returned, otherwise nullptr.
  template <typename PredT>
  Instruction *matchAndReassociateMinOrMax(Instruction *I,
                                           const SCEV *&OrigSCEV);

  // Reassociate Min/Max.
  template <typename MaxMinT>
  Value *tryReassociateMinOrMax(Instruction *I, MaxMinT MaxMinMatch, Value *LHS,
                                Value *RHS);

  // GetElementPtrInst implicitly sign-extends an index if the index is shorter
  // than the pointer size. This function returns whether Index is shorter than
  // GEP's pointer size, i.e., whether Index needs to be sign-extended in order
  // to be an index of GEP.
  bool requiresSignExtension(Value *Index, GetElementPtrInst *GEP);

  AssumptionCache *AC;
  const DataLayout *DL;
  DominatorTree *DT;
  ScalarEvolution *SE;
  TargetLibraryInfo *TLI;
  TargetTransformInfo *TTI;

  // A lookup table quickly telling which instructions compute the given SCEV.
  // Note that there can be multiple instructions at different locations
  // computing to the same SCEV, so we map a SCEV to an instruction list.  For
  // example,
  //
  //   if (p1)
  //     foo(a + b);
  //   if (p2)
  //     bar(a + b);
  DenseMap<const SCEV *, SmallVector<WeakTrackingVH, 2>> SeenExprs;
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_SCALAR_NARYREASSOCIATE_H
