1*cb58558cSMatthew Simpson //===- CalledValuePropagation.cpp - Propagate called values -----*- C++ -*-===//
2*cb58558cSMatthew Simpson //
3*cb58558cSMatthew Simpson //                     The LLVM Compiler Infrastructure
4*cb58558cSMatthew Simpson //
5*cb58558cSMatthew Simpson // This file is distributed under the University of Illinois Open Source
6*cb58558cSMatthew Simpson // License. See LICENSE.TXT for details.
7*cb58558cSMatthew Simpson //
8*cb58558cSMatthew Simpson //===----------------------------------------------------------------------===//
9*cb58558cSMatthew Simpson //
10*cb58558cSMatthew Simpson // This file implements a transformation that attaches !callees metadata to
11*cb58558cSMatthew Simpson // indirect call sites. For a given call site, the metadata, if present,
12*cb58558cSMatthew Simpson // indicates the set of functions the call site could possibly target at
13*cb58558cSMatthew Simpson // run-time. This metadata is added to indirect call sites when the set of
14*cb58558cSMatthew Simpson // possible targets can be determined by analysis and is known to be small. The
15*cb58558cSMatthew Simpson // analysis driving the transformation is similar to constant propagation and
16*cb58558cSMatthew Simpson // makes uses of the generic sparse propagation solver.
17*cb58558cSMatthew Simpson //
18*cb58558cSMatthew Simpson //===----------------------------------------------------------------------===//
19*cb58558cSMatthew Simpson 
20*cb58558cSMatthew Simpson #include "llvm/Transforms/IPO/CalledValuePropagation.h"
21*cb58558cSMatthew Simpson #include "llvm/Analysis/SparsePropagation.h"
22*cb58558cSMatthew Simpson #include "llvm/Analysis/ValueLatticeUtils.h"
23*cb58558cSMatthew Simpson #include "llvm/IR/InstVisitor.h"
24*cb58558cSMatthew Simpson #include "llvm/IR/MDBuilder.h"
25*cb58558cSMatthew Simpson #include "llvm/Transforms/IPO.h"
26*cb58558cSMatthew Simpson using namespace llvm;
27*cb58558cSMatthew Simpson 
28*cb58558cSMatthew Simpson #define DEBUG_TYPE "called-value-propagation"
29*cb58558cSMatthew Simpson 
30*cb58558cSMatthew Simpson /// The maximum number of functions to track per lattice value. Once the number
31*cb58558cSMatthew Simpson /// of functions a call site can possibly target exceeds this threshold, it's
32*cb58558cSMatthew Simpson /// lattice value becomes overdefined. The number of possible lattice values is
33*cb58558cSMatthew Simpson /// bounded by Ch(F, M), where F is the number of functions in the module and M
34*cb58558cSMatthew Simpson /// is MaxFunctionsPerValue. As such, this value should be kept very small. We
35*cb58558cSMatthew Simpson /// likely can't do anything useful for call sites with a large number of
36*cb58558cSMatthew Simpson /// possible targets, anyway.
37*cb58558cSMatthew Simpson static cl::opt<unsigned> MaxFunctionsPerValue(
38*cb58558cSMatthew Simpson     "cvp-max-functions-per-value", cl::Hidden, cl::init(4),
39*cb58558cSMatthew Simpson     cl::desc("The maximum number of functions to track per lattice value"));
40*cb58558cSMatthew Simpson 
41*cb58558cSMatthew Simpson namespace {
42*cb58558cSMatthew Simpson /// To enable interprocedural analysis, we assign LLVM values to the following
43*cb58558cSMatthew Simpson /// groups. The register group represents SSA registers, the return group
44*cb58558cSMatthew Simpson /// represents the return values of functions, and the memory group represents
45*cb58558cSMatthew Simpson /// in-memory values. An LLVM Value can technically be in more than one group.
46*cb58558cSMatthew Simpson /// It's necessary to distinguish these groups so we can, for example, track a
47*cb58558cSMatthew Simpson /// global variable separately from the value stored at its location.
48*cb58558cSMatthew Simpson enum class IPOGrouping { Register, Return, Memory };
49*cb58558cSMatthew Simpson 
50*cb58558cSMatthew Simpson /// Our LatticeKeys are PointerIntPairs composed of LLVM values and groupings.
51*cb58558cSMatthew Simpson using CVPLatticeKey = PointerIntPair<Value *, 2, IPOGrouping>;
52*cb58558cSMatthew Simpson 
53*cb58558cSMatthew Simpson /// The lattice value type used by our custom lattice function. It holds the
54*cb58558cSMatthew Simpson /// lattice state, and a set of functions.
55*cb58558cSMatthew Simpson class CVPLatticeVal {
56*cb58558cSMatthew Simpson public:
57*cb58558cSMatthew Simpson   /// The states of the lattice values. Only the FunctionSet state is
58*cb58558cSMatthew Simpson   /// interesting. It indicates the set of functions to which an LLVM value may
59*cb58558cSMatthew Simpson   /// refer.
60*cb58558cSMatthew Simpson   enum CVPLatticeStateTy { Undefined, FunctionSet, Overdefined, Untracked };
61*cb58558cSMatthew Simpson 
62*cb58558cSMatthew Simpson   /// Comparator for sorting the functions set. We want to keep the order
63*cb58558cSMatthew Simpson   /// deterministic for testing, etc.
64*cb58558cSMatthew Simpson   struct Compare {
65*cb58558cSMatthew Simpson     bool operator()(const Function *LHS, const Function *RHS) const {
66*cb58558cSMatthew Simpson       return LHS->getName() < RHS->getName();
67*cb58558cSMatthew Simpson     }
68*cb58558cSMatthew Simpson   };
69*cb58558cSMatthew Simpson 
70*cb58558cSMatthew Simpson   CVPLatticeVal() : LatticeState(Undefined) {}
71*cb58558cSMatthew Simpson   CVPLatticeVal(CVPLatticeStateTy LatticeState) : LatticeState(LatticeState) {}
72*cb58558cSMatthew Simpson   CVPLatticeVal(std::set<Function *, Compare> &&Functions)
73*cb58558cSMatthew Simpson       : LatticeState(FunctionSet), Functions(Functions) {}
74*cb58558cSMatthew Simpson 
75*cb58558cSMatthew Simpson   /// Get a reference to the functions held by this lattice value. The number
76*cb58558cSMatthew Simpson   /// of functions will be zero for states other than FunctionSet.
77*cb58558cSMatthew Simpson   const std::set<Function *, Compare> &getFunctions() const {
78*cb58558cSMatthew Simpson     return Functions;
79*cb58558cSMatthew Simpson   }
80*cb58558cSMatthew Simpson 
81*cb58558cSMatthew Simpson   /// Returns true if the lattice value is in the FunctionSet state.
82*cb58558cSMatthew Simpson   bool isFunctionSet() const { return LatticeState == FunctionSet; }
83*cb58558cSMatthew Simpson 
84*cb58558cSMatthew Simpson   bool operator==(const CVPLatticeVal &RHS) const {
85*cb58558cSMatthew Simpson     return LatticeState == RHS.LatticeState && Functions == RHS.Functions;
86*cb58558cSMatthew Simpson   }
87*cb58558cSMatthew Simpson 
88*cb58558cSMatthew Simpson   bool operator!=(const CVPLatticeVal &RHS) const {
89*cb58558cSMatthew Simpson     return LatticeState != RHS.LatticeState || Functions != RHS.Functions;
90*cb58558cSMatthew Simpson   }
91*cb58558cSMatthew Simpson 
92*cb58558cSMatthew Simpson private:
93*cb58558cSMatthew Simpson   /// Holds the state this lattice value is in.
94*cb58558cSMatthew Simpson   CVPLatticeStateTy LatticeState;
95*cb58558cSMatthew Simpson 
96*cb58558cSMatthew Simpson   /// Holds functions indicating the possible targets of call sites. This set
97*cb58558cSMatthew Simpson   /// is empty for lattice values in the undefined, overdefined, and untracked
98*cb58558cSMatthew Simpson   /// states. The maximum size of the set is controlled by
99*cb58558cSMatthew Simpson   /// MaxFunctionsPerValue. Since most LLVM values are expected to be in
100*cb58558cSMatthew Simpson   /// uninteresting states (i.e., overdefined), CVPLatticeVal objects should be
101*cb58558cSMatthew Simpson   /// small and efficiently copyable.
102*cb58558cSMatthew Simpson   std::set<Function *, Compare> Functions;
103*cb58558cSMatthew Simpson };
104*cb58558cSMatthew Simpson 
105*cb58558cSMatthew Simpson /// The custom lattice function used by the generic sparse propagation solver.
106*cb58558cSMatthew Simpson /// It handles merging lattice values and computing new lattice values for
107*cb58558cSMatthew Simpson /// constants, arguments, values returned from trackable functions, and values
108*cb58558cSMatthew Simpson /// located in trackable global variables. It also computes the lattice values
109*cb58558cSMatthew Simpson /// that change as a result of executing instructions.
110*cb58558cSMatthew Simpson class CVPLatticeFunc
111*cb58558cSMatthew Simpson     : public AbstractLatticeFunction<CVPLatticeKey, CVPLatticeVal> {
112*cb58558cSMatthew Simpson public:
113*cb58558cSMatthew Simpson   CVPLatticeFunc()
114*cb58558cSMatthew Simpson       : AbstractLatticeFunction(CVPLatticeVal(CVPLatticeVal::Undefined),
115*cb58558cSMatthew Simpson                                 CVPLatticeVal(CVPLatticeVal::Overdefined),
116*cb58558cSMatthew Simpson                                 CVPLatticeVal(CVPLatticeVal::Untracked)) {}
117*cb58558cSMatthew Simpson 
118*cb58558cSMatthew Simpson   /// Compute and return a CVPLatticeVal for the given CVPLatticeKey.
119*cb58558cSMatthew Simpson   CVPLatticeVal ComputeLatticeVal(CVPLatticeKey Key) override {
120*cb58558cSMatthew Simpson     switch (Key.getInt()) {
121*cb58558cSMatthew Simpson     case IPOGrouping::Register:
122*cb58558cSMatthew Simpson       if (isa<Instruction>(Key.getPointer())) {
123*cb58558cSMatthew Simpson         return getUndefVal();
124*cb58558cSMatthew Simpson       } else if (auto *A = dyn_cast<Argument>(Key.getPointer())) {
125*cb58558cSMatthew Simpson         if (canTrackArgumentsInterprocedurally(A->getParent()))
126*cb58558cSMatthew Simpson           return getUndefVal();
127*cb58558cSMatthew Simpson       } else if (auto *C = dyn_cast<Constant>(Key.getPointer())) {
128*cb58558cSMatthew Simpson         return computeConstant(C);
129*cb58558cSMatthew Simpson       }
130*cb58558cSMatthew Simpson       return getOverdefinedVal();
131*cb58558cSMatthew Simpson     case IPOGrouping::Memory:
132*cb58558cSMatthew Simpson     case IPOGrouping::Return:
133*cb58558cSMatthew Simpson       if (auto *GV = dyn_cast<GlobalVariable>(Key.getPointer())) {
134*cb58558cSMatthew Simpson         if (canTrackGlobalVariableInterprocedurally(GV))
135*cb58558cSMatthew Simpson           return computeConstant(GV->getInitializer());
136*cb58558cSMatthew Simpson       } else if (auto *F = cast<Function>(Key.getPointer()))
137*cb58558cSMatthew Simpson         if (canTrackReturnsInterprocedurally(F))
138*cb58558cSMatthew Simpson           return getUndefVal();
139*cb58558cSMatthew Simpson     }
140*cb58558cSMatthew Simpson     return getOverdefinedVal();
141*cb58558cSMatthew Simpson   }
142*cb58558cSMatthew Simpson 
143*cb58558cSMatthew Simpson   /// Merge the two given lattice values. The interesting cases are merging two
144*cb58558cSMatthew Simpson   /// FunctionSet values and a FunctionSet value with an Undefined value. For
145*cb58558cSMatthew Simpson   /// these cases, we simply union the function sets. If the size of the union
146*cb58558cSMatthew Simpson   /// is greater than the maximum functions we track, the merged value is
147*cb58558cSMatthew Simpson   /// overdefined.
148*cb58558cSMatthew Simpson   CVPLatticeVal MergeValues(CVPLatticeVal X, CVPLatticeVal Y) override {
149*cb58558cSMatthew Simpson     if (X == getOverdefinedVal() || Y == getOverdefinedVal())
150*cb58558cSMatthew Simpson       return getOverdefinedVal();
151*cb58558cSMatthew Simpson     if (X == getUndefVal() && Y == getUndefVal())
152*cb58558cSMatthew Simpson       return getUndefVal();
153*cb58558cSMatthew Simpson     std::set<Function *, CVPLatticeVal::Compare> Union;
154*cb58558cSMatthew Simpson     std::set_union(X.getFunctions().begin(), X.getFunctions().end(),
155*cb58558cSMatthew Simpson                    Y.getFunctions().begin(), Y.getFunctions().end(),
156*cb58558cSMatthew Simpson                    std::inserter(Union, Union.begin()));
157*cb58558cSMatthew Simpson     if (Union.size() > MaxFunctionsPerValue)
158*cb58558cSMatthew Simpson       return getOverdefinedVal();
159*cb58558cSMatthew Simpson     return CVPLatticeVal(std::move(Union));
160*cb58558cSMatthew Simpson   }
161*cb58558cSMatthew Simpson 
162*cb58558cSMatthew Simpson   /// Compute the lattice values that change as a result of executing the given
163*cb58558cSMatthew Simpson   /// instruction. The changed values are stored in \p ChangedValues. We handle
164*cb58558cSMatthew Simpson   /// just a few kinds of instructions since we're only propagating values that
165*cb58558cSMatthew Simpson   /// can be called.
166*cb58558cSMatthew Simpson   void ComputeInstructionState(
167*cb58558cSMatthew Simpson       Instruction &I, DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
168*cb58558cSMatthew Simpson       SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) override {
169*cb58558cSMatthew Simpson     switch (I.getOpcode()) {
170*cb58558cSMatthew Simpson     case Instruction::Call:
171*cb58558cSMatthew Simpson       return visitCallSite(cast<CallInst>(&I), ChangedValues, SS);
172*cb58558cSMatthew Simpson     case Instruction::Invoke:
173*cb58558cSMatthew Simpson       return visitCallSite(cast<InvokeInst>(&I), ChangedValues, SS);
174*cb58558cSMatthew Simpson     case Instruction::Load:
175*cb58558cSMatthew Simpson       return visitLoad(*cast<LoadInst>(&I), ChangedValues, SS);
176*cb58558cSMatthew Simpson     case Instruction::Ret:
177*cb58558cSMatthew Simpson       return visitReturn(*cast<ReturnInst>(&I), ChangedValues, SS);
178*cb58558cSMatthew Simpson     case Instruction::Select:
179*cb58558cSMatthew Simpson       return visitSelect(*cast<SelectInst>(&I), ChangedValues, SS);
180*cb58558cSMatthew Simpson     case Instruction::Store:
181*cb58558cSMatthew Simpson       return visitStore(*cast<StoreInst>(&I), ChangedValues, SS);
182*cb58558cSMatthew Simpson     default:
183*cb58558cSMatthew Simpson       return visitInst(I, ChangedValues, SS);
184*cb58558cSMatthew Simpson     }
185*cb58558cSMatthew Simpson   }
186*cb58558cSMatthew Simpson 
187*cb58558cSMatthew Simpson   /// Print the given CVPLatticeVal to the specified stream.
188*cb58558cSMatthew Simpson   void PrintLatticeVal(CVPLatticeVal LV, raw_ostream &OS) override {
189*cb58558cSMatthew Simpson     if (LV == getUndefVal())
190*cb58558cSMatthew Simpson       OS << "Undefined  ";
191*cb58558cSMatthew Simpson     else if (LV == getOverdefinedVal())
192*cb58558cSMatthew Simpson       OS << "Overdefined";
193*cb58558cSMatthew Simpson     else if (LV == getUntrackedVal())
194*cb58558cSMatthew Simpson       OS << "Untracked  ";
195*cb58558cSMatthew Simpson     else
196*cb58558cSMatthew Simpson       OS << "FunctionSet";
197*cb58558cSMatthew Simpson   }
198*cb58558cSMatthew Simpson 
199*cb58558cSMatthew Simpson   /// Print the given CVPLatticeKey to the specified stream.
200*cb58558cSMatthew Simpson   void PrintLatticeKey(CVPLatticeKey Key, raw_ostream &OS) override {
201*cb58558cSMatthew Simpson     if (Key.getInt() == IPOGrouping::Register)
202*cb58558cSMatthew Simpson       OS << "<reg> ";
203*cb58558cSMatthew Simpson     else if (Key.getInt() == IPOGrouping::Memory)
204*cb58558cSMatthew Simpson       OS << "<mem> ";
205*cb58558cSMatthew Simpson     else if (Key.getInt() == IPOGrouping::Return)
206*cb58558cSMatthew Simpson       OS << "<ret> ";
207*cb58558cSMatthew Simpson     if (isa<Function>(Key.getPointer()))
208*cb58558cSMatthew Simpson       OS << Key.getPointer()->getName();
209*cb58558cSMatthew Simpson     else
210*cb58558cSMatthew Simpson       OS << *Key.getPointer();
211*cb58558cSMatthew Simpson   }
212*cb58558cSMatthew Simpson 
213*cb58558cSMatthew Simpson   /// We collect a set of indirect calls when visiting call sites. This method
214*cb58558cSMatthew Simpson   /// returns a reference to that set.
215*cb58558cSMatthew Simpson   SmallPtrSetImpl<Instruction *> &getIndirectCalls() { return IndirectCalls; }
216*cb58558cSMatthew Simpson 
217*cb58558cSMatthew Simpson private:
218*cb58558cSMatthew Simpson   /// Holds the indirect calls we encounter during the analysis. We will attach
219*cb58558cSMatthew Simpson   /// metadata to these calls after the analysis indicating the functions the
220*cb58558cSMatthew Simpson   /// calls can possibly target.
221*cb58558cSMatthew Simpson   SmallPtrSet<Instruction *, 32> IndirectCalls;
222*cb58558cSMatthew Simpson 
223*cb58558cSMatthew Simpson   /// Compute a new lattice value for the given constant. The constant, after
224*cb58558cSMatthew Simpson   /// stripping any pointer casts, should be a Function. We ignore null
225*cb58558cSMatthew Simpson   /// pointers as an optimization, since calling these values is undefined
226*cb58558cSMatthew Simpson   /// behavior.
227*cb58558cSMatthew Simpson   CVPLatticeVal computeConstant(Constant *C) {
228*cb58558cSMatthew Simpson     if (isa<ConstantPointerNull>(C))
229*cb58558cSMatthew Simpson       return CVPLatticeVal(CVPLatticeVal::FunctionSet);
230*cb58558cSMatthew Simpson     if (auto *F = dyn_cast<Function>(C->stripPointerCasts()))
231*cb58558cSMatthew Simpson       return CVPLatticeVal({F});
232*cb58558cSMatthew Simpson     return getOverdefinedVal();
233*cb58558cSMatthew Simpson   }
234*cb58558cSMatthew Simpson 
235*cb58558cSMatthew Simpson   /// Handle return instructions. The function's return state is the merge of
236*cb58558cSMatthew Simpson   /// the returned value state and the function's return state.
237*cb58558cSMatthew Simpson   void visitReturn(ReturnInst &I,
238*cb58558cSMatthew Simpson                    DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
239*cb58558cSMatthew Simpson                    SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
240*cb58558cSMatthew Simpson     Function *F = I.getParent()->getParent();
241*cb58558cSMatthew Simpson     if (F->getReturnType()->isVoidTy())
242*cb58558cSMatthew Simpson       return;
243*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(I.getReturnValue(), IPOGrouping::Register);
244*cb58558cSMatthew Simpson     auto RetF = CVPLatticeKey(F, IPOGrouping::Return);
245*cb58558cSMatthew Simpson     ChangedValues[RetF] =
246*cb58558cSMatthew Simpson         MergeValues(SS.getValueState(RegI), SS.getValueState(RetF));
247*cb58558cSMatthew Simpson   }
248*cb58558cSMatthew Simpson 
249*cb58558cSMatthew Simpson   /// Handle call sites. The state of a called function's formal arguments is
250*cb58558cSMatthew Simpson   /// the merge of the argument state with the call sites corresponding actual
251*cb58558cSMatthew Simpson   /// argument state. The call site state is the merge of the call site state
252*cb58558cSMatthew Simpson   /// with the returned value state of the called function.
253*cb58558cSMatthew Simpson   void visitCallSite(CallSite CS,
254*cb58558cSMatthew Simpson                      DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
255*cb58558cSMatthew Simpson                      SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
256*cb58558cSMatthew Simpson     Function *F = CS.getCalledFunction();
257*cb58558cSMatthew Simpson     Instruction *I = CS.getInstruction();
258*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(I, IPOGrouping::Register);
259*cb58558cSMatthew Simpson 
260*cb58558cSMatthew Simpson     // If this is an indirect call, save it so we can quickly revisit it when
261*cb58558cSMatthew Simpson     // attaching metadata.
262*cb58558cSMatthew Simpson     if (!F)
263*cb58558cSMatthew Simpson       IndirectCalls.insert(I);
264*cb58558cSMatthew Simpson 
265*cb58558cSMatthew Simpson     // If we can't track the function's return values, there's nothing to do.
266*cb58558cSMatthew Simpson     if (!F || !canTrackReturnsInterprocedurally(F)) {
267*cb58558cSMatthew Simpson       ChangedValues[RegI] = getOverdefinedVal();
268*cb58558cSMatthew Simpson       return;
269*cb58558cSMatthew Simpson     }
270*cb58558cSMatthew Simpson 
271*cb58558cSMatthew Simpson     // Inform the solver that the called function is executable, and perform
272*cb58558cSMatthew Simpson     // the merges for the arguments and return value.
273*cb58558cSMatthew Simpson     SS.MarkBlockExecutable(&F->front());
274*cb58558cSMatthew Simpson     auto RetF = CVPLatticeKey(F, IPOGrouping::Return);
275*cb58558cSMatthew Simpson     for (Argument &A : F->args()) {
276*cb58558cSMatthew Simpson       auto RegFormal = CVPLatticeKey(&A, IPOGrouping::Register);
277*cb58558cSMatthew Simpson       auto RegActual =
278*cb58558cSMatthew Simpson           CVPLatticeKey(CS.getArgument(A.getArgNo()), IPOGrouping::Register);
279*cb58558cSMatthew Simpson       ChangedValues[RegFormal] =
280*cb58558cSMatthew Simpson           MergeValues(SS.getValueState(RegFormal), SS.getValueState(RegActual));
281*cb58558cSMatthew Simpson     }
282*cb58558cSMatthew Simpson     ChangedValues[RegI] =
283*cb58558cSMatthew Simpson         MergeValues(SS.getValueState(RegI), SS.getValueState(RetF));
284*cb58558cSMatthew Simpson   }
285*cb58558cSMatthew Simpson 
286*cb58558cSMatthew Simpson   /// Handle select instructions. The select instruction state is the merge the
287*cb58558cSMatthew Simpson   /// true and false value states.
288*cb58558cSMatthew Simpson   void visitSelect(SelectInst &I,
289*cb58558cSMatthew Simpson                    DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
290*cb58558cSMatthew Simpson                    SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
291*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(&I, IPOGrouping::Register);
292*cb58558cSMatthew Simpson     auto RegT = CVPLatticeKey(I.getTrueValue(), IPOGrouping::Register);
293*cb58558cSMatthew Simpson     auto RegF = CVPLatticeKey(I.getFalseValue(), IPOGrouping::Register);
294*cb58558cSMatthew Simpson     ChangedValues[RegI] =
295*cb58558cSMatthew Simpson         MergeValues(SS.getValueState(RegT), SS.getValueState(RegF));
296*cb58558cSMatthew Simpson   }
297*cb58558cSMatthew Simpson 
298*cb58558cSMatthew Simpson   /// Handle load instructions. If the pointer operand of the load is a global
299*cb58558cSMatthew Simpson   /// variable, we attempt to track the value. The loaded value state is the
300*cb58558cSMatthew Simpson   /// merge of the loaded value state with the global variable state.
301*cb58558cSMatthew Simpson   void visitLoad(LoadInst &I,
302*cb58558cSMatthew Simpson                  DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
303*cb58558cSMatthew Simpson                  SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
304*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(&I, IPOGrouping::Register);
305*cb58558cSMatthew Simpson     if (auto *GV = dyn_cast<GlobalVariable>(I.getPointerOperand())) {
306*cb58558cSMatthew Simpson       auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
307*cb58558cSMatthew Simpson       ChangedValues[RegI] =
308*cb58558cSMatthew Simpson           MergeValues(SS.getValueState(RegI), SS.getValueState(MemGV));
309*cb58558cSMatthew Simpson     } else {
310*cb58558cSMatthew Simpson       ChangedValues[RegI] = getOverdefinedVal();
311*cb58558cSMatthew Simpson     }
312*cb58558cSMatthew Simpson   }
313*cb58558cSMatthew Simpson 
314*cb58558cSMatthew Simpson   /// Handle store instructions. If the pointer operand of the store is a
315*cb58558cSMatthew Simpson   /// global variable, we attempt to track the value. The global variable state
316*cb58558cSMatthew Simpson   /// is the merge of the stored value state with the global variable state.
317*cb58558cSMatthew Simpson   void visitStore(StoreInst &I,
318*cb58558cSMatthew Simpson                   DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
319*cb58558cSMatthew Simpson                   SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
320*cb58558cSMatthew Simpson     auto *GV = dyn_cast<GlobalVariable>(I.getPointerOperand());
321*cb58558cSMatthew Simpson     if (!GV)
322*cb58558cSMatthew Simpson       return;
323*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(I.getValueOperand(), IPOGrouping::Register);
324*cb58558cSMatthew Simpson     auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
325*cb58558cSMatthew Simpson     ChangedValues[MemGV] =
326*cb58558cSMatthew Simpson         MergeValues(SS.getValueState(RegI), SS.getValueState(MemGV));
327*cb58558cSMatthew Simpson   }
328*cb58558cSMatthew Simpson 
329*cb58558cSMatthew Simpson   /// Handle all other instructions. All other instructions are marked
330*cb58558cSMatthew Simpson   /// overdefined.
331*cb58558cSMatthew Simpson   void visitInst(Instruction &I,
332*cb58558cSMatthew Simpson                  DenseMap<CVPLatticeKey, CVPLatticeVal> &ChangedValues,
333*cb58558cSMatthew Simpson                  SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
334*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(&I, IPOGrouping::Register);
335*cb58558cSMatthew Simpson     ChangedValues[RegI] = getOverdefinedVal();
336*cb58558cSMatthew Simpson   }
337*cb58558cSMatthew Simpson };
338*cb58558cSMatthew Simpson } // namespace
339*cb58558cSMatthew Simpson 
340*cb58558cSMatthew Simpson namespace llvm {
341*cb58558cSMatthew Simpson /// A specialization of LatticeKeyInfo for CVPLatticeKeys. The generic solver
342*cb58558cSMatthew Simpson /// must translate between LatticeKeys and LLVM Values when adding Values to
343*cb58558cSMatthew Simpson /// its work list and inspecting the state of control-flow related values.
344*cb58558cSMatthew Simpson template <> struct LatticeKeyInfo<CVPLatticeKey> {
345*cb58558cSMatthew Simpson   static inline Value *getValueFromLatticeKey(CVPLatticeKey Key) {
346*cb58558cSMatthew Simpson     return Key.getPointer();
347*cb58558cSMatthew Simpson   }
348*cb58558cSMatthew Simpson   static inline CVPLatticeKey getLatticeKeyFromValue(Value *V) {
349*cb58558cSMatthew Simpson     return CVPLatticeKey(V, IPOGrouping::Register);
350*cb58558cSMatthew Simpson   }
351*cb58558cSMatthew Simpson };
352*cb58558cSMatthew Simpson } // namespace llvm
353*cb58558cSMatthew Simpson 
354*cb58558cSMatthew Simpson static bool runCVP(Module &M) {
355*cb58558cSMatthew Simpson   // Our custom lattice function and generic sparse propagation solver.
356*cb58558cSMatthew Simpson   CVPLatticeFunc Lattice;
357*cb58558cSMatthew Simpson   SparseSolver<CVPLatticeKey, CVPLatticeVal> Solver(&Lattice);
358*cb58558cSMatthew Simpson 
359*cb58558cSMatthew Simpson   // For each function in the module, if we can't track its arguments, let the
360*cb58558cSMatthew Simpson   // generic solver assume it is executable.
361*cb58558cSMatthew Simpson   for (Function &F : M)
362*cb58558cSMatthew Simpson     if (!F.isDeclaration() && !canTrackArgumentsInterprocedurally(&F))
363*cb58558cSMatthew Simpson       Solver.MarkBlockExecutable(&F.front());
364*cb58558cSMatthew Simpson 
365*cb58558cSMatthew Simpson   // Solver our custom lattice. In doing so, we will also build a set of
366*cb58558cSMatthew Simpson   // indirect call sites.
367*cb58558cSMatthew Simpson   Solver.Solve();
368*cb58558cSMatthew Simpson 
369*cb58558cSMatthew Simpson   // Attach metadata to the indirect call sites that were collected indicating
370*cb58558cSMatthew Simpson   // the set of functions they can possibly target.
371*cb58558cSMatthew Simpson   bool Changed = false;
372*cb58558cSMatthew Simpson   MDBuilder MDB(M.getContext());
373*cb58558cSMatthew Simpson   for (Instruction *C : Lattice.getIndirectCalls()) {
374*cb58558cSMatthew Simpson     CallSite CS(C);
375*cb58558cSMatthew Simpson     auto RegI = CVPLatticeKey(CS.getCalledValue(), IPOGrouping::Register);
376*cb58558cSMatthew Simpson     CVPLatticeVal LV = Solver.getExistingValueState(RegI);
377*cb58558cSMatthew Simpson     if (!LV.isFunctionSet() || LV.getFunctions().empty())
378*cb58558cSMatthew Simpson       continue;
379*cb58558cSMatthew Simpson     MDNode *Callees = MDB.createCallees(SmallVector<Function *, 4>(
380*cb58558cSMatthew Simpson         LV.getFunctions().begin(), LV.getFunctions().end()));
381*cb58558cSMatthew Simpson     C->setMetadata(LLVMContext::MD_callees, Callees);
382*cb58558cSMatthew Simpson     Changed = true;
383*cb58558cSMatthew Simpson   }
384*cb58558cSMatthew Simpson 
385*cb58558cSMatthew Simpson   return Changed;
386*cb58558cSMatthew Simpson }
387*cb58558cSMatthew Simpson 
388*cb58558cSMatthew Simpson PreservedAnalyses CalledValuePropagationPass::run(Module &M,
389*cb58558cSMatthew Simpson                                                   ModuleAnalysisManager &) {
390*cb58558cSMatthew Simpson   runCVP(M);
391*cb58558cSMatthew Simpson   return PreservedAnalyses::all();
392*cb58558cSMatthew Simpson }
393*cb58558cSMatthew Simpson 
394*cb58558cSMatthew Simpson namespace {
395*cb58558cSMatthew Simpson class CalledValuePropagationLegacyPass : public ModulePass {
396*cb58558cSMatthew Simpson public:
397*cb58558cSMatthew Simpson   static char ID;
398*cb58558cSMatthew Simpson 
399*cb58558cSMatthew Simpson   void getAnalysisUsage(AnalysisUsage &AU) const override {
400*cb58558cSMatthew Simpson     AU.setPreservesAll();
401*cb58558cSMatthew Simpson   }
402*cb58558cSMatthew Simpson 
403*cb58558cSMatthew Simpson   CalledValuePropagationLegacyPass() : ModulePass(ID) {
404*cb58558cSMatthew Simpson     initializeCalledValuePropagationLegacyPassPass(
405*cb58558cSMatthew Simpson         *PassRegistry::getPassRegistry());
406*cb58558cSMatthew Simpson   }
407*cb58558cSMatthew Simpson 
408*cb58558cSMatthew Simpson   bool runOnModule(Module &M) override {
409*cb58558cSMatthew Simpson     if (skipModule(M))
410*cb58558cSMatthew Simpson       return false;
411*cb58558cSMatthew Simpson     return runCVP(M);
412*cb58558cSMatthew Simpson   }
413*cb58558cSMatthew Simpson };
414*cb58558cSMatthew Simpson } // namespace
415*cb58558cSMatthew Simpson 
416*cb58558cSMatthew Simpson char CalledValuePropagationLegacyPass::ID = 0;
417*cb58558cSMatthew Simpson INITIALIZE_PASS(CalledValuePropagationLegacyPass, "called-value-propagation",
418*cb58558cSMatthew Simpson                 "Called Value Propagation", false, false)
419*cb58558cSMatthew Simpson 
420*cb58558cSMatthew Simpson ModulePass *llvm::createCalledValuePropagationPass() {
421*cb58558cSMatthew Simpson   return new CalledValuePropagationLegacyPass();
422*cb58558cSMatthew Simpson }
423