Home | History | Annotate | Line # | Download | only in IR
      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.
     50 class AbstractCallSite {
     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.
     66     using ParameterEncodingTy = SmallVector<int, 0>;
     67     ParameterEncodingTy ParameterEncoding;
     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.
    132   bool isCallee(Value::const_user_iterator UI) const {
    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.
    163   int getCallArgOperandNo(Argument &Arg) const {
    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.
    177   Value *getCallArgOperand(Argument &Arg) const {
    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!
    194   int getCallArgOperandNoForCallee() const {
    195     assert(isCallbackCall());
    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.
    210   Value *getCalledOperand() const {
    211     if (isDirectCall())
    212       return CB->getCalledOperand();
    213     return CB->getArgOperand(getCallArgOperandNoForCallee());
    214   }
    215 
    216   /// Return the function being called if this is a direct call, otherwise
    217   /// return null (if it's an indirect call).
    218   Function *getCalledFunction() const {
    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
    248