blob: 363cb49af3823632fd77f0c4b9537b9e9509963f [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interface for lazy computation of value constraint
10// information.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
15#define LLVM_ANALYSIS_LAZYVALUEINFO_H
16
17#include "llvm/IR/PassManager.h"
18#include "llvm/Pass.h"
19
20namespace llvm {
21 class AssumptionCache;
22 class Constant;
23 class ConstantRange;
24 class DataLayout;
25 class DominatorTree;
26 class Instruction;
27 class TargetLibraryInfo;
28 class Value;
29
30/// This pass computes, caches, and vends lazy value constraint information.
31class LazyValueInfo {
32 friend class LazyValueInfoWrapperPass;
33 AssumptionCache *AC = nullptr;
34 const DataLayout *DL = nullptr;
35 class TargetLibraryInfo *TLI = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010036 void *PImpl = nullptr;
37 LazyValueInfo(const LazyValueInfo&) = delete;
38 void operator=(const LazyValueInfo&) = delete;
39public:
40 ~LazyValueInfo();
41 LazyValueInfo() {}
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020042 LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_,
43 TargetLibraryInfo *TLI_)
44 : AC(AC_), DL(DL_), TLI(TLI_) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010045 LazyValueInfo(LazyValueInfo &&Arg)
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020046 : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), PImpl(Arg.PImpl) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010047 Arg.PImpl = nullptr;
48 }
49 LazyValueInfo &operator=(LazyValueInfo &&Arg) {
50 releaseMemory();
51 AC = Arg.AC;
52 DL = Arg.DL;
53 TLI = Arg.TLI;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010054 PImpl = Arg.PImpl;
55 Arg.PImpl = nullptr;
56 return *this;
57 }
58
59 /// This is used to return true/false/dunno results.
60 enum Tristate {
61 Unknown = -1, False = 0, True = 1
62 };
63
64 // Public query interface.
65
66 /// Determine whether the specified value comparison with a constant is known
67 /// to be true or false on the specified CFG edge.
68 /// Pred is a CmpInst predicate.
69 Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
70 BasicBlock *FromBB, BasicBlock *ToBB,
71 Instruction *CxtI = nullptr);
72
73 /// Determine whether the specified value comparison with a constant is known
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020074 /// to be true or false at the specified instruction.
75 /// \p Pred is a CmpInst predicate. If \p UseBlockValue is true, the block
76 /// value is also taken into account.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010077 Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020078 Instruction *CxtI, bool UseBlockValue = false);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010079
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020080 /// Determine whether the specified value is known to be a constant at the
81 /// specified instruction. Return null if not.
82 Constant *getConstant(Value *V, Instruction *CxtI);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083
84 /// Return the ConstantRange constraint that is known to hold for the
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020085 /// specified value at the specified instruction. This may only be called
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010086 /// on integer-typed Values.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020087 ConstantRange getConstantRange(Value *V, Instruction *CxtI,
88 bool UndefAllowed = true);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010089
90 /// Determine whether the specified value is known to be a
91 /// constant on the specified edge. Return null if not.
92 Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
93 Instruction *CxtI = nullptr);
94
95 /// Return the ConstantRage constraint that is known to hold for the
96 /// specified value on the specified edge. This may be only be called
97 /// on integer-typed Values.
98 ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
99 BasicBlock *ToBB,
100 Instruction *CxtI = nullptr);
101
102 /// Inform the analysis cache that we have threaded an edge from
103 /// PredBB to OldSucc to be from PredBB to NewSucc instead.
104 void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
105
106 /// Inform the analysis cache that we have erased a block.
107 void eraseBlock(BasicBlock *BB);
108
109 /// Print the \LazyValueInfo Analysis.
110 /// We pass in the DTree that is required for identifying which basic blocks
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200111 /// we can solve/print for, in the LVIPrinter.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100112 void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
113
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100114 // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
115 void releaseMemory();
116
117 /// Handle invalidation events in the new pass manager.
118 bool invalidate(Function &F, const PreservedAnalyses &PA,
119 FunctionAnalysisManager::Invalidator &Inv);
120};
121
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100122/// Analysis to compute lazy value information.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100123class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> {
124public:
125 typedef LazyValueInfo Result;
126 Result run(Function &F, FunctionAnalysisManager &FAM);
127
128private:
129 static AnalysisKey Key;
130 friend struct AnalysisInfoMixin<LazyValueAnalysis>;
131};
132
133/// Wrapper around LazyValueInfo.
134class LazyValueInfoWrapperPass : public FunctionPass {
135 LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete;
136 void operator=(const LazyValueInfoWrapperPass&) = delete;
137public:
138 static char ID;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200139 LazyValueInfoWrapperPass();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100140 ~LazyValueInfoWrapperPass() override {
141 assert(!Info.PImpl && "releaseMemory not called");
142 }
143
144 LazyValueInfo &getLVI();
145
146 void getAnalysisUsage(AnalysisUsage &AU) const override;
147 void releaseMemory() override;
148 bool runOnFunction(Function &F) override;
149private:
150 LazyValueInfo Info;
151};
152
153} // end namespace llvm
154
155#endif
156