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