LLVM  13.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 #include "llvm/Support/Debug.h"
20 
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "abstract-call-sites"
24 
25 STATISTIC(NumCallbackCallSites, "Number of callback call sites created");
26 STATISTIC(NumDirectAbstractCallSites,
27  "Number of direct abstract call sites created");
28 STATISTIC(NumInvalidAbstractCallSitesUnknownUse,
29  "Number of invalid abstract call sites created (unknown use)");
30 STATISTIC(NumInvalidAbstractCallSitesUnknownCallee,
31  "Number of invalid abstract call sites created (unknown callee)");
32 STATISTIC(NumInvalidAbstractCallSitesNoCallback,
33  "Number of invalid abstract call sites created (no callback)");
34 
36  const CallBase &CB, SmallVectorImpl<const Use *> &CallbackUses) {
37  const Function *Callee = CB.getCalledFunction();
38  if (!Callee)
39  return;
40 
41  MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
42  if (!CallbackMD)
43  return;
44 
45  for (const MDOperand &Op : CallbackMD->operands()) {
46  MDNode *OpMD = cast<MDNode>(Op.get());
47  auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
48  uint64_t CBCalleeIdx =
49  cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
50  if (CBCalleeIdx < CB.arg_size())
51  CallbackUses.push_back(CB.arg_begin() + CBCalleeIdx);
52  }
53 }
54 
55 /// Create an abstract call site from a use.
57  : CB(dyn_cast<CallBase>(U->getUser())) {
58 
59  // First handle unknown users.
60  if (!CB) {
61 
62  // If the use is actually in a constant cast expression which itself
63  // has only one use, we look through the constant cast expression.
64  // This happens by updating the use @p U to the use of the constant
65  // cast expression and afterwards re-initializing CB accordingly.
66  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U->getUser()))
67  if (CE->hasOneUse() && CE->isCast()) {
68  U = &*CE->use_begin();
69  CB = dyn_cast<CallBase>(U->getUser());
70  }
71 
72  if (!CB) {
73  NumInvalidAbstractCallSitesUnknownUse++;
74  return;
75  }
76  }
77 
78  // Then handle direct or indirect calls. Thus, if U is the callee of the
79  // call site CB it is not a callback and we are done.
80  if (CB->isCallee(U)) {
81  NumDirectAbstractCallSites++;
82  return;
83  }
84 
85  // If we cannot identify the broker function we cannot create a callback and
86  // invalidate the abstract call site.
88  if (!Callee) {
89  NumInvalidAbstractCallSitesUnknownCallee++;
90  CB = nullptr;
91  return;
92  }
93 
94  MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
95  if (!CallbackMD) {
96  NumInvalidAbstractCallSitesNoCallback++;
97  CB = nullptr;
98  return;
99  }
100 
101  unsigned UseIdx = CB->getArgOperandNo(U);
102  MDNode *CallbackEncMD = nullptr;
103  for (const MDOperand &Op : CallbackMD->operands()) {
104  MDNode *OpMD = cast<MDNode>(Op.get());
105  auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
106  uint64_t CBCalleeIdx =
107  cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
108  if (CBCalleeIdx != UseIdx)
109  continue;
110  CallbackEncMD = OpMD;
111  break;
112  }
113 
114  if (!CallbackEncMD) {
115  NumInvalidAbstractCallSitesNoCallback++;
116  CB = nullptr;
117  return;
118  }
119 
120  NumCallbackCallSites++;
121 
122  assert(CallbackEncMD->getNumOperands() >= 2 && "Incomplete !callback metadata");
123 
124  unsigned NumCallOperands = CB->getNumArgOperands();
125  // Skip the var-arg flag at the end when reading the metadata.
126  for (unsigned u = 0, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) {
127  Metadata *OpAsM = CallbackEncMD->getOperand(u).get();
128  auto *OpAsCM = cast<ConstantAsMetadata>(OpAsM);
129  assert(OpAsCM->getType()->isIntegerTy(64) &&
130  "Malformed !callback metadata");
131 
132  int64_t Idx = cast<ConstantInt>(OpAsCM->getValue())->getSExtValue();
133  assert(-1 <= Idx && Idx <= NumCallOperands &&
134  "Out-of-bounds !callback metadata index");
135 
136  CI.ParameterEncoding.push_back(Idx);
137  }
138 
139  if (!Callee->isVarArg())
140  return;
141 
142  Metadata *VarArgFlagAsM =
143  CallbackEncMD->getOperand(CallbackEncMD->getNumOperands() - 1).get();
144  auto *VarArgFlagAsCM = cast<ConstantAsMetadata>(VarArgFlagAsM);
145  assert(VarArgFlagAsCM->getType()->isIntegerTy(1) &&
146  "Malformed !callback metadata var-arg flag");
147 
148  if (VarArgFlagAsCM->getValue()->isNullValue())
149  return;
150 
151  // Add all variadic arguments at the end.
152  for (unsigned u = Callee->arg_size(); u < NumCallOperands; u++)
153  CI.ParameterEncoding.push_back(u);
154 }
llvm
Definition: AllocatorList.h:23
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:35
llvm::Function
Definition: Function.h:61
Statistic.h
llvm::dyn_cast
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:334
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:1404
llvm::CallBase::getNumArgOperands
unsigned getNumArgOperands() const
Definition: InstrTypes.h:1339
llvm::CallBase::arg_begin
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1306
llvm::MDNode::operands
op_range operands() const
Definition: Metadata.h:1100
llvm::MDNode::getNumOperands
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1108
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.
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:56
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1102
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:897
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:206
llvm::ConstantExpr
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:931
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::CallBase::arg_size
unsigned arg_size() const
Definition: InstrTypes.h:1329
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:43
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1164
AbstractCallSite.h
llvm::MDOperand::get
Metadata * get() const
Definition: Metadata.h:755
Debug.h
llvm::MDOperand
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:744
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44