LLVM  10.0.0svn
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 
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/IR/CallSite.h"
20 #include "llvm/Support/Debug.h"
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "abstract-call-sites"
25 
26 STATISTIC(NumCallbackCallSites, "Number of callback call sites created");
27 STATISTIC(NumDirectAbstractCallSites,
28  "Number of direct abstract call sites created");
29 STATISTIC(NumInvalidAbstractCallSitesUnknownUse,
30  "Number of invalid abstract call sites created (unknown use)");
31 STATISTIC(NumInvalidAbstractCallSitesUnknownCallee,
32  "Number of invalid abstract call sites created (unknown callee)");
33 STATISTIC(NumInvalidAbstractCallSitesNoCallback,
34  "Number of invalid abstract call sites created (no callback)");
35 
36 /// Create an abstract call site from a use.
37 AbstractCallSite::AbstractCallSite(const Use *U) : CS(U->getUser()) {
38 
39  // First handle unknown users.
40  if (!CS) {
41 
42  // If the use is actually in a constant cast expression which itself
43  // has only one use, we look through the constant cast expression.
44  // This happens by updating the use @p U to the use of the constant
45  // cast expression and afterwards re-initializing CS accordingly.
46  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U->getUser()))
47  if (CE->getNumUses() == 1 && CE->isCast()) {
48  U = &*CE->use_begin();
49  CS = CallSite(U->getUser());
50  }
51 
52  if (!CS) {
53  NumInvalidAbstractCallSitesUnknownUse++;
54  return;
55  }
56  }
57 
58  // Then handle direct or indirect calls. Thus, if U is the callee of the
59  // call site CS it is not a callback and we are done.
60  if (CS.isCallee(U)) {
61  NumDirectAbstractCallSites++;
62  return;
63  }
64 
65  // If we cannot identify the broker function we cannot create a callback and
66  // invalidate the abstract call site.
68  if (!Callee) {
69  NumInvalidAbstractCallSitesUnknownCallee++;
70  CS = CallSite();
71  return;
72  }
73 
74  MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
75  if (!CallbackMD) {
76  NumInvalidAbstractCallSitesNoCallback++;
77  CS = CallSite();
78  return;
79  }
80 
81  unsigned UseIdx = CS.getArgumentNo(U);
82  MDNode *CallbackEncMD = nullptr;
83  for (const MDOperand &Op : CallbackMD->operands()) {
84  MDNode *OpMD = cast<MDNode>(Op.get());
85  auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
86  uint64_t CBCalleeIdx =
87  cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
88  if (CBCalleeIdx != UseIdx)
89  continue;
90  CallbackEncMD = OpMD;
91  break;
92  }
93 
94  if (!CallbackEncMD) {
95  NumInvalidAbstractCallSitesNoCallback++;
96  CS = CallSite();
97  return;
98  }
99 
100  NumCallbackCallSites++;
101 
102  assert(CallbackEncMD->getNumOperands() >= 2 && "Incomplete !callback metadata");
103 
104  unsigned NumCallOperands = CS.getNumArgOperands();
105  // Skip the var-arg flag at the end when reading the metadata.
106  for (unsigned u = 0, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) {
107  Metadata *OpAsM = CallbackEncMD->getOperand(u).get();
108  auto *OpAsCM = cast<ConstantAsMetadata>(OpAsM);
109  assert(OpAsCM->getType()->isIntegerTy(64) &&
110  "Malformed !callback metadata");
111 
112  int64_t Idx = cast<ConstantInt>(OpAsCM->getValue())->getSExtValue();
113  assert(-1 <= Idx && Idx <= NumCallOperands &&
114  "Out-of-bounds !callback metadata index");
115 
117  }
118 
119  if (!Callee->isVarArg())
120  return;
121 
122  Metadata *VarArgFlagAsM =
123  CallbackEncMD->getOperand(CallbackEncMD->getNumOperands() - 1).get();
124  auto *VarArgFlagAsCM = cast<ConstantAsMetadata>(VarArgFlagAsM);
125  assert(VarArgFlagAsCM->getType()->isIntegerTy(1) &&
126  "Malformed !callback metadata var-arg flag");
127 
128  if (VarArgFlagAsCM->getValue()->isNullValue())
129  return;
130 
131  // Add all variadic arguments at the end.
132  for (unsigned u = Callee->arg_size(); u < NumCallOperands; u++)
134 }
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Definition: Function.h:176
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:710
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void push_back(const T &Elt)
Definition: SmallVector.h:211
STATISTIC(NumFunctions, "Total number of functions")
Metadata node.
Definition: Metadata.h:863
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1068
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it&#39;s an indirect...
Definition: CallSite.h:111
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
Definition: Metadata.cpp:1440
unsigned getArgumentNo(Value::const_user_iterator I) const
Given a value use iterator, returns the argument that corresponds to it.
Definition: CallSite.h:206
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:888
op_range operands() const
Definition: Metadata.h:1066
ParameterEncodingTy ParameterEncoding
Definition: CallSite.h:735
unsigned getNumArgOperands() const
Definition: CallSite.h:303
size_t arg_size() const
Definition: Function.h:728
amdgpu Simplify well known AMD library false FunctionCallee Callee
AbstractCallSite(const Use *U)
Sole constructor for abstract call sites (ACS).
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand&#39;s Use.
Definition: CallSite.h:150
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Metadata * get() const
Definition: Metadata.h:721
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1074
Root of the metadata hierarchy.
Definition: Metadata.h:57