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 | |
23 | namespace llvm { |
24 | |
25 | class Argument; |
26 | class 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. |
50 | class AbstractCallSite { |
51 | public: |
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 | |
71 | private: |
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 | |
81 | public: |
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. |
225 | template <typename UnaryFunction> |
226 | void 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. |
237 | template <typename UnaryFunction> |
238 | void 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 | |