1//===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the interface for lazy computation of value constraint
11// information.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
16#define LLVM_ANALYSIS_LAZYVALUEINFO_H
17
18#include "llvm/IR/PassManager.h"
19#include "llvm/Pass.h"
20
21namespace llvm {
22  class AssumptionCache;
23  class Constant;
24  class ConstantRange;
25  class DataLayout;
26  class DominatorTree;
27  class Instruction;
28  class TargetLibraryInfo;
29  class Value;
30
31/// This pass computes, caches, and vends lazy value constraint information.
32class LazyValueInfo {
33  friend class LazyValueInfoWrapperPass;
34  AssumptionCache *AC = nullptr;
35  class TargetLibraryInfo *TLI = nullptr;
36  DominatorTree *DT = nullptr;
37  void *PImpl = nullptr;
38  LazyValueInfo(const LazyValueInfo&) = delete;
39  void operator=(const LazyValueInfo&) = delete;
40public:
41  ~LazyValueInfo();
42  LazyValueInfo() {}
43  LazyValueInfo(AssumptionCache *AC_, TargetLibraryInfo *TLI_,
44                DominatorTree *DT_)
45      : AC(AC_), TLI(TLI_), DT(DT_) {}
46  LazyValueInfo(LazyValueInfo &&Arg)
47      : AC(Arg.AC), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
48    Arg.PImpl = nullptr;
49  }
50  LazyValueInfo &operator=(LazyValueInfo &&Arg) {
51    releaseMemory();
52    AC = Arg.AC;
53    TLI = Arg.TLI;
54    DT = Arg.DT;
55    PImpl = Arg.PImpl;
56    Arg.PImpl = nullptr;
57    return *this;
58  }
59
60  /// This is used to return true/false/dunno results.
61  enum Tristate {
62    Unknown = -1, False = 0, True = 1
63  };
64
65  // Public query interface.
66
67  /// Determine whether the specified value comparison with a constant is known
68  /// to be true or false on the specified CFG edge.
69  /// Pred is a CmpInst predicate.
70  Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
71                              BasicBlock *FromBB, BasicBlock *ToBB,
72                              Instruction *CxtI = nullptr);
73
74  /// Determine whether the specified value comparison with a constant is known
75  /// to be true or false at the specified instruction
76  /// (from an assume intrinsic). Pred is a CmpInst predicate.
77  Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C,
78                          Instruction *CxtI);
79
80  /// Determine whether the specified value is known to be a
81  /// constant at the end of the specified block.  Return null if not.
82  Constant *getConstant(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr);
83
84  /// Return the ConstantRange constraint that is known to hold for the
85  /// specified value at the end of the specified block. This may only be called
86  /// on integer-typed Values.
87  ConstantRange getConstantRange(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr);
88
89  /// Determine whether the specified value is known to be a
90  /// constant on the specified edge.  Return null if not.
91  Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
92                              Instruction *CxtI = nullptr);
93
94  /// Inform the analysis cache that we have threaded an edge from
95  /// PredBB to OldSucc to be from PredBB to NewSucc instead.
96  void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
97
98  /// Inform the analysis cache that we have erased a block.
99  void eraseBlock(BasicBlock *BB);
100
101  // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
102  void releaseMemory();
103};
104
105/// \brief Analysis to compute lazy value information.
106class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> {
107public:
108  typedef LazyValueInfo Result;
109  Result run(Function &F, FunctionAnalysisManager &FAM);
110
111private:
112  static char PassID;
113  friend struct AnalysisInfoMixin<LazyValueAnalysis>;
114};
115
116/// Wrapper around LazyValueInfo.
117class LazyValueInfoWrapperPass : public FunctionPass {
118  LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete;
119  void operator=(const LazyValueInfoWrapperPass&) = delete;
120public:
121  static char ID;
122  LazyValueInfoWrapperPass() : FunctionPass(ID) {
123    initializeLazyValueInfoWrapperPassPass(*PassRegistry::getPassRegistry());
124  }
125  ~LazyValueInfoWrapperPass() override {
126    assert(!Info.PImpl && "releaseMemory not called");
127  }
128
129  LazyValueInfo &getLVI();
130
131  void getAnalysisUsage(AnalysisUsage &AU) const override;
132  void releaseMemory() override;
133  bool runOnFunction(Function &F) override;
134private:
135  LazyValueInfo Info;
136};
137
138}  // end namespace llvm
139
140#endif
141
142