AbstractCallSite.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. #include "llvm/IR/AbstractCallSite.h"
  17. #include "llvm/ADT/Statistic.h"
  18. #include "llvm/Support/Debug.h"
  19. using namespace llvm;
  20. #define DEBUG_TYPE "abstract-call-sites"
  21. STATISTIC(NumCallbackCallSites, "Number of callback call sites created");
  22. STATISTIC(NumDirectAbstractCallSites,
  23. "Number of direct abstract call sites created");
  24. STATISTIC(NumInvalidAbstractCallSitesUnknownUse,
  25. "Number of invalid abstract call sites created (unknown use)");
  26. STATISTIC(NumInvalidAbstractCallSitesUnknownCallee,
  27. "Number of invalid abstract call sites created (unknown callee)");
  28. STATISTIC(NumInvalidAbstractCallSitesNoCallback,
  29. "Number of invalid abstract call sites created (no callback)");
  30. void AbstractCallSite::getCallbackUses(
  31. const CallBase &CB, SmallVectorImpl<const Use *> &CallbackUses) {
  32. const Function *Callee = CB.getCalledFunction();
  33. if (!Callee)
  34. return;
  35. MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
  36. if (!CallbackMD)
  37. return;
  38. for (const MDOperand &Op : CallbackMD->operands()) {
  39. MDNode *OpMD = cast<MDNode>(Op.get());
  40. auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
  41. uint64_t CBCalleeIdx =
  42. cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
  43. if (CBCalleeIdx < CB.arg_size())
  44. CallbackUses.push_back(CB.arg_begin() + CBCalleeIdx);
  45. }
  46. }
  47. /// Create an abstract call site from a use.
  48. AbstractCallSite::AbstractCallSite(const Use *U)
  49. : CB(dyn_cast<CallBase>(U->getUser())) {
  50. // First handle unknown users.
  51. if (!CB) {
  52. // If the use is actually in a constant cast expression which itself
  53. // has only one use, we look through the constant cast expression.
  54. // This happens by updating the use @p U to the use of the constant
  55. // cast expression and afterwards re-initializing CB accordingly.
  56. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U->getUser()))
  57. if (CE->hasOneUse() && CE->isCast()) {
  58. U = &*CE->use_begin();
  59. CB = dyn_cast<CallBase>(U->getUser());
  60. }
  61. if (!CB) {
  62. NumInvalidAbstractCallSitesUnknownUse++;
  63. return;
  64. }
  65. }
  66. // Then handle direct or indirect calls. Thus, if U is the callee of the
  67. // call site CB it is not a callback and we are done.
  68. if (CB->isCallee(U)) {
  69. NumDirectAbstractCallSites++;
  70. return;
  71. }
  72. // If we cannot identify the broker function we cannot create a callback and
  73. // invalidate the abstract call site.
  74. Function *Callee = CB->getCalledFunction();
  75. if (!Callee) {
  76. NumInvalidAbstractCallSitesUnknownCallee++;
  77. CB = nullptr;
  78. return;
  79. }
  80. MDNode *CallbackMD = Callee->getMetadata(LLVMContext::MD_callback);
  81. if (!CallbackMD) {
  82. NumInvalidAbstractCallSitesNoCallback++;
  83. CB = nullptr;
  84. return;
  85. }
  86. unsigned UseIdx = CB->getArgOperandNo(U);
  87. MDNode *CallbackEncMD = nullptr;
  88. for (const MDOperand &Op : CallbackMD->operands()) {
  89. MDNode *OpMD = cast<MDNode>(Op.get());
  90. auto *CBCalleeIdxAsCM = cast<ConstantAsMetadata>(OpMD->getOperand(0));
  91. uint64_t CBCalleeIdx =
  92. cast<ConstantInt>(CBCalleeIdxAsCM->getValue())->getZExtValue();
  93. if (CBCalleeIdx != UseIdx)
  94. continue;
  95. CallbackEncMD = OpMD;
  96. break;
  97. }
  98. if (!CallbackEncMD) {
  99. NumInvalidAbstractCallSitesNoCallback++;
  100. CB = nullptr;
  101. return;
  102. }
  103. NumCallbackCallSites++;
  104. assert(CallbackEncMD->getNumOperands() >= 2 && "Incomplete !callback metadata");
  105. unsigned NumCallOperands = CB->arg_size();
  106. // Skip the var-arg flag at the end when reading the metadata.
  107. for (unsigned u = 0, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) {
  108. Metadata *OpAsM = CallbackEncMD->getOperand(u).get();
  109. auto *OpAsCM = cast<ConstantAsMetadata>(OpAsM);
  110. assert(OpAsCM->getType()->isIntegerTy(64) &&
  111. "Malformed !callback metadata");
  112. int64_t Idx = cast<ConstantInt>(OpAsCM->getValue())->getSExtValue();
  113. assert(-1 <= Idx && Idx <= NumCallOperands &&
  114. "Out-of-bounds !callback metadata index");
  115. CI.ParameterEncoding.push_back(Idx);
  116. }
  117. if (!Callee->isVarArg())
  118. return;
  119. Metadata *VarArgFlagAsM =
  120. CallbackEncMD->getOperand(CallbackEncMD->getNumOperands() - 1).get();
  121. auto *VarArgFlagAsCM = cast<ConstantAsMetadata>(VarArgFlagAsM);
  122. assert(VarArgFlagAsCM->getType()->isIntegerTy(1) &&
  123. "Malformed !callback metadata var-arg flag");
  124. if (VarArgFlagAsCM->getValue()->isNullValue())
  125. return;
  126. // Add all variadic arguments at the end.
  127. for (unsigned u = Callee->arg_size(); u < NumCallOperands; u++)
  128. CI.ParameterEncoding.push_back(u);
  129. }