LLVM  15.0.0git
AbstractCallSite.cpp
Go to the documentation of this file.
1 //===-- AbstractCallSite.cpp - Implementation of abstract call sites ------===//
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 implements abstract call sites which unify the interface for
10 // direct, indirect, and callback call sites.
11 //
12 // For more information see:
13 // https://llvm.org/devmtg/2018-10/talk-abstracts.html#talk20
14 //
15 //===----------------------------------------------------------------------===//
16 
18 #include "llvm/ADT/Statistic.h"
19 
20 using namespace llvm;
21 
22 #define DEBUG_TYPE "abstract-call-sites"
23 
24 STATISTIC(NumCallbackCallSites, "Number of callback call sites created");
25 STATISTIC(NumDirectAbstractCallSites,
26  "Number of direct abstract call sites created");
27 STATISTIC(NumInvalidAbstractCallSitesUnknownUse,
28  "Number of invalid abstract call sites created (unknown use)");
29 STATISTIC(NumInvalidAbstractCallSitesUnknownCallee,
30  "Number of invalid abstract call sites created (unknown callee)");
31 STATISTIC(NumInvalidAbstractCallSitesNoCallback,
32  "Number of invalid abstract call sites created (no callback)");
33 
35  const CallBase &CB, SmallVectorImpl<const Use *> &CallbackUses) {
36  const Function *Callee = CB.getCalledFunction();
37  if (!Callee)
38  return;
39 
40  MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
41  if (!CallbackMD)
42  return;
43 
44  for (const MDOperand &Op : CallbackMD->operands()) {
45  MDNode *OpMD = cast<MDNode>(Op.get());
46  auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
47  uint64_t CBCalleeIdx =
48  cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
49  if (CBCalleeIdx < CB.arg_size())
50  CallbackUses.push_back(CB.arg_begin() + CBCalleeIdx);
51  }
52 }
53 
54 /// Create an abstract call site from a use.
56  : CB(dyn_cast<CallBase>(U->getUser())) {
57 
58  // First handle unknown users.
59  if (!CB) {
60 
61  // If the use is actually in a constant cast expression which itself
62  // has only one use, we look through the constant cast expression.
63  // This happens by updating the use @p U to the use of the constant
64  // cast expression and afterwards re-initializing CB accordingly.
65  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U->getUser()))
66  if (CE->hasOneUse() && CE->isCast()) {
67  U = &*CE->use_begin();
68  CB = dyn_cast<CallBase>(U->getUser());
69  }
70 
71  if (!CB) {
72  NumInvalidAbstractCallSitesUnknownUse++;
73  return;
74  }
75  }
76 
77  // Then handle direct or indirect calls. Thus, if U is the callee of the
78  // call site CB it is not a callback and we are done.
79  if (CB->isCallee(U)) {
80  NumDirectAbstractCallSites++;
81  return;
82  }
83 
84  // If we cannot identify the broker function we cannot create a callback and
85  // invalidate the abstract call site.
87  if (!Callee) {
88  NumInvalidAbstractCallSitesUnknownCallee++;
89  CB = nullptr;
90  return;
91  }
92 
93  MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
94  if (!CallbackMD) {
95  NumInvalidAbstractCallSitesNoCallback++;
96  CB = nullptr;
97  return;
98  }
99 
100  unsigned UseIdx = CB->getArgOperandNo(U);
101  MDNode *CallbackEncMD = nullptr;
102  for (const MDOperand &Op : CallbackMD->operands()) {
103  MDNode *OpMD = cast<MDNode>(Op.get());
104  auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
105  uint64_t CBCalleeIdx =
106  cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
107  if (CBCalleeIdx != UseIdx)
108  continue;
109  CallbackEncMD = OpMD;
110  break;
111  }
112 
113  if (!CallbackEncMD) {
114  NumInvalidAbstractCallSitesNoCallback++;
115  CB = nullptr;
116  return;
117  }
118 
119  NumCallbackCallSites++;
120 
121  assert(CallbackEncMD->getNumOperands() >= 2 && "Incomplete !callback metadata");
122 
123  unsigned NumCallOperands = CB->arg_size();
124  // Skip the var-arg flag at the end when reading the metadata.
125  for (unsigned u = 0, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) {
126  Metadata *OpAsM = CallbackEncMD->getOperand(u).get();
127  auto *OpAsCM = cast<ConstantAsMetadata>(OpAsM);
128  assert(OpAsCM->getType()->isIntegerTy(64) &&
129  "Malformed !callback metadata");
130 
131  int64_t Idx = cast<ConstantInt>(OpAsCM->getValue())->getSExtValue();
132  assert(-1 <= Idx && Idx <= NumCallOperands &&
133  "Out-of-bounds !callback metadata index");
134 
135  CI.ParameterEncoding.push_back(Idx);
136  }
137 
138  if (!Callee->isVarArg())
139  return;
140 
141  Metadata *VarArgFlagAsM =
142  CallbackEncMD->getOperand(CallbackEncMD->getNumOperands() - 1).get();
143  auto *VarArgFlagAsCM = cast<ConstantAsMetadata>(VarArgFlagAsM);
144  assert(VarArgFlagAsCM->getType()->isIntegerTy(1) &&
145  "Malformed !callback metadata var-arg flag");
146 
147  if (VarArgFlagAsCM->getValue()->isNullValue())
148  return;
149 
150  // Add all variadic arguments at the end.
151  for (unsigned u = Callee->arg_size(); u < NumCallOperands; u++)
152  CI.ParameterEncoding.push_back(u);
153 }
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::AbstractCallSite::getCallbackUses
static void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
Definition: AbstractCallSite.cpp:34
llvm::Function
Definition: Function.h:60
Statistic.h
llvm::CallBase::isCallee
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Definition: InstrTypes.h:1407
llvm::CallBase::arg_begin
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1316
llvm::MDNode::operands
op_range operands() const
Definition: Metadata.h:1191
llvm::MDNode::getNumOperands
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1199
llvm::AbstractCallSite::CallbackInfo::ParameterEncoding
ParameterEncodingTy ParameterEncoding
Definition: AbstractCallSite.h:67
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1396
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::AbstractCallSite::AbstractCallSite
AbstractCallSite(const Use *U)
Sole constructor for abstract call sites (ACS).
Definition: AbstractCallSite.cpp:55
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1193
uint64_t
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MDNode
Metadata node.
Definition: Metadata.h:926
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:186
llvm::ConstantExpr
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:971
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:341
llvm::CallBase::arg_size
unsigned arg_size() const
Definition: InstrTypes.h:1339
llvm::CallBase::getArgOperandNo
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Definition: InstrTypes.h:1372
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1174
AbstractCallSite.h
llvm::MDOperand::get
Metadata * get() const
Definition: Metadata.h:784
llvm::MDOperand
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:773
llvm::dyn_cast
decltype(auto) LLVM_NODISCARD dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition: Casting.h:600
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43