AbstractCallSite.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- AbstractCallSite.h - Abstract call sites -----------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the AbstractCallSite class, which is a is a wrapper that
  15. // allows treating direct, indirect, and callback calls the same.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_IR_ABSTRACTCALLSITE_H
  19. #define LLVM_IR_ABSTRACTCALLSITE_H
  20. #include "llvm/IR/Function.h"
  21. #include "llvm/IR/InstrTypes.h"
  22. #include "llvm/IR/Instruction.h"
  23. #include "llvm/IR/Use.h"
  24. #include "llvm/IR/User.h"
  25. #include "llvm/IR/Value.h"
  26. #include "llvm/Support/Casting.h"
  27. #include <cassert>
  28. namespace llvm {
  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. /// The encoding of a callback with regards to the underlying instruction.
  54. struct CallbackInfo {
  55. /// For direct/indirect calls the parameter encoding is empty. If it is not,
  56. /// the abstract call site represents a callback. In that case, the first
  57. /// element of the encoding vector represents which argument of the call
  58. /// site CB is the callback callee. The remaining elements map parameters
  59. /// (identified by their position) to the arguments that will be passed
  60. /// through (also identified by position but in the call site instruction).
  61. ///
  62. /// NOTE that we use LLVM argument numbers (starting at 0) and not
  63. /// clang/source argument numbers (starting at 1). The -1 entries represent
  64. /// unknown values that are passed to the callee.
  65. using ParameterEncodingTy = SmallVector<int, 0>;
  66. ParameterEncodingTy ParameterEncoding;
  67. };
  68. private:
  69. /// The underlying call site:
  70. /// caller -> callee, if this is a direct or indirect call site
  71. /// caller -> broker function, if this is a callback call site
  72. CallBase *CB;
  73. /// The encoding of a callback with regards to the underlying instruction.
  74. CallbackInfo CI;
  75. public:
  76. /// Sole constructor for abstract call sites (ACS).
  77. ///
  78. /// An abstract call site can only be constructed through a llvm::Use because
  79. /// each operand (=use) of an instruction could potentially be a different
  80. /// abstract call site. Furthermore, even if the value of the llvm::Use is the
  81. /// same, and the user is as well, the abstract call sites might not be.
  82. ///
  83. /// If a use is not associated with an abstract call site the constructed ACS
  84. /// will evaluate to false if converted to a boolean.
  85. ///
  86. /// If the use is the callee use of a call or invoke instruction, the
  87. /// constructed abstract call site will behave as a llvm::CallSite would.
  88. ///
  89. /// If the use is not a callee use of a call or invoke instruction, the
  90. /// callback metadata is used to determine the argument <-> parameter mapping
  91. /// as well as the callee of the abstract call site.
  92. AbstractCallSite(const Use *U);
  93. /// Add operand uses of \p CB that represent callback uses into
  94. /// \p CallbackUses.
  95. ///
  96. /// All uses added to \p CallbackUses can be used to create abstract call
  97. /// sites for which AbstractCallSite::isCallbackCall() will return true.
  98. static void getCallbackUses(const CallBase &CB,
  99. SmallVectorImpl<const Use *> &CallbackUses);
  100. /// Conversion operator to conveniently check for a valid/initialized ACS.
  101. explicit operator bool() const { return CB != nullptr; }
  102. /// Return the underlying instruction.
  103. CallBase *getInstruction() const { return CB; }
  104. /// Return true if this ACS represents a direct call.
  105. bool isDirectCall() const {
  106. return !isCallbackCall() && !CB->isIndirectCall();
  107. }
  108. /// Return true if this ACS represents an indirect call.
  109. bool isIndirectCall() const {
  110. return !isCallbackCall() && CB->isIndirectCall();
  111. }
  112. /// Return true if this ACS represents a callback call.
  113. bool isCallbackCall() const {
  114. // For a callback call site the callee is ALWAYS stored first in the
  115. // transitive values vector. Thus, a non-empty vector indicates a callback.
  116. return !CI.ParameterEncoding.empty();
  117. }
  118. /// Return true if @p UI is the use that defines the callee of this ACS.
  119. bool isCallee(Value::const_user_iterator UI) const {
  120. return isCallee(&UI.getUse());
  121. }
  122. /// Return true if @p U is the use that defines the callee of this ACS.
  123. bool isCallee(const Use *U) const {
  124. if (isDirectCall())
  125. return CB->isCallee(U);
  126. assert(!CI.ParameterEncoding.empty() &&
  127. "Callback without parameter encoding!");
  128. // If the use is actually in a constant cast expression which itself
  129. // has only one use, we look through the constant cast expression.
  130. if (auto *CE = dyn_cast<ConstantExpr>(U->getUser()))
  131. if (CE->hasOneUse() && CE->isCast())
  132. U = &*CE->use_begin();
  133. return (int)CB->getArgOperandNo(U) == CI.ParameterEncoding[0];
  134. }
  135. /// Return the number of parameters of the callee.
  136. unsigned getNumArgOperands() const {
  137. if (isDirectCall())
  138. return CB->getNumArgOperands();
  139. // Subtract 1 for the callee encoding.
  140. return CI.ParameterEncoding.size() - 1;
  141. }
  142. /// Return the operand index of the underlying instruction associated with @p
  143. /// Arg.
  144. int getCallArgOperandNo(Argument &Arg) const {
  145. return getCallArgOperandNo(Arg.getArgNo());
  146. }
  147. /// Return the operand index of the underlying instruction associated with
  148. /// the function parameter number @p ArgNo or -1 if there is none.
  149. int getCallArgOperandNo(unsigned ArgNo) const {
  150. if (isDirectCall())
  151. return ArgNo;
  152. // Add 1 for the callee encoding.
  153. return CI.ParameterEncoding[ArgNo + 1];
  154. }
  155. /// Return the operand of the underlying instruction associated with @p Arg.
  156. Value *getCallArgOperand(Argument &Arg) const {
  157. return getCallArgOperand(Arg.getArgNo());
  158. }
  159. /// Return the operand of the underlying instruction associated with the
  160. /// function parameter number @p ArgNo or nullptr if there is none.
  161. Value *getCallArgOperand(unsigned ArgNo) const {
  162. if (isDirectCall())
  163. return CB->getArgOperand(ArgNo);
  164. // Add 1 for the callee encoding.
  165. return CI.ParameterEncoding[ArgNo + 1] >= 0
  166. ? CB->getArgOperand(CI.ParameterEncoding[ArgNo + 1])
  167. : nullptr;
  168. }
  169. /// Return the operand index of the underlying instruction associated with the
  170. /// callee of this ACS. Only valid for callback calls!
  171. int getCallArgOperandNoForCallee() const {
  172. assert(isCallbackCall());
  173. assert(CI.ParameterEncoding.size() && CI.ParameterEncoding[0] >= 0);
  174. return CI.ParameterEncoding[0];
  175. }
  176. /// Return the use of the callee value in the underlying instruction. Only
  177. /// valid for callback calls!
  178. const Use &getCalleeUseForCallback() const {
  179. int CalleeArgIdx = getCallArgOperandNoForCallee();
  180. assert(CalleeArgIdx >= 0 &&
  181. unsigned(CalleeArgIdx) < getInstruction()->getNumOperands());
  182. return getInstruction()->getOperandUse(CalleeArgIdx);
  183. }
  184. /// Return the pointer to function that is being called.
  185. Value *getCalledOperand() const {
  186. if (isDirectCall())
  187. return CB->getCalledOperand();
  188. return CB->getArgOperand(getCallArgOperandNoForCallee());
  189. }
  190. /// Return the function being called if this is a direct call, otherwise
  191. /// return null (if it's an indirect call).
  192. Function *getCalledFunction() const {
  193. Value *V = getCalledOperand();
  194. return V ? dyn_cast<Function>(V->stripPointerCasts()) : nullptr;
  195. }
  196. };
  197. /// Apply function Func to each CB's callback call site.
  198. template <typename UnaryFunction>
  199. void forEachCallbackCallSite(const CallBase &CB, UnaryFunction Func) {
  200. SmallVector<const Use *, 4u> CallbackUses;
  201. AbstractCallSite::getCallbackUses(CB, CallbackUses);
  202. for (const Use *U : CallbackUses) {
  203. AbstractCallSite ACS(U);
  204. assert(ACS && ACS.isCallbackCall() && "must be a callback call");
  205. Func(ACS);
  206. }
  207. }
  208. /// Apply function Func to each CB's callback function.
  209. template <typename UnaryFunction>
  210. void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func) {
  211. forEachCallbackCallSite(CB, [&Func](AbstractCallSite &ACS) {
  212. if (Function *Callback = ACS.getCalledFunction())
  213. Func(Callback);
  214. });
  215. }
  216. } // end namespace llvm
  217. #endif // LLVM_IR_ABSTRACTCALLSITE_H
  218. #ifdef __GNUC__
  219. #pragma GCC diagnostic pop
  220. #endif