Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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/Constants.h"
18
#include "llvm/IR/Function.h"
19
#include "llvm/IR/InstrTypes.h"
20
#include "llvm/IR/Value.h"
21
#include <cassert>
22
 
23
namespace llvm {
24
 
25
class Argument;
26
class Use;
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->arg_size();
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