xref: /aosp_15_r20/external/llvm/include/llvm/Transforms/Utils/Evaluator.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1 //===-- Evaluator.h - LLVM IR evaluator -------------------------*- 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 // Function evaluator for LLVM IR.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_TRANSFORMS_UTILS_EVALUATOR_H
15 #define LLVM_TRANSFORMS_UTILS_EVALUATOR_H
16 
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/SmallPtrSet.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/IR/BasicBlock.h"
21 #include "llvm/IR/Constant.h"
22 #include "llvm/IR/GlobalVariable.h"
23 
24 #include <deque>
25 #include <memory>
26 
27 namespace llvm {
28 
29 class DataLayout;
30 class Function;
31 class TargetLibraryInfo;
32 
33 /// This class evaluates LLVM IR, producing the Constant representing each SSA
34 /// instruction.  Changes to global variables are stored in a mapping that can
35 /// be iterated over after the evaluation is complete.  Once an evaluation call
36 /// fails, the evaluation object should not be reused.
37 class Evaluator {
38 public:
Evaluator(const DataLayout & DL,const TargetLibraryInfo * TLI)39   Evaluator(const DataLayout &DL, const TargetLibraryInfo *TLI)
40       : DL(DL), TLI(TLI) {
41     ValueStack.emplace_back();
42   }
43 
~Evaluator()44   ~Evaluator() {
45     for (auto &Tmp : AllocaTmps)
46       // If there are still users of the alloca, the program is doing something
47       // silly, e.g. storing the address of the alloca somewhere and using it
48       // later.  Since this is undefined, we'll just make it be null.
49       if (!Tmp->use_empty())
50         Tmp->replaceAllUsesWith(Constant::getNullValue(Tmp->getType()));
51   }
52 
53   /// Evaluate a call to function F, returning true if successful, false if we
54   /// can't evaluate it.  ActualArgs contains the formal arguments for the
55   /// function.
56   bool EvaluateFunction(Function *F, Constant *&RetVal,
57                         const SmallVectorImpl<Constant*> &ActualArgs);
58 
59   /// Evaluate all instructions in block BB, returning true if successful, false
60   /// if we can't evaluate it.  NewBB returns the next BB that control flows
61   /// into, or null upon return.
62   bool EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB);
63 
getVal(Value * V)64   Constant *getVal(Value *V) {
65     if (Constant *CV = dyn_cast<Constant>(V)) return CV;
66     Constant *R = ValueStack.back().lookup(V);
67     assert(R && "Reference to an uncomputed value!");
68     return R;
69   }
70 
setVal(Value * V,Constant * C)71   void setVal(Value *V, Constant *C) {
72     ValueStack.back()[V] = C;
73   }
74 
getMutatedMemory()75   const DenseMap<Constant*, Constant*> &getMutatedMemory() const {
76     return MutatedMemory;
77   }
78 
getInvariants()79   const SmallPtrSetImpl<GlobalVariable*> &getInvariants() const {
80     return Invariants;
81   }
82 
83 private:
84   Constant *ComputeLoadResult(Constant *P);
85 
86   /// As we compute SSA register values, we store their contents here. The back
87   /// of the deque contains the current function and the stack contains the
88   /// values in the calling frames.
89   std::deque<DenseMap<Value*, Constant*>> ValueStack;
90 
91   /// This is used to detect recursion.  In pathological situations we could hit
92   /// exponential behavior, but at least there is nothing unbounded.
93   SmallVector<Function*, 4> CallStack;
94 
95   /// For each store we execute, we update this map.  Loads check this to get
96   /// the most up-to-date value.  If evaluation is successful, this state is
97   /// committed to the process.
98   DenseMap<Constant*, Constant*> MutatedMemory;
99 
100   /// To 'execute' an alloca, we create a temporary global variable to represent
101   /// its body.  This vector is needed so we can delete the temporary globals
102   /// when we are done.
103   SmallVector<std::unique_ptr<GlobalVariable>, 32> AllocaTmps;
104 
105   /// These global variables have been marked invariant by the static
106   /// constructor.
107   SmallPtrSet<GlobalVariable*, 8> Invariants;
108 
109   /// These are constants we have checked and know to be simple enough to live
110   /// in a static initializer of a global.
111   SmallPtrSet<Constant*, 8> SimpleConstants;
112 
113   const DataLayout &DL;
114   const TargetLibraryInfo *TLI;
115 };
116 
117 }
118 
119 #endif
120