30#define DEBUG_TYPE "called-value-propagation"
51 enum CVPLatticeStateTy { Undefined, FunctionSet, Overdefined, Untracked };
57 return LHS->getName() <
RHS->getName();
61 CVPLatticeVal() =
default;
62 CVPLatticeVal(CVPLatticeStateTy LatticeState) : LatticeState(LatticeState) {}
63 CVPLatticeVal(std::vector<Function *> &&Functions)
64 : LatticeState(FunctionSet), Functions(std::move(Functions)) {
70 const std::vector<Function *> &getFunctions()
const {
75 bool isFunctionSet()
const {
return LatticeState == FunctionSet; }
78 return LatticeState ==
RHS.LatticeState && Functions ==
RHS.Functions;
82 return LatticeState !=
RHS.LatticeState || Functions !=
RHS.Functions;
87 CVPLatticeStateTy LatticeState = Undefined;
96 std::vector<Function *> Functions;
106 const IPOOptions &Opts;
109 explicit CVPLatticeFunc(
const IPOOptions &Opts)
111 CVPLatticeVal(CVPLatticeVal::Overdefined),
112 CVPLatticeVal(CVPLatticeVal::Untracked)),
116 CVPLatticeVal ComputeLatticeVal(CVPLatticeKey
Key)
override {
117 switch (
Key.getInt()) {
118 case IPOGrouping::Register:
120 return getUndefVal();
123 return getUndefVal();
125 return computeConstant(
C);
127 return getOverdefinedVal();
128 case IPOGrouping::Memory:
129 case IPOGrouping::Return:
132 return computeConstant(GV->getInitializer());
135 return getUndefVal();
137 return getOverdefinedVal();
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));
163 void ComputeInstructionState(
167 switch (
I.getOpcode()) {
168 case Instruction::Call:
169 case Instruction::Invoke:
171 case Instruction::Load:
173 case Instruction::Ret:
175 case Instruction::Select:
177 case Instruction::Store:
180 return visitInst(
I, ChangedValues, SS);
185 void PrintLatticeVal(CVPLatticeVal LV,
raw_ostream &OS)
override {
186 if (LV == getUndefVal())
188 else if (LV == getOverdefinedVal())
190 else if (LV == getUntrackedVal())
197 void PrintLatticeKey(CVPLatticeKey
Key,
raw_ostream &OS)
override {
198 if (
Key.getInt() == IPOGrouping::Register)
200 else if (
Key.getInt() == IPOGrouping::Memory)
202 else if (
Key.getInt() == IPOGrouping::Return)
205 OS <<
Key.getPointer()->getName();
207 OS << *
Key.getPointer();
224 CVPLatticeVal computeConstant(
Constant *
C) {
226 return CVPLatticeVal(CVPLatticeVal::FunctionSet);
228 return CVPLatticeVal({
F});
229 return getOverdefinedVal();
239 if (
F->getReturnType()->isVoidTy())
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));
256 auto RegI = CVPLatticeKey(&CB, IPOGrouping::Register);
261 IndirectCalls.
insert(&CB);
269 ChangedValues[RegI] = getOverdefinedVal();
275 SS.MarkBlockExecutable(&
F->front());
276 auto RetF = CVPLatticeKey(
F, IPOGrouping::Return);
278 auto RegFormal = CVPLatticeKey(&
A, IPOGrouping::Register);
280 CVPLatticeKey(CB.
getArgOperand(
A.getArgNo()), IPOGrouping::Register);
281 ChangedValues[RegFormal] =
282 MergeValues(SS.getValueState(RegFormal), SS.getValueState(RegActual));
290 ChangedValues[RegI] =
291 MergeValues(SS.getValueState(RegI), SS.getValueState(RetF));
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));
313 auto RegI = CVPLatticeKey(&
I, IPOGrouping::Register);
315 auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
316 ChangedValues[RegI] =
317 MergeValues(SS.getValueState(RegI), SS.getValueState(MemGV));
319 ChangedValues[RegI] = getOverdefinedVal();
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));
347 auto RegI = CVPLatticeKey(&
I, IPOGrouping::Register);
348 ChangedValues[RegI] = getOverdefinedVal();
359 return Key.getPointer();
362 return CVPLatticeKey(V, IPOGrouping::Register);
386 for (
CallBase *
C : Lattice.getIndirectCalls()) {
387 auto RegI = CVPLatticeKey(
C->getCalledOperand(), IPOGrouping::Register);
389 if (!LV.isFunctionSet() || LV.getFunctions().empty())
392 C->setMetadata(LLVMContext::MD_callees, Callees);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
AbstractLatticeFunction - This class is implemented by the dataflow instance to specify what the latt...
This class represents an incoming formal argument to a Function.
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.
An instruction for reading from memory.
LLVM_ABI MDNode * createCallees(ArrayRef< Function * > Callees)
Return metadata indicating the possible callees of indirect calls.
A Module instance is used to store all the information related to an LLVM module.
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
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'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
This class implements an extremely fast bulk output stream that can only output to a stream.
This class provides various memory handling functions that manipulate MemoryBlock instances.
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.
bool operator!=(uint64_t V1, const APInt &V2)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
const IPOOptions & getIPOOptions(const LLVMContext &C)
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...
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...
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.
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.
static CVPLatticeKey getLatticeKeyFromValue(Value *V)
static Value * getValueFromLatticeKey(CVPLatticeKey Key)
A template for translating between LLVM Values and LatticeKeys.