1//===- AbstractCallSite.h - Abstract call sites -----------------*- C++ -*-===//
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 defines the AbstractCallSite class, which is a is a wrapper that
10// allows treating direct, indirect, and callback calls the same.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_ABSTRACTCALLSITE_H
15#define LLVM_IR_ABSTRACTCALLSITE_H
16
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/Function.h"
19#include "llvm/IR/InstrTypes.h"
20#include "llvm/IR/Value.h"
21#include <cassert>
22
23namespace llvm {
24
25class Argument;
26class Use;
27
28/// AbstractCallSite
29///
30/// An abstract call site is a wrapper that allows to treat direct,
31/// indirect, and callback calls the same. If an abstract call site
32/// represents a direct or indirect call site it behaves like a stripped
33/// down version of a normal call site object. The abstract call site can
34/// also represent a callback call, thus the fact that the initially
35/// called function (=broker) may invoke a third one (=callback callee).
36/// In this case, the abstract call site hides the middle man, hence the
37/// broker function. The result is a representation of the callback call,
38/// inside the broker, but in the context of the original call to the broker.
39///
40/// There are up to three functions involved when we talk about callback call
41/// sites. The caller (1), which invokes the broker function. The broker
42/// function (2), that will invoke the callee zero or more times. And finally
43/// the callee (3), which is the target of the callback call.
44///
45/// The abstract call site will handle the mapping from parameters to arguments
46/// depending on the semantic of the broker function. However, it is important
47/// to note that the mapping is often partial. Thus, some arguments of the
48/// call/invoke instruction are mapped to parameters of the callee while others
49/// are not.
50class AbstractCallSite {
51public:
52
53 /// The encoding of a callback with regards to the underlying instruction.
54 struct CallbackInfo {
55
56 /// For direct/indirect calls the parameter encoding is empty. If it is not,
57 /// the abstract call site represents a callback. In that case, the first
58 /// element of the encoding vector represents which argument of the call
59 /// site CB is the callback callee. The remaining elements map parameters
60 /// (identified by their position) to the arguments that will be passed
61 /// through (also identified by position but in the call site instruction).
62 ///
63 /// NOTE that we use LLVM argument numbers (starting at 0) and not
64 /// clang/source argument numbers (starting at 1). The -1 entries represent
65 /// unknown values that are passed to the callee.
66 using ParameterEncodingTy = SmallVector<int, 0>;
67 ParameterEncodingTy ParameterEncoding;
68
69 };
70
71private:
72
73 /// The underlying call site:
74 /// caller -> callee, if this is a direct or indirect call site
75 /// caller -> broker function, if this is a callback call site
76 CallBase *CB;
77
78 /// The encoding of a callback with regards to the underlying instruction.
79 CallbackInfo CI;
80
81public:
82 /// Sole constructor for abstract call sites (ACS).
83 ///
84 /// An abstract call site can only be constructed through a llvm::Use because
85 /// each operand (=use) of an instruction could potentially be a different
86 /// abstract call site. Furthermore, even if the value of the llvm::Use is the
87 /// same, and the user is as well, the abstract call sites might not be.
88 ///
89 /// If a use is not associated with an abstract call site the constructed ACS
90 /// will evaluate to false if converted to a boolean.
91 ///
92 /// If the use is the callee use of a call or invoke instruction, the
93 /// constructed abstract call site will behave as a llvm::CallSite would.
94 ///
95 /// If the use is not a callee use of a call or invoke instruction, the
96 /// callback metadata is used to determine the argument <-> parameter mapping
97 /// as well as the callee of the abstract call site.
98 AbstractCallSite(const Use *U);
99
100 /// Add operand uses of \p CB that represent callback uses into
101 /// \p CallbackUses.
102 ///
103 /// All uses added to \p CallbackUses can be used to create abstract call
104 /// sites for which AbstractCallSite::isCallbackCall() will return true.
105 static void getCallbackUses(const CallBase &CB,
106 SmallVectorImpl<const Use *> &CallbackUses);
107
108 /// Conversion operator to conveniently check for a valid/initialized ACS.
109 explicit operator bool() const { return CB != nullptr; }
110
111 /// Return the underlying instruction.
112 CallBase *getInstruction() const { return CB; }
113
114 /// Return true if this ACS represents a direct call.
115 bool isDirectCall() const {
116 return !isCallbackCall() && !CB->isIndirectCall();
117 }
118
119 /// Return true if this ACS represents an indirect call.
120 bool isIndirectCall() const {
121 return !isCallbackCall() && CB->isIndirectCall();
122 }
123
124 /// Return true if this ACS represents a callback call.
125 bool isCallbackCall() const {
126 // For a callback call site the callee is ALWAYS stored first in the
127 // transitive values vector. Thus, a non-empty vector indicates a callback.
128 return !CI.ParameterEncoding.empty();
129 }
130
131 /// Return true if @p UI is the use that defines the callee of this ACS.
132 bool isCallee(Value::const_user_iterator UI) const {
133 return isCallee(U: &UI.getUse());
134 }
135
136 /// Return true if @p U is the use that defines the callee of this ACS.
137 bool isCallee(const Use *U) const {
138 if (isDirectCall())
139 return CB->isCallee(U);
140
141 assert(!CI.ParameterEncoding.empty() &&
142 "Callback without parameter encoding!");
143
144 // If the use is actually in a constant cast expression which itself
145 // has only one use, we look through the constant cast expression.
146 if (auto *CE = dyn_cast<ConstantExpr>(Val: U->getUser()))
147 if (CE->hasOneUse() && CE->isCast())
148 U = &*CE->use_begin();
149
150 return (int)CB->getArgOperandNo(U) == CI.ParameterEncoding[0];
151 }
152
153 /// Return the number of parameters of the callee.
154 unsigned getNumArgOperands() const {
155 if (isDirectCall())
156 return CB->arg_size();
157 // Subtract 1 for the callee encoding.
158 return CI.ParameterEncoding.size() - 1;
159 }
160
161 /// Return the operand index of the underlying instruction associated with @p
162 /// Arg.
163 int getCallArgOperandNo(Argument &Arg) const {
164 return getCallArgOperandNo(ArgNo: Arg.getArgNo());
165 }
166
167 /// Return the operand index of the underlying instruction associated with
168 /// the function parameter number @p ArgNo or -1 if there is none.
169 int getCallArgOperandNo(unsigned ArgNo) const {
170 if (isDirectCall())
171 return ArgNo;
172 // Add 1 for the callee encoding.
173 return CI.ParameterEncoding[ArgNo + 1];
174 }
175
176 /// Return the operand of the underlying instruction associated with @p Arg.
177 Value *getCallArgOperand(Argument &Arg) const {
178 return getCallArgOperand(ArgNo: Arg.getArgNo());
179 }
180
181 /// Return the operand of the underlying instruction associated with the
182 /// function parameter number @p ArgNo or nullptr if there is none.
183 Value *getCallArgOperand(unsigned ArgNo) const {
184 if (isDirectCall())
185 return CB->getArgOperand(i: ArgNo);
186 // Add 1 for the callee encoding.
187 return CI.ParameterEncoding[ArgNo + 1] >= 0
188 ? CB->getArgOperand(i: CI.ParameterEncoding[ArgNo + 1])
189 : nullptr;
190 }
191
192 /// Return the operand index of the underlying instruction associated with the
193 /// callee of this ACS. Only valid for callback calls!
194 int getCallArgOperandNoForCallee() const {
195 assert(isCallbackCall());
196 assert(CI.ParameterEncoding.size() && CI.ParameterEncoding[0] >= 0);
197 return CI.ParameterEncoding[0];
198 }
199
200 /// Return the use of the callee value in the underlying instruction. Only
201 /// valid for callback calls!
202 const Use &getCalleeUseForCallback() const {
203 int CalleeArgIdx = getCallArgOperandNoForCallee();
204 assert(CalleeArgIdx >= 0 &&
205 unsigned(CalleeArgIdx) < getInstruction()->getNumOperands());
206 return getInstruction()->getOperandUse(i: CalleeArgIdx);
207 }
208
209 /// Return the pointer to function that is being called.
210 Value *getCalledOperand() const {
211 if (isDirectCall())
212 return CB->getCalledOperand();
213 return CB->getArgOperand(i: getCallArgOperandNoForCallee());
214 }
215
216 /// Return the function being called if this is a direct call, otherwise
217 /// return null (if it's an indirect call).
218 Function *getCalledFunction() const {
219 Value *V = getCalledOperand();
220 return V ? dyn_cast<Function>(Val: V->stripPointerCasts()) : nullptr;
221 }
222};
223
224/// Apply function Func to each CB's callback call site.
225template <typename UnaryFunction>
226void forEachCallbackCallSite(const CallBase &CB, UnaryFunction Func) {
227 SmallVector<const Use *, 4u> CallbackUses;
228 AbstractCallSite::getCallbackUses(CB, CallbackUses);
229 for (const Use *U : CallbackUses) {
230 AbstractCallSite ACS(U);
231 assert(ACS && ACS.isCallbackCall() && "must be a callback call");
232 Func(ACS);
233 }
234}
235
236/// Apply function Func to each CB's callback function.
237template <typename UnaryFunction>
238void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func) {
239 forEachCallbackCallSite(CB, [&Func](AbstractCallSite &ACS) {
240 if (Function *Callback = ACS.getCalledFunction())
241 Func(Callback);
242 });
243}
244
245} // end namespace llvm
246
247#endif // LLVM_IR_ABSTRACTCALLSITE_H
248

source code of llvm/include/llvm/IR/AbstractCallSite.h