Back to home page

EIC code displayed by LXR

 
 

    


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