22#define DEBUG_TYPE "abstract-call-sites"
24STATISTIC(NumCallbackCallSites,
"Number of callback call sites created");
26 "Number of direct abstract call sites created");
28 "Number of invalid abstract call sites created (unknown use)");
30 "Number of invalid abstract call sites created (unknown callee)");
32 "Number of invalid abstract call sites created (no callback)");
36 const Function *Callee = CB.getCalledFunction();
40 MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
49 if (CBCalleeIdx < CB.arg_size())
50 CallbackUses.
push_back(CB.arg_begin() + CBCalleeIdx);
66 if (CE->hasOneUse() && CE->isCast()) {
67 U = &*CE->use_begin();
72 NumInvalidAbstractCallSitesUnknownUse++;
79 if (CB->isCallee(U)) {
80 NumDirectAbstractCallSites++;
86 Function *Callee = CB->getCalledFunction();
88 NumInvalidAbstractCallSitesUnknownCallee++;
93 MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
95 NumInvalidAbstractCallSitesNoCallback++;
100 unsigned UseIdx = CB->getArgOperandNo(U);
101 MDNode *CallbackEncMD =
nullptr;
103 MDNode *OpMD = cast<MDNode>(Op.get());
104 auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
105 uint64_t CBCalleeIdx =
106 cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
107 if (CBCalleeIdx != UseIdx)
109 CallbackEncMD = OpMD;
113 if (!CallbackEncMD) {
114 NumInvalidAbstractCallSitesNoCallback++;
119 NumCallbackCallSites++;
123 unsigned NumCallOperands = CB->arg_size();
125 for (
unsigned u = 0, e = CallbackEncMD->
getNumOperands() - 1; u < e; u++) {
128 assert(OpAsCM->getType()->isIntegerTy(64) &&
129 "Malformed !callback metadata");
132 assert(-1 <= Idx && Idx <= NumCallOperands &&
133 "Out-of-bounds !callback metadata index");
135 CI.ParameterEncoding.push_back(Idx);
138 if (!Callee->isVarArg())
144 assert(VarArgFlagAsCM->getType()->isIntegerTy(1) &&
145 "Malformed !callback metadata var-arg flag");
147 if (VarArgFlagAsCM->getValue()->isNullValue())
151 for (
unsigned u = Callee->arg_size(); u < NumCallOperands; u++)
152 CI.ParameterEncoding.push_back(u);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
LLVM_ABI AbstractCallSite(const Use *U)
Sole constructor for abstract call sites (ACS).
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
A constant value that is initialized with an expression using other constant values.
const MDOperand & getOperand(unsigned I) const
ArrayRef< MDOperand > operands() const
unsigned getNumOperands() const
Return number of MDNode operands.
Tracking metadata reference owned by Metadata.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
A Use represents the edge between a Value definition and its users.
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.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.