LLVM  14.0.0git
AbstractCallSite.h
Go to the documentation of this file.
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/Function.h"
18 #include "llvm/IR/InstrTypes.h"
19 #include "llvm/IR/Instruction.h"
20 #include "llvm/IR/Use.h"
21 #include "llvm/IR/User.h"
22 #include "llvm/IR/Value.h"
23 #include "llvm/Support/Casting.h"
24 #include <cassert>
25 
26 namespace llvm {
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.
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.
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.
133  return isCallee(&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>(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->getNumArgOperands();
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.
164  return getCallArgOperandNo(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.
178  return getCallArgOperand(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(ArgNo);
186  // Add 1 for the callee encoding.
187  return CI.ParameterEncoding[ArgNo + 1] >= 0
188  ? CB->getArgOperand(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!
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(CalleeArgIdx);
207  }
208 
209  /// Return the pointer to function that is being called.
211  if (isDirectCall())
212  return CB->getCalledOperand();
214  }
215 
216  /// Return the function being called if this is a direct call, otherwise
217  /// return null (if it's an indirect call).
219  Value *V = getCalledOperand();
220  return V ? dyn_cast<Function>(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
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
llvm::Value::const_user_iterator
user_iterator_impl< const User > const_user_iterator
Definition: Value.h:392
llvm::forEachCallbackCallSite
void forEachCallbackCallSite(const CallBase &CB, UnaryFunction Func)
Apply function Func to each CB's callback call site.
Definition: AbstractCallSite.h:226
llvm::AbstractCallSite::getCalledOperand
Value * getCalledOperand() const
Return the pointer to function that is being called.
Definition: AbstractCallSite.h:210
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::AbstractCallSite::CallbackInfo
The encoding of a callback with regards to the underlying instruction.
Definition: AbstractCallSite.h:54
llvm::AbstractCallSite::getCallbackUses
static void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
Definition: AbstractCallSite.cpp:35
llvm::Function
Definition: Function.h:61
llvm::AbstractCallSite::isCallee
bool isCallee(const Use *U) const
Return true if U is the use that defines the callee of this ACS.
Definition: AbstractCallSite.h:137
llvm::AbstractCallSite::getCallArgOperandNoForCallee
int getCallArgOperandNoForCallee() const
Return the operand index of the underlying instruction associated with the callee of this ACS.
Definition: AbstractCallSite.h:194
llvm::SmallVector< int, 0 >
llvm::CallBase::isCallee
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Definition: InstrTypes.h:1401
llvm::AbstractCallSite::getCallArgOperandNo
int getCallArgOperandNo(unsigned ArgNo) const
Return the operand index of the underlying instruction associated with the function parameter number ...
Definition: AbstractCallSite.h:169
llvm::CallBase::getNumArgOperands
unsigned getNumArgOperands() const
Definition: InstrTypes.h:1336
llvm::AbstractCallSite
AbstractCallSite.
Definition: AbstractCallSite.h:50
llvm::AbstractCallSite::getNumArgOperands
unsigned getNumArgOperands() const
Return the number of parameters of the callee.
Definition: AbstractCallSite.h:154
Use.h
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
llvm::User::getOperandUse
const Use & getOperandUse(unsigned i) const
Definition: User.h:182
Instruction.h
llvm::AbstractCallSite::isDirectCall
bool isDirectCall() const
Return true if this ACS represents a direct call.
Definition: AbstractCallSite.h:115
llvm::AbstractCallSite::CallbackInfo::ParameterEncoding
ParameterEncodingTy ParameterEncoding
Definition: AbstractCallSite.h:67
InstrTypes.h
llvm::AbstractCallSite::AbstractCallSite
AbstractCallSite(const Use *U)
Sole constructor for abstract call sites (ACS).
Definition: AbstractCallSite.cpp:56
llvm::AbstractCallSite::getInstruction
CallBase * getInstruction() const
Return the underlying instruction.
Definition: AbstractCallSite.h:112
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AbstractCallSite::getCalleeUseForCallback
const Use & getCalleeUseForCallback() const
Return the use of the callee value in the underlying instruction.
Definition: AbstractCallSite.h:202
llvm::AbstractCallSite::isCallbackCall
bool isCallbackCall() const
Return true if this ACS represents a callback call.
Definition: AbstractCallSite.h:125
llvm::Value::stripPointerCasts
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:675
llvm::AbstractCallSite::getCallArgOperand
Value * getCallArgOperand(unsigned ArgNo) const
Return the operand of the underlying instruction associated with the function parameter number ArgNo ...
Definition: AbstractCallSite.h:183
Casting.h
Function.h
llvm::CallBase::isIndirectCall
bool isIndirectCall() const
Return true if the callsite is an indirect call.
Definition: Instructions.cpp:289
llvm::CallBase::getArgOperandNo
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:1369
llvm::forEachCallbackFunction
void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func)
Apply function Func to each CB's callback function.
Definition: AbstractCallSite.h:238
llvm::CallBase::getCalledOperand
Value * getCalledOperand() const
Definition: InstrTypes.h:1386
llvm::AbstractCallSite::isIndirectCall
bool isIndirectCall() const
Return true if this ACS represents an indirect call.
Definition: AbstractCallSite.h:120
User.h
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1338
llvm::AbstractCallSite::isCallee
bool isCallee(Value::const_user_iterator UI) const
Return true if UI is the use that defines the callee of this ACS.
Definition: AbstractCallSite.h:132
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1161
llvm::AbstractCallSite::getCalledFunction
Function * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
Definition: AbstractCallSite.h:218
llvm::AbstractCallSite::getCallArgOperand
Value * getCallArgOperand(Argument &Arg) const
Return the operand of the underlying instruction associated with Arg.
Definition: AbstractCallSite.h:177
Value.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::AbstractCallSite::getCallArgOperandNo
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Definition: AbstractCallSite.h:163
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44