//===- LazyValueInfo.h - Value constraint analysis --------------*- 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 file defines the interface for lazy computation of value constraint
 
// information.
 
//
 
//===----------------------------------------------------------------------===//
 
 
 
#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
 
#define LLVM_ANALYSIS_LAZYVALUEINFO_H
 
 
 
#include "llvm/IR/PassManager.h"
 
#include "llvm/Pass.h"
 
 
 
namespace llvm {
 
  class AssumptionCache;
 
  class Constant;
 
  class ConstantRange;
 
  class DataLayout;
 
  class DominatorTree;
 
  class Instruction;
 
  class TargetLibraryInfo;
 
  class Value;
 
 
 
/// This pass computes, caches, and vends lazy value constraint information.
 
class LazyValueInfo {
 
  friend class LazyValueInfoWrapperPass;
 
  AssumptionCache *AC = nullptr;
 
  const DataLayout *DL = nullptr;
 
  class TargetLibraryInfo *TLI = nullptr;
 
  void *PImpl = nullptr;
 
  LazyValueInfo(const LazyValueInfo&) = delete;
 
  void operator=(const LazyValueInfo&) = delete;
 
public:
 
  ~LazyValueInfo();
 
  LazyValueInfo() = default;
 
  LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_,
 
                TargetLibraryInfo *TLI_)
 
      : AC(AC_), DL(DL_), TLI(TLI_) {}
 
  LazyValueInfo(LazyValueInfo &&Arg)
 
      : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), PImpl(Arg.PImpl) {
 
    Arg.PImpl = nullptr;
 
  }
 
  LazyValueInfo &operator=(LazyValueInfo &&Arg) {
 
    releaseMemory();
 
    AC = Arg.AC;
 
    DL = Arg.DL;
 
    TLI = Arg.TLI;
 
    PImpl = Arg.PImpl;
 
    Arg.PImpl = nullptr;
 
    return *this;
 
  }
 
 
 
  /// This is used to return true/false/dunno results.
 
  enum Tristate {
 
    Unknown = -1, False = 0, True = 1
 
  };
 
 
 
  // Public query interface.
 
 
 
  /// Determine whether the specified value comparison with a constant is known
 
  /// to be true or false on the specified CFG edge.
 
  /// Pred is a CmpInst predicate.
 
  Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
 
                              BasicBlock *FromBB, BasicBlock *ToBB,
 
                              Instruction *CxtI = nullptr);
 
 
 
  /// Determine whether the specified value comparison with a constant is known
 
  /// to be true or false at the specified instruction.
 
  /// \p Pred is a CmpInst predicate. If \p UseBlockValue is true, the block
 
  /// value is also taken into account.
 
  Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C,
 
                          Instruction *CxtI, bool UseBlockValue);
 
 
 
  /// Determine whether the specified value comparison is known to be true
 
  /// or false at the specified instruction. While this takes two Value's,
 
  /// it still requires that one of them is a constant.
 
  /// \p Pred is a CmpInst predicate.
 
  /// If \p UseBlockValue is true, the block value is also taken into account.
 
  Tristate getPredicateAt(unsigned Pred, Value *LHS, Value *RHS,
 
                          Instruction *CxtI, bool UseBlockValue);
 
 
 
  /// Determine whether the specified value is known to be a constant at the
 
  /// specified instruction. Return null if not.
 
  Constant *getConstant(Value *V, Instruction *CxtI);
 
 
 
  /// Return the ConstantRange constraint that is known to hold for the
 
  /// specified value at the specified instruction. This may only be called
 
  /// on integer-typed Values.
 
  ConstantRange getConstantRange(Value *V, Instruction *CxtI,
 
                                 bool UndefAllowed = true);
 
 
 
  /// Return the ConstantRange constraint that is known to hold for the value
 
  /// at a specific use-site.
 
  ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed = true);
 
 
 
  /// Determine whether the specified value is known to be a
 
  /// constant on the specified edge.  Return null if not.
 
  Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
 
                              Instruction *CxtI = nullptr);
 
 
 
  /// Return the ConstantRage constraint that is known to hold for the
 
  /// specified value on the specified edge. This may be only be called
 
  /// on integer-typed Values.
 
  ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
 
                                       BasicBlock *ToBB,
 
                                       Instruction *CxtI = nullptr);
 
 
 
  /// Inform the analysis cache that we have threaded an edge from
 
  /// PredBB to OldSucc to be from PredBB to NewSucc instead.
 
  void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
 
 
 
  /// Inform the analysis cache that we have erased a block.
 
  void eraseBlock(BasicBlock *BB);
 
 
 
  /// Complete flush all previously computed values
 
  void clear(const Module *M);
 
 
 
  /// Print the \LazyValueInfo Analysis.
 
  /// We pass in the DTree that is required for identifying which basic blocks
 
  /// we can solve/print for, in the LVIPrinter.
 
  void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
 
 
 
  // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
 
  void releaseMemory();
 
 
 
  /// Handle invalidation events in the new pass manager.
 
  bool invalidate(Function &F, const PreservedAnalyses &PA,
 
                  FunctionAnalysisManager::Invalidator &Inv);
 
};
 
 
 
/// Analysis to compute lazy value information.
 
class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> {
 
public:
 
  typedef LazyValueInfo Result;
 
  Result run(Function &F, FunctionAnalysisManager &FAM);
 
 
 
private:
 
  static AnalysisKey Key;
 
  friend struct AnalysisInfoMixin<LazyValueAnalysis>;
 
};
 
 
 
/// Wrapper around LazyValueInfo.
 
class LazyValueInfoWrapperPass : public FunctionPass {
 
  LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete;
 
  void operator=(const LazyValueInfoWrapperPass&) = delete;
 
public:
 
  static char ID;
 
  LazyValueInfoWrapperPass();
 
  ~LazyValueInfoWrapperPass() override {
 
    assert(!Info.PImpl && "releaseMemory not called");
 
  }
 
 
 
  LazyValueInfo &getLVI();
 
 
 
  void getAnalysisUsage(AnalysisUsage &AU) const override;
 
  void releaseMemory() override;
 
  bool runOnFunction(Function &F) override;
 
private:
 
  LazyValueInfo Info;
 
};
 
 
 
}  // end namespace llvm
 
 
 
#endif