LLVM 24.0.0git
CalledValuePropagation.cpp
Go to the documentation of this file.
1//===- CalledValuePropagation.cpp - Propagate called values -----*- C++ -*-===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a transformation that attaches !callees metadata to
10// indirect call sites. For a given call site, the metadata, if present,
11// indicates the set of functions the call site could possibly target at
12// run-time. This metadata is added to indirect call sites when the set of
13// possible targets can be determined by analysis and is known to be small. The
14// analysis driving the transformation is similar to constant propagation and
15// makes uses of the generic sparse propagation solver.
16//
17//===----------------------------------------------------------------------===//
18
20#include "IPOOptions.h"
23#include "llvm/IR/Constants.h"
24#include "llvm/IR/MDBuilder.h"
25#include "llvm/IR/Module.h"
26#include "llvm/Transforms/IPO.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE "called-value-propagation"
31
32namespace {
33/// To enable interprocedural analysis, we assign LLVM values to the following
34/// groups. The register group represents SSA registers, the return group
35/// represents the return values of functions, and the memory group represents
36/// in-memory values. An LLVM Value can technically be in more than one group.
37/// It's necessary to distinguish these groups so we can, for example, track a
38/// global variable separately from the value stored at its location.
39enum class IPOGrouping { Register, Return, Memory };
40
41/// Our LatticeKeys are PointerIntPairs composed of LLVM values and groupings.
42using CVPLatticeKey = PointerIntPair<Value *, 2, IPOGrouping>;
43
44/// The lattice value type used by our custom lattice function. It holds the
45/// lattice state, and a set of functions.
46class CVPLatticeVal {
47public:
48 /// The states of the lattice values. Only the FunctionSet state is
49 /// interesting. It indicates the set of functions to which an LLVM value may
50 /// refer.
51 enum CVPLatticeStateTy { Undefined, FunctionSet, Overdefined, Untracked };
52
53 /// Comparator for sorting the functions set. We want to keep the order
54 /// deterministic for testing, etc.
55 struct Compare {
56 bool operator()(const Function *LHS, const Function *RHS) const {
57 return LHS->getName() < RHS->getName();
58 }
59 };
60
61 CVPLatticeVal() = default;
62 CVPLatticeVal(CVPLatticeStateTy LatticeState) : LatticeState(LatticeState) {}
63 CVPLatticeVal(std::vector<Function *> &&Functions)
64 : LatticeState(FunctionSet), Functions(std::move(Functions)) {
65 assert(llvm::is_sorted(this->Functions, Compare()));
66 }
67
68 /// Get a reference to the functions held by this lattice value. The number
69 /// of functions will be zero for states other than FunctionSet.
70 const std::vector<Function *> &getFunctions() const {
71 return Functions;
72 }
73
74 /// Returns true if the lattice value is in the FunctionSet state.
75 bool isFunctionSet() const { return LatticeState == FunctionSet; }
76
77 bool operator==(const CVPLatticeVal &RHS) const {
78 return LatticeState == RHS.LatticeState && Functions == RHS.Functions;
79 }
80
81 bool operator!=(const CVPLatticeVal &RHS) const {
82 return LatticeState != RHS.LatticeState || Functions != RHS.Functions;
83 }
84
85private:
86 /// Holds the state this lattice value is in.
87 CVPLatticeStateTy LatticeState = Undefined;
88
89 /// Holds functions indicating the possible targets of call sites. This set
90 /// is empty for lattice values in the undefined, overdefined, and untracked
91 /// states. The maximum size of the set is controlled by
92 /// -cvp-max-functions-per-value. Since most LLVM values are expected to be in
93 /// uninteresting states (i.e., overdefined), CVPLatticeVal objects should be
94 /// small and efficiently copyable.
95 // FIXME: This could be a TinyPtrVector and/or merge with LatticeState.
96 std::vector<Function *> Functions;
97};
98
99/// The custom lattice function used by the generic sparse propagation solver.
100/// It handles merging lattice values and computing new lattice values for
101/// constants, arguments, values returned from trackable functions, and values
102/// located in trackable global variables. It also computes the lattice values
103/// that change as a result of executing instructions.
104class CVPLatticeFunc
105 : public AbstractLatticeFunction<CVPLatticeKey, CVPLatticeVal> {
106 const IPOOptions &Opts;
107
108public:
109 explicit CVPLatticeFunc(const IPOOptions &Opts)
110 : AbstractLatticeFunction(CVPLatticeVal(CVPLatticeVal::Undefined),
111 CVPLatticeVal(CVPLatticeVal::Overdefined),
112 CVPLatticeVal(CVPLatticeVal::Untracked)),
113 Opts(Opts) {}
114
115 /// Compute and return a CVPLatticeVal for the given CVPLatticeKey.
116 CVPLatticeVal ComputeLatticeVal(CVPLatticeKey Key) override {
117 switch (Key.getInt()) {
118 case IPOGrouping::Register:
119 if (isa<Instruction>(Key.getPointer())) {
120 return getUndefVal();
121 } else if (auto *A = dyn_cast<Argument>(Key.getPointer())) {
122 if (canTrackArgumentsInterprocedurally(A->getParent()))
123 return getUndefVal();
124 } else if (auto *C = dyn_cast<Constant>(Key.getPointer())) {
125 return computeConstant(C);
126 }
127 return getOverdefinedVal();
128 case IPOGrouping::Memory:
129 case IPOGrouping::Return:
130 if (auto *GV = dyn_cast<GlobalVariable>(Key.getPointer())) {
132 return computeConstant(GV->getInitializer());
133 } else if (auto *F = cast<Function>(Key.getPointer()))
135 return getUndefVal();
136 }
137 return getOverdefinedVal();
138 }
139
140 /// Merge the two given lattice values. The interesting cases are merging two
141 /// FunctionSet values and a FunctionSet value with an Undefined value. For
142 /// these cases, we simply union the function sets. If the size of the union
143 /// is greater than the maximum functions we track, the merged value is
144 /// overdefined.
145 CVPLatticeVal MergeValues(CVPLatticeVal X, CVPLatticeVal Y) override {
146 if (X == getOverdefinedVal() || Y == getOverdefinedVal())
147 return getOverdefinedVal();
148 if (X == getUndefVal() && Y == getUndefVal())
149 return getUndefVal();
150 std::vector<Function *> Union;
151 std::set_union(X.getFunctions().begin(), X.getFunctions().end(),
152 Y.getFunctions().begin(), Y.getFunctions().end(),
153 std::back_inserter(Union), CVPLatticeVal::Compare{});
154 if (Union.size() > Opts.cvp_max_functions_per_value)
155 return getOverdefinedVal();
156 return CVPLatticeVal(std::move(Union));
157 }
158
159 /// Compute the lattice values that change as a result of executing the given
160 /// instruction. The changed values are stored in \p ChangedValues. We handle
161 /// just a few kinds of instructions since we're only propagating values that
162 /// can be called.
163 void ComputeInstructionState(
164 Instruction &I,
167 switch (I.getOpcode()) {
168 case Instruction::Call:
169 case Instruction::Invoke:
170 return visitCallBase(cast<CallBase>(I), ChangedValues, SS);
171 case Instruction::Load:
172 return visitLoad(*cast<LoadInst>(&I), ChangedValues, SS);
173 case Instruction::Ret:
174 return visitReturn(*cast<ReturnInst>(&I), ChangedValues, SS);
175 case Instruction::Select:
176 return visitSelect(*cast<SelectInst>(&I), ChangedValues, SS);
177 case Instruction::Store:
178 return visitStore(*cast<StoreInst>(&I), ChangedValues, SS);
179 default:
180 return visitInst(I, ChangedValues, SS);
181 }
182 }
183
184 /// Print the given CVPLatticeVal to the specified stream.
185 void PrintLatticeVal(CVPLatticeVal LV, raw_ostream &OS) override {
186 if (LV == getUndefVal())
187 OS << "Undefined ";
188 else if (LV == getOverdefinedVal())
189 OS << "Overdefined";
190 else if (LV == getUntrackedVal())
191 OS << "Untracked ";
192 else
193 OS << "FunctionSet";
194 }
195
196 /// Print the given CVPLatticeKey to the specified stream.
197 void PrintLatticeKey(CVPLatticeKey Key, raw_ostream &OS) override {
198 if (Key.getInt() == IPOGrouping::Register)
199 OS << "<reg> ";
200 else if (Key.getInt() == IPOGrouping::Memory)
201 OS << "<mem> ";
202 else if (Key.getInt() == IPOGrouping::Return)
203 OS << "<ret> ";
204 if (isa<Function>(Key.getPointer()))
205 OS << Key.getPointer()->getName();
206 else
207 OS << *Key.getPointer();
208 }
209
210 /// We collect a set of indirect calls when visiting call sites. This method
211 /// returns a reference to that set.
212 SmallPtrSetImpl<CallBase *> &getIndirectCalls() { return IndirectCalls; }
213
214private:
215 /// Holds the indirect calls we encounter during the analysis. We will attach
216 /// metadata to these calls after the analysis indicating the functions the
217 /// calls can possibly target.
218 SmallPtrSet<CallBase *, 32> IndirectCalls;
219
220 /// Compute a new lattice value for the given constant. The constant, after
221 /// stripping any pointer casts, should be a Function. We ignore null
222 /// pointers as an optimization, since calling these values is undefined
223 /// behavior.
224 CVPLatticeVal computeConstant(Constant *C) {
226 return CVPLatticeVal(CVPLatticeVal::FunctionSet);
227 if (auto *F = dyn_cast<Function>(C->stripPointerCasts()))
228 return CVPLatticeVal({F});
229 return getOverdefinedVal();
230 }
231
232 /// Handle return instructions. The function's return state is the merge of
233 /// the returned value state and the function's return state.
234 void
235 visitReturn(ReturnInst &I,
238 Function *F = I.getParent()->getParent();
239 if (F->getReturnType()->isVoidTy())
240 return;
241 auto RegI = CVPLatticeKey(I.getReturnValue(), IPOGrouping::Register);
242 auto RetF = CVPLatticeKey(F, IPOGrouping::Return);
243 ChangedValues[RetF] =
244 MergeValues(SS.getValueState(RegI), SS.getValueState(RetF));
245 }
246
247 /// Handle call sites. The state of a called function's formal arguments is
248 /// the merge of the argument state with the call sites corresponding actual
249 /// argument state. The call site state is the merge of the call site state
250 /// with the returned value state of the called function.
251 void
252 visitCallBase(CallBase &CB,
256 auto RegI = CVPLatticeKey(&CB, IPOGrouping::Register);
257
258 // If this is an indirect call, save it so we can quickly revisit it when
259 // attaching metadata.
260 if (!F)
261 IndirectCalls.insert(&CB);
262
263 // If we can't track the function's return values, there's nothing to do.
265 // Void return, No need to create and update CVPLattice state as no one
266 // can use it.
267 if (CB.getType()->isVoidTy())
268 return;
269 ChangedValues[RegI] = getOverdefinedVal();
270 return;
271 }
272
273 // Inform the solver that the called function is executable, and perform
274 // the merges for the arguments and return value.
275 SS.MarkBlockExecutable(&F->front());
276 auto RetF = CVPLatticeKey(F, IPOGrouping::Return);
277 for (Argument &A : F->args()) {
278 auto RegFormal = CVPLatticeKey(&A, IPOGrouping::Register);
279 auto RegActual =
280 CVPLatticeKey(CB.getArgOperand(A.getArgNo()), IPOGrouping::Register);
281 ChangedValues[RegFormal] =
282 MergeValues(SS.getValueState(RegFormal), SS.getValueState(RegActual));
283 }
284
285 // Void return, No need to create and update CVPLattice state as no one can
286 // use it.
287 if (CB.getType()->isVoidTy())
288 return;
289
290 ChangedValues[RegI] =
291 MergeValues(SS.getValueState(RegI), SS.getValueState(RetF));
292 }
293
294 /// Handle select instructions. The select instruction state is the merge the
295 /// true and false value states.
296 void
297 visitSelect(SelectInst &I,
300 auto RegI = CVPLatticeKey(&I, IPOGrouping::Register);
301 auto RegT = CVPLatticeKey(I.getTrueValue(), IPOGrouping::Register);
302 auto RegF = CVPLatticeKey(I.getFalseValue(), IPOGrouping::Register);
303 ChangedValues[RegI] =
304 MergeValues(SS.getValueState(RegT), SS.getValueState(RegF));
305 }
306
307 /// Handle load instructions. If the pointer operand of the load is a global
308 /// variable, we attempt to track the value. The loaded value state is the
309 /// merge of the loaded value state with the global variable state.
310 void visitLoad(LoadInst &I,
313 auto RegI = CVPLatticeKey(&I, IPOGrouping::Register);
314 if (auto *GV = dyn_cast<GlobalVariable>(I.getPointerOperand())) {
315 auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
316 ChangedValues[RegI] =
317 MergeValues(SS.getValueState(RegI), SS.getValueState(MemGV));
318 } else {
319 ChangedValues[RegI] = getOverdefinedVal();
320 }
321 }
322
323 /// Handle store instructions. If the pointer operand of the store is a
324 /// global variable, we attempt to track the value. The global variable state
325 /// is the merge of the stored value state with the global variable state.
326 void
327 visitStore(StoreInst &I,
330 auto *GV = dyn_cast<GlobalVariable>(I.getPointerOperand());
331 if (!GV)
332 return;
333 auto RegI = CVPLatticeKey(I.getValueOperand(), IPOGrouping::Register);
334 auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
335 ChangedValues[MemGV] =
336 MergeValues(SS.getValueState(RegI), SS.getValueState(MemGV));
337 }
338
339 /// Handle all other instructions. All other instructions are marked
340 /// overdefined.
341 void visitInst(Instruction &I,
344 // Simply bail if this instruction has no user.
345 if (I.use_empty())
346 return;
347 auto RegI = CVPLatticeKey(&I, IPOGrouping::Register);
348 ChangedValues[RegI] = getOverdefinedVal();
349 }
350};
351} // namespace
352
353namespace llvm {
354/// A specialization of LatticeKeyInfo for CVPLatticeKeys. The generic solver
355/// must translate between LatticeKeys and LLVM Values when adding Values to
356/// its work list and inspecting the state of control-flow related values.
357template <> struct LatticeKeyInfo<CVPLatticeKey> {
358 static inline Value *getValueFromLatticeKey(CVPLatticeKey Key) {
359 return Key.getPointer();
360 }
361 static inline CVPLatticeKey getLatticeKeyFromValue(Value *V) {
362 return CVPLatticeKey(V, IPOGrouping::Register);
363 }
364};
365} // namespace llvm
366
367static bool runCVP(Module &M) {
368 // Our custom lattice function and generic sparse propagation solver.
369 CVPLatticeFunc Lattice(getIPOOptions(M));
371
372 // For each function in the module, if we can't track its arguments, let the
373 // generic solver assume it is executable.
374 for (Function &F : M)
375 if (!F.isDeclaration() && !canTrackArgumentsInterprocedurally(&F))
376 Solver.MarkBlockExecutable(&F.front());
377
378 // Solver our custom lattice. In doing so, we will also build a set of
379 // indirect call sites.
380 Solver.Solve();
381
382 // Attach metadata to the indirect call sites that were collected indicating
383 // the set of functions they can possibly target.
384 bool Changed = false;
385 MDBuilder MDB(M.getContext());
386 for (CallBase *C : Lattice.getIndirectCalls()) {
387 auto RegI = CVPLatticeKey(C->getCalledOperand(), IPOGrouping::Register);
388 CVPLatticeVal LV = Solver.getExistingValueState(RegI);
389 if (!LV.isFunctionSet() || LV.getFunctions().empty())
390 continue;
391 MDNode *Callees = MDB.createCallees(LV.getFunctions());
392 C->setMetadata(LLVMContext::MD_callees, Callees);
393 Changed = true;
394 }
395
396 return Changed;
397}
398
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool runCVP(Module &M)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Value * RHS
Value * LHS
AbstractLatticeFunction - This class is implemented by the dataflow instance to specify what the latt...
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
This is an important base class in LLVM.
Definition Constant.h:44
An instruction for reading from memory.
LLVM_ABI MDNode * createCallees(ArrayRef< Function * > Callees)
Return metadata indicating the possible callees of indirect calls.
Metadata node.
Definition Metadata.h:1081
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
PointerIntPair - This class implements a pair of a pointer and small integer.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Return a value (possibly void), from a function.
This class represents the LLVM 'select' instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SparseSolver - This class is a general purpose solver for Sparse Conditional Propagation with a progr...
void MarkBlockExecutable(BasicBlock *BB)
MarkBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
void Solve()
Solve - Solve for constants and executable blocks.
LatticeVal getExistingValueState(LatticeKey Key) const
getExistingValueState - Return the LatticeVal object corresponding to the given value from the ValueS...
An instruction for storing to memory.
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This class provides various memory handling functions that manipulate MemoryBlock instances.
Definition Memory.h:54
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2139
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
const IPOOptions & getIPOOptions(const LLVMContext &C)
Definition IPOOptions.h:33
LLVM_ABI bool canTrackGlobalVariableInterprocedurally(GlobalVariable *GV)
Determine if the value maintained in the given global variable can be tracked interprocedurally.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition STLExtras.h:1986
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool canTrackArgumentsInterprocedurally(Function *F)
Determine if the values of the given function's arguments can be tracked interprocedurally.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
static CVPLatticeKey getLatticeKeyFromValue(Value *V)
static Value * getValueFromLatticeKey(CVPLatticeKey Key)
A template for translating between LLVM Values and LatticeKeys.