30#define DEBUG_TYPE "called-value-propagation" 
   41    cl::desc(
"The maximum number of functions to track per lattice value"));
 
   62  enum CVPLatticeStateTy { Undefined, FunctionSet, Overdefined, Untracked };
 
   67    bool operator()(
const Function *
LHS, 
const Function *
RHS)
 const {
 
   72  CVPLatticeVal() = 
default;
 
   73  CVPLatticeVal(CVPLatticeStateTy LatticeState) : LatticeState(LatticeState) {}
 
   74  CVPLatticeVal(std::vector<Function *> &&Functions)
 
   75      : LatticeState(FunctionSet), Functions(std::
move(Functions)) {
 
   81  const std::vector<Function *> &getFunctions()
 const {
 
   86  bool isFunctionSet()
 const { 
return LatticeState == FunctionSet; }
 
   89    return LatticeState == 
RHS.LatticeState && Functions == 
RHS.Functions;
 
   93    return LatticeState != 
RHS.LatticeState || Functions != 
RHS.Functions;
 
   98  CVPLatticeStateTy LatticeState = Undefined;
 
  107  std::vector<Function *> Functions;
 
  119      : AbstractLatticeFunction(CVPLatticeVal(CVPLatticeVal::
Undefined),
 
  120                                CVPLatticeVal(CVPLatticeVal::Overdefined),
 
  121                                CVPLatticeVal(CVPLatticeVal::Untracked)) {}
 
  124  CVPLatticeVal ComputeLatticeVal(CVPLatticeKey 
Key)
 override {
 
  125    switch (
Key.getInt()) {
 
  126    case IPOGrouping::Register:
 
  128        return getUndefVal();
 
  131          return getUndefVal();
 
  133        return computeConstant(
C);
 
  135      return getOverdefinedVal();
 
  136    case IPOGrouping::Memory:
 
  137    case IPOGrouping::Return:
 
  140          return computeConstant(GV->getInitializer());
 
  143          return getUndefVal();
 
  145    return getOverdefinedVal();
 
  153  CVPLatticeVal MergeValues(CVPLatticeVal 
X, CVPLatticeVal 
Y)
 override {
 
  154    if (
X == getOverdefinedVal() || 
Y == getOverdefinedVal())
 
  155      return getOverdefinedVal();
 
  156    if (
X == getUndefVal() && 
Y == getUndefVal())
 
  157      return getUndefVal();
 
  158    std::vector<Function *> 
Union;
 
  159    std::set_union(
X.getFunctions().begin(), 
X.getFunctions().end(),
 
  160                   Y.getFunctions().begin(), 
Y.getFunctions().end(),
 
  161                   std::back_inserter(Union), CVPLatticeVal::Compare{});
 
  163      return getOverdefinedVal();
 
  164    return CVPLatticeVal(std::move(Union));
 
  171  void ComputeInstructionState(
 
  173      SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  174      SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS)
 override {
 
  175    switch (
I.getOpcode()) {
 
  176    case Instruction::Call:
 
  177    case Instruction::Invoke:
 
  179    case Instruction::Load:
 
  181    case Instruction::Ret:
 
  183    case Instruction::Select:
 
  185    case Instruction::Store:
 
  188      return visitInst(
I, ChangedValues, SS);
 
  193  void PrintLatticeVal(CVPLatticeVal LV, raw_ostream &OS)
 override {
 
  194    if (LV == getUndefVal())
 
  196    else if (LV == getOverdefinedVal())
 
  198    else if (LV == getUntrackedVal())
 
  205  void PrintLatticeKey(CVPLatticeKey 
Key, raw_ostream &OS)
 override {
 
  206    if (
Key.getInt() == IPOGrouping::Register)
 
  208    else if (
Key.getInt() == IPOGrouping::Memory)
 
  210    else if (
Key.getInt() == IPOGrouping::Return)
 
  213      OS << 
Key.getPointer()->getName();
 
  215      OS << *
Key.getPointer();
 
  220  SmallPtrSetImpl<CallBase *> &getIndirectCalls() { 
return IndirectCalls; }
 
  226  SmallPtrSet<CallBase *, 32> IndirectCalls;
 
  232  CVPLatticeVal computeConstant(Constant *
C) {
 
  234      return CVPLatticeVal(CVPLatticeVal::FunctionSet);
 
  236      return CVPLatticeVal({
F});
 
  237    return getOverdefinedVal();
 
  243  visitReturn(ReturnInst &
I,
 
  244              SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  245              SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
 
  247    if (
F->getReturnType()->isVoidTy())
 
  249    auto RegI = CVPLatticeKey(
I.getReturnValue(), IPOGrouping::Register);
 
  250    auto RetF = CVPLatticeKey(
F, IPOGrouping::Return);
 
  251    ChangedValues[RetF] =
 
  252        MergeValues(
SS.getValueState(RegI), 
SS.getValueState(RetF));
 
  260  visitCallBase(CallBase &CB,
 
  261                SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  262                SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
 
  264    auto RegI = CVPLatticeKey(&CB, IPOGrouping::Register);
 
  269      IndirectCalls.insert(&CB);
 
  277      ChangedValues[RegI] = getOverdefinedVal();
 
  283    SS.MarkBlockExecutable(&
F->front());
 
  284    auto RetF = CVPLatticeKey(
F, IPOGrouping::Return);
 
  285    for (Argument &
A : 
F->args()) {
 
  286      auto RegFormal = CVPLatticeKey(&
A, IPOGrouping::Register);
 
  288          CVPLatticeKey(CB.
getArgOperand(
A.getArgNo()), IPOGrouping::Register);
 
  289      ChangedValues[RegFormal] =
 
  290          MergeValues(
SS.getValueState(RegFormal), 
SS.getValueState(RegActual));
 
  298    ChangedValues[RegI] =
 
  299        MergeValues(
SS.getValueState(RegI), 
SS.getValueState(RetF));
 
  305  visitSelect(SelectInst &
I,
 
  306              SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  307              SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
 
  308    auto RegI = CVPLatticeKey(&
I, IPOGrouping::Register);
 
  309    auto RegT = CVPLatticeKey(
I.getTrueValue(), IPOGrouping::Register);
 
  310    auto RegF = CVPLatticeKey(
I.getFalseValue(), IPOGrouping::Register);
 
  311    ChangedValues[RegI] =
 
  312        MergeValues(
SS.getValueState(RegT), 
SS.getValueState(RegF));
 
  318  void visitLoad(LoadInst &
I,
 
  319                 SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  320                 SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
 
  321    auto RegI = CVPLatticeKey(&
I, IPOGrouping::Register);
 
  323      auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
 
  324      ChangedValues[RegI] =
 
  325          MergeValues(
SS.getValueState(RegI), 
SS.getValueState(MemGV));
 
  327      ChangedValues[RegI] = getOverdefinedVal();
 
  335  visitStore(StoreInst &
I,
 
  336             SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  337             SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
 
  341    auto RegI = CVPLatticeKey(
I.getValueOperand(), IPOGrouping::Register);
 
  342    auto MemGV = CVPLatticeKey(GV, IPOGrouping::Memory);
 
  343    ChangedValues[MemGV] =
 
  344        MergeValues(
SS.getValueState(RegI), 
SS.getValueState(MemGV));
 
  349  void visitInst(Instruction &
I,
 
  350                 SmallDenseMap<CVPLatticeKey, CVPLatticeVal, 16> &ChangedValues,
 
  351                 SparseSolver<CVPLatticeKey, CVPLatticeVal> &SS) {
 
  355    auto RegI = CVPLatticeKey(&
I, IPOGrouping::Register);
 
  356    ChangedValues[RegI] = getOverdefinedVal();
 
  367    return Key.getPointer();
 
 
  370    return CVPLatticeKey(V, IPOGrouping::Register);
 
 
 
  377  CVPLatticeFunc Lattice;
 
  394  for (
CallBase *
C : Lattice.getIndirectCalls()) {
 
  395    auto RegI = CVPLatticeKey(
C->getCalledOperand(), IPOGrouping::Register);
 
  397    if (!LV.isFunctionSet() || LV.getFunctions().empty())
 
  400    C->setMetadata(LLVMContext::MD_callees, Callees);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
 
static cl::opt< unsigned > MaxFunctionsPerValue("cvp-max-functions-per-value", cl::Hidden, cl::init(4), cl::desc("The maximum number of functions to track per lattice value"))
The maximum number of functions to track per lattice value.
 
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")
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
 
AbstractLatticeFunction - This class is implemented by the dataflow instance to specify what the latt...
 
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
 
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
 
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.
 
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...
 
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.
 
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
 
This class provides various memory handling functions that manipulate MemoryBlock instances.
 
@ C
The default llvm calling convention, compatible with C.
 
initializer< Ty > init(const Ty &Val)
 
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)
 
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
 
bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
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.