LLVM 22.0.0git
AbstractCallSite.cpp
Go to the documentation of this file.
1//===-- AbstractCallSite.cpp - Implementation of abstract call sites ------===//
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 abstract call sites which unify the interface for
10// direct, indirect, and callback call sites.
11//
12// For more information see:
13// https://llvm.org/devmtg/2018-10/talk-abstracts.html#talk20
14//
15//===----------------------------------------------------------------------===//
16
18#include "llvm/ADT/Statistic.h"
19
20using namespace llvm;
21
22#define DEBUG_TYPE "abstract-call-sites"
23
24STATISTIC(NumCallbackCallSites, "Number of callback call sites created");
25STATISTIC(NumDirectAbstractCallSites,
26 "Number of direct abstract call sites created");
27STATISTIC(NumInvalidAbstractCallSitesUnknownUse,
28 "Number of invalid abstract call sites created (unknown use)");
29STATISTIC(NumInvalidAbstractCallSitesUnknownCallee,
30 "Number of invalid abstract call sites created (unknown callee)");
31STATISTIC(NumInvalidAbstractCallSitesNoCallback,
32 "Number of invalid abstract call sites created (no callback)");
33
35 const CallBase &CB, SmallVectorImpl<const Use *> &CallbackUses) {
36 const Function *Callee = CB.getCalledFunction();
37 if (!Callee)
38 return;
39
40 MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
41 if (!CallbackMD)
42 return;
43
44 for (const MDOperand &Op : CallbackMD->operands()) {
45 MDNode *OpMD = cast<MDNode>(Op.get());
46 auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
47 uint64_t CBCalleeIdx =
48 cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
49 if (CBCalleeIdx < CB.arg_size())
50 CallbackUses.push_back(CB.arg_begin() + CBCalleeIdx);
51 }
52}
53
54/// Create an abstract call site from a use.
56 : CB(dyn_cast<CallBase>(U->getUser())) {
57
58 // First handle unknown users.
59 if (!CB) {
60
61 // If the use is actually in a constant cast expression which itself
62 // has only one use, we look through the constant cast expression.
63 // This happens by updating the use @p U to the use of the constant
64 // cast expression and afterwards re-initializing CB accordingly.
65 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U->getUser()))
66 if (CE->hasOneUse() && CE->isCast()) {
67 U = &*CE->use_begin();
68 CB = dyn_cast<CallBase>(U->getUser());
69 }
70
71 if (!CB) {
72 NumInvalidAbstractCallSitesUnknownUse++;
73 return;
74 }
75 }
76
77 // Then handle direct or indirect calls. Thus, if U is the callee of the
78 // call site CB it is not a callback and we are done.
79 if (CB->isCallee(U)) {
80 NumDirectAbstractCallSites++;
81 return;
82 }
83
84 // If we cannot identify the broker function we cannot create a callback and
85 // invalidate the abstract call site.
86 Function *Callee = CB->getCalledFunction();
87 if (!Callee) {
88 NumInvalidAbstractCallSitesUnknownCallee++;
89 CB = nullptr;
90 return;
91 }
92
93 MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
94 if (!CallbackMD) {
95 NumInvalidAbstractCallSitesNoCallback++;
96 CB = nullptr;
97 return;
98 }
99
100 unsigned UseIdx = CB->getArgOperandNo(U);
101 MDNode *CallbackEncMD = nullptr;
102 for (const MDOperand &Op : CallbackMD->operands()) {
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)
108 continue;
109 CallbackEncMD = OpMD;
110 break;
111 }
112
113 if (!CallbackEncMD) {
114 NumInvalidAbstractCallSitesNoCallback++;
115 CB = nullptr;
116 return;
117 }
118
119 NumCallbackCallSites++;
120
121 assert(CallbackEncMD->getNumOperands() >= 2 && "Incomplete !callback metadata");
122
123 unsigned NumCallOperands = CB->arg_size();
124 // Skip the var-arg flag at the end when reading the metadata.
125 for (unsigned u = 0, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) {
126 Metadata *OpAsM = CallbackEncMD->getOperand(u).get();
127 auto *OpAsCM = cast<ConstantAsMetadata>(OpAsM);
128 assert(OpAsCM->getType()->isIntegerTy(64) &&
129 "Malformed !callback metadata");
130
131 int64_t Idx = cast<ConstantInt>(OpAsCM->getValue())->getSExtValue();
132 assert(-1 <= Idx && Idx <= NumCallOperands &&
133 "Out-of-bounds !callback metadata index");
134
136 }
137
138 if (!Callee->isVarArg())
139 return;
140
141 Metadata *VarArgFlagAsM =
142 CallbackEncMD->getOperand(CallbackEncMD->getNumOperands() - 1).get();
143 auto *VarArgFlagAsCM = cast<ConstantAsMetadata>(VarArgFlagAsM);
144 assert(VarArgFlagAsCM->getType()->isIntegerTy(1) &&
145 "Malformed !callback metadata var-arg flag");
146
147 if (VarArgFlagAsCM->getValue()->isNullValue())
148 return;
149
150 // Add all variadic arguments at the end.
151 for (unsigned u = Callee->arg_size(); u < NumCallOperands; u++)
153}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
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...
Definition: InstrTypes.h:1116
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1348
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1267
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Definition: InstrTypes.h:1359
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Definition: InstrTypes.h:1323
unsigned arg_size() const
Definition: InstrTypes.h:1290
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1120
This class represents an Operation in the Expression.
Metadata node.
Definition: Metadata.h:1077
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1445
ArrayRef< MDOperand > operands() const
Definition: Metadata.h:1443
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1451
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:899
Metadata * get() const
Definition: Metadata.h:928
Root of the metadata hierarchy.
Definition: Metadata.h:63
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:649