AbstractCallSite.cpp 5.1 KB

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