|
|
|||
File indexing completed on 2026-05-10 08:43:56
0001 //===- AbstractCallSite.h - Abstract call sites -----------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines the AbstractCallSite class, which is a is a wrapper that 0010 // allows treating direct, indirect, and callback calls the same. 0011 // 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_IR_ABSTRACTCALLSITE_H 0015 #define LLVM_IR_ABSTRACTCALLSITE_H 0016 0017 #include "llvm/IR/Constants.h" 0018 #include "llvm/IR/Function.h" 0019 #include "llvm/IR/InstrTypes.h" 0020 #include "llvm/IR/Value.h" 0021 #include <cassert> 0022 0023 namespace llvm { 0024 0025 class Argument; 0026 class Use; 0027 0028 /// AbstractCallSite 0029 /// 0030 /// An abstract call site is a wrapper that allows to treat direct, 0031 /// indirect, and callback calls the same. If an abstract call site 0032 /// represents a direct or indirect call site it behaves like a stripped 0033 /// down version of a normal call site object. The abstract call site can 0034 /// also represent a callback call, thus the fact that the initially 0035 /// called function (=broker) may invoke a third one (=callback callee). 0036 /// In this case, the abstract call site hides the middle man, hence the 0037 /// broker function. The result is a representation of the callback call, 0038 /// inside the broker, but in the context of the original call to the broker. 0039 /// 0040 /// There are up to three functions involved when we talk about callback call 0041 /// sites. The caller (1), which invokes the broker function. The broker 0042 /// function (2), that will invoke the callee zero or more times. And finally 0043 /// the callee (3), which is the target of the callback call. 0044 /// 0045 /// The abstract call site will handle the mapping from parameters to arguments 0046 /// depending on the semantic of the broker function. However, it is important 0047 /// to note that the mapping is often partial. Thus, some arguments of the 0048 /// call/invoke instruction are mapped to parameters of the callee while others 0049 /// are not. 0050 class AbstractCallSite { 0051 public: 0052 0053 /// The encoding of a callback with regards to the underlying instruction. 0054 struct CallbackInfo { 0055 0056 /// For direct/indirect calls the parameter encoding is empty. If it is not, 0057 /// the abstract call site represents a callback. In that case, the first 0058 /// element of the encoding vector represents which argument of the call 0059 /// site CB is the callback callee. The remaining elements map parameters 0060 /// (identified by their position) to the arguments that will be passed 0061 /// through (also identified by position but in the call site instruction). 0062 /// 0063 /// NOTE that we use LLVM argument numbers (starting at 0) and not 0064 /// clang/source argument numbers (starting at 1). The -1 entries represent 0065 /// unknown values that are passed to the callee. 0066 using ParameterEncodingTy = SmallVector<int, 0>; 0067 ParameterEncodingTy ParameterEncoding; 0068 0069 }; 0070 0071 private: 0072 0073 /// The underlying call site: 0074 /// caller -> callee, if this is a direct or indirect call site 0075 /// caller -> broker function, if this is a callback call site 0076 CallBase *CB; 0077 0078 /// The encoding of a callback with regards to the underlying instruction. 0079 CallbackInfo CI; 0080 0081 public: 0082 /// Sole constructor for abstract call sites (ACS). 0083 /// 0084 /// An abstract call site can only be constructed through a llvm::Use because 0085 /// each operand (=use) of an instruction could potentially be a different 0086 /// abstract call site. Furthermore, even if the value of the llvm::Use is the 0087 /// same, and the user is as well, the abstract call sites might not be. 0088 /// 0089 /// If a use is not associated with an abstract call site the constructed ACS 0090 /// will evaluate to false if converted to a boolean. 0091 /// 0092 /// If the use is the callee use of a call or invoke instruction, the 0093 /// constructed abstract call site will behave as a llvm::CallSite would. 0094 /// 0095 /// If the use is not a callee use of a call or invoke instruction, the 0096 /// callback metadata is used to determine the argument <-> parameter mapping 0097 /// as well as the callee of the abstract call site. 0098 AbstractCallSite(const Use *U); 0099 0100 /// Add operand uses of \p CB that represent callback uses into 0101 /// \p CallbackUses. 0102 /// 0103 /// All uses added to \p CallbackUses can be used to create abstract call 0104 /// sites for which AbstractCallSite::isCallbackCall() will return true. 0105 static void getCallbackUses(const CallBase &CB, 0106 SmallVectorImpl<const Use *> &CallbackUses); 0107 0108 /// Conversion operator to conveniently check for a valid/initialized ACS. 0109 explicit operator bool() const { return CB != nullptr; } 0110 0111 /// Return the underlying instruction. 0112 CallBase *getInstruction() const { return CB; } 0113 0114 /// Return true if this ACS represents a direct call. 0115 bool isDirectCall() const { 0116 return !isCallbackCall() && !CB->isIndirectCall(); 0117 } 0118 0119 /// Return true if this ACS represents an indirect call. 0120 bool isIndirectCall() const { 0121 return !isCallbackCall() && CB->isIndirectCall(); 0122 } 0123 0124 /// Return true if this ACS represents a callback call. 0125 bool isCallbackCall() const { 0126 // For a callback call site the callee is ALWAYS stored first in the 0127 // transitive values vector. Thus, a non-empty vector indicates a callback. 0128 return !CI.ParameterEncoding.empty(); 0129 } 0130 0131 /// Return true if @p UI is the use that defines the callee of this ACS. 0132 bool isCallee(Value::const_user_iterator UI) const { 0133 return isCallee(&UI.getUse()); 0134 } 0135 0136 /// Return true if @p U is the use that defines the callee of this ACS. 0137 bool isCallee(const Use *U) const { 0138 if (isDirectCall()) 0139 return CB->isCallee(U); 0140 0141 assert(!CI.ParameterEncoding.empty() && 0142 "Callback without parameter encoding!"); 0143 0144 // If the use is actually in a constant cast expression which itself 0145 // has only one use, we look through the constant cast expression. 0146 if (auto *CE = dyn_cast<ConstantExpr>(U->getUser())) 0147 if (CE->hasOneUse() && CE->isCast()) 0148 U = &*CE->use_begin(); 0149 0150 return (int)CB->getArgOperandNo(U) == CI.ParameterEncoding[0]; 0151 } 0152 0153 /// Return the number of parameters of the callee. 0154 unsigned getNumArgOperands() const { 0155 if (isDirectCall()) 0156 return CB->arg_size(); 0157 // Subtract 1 for the callee encoding. 0158 return CI.ParameterEncoding.size() - 1; 0159 } 0160 0161 /// Return the operand index of the underlying instruction associated with @p 0162 /// Arg. 0163 int getCallArgOperandNo(Argument &Arg) const { 0164 return getCallArgOperandNo(Arg.getArgNo()); 0165 } 0166 0167 /// Return the operand index of the underlying instruction associated with 0168 /// the function parameter number @p ArgNo or -1 if there is none. 0169 int getCallArgOperandNo(unsigned ArgNo) const { 0170 if (isDirectCall()) 0171 return ArgNo; 0172 // Add 1 for the callee encoding. 0173 return CI.ParameterEncoding[ArgNo + 1]; 0174 } 0175 0176 /// Return the operand of the underlying instruction associated with @p Arg. 0177 Value *getCallArgOperand(Argument &Arg) const { 0178 return getCallArgOperand(Arg.getArgNo()); 0179 } 0180 0181 /// Return the operand of the underlying instruction associated with the 0182 /// function parameter number @p ArgNo or nullptr if there is none. 0183 Value *getCallArgOperand(unsigned ArgNo) const { 0184 if (isDirectCall()) 0185 return CB->getArgOperand(ArgNo); 0186 // Add 1 for the callee encoding. 0187 return CI.ParameterEncoding[ArgNo + 1] >= 0 0188 ? CB->getArgOperand(CI.ParameterEncoding[ArgNo + 1]) 0189 : nullptr; 0190 } 0191 0192 /// Return the operand index of the underlying instruction associated with the 0193 /// callee of this ACS. Only valid for callback calls! 0194 int getCallArgOperandNoForCallee() const { 0195 assert(isCallbackCall()); 0196 assert(CI.ParameterEncoding.size() && CI.ParameterEncoding[0] >= 0); 0197 return CI.ParameterEncoding[0]; 0198 } 0199 0200 /// Return the use of the callee value in the underlying instruction. Only 0201 /// valid for callback calls! 0202 const Use &getCalleeUseForCallback() const { 0203 int CalleeArgIdx = getCallArgOperandNoForCallee(); 0204 assert(CalleeArgIdx >= 0 && 0205 unsigned(CalleeArgIdx) < getInstruction()->getNumOperands()); 0206 return getInstruction()->getOperandUse(CalleeArgIdx); 0207 } 0208 0209 /// Return the pointer to function that is being called. 0210 Value *getCalledOperand() const { 0211 if (isDirectCall()) 0212 return CB->getCalledOperand(); 0213 return CB->getArgOperand(getCallArgOperandNoForCallee()); 0214 } 0215 0216 /// Return the function being called if this is a direct call, otherwise 0217 /// return null (if it's an indirect call). 0218 Function *getCalledFunction() const { 0219 Value *V = getCalledOperand(); 0220 return V ? dyn_cast<Function>(V->stripPointerCasts()) : nullptr; 0221 } 0222 }; 0223 0224 /// Apply function Func to each CB's callback call site. 0225 template <typename UnaryFunction> 0226 void forEachCallbackCallSite(const CallBase &CB, UnaryFunction Func) { 0227 SmallVector<const Use *, 4u> CallbackUses; 0228 AbstractCallSite::getCallbackUses(CB, CallbackUses); 0229 for (const Use *U : CallbackUses) { 0230 AbstractCallSite ACS(U); 0231 assert(ACS && ACS.isCallbackCall() && "must be a callback call"); 0232 Func(ACS); 0233 } 0234 } 0235 0236 /// Apply function Func to each CB's callback function. 0237 template <typename UnaryFunction> 0238 void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func) { 0239 forEachCallbackCallSite(CB, [&Func](AbstractCallSite &ACS) { 0240 if (Function *Callback = ACS.getCalledFunction()) 0241 Func(Callback); 0242 }); 0243 } 0244 0245 } // end namespace llvm 0246 0247 #endif // LLVM_IR_ABSTRACTCALLSITE_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|