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