PPCLowerMASSVEntries.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //===-- PPCLowerMASSVEntries.cpp ------------------------------------------===//
  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 lowering of MASSV (SIMD) entries for specific PowerPC
  10. // subtargets.
  11. // Following is an example of a conversion specific to Power9 subtarget:
  12. // __sind2_massv ---> __sind2_P9
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "PPC.h"
  16. #include "PPCSubtarget.h"
  17. #include "PPCTargetMachine.h"
  18. #include "llvm/ADT/STLExtras.h"
  19. #include "llvm/Analysis/TargetTransformInfo.h"
  20. #include "llvm/CodeGen/TargetPassConfig.h"
  21. #include "llvm/IR/Instructions.h"
  22. #include "llvm/IR/Module.h"
  23. #define DEBUG_TYPE "ppc-lower-massv-entries"
  24. using namespace llvm;
  25. namespace {
  26. // Length of the suffix "massv", which is specific to IBM MASSV library entries.
  27. const unsigned MASSVSuffixLength = 5;
  28. static StringRef MASSVFuncs[] = {
  29. #define TLI_DEFINE_MASSV_VECFUNCS_NAMES
  30. #include "llvm/Analysis/VecFuncs.def"
  31. };
  32. class PPCLowerMASSVEntries : public ModulePass {
  33. public:
  34. static char ID;
  35. PPCLowerMASSVEntries() : ModulePass(ID) {}
  36. bool runOnModule(Module &M) override;
  37. StringRef getPassName() const override { return "PPC Lower MASS Entries"; }
  38. void getAnalysisUsage(AnalysisUsage &AU) const override {
  39. AU.addRequired<TargetTransformInfoWrapperPass>();
  40. }
  41. private:
  42. static bool isMASSVFunc(StringRef Name);
  43. static StringRef getCPUSuffix(const PPCSubtarget *Subtarget);
  44. static std::string createMASSVFuncName(Function &Func,
  45. const PPCSubtarget *Subtarget);
  46. bool handlePowSpecialCases(CallInst *CI, Function &Func, Module &M);
  47. bool lowerMASSVCall(CallInst *CI, Function &Func, Module &M,
  48. const PPCSubtarget *Subtarget);
  49. };
  50. } // namespace
  51. /// Checks if the specified function name represents an entry in the MASSV
  52. /// library.
  53. bool PPCLowerMASSVEntries::isMASSVFunc(StringRef Name) {
  54. return llvm::is_contained(MASSVFuncs, Name);
  55. }
  56. // FIXME:
  57. /// Returns a string corresponding to the specified PowerPC subtarget. e.g.:
  58. /// "P8" for Power8, "P9" for Power9. The string is used as a suffix while
  59. /// generating subtarget-specific MASSV library functions. Current support
  60. /// includes Power8 and Power9 subtargets.
  61. StringRef PPCLowerMASSVEntries::getCPUSuffix(const PPCSubtarget *Subtarget) {
  62. // Assume Power8 when Subtarget is unavailable.
  63. if (!Subtarget)
  64. return "P8";
  65. if (Subtarget->hasP9Vector())
  66. return "P9";
  67. if (Subtarget->hasP8Vector())
  68. return "P8";
  69. report_fatal_error("Unsupported Subtarget: MASSV is supported only on "
  70. "Power8 and Power9 subtargets.");
  71. }
  72. /// Creates PowerPC subtarget-specific name corresponding to the specified
  73. /// generic MASSV function, and the PowerPC subtarget.
  74. std::string
  75. PPCLowerMASSVEntries::createMASSVFuncName(Function &Func,
  76. const PPCSubtarget *Subtarget) {
  77. StringRef Suffix = getCPUSuffix(Subtarget);
  78. auto GenericName = Func.getName().drop_back(MASSVSuffixLength).str();
  79. std::string MASSVEntryName = GenericName + Suffix.str();
  80. return MASSVEntryName;
  81. }
  82. /// If there are proper fast-math flags, this function creates llvm.pow
  83. /// intrinsics when the exponent is 0.25 or 0.75.
  84. bool PPCLowerMASSVEntries::handlePowSpecialCases(CallInst *CI, Function &Func,
  85. Module &M) {
  86. if (Func.getName() != "__powf4_massv" && Func.getName() != "__powd2_massv")
  87. return false;
  88. if (Constant *Exp = dyn_cast<Constant>(CI->getArgOperand(1)))
  89. if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(Exp->getSplatValue())) {
  90. // If the argument is 0.75 or 0.25 it is cheaper to turn it into pow
  91. // intrinsic so that it could be optimzed as sequence of sqrt's.
  92. if (!CI->hasNoInfs() || !CI->hasApproxFunc())
  93. return false;
  94. if (!CFP->isExactlyValue(0.75) && !CFP->isExactlyValue(0.25))
  95. return false;
  96. if (CFP->isExactlyValue(0.25) && !CI->hasNoSignedZeros())
  97. return false;
  98. CI->setCalledFunction(
  99. Intrinsic::getDeclaration(&M, Intrinsic::pow, CI->getType()));
  100. return true;
  101. }
  102. return false;
  103. }
  104. /// Lowers generic MASSV entries to PowerPC subtarget-specific MASSV entries.
  105. /// e.g.: __sind2_massv --> __sind2_P9 for a Power9 subtarget.
  106. /// Both function prototypes and their callsites are updated during lowering.
  107. bool PPCLowerMASSVEntries::lowerMASSVCall(CallInst *CI, Function &Func,
  108. Module &M,
  109. const PPCSubtarget *Subtarget) {
  110. if (CI->use_empty())
  111. return false;
  112. // Handling pow(x, 0.25), pow(x, 0.75), powf(x, 0.25), powf(x, 0.75)
  113. if (handlePowSpecialCases(CI, Func, M))
  114. return true;
  115. std::string MASSVEntryName = createMASSVFuncName(Func, Subtarget);
  116. FunctionCallee FCache = M.getOrInsertFunction(
  117. MASSVEntryName, Func.getFunctionType(), Func.getAttributes());
  118. CI->setCalledFunction(FCache);
  119. return true;
  120. }
  121. bool PPCLowerMASSVEntries::runOnModule(Module &M) {
  122. bool Changed = false;
  123. auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
  124. if (!TPC)
  125. return Changed;
  126. auto &TM = TPC->getTM<PPCTargetMachine>();
  127. const PPCSubtarget *Subtarget;
  128. for (Function &Func : M) {
  129. if (!Func.isDeclaration())
  130. continue;
  131. if (!isMASSVFunc(Func.getName()))
  132. continue;
  133. // Call to lowerMASSVCall() invalidates the iterator over users upon
  134. // replacing the users. Precomputing the current list of users allows us to
  135. // replace all the call sites.
  136. SmallVector<User *, 4> MASSVUsers;
  137. for (auto *User: Func.users())
  138. MASSVUsers.push_back(User);
  139. for (auto *User : MASSVUsers) {
  140. auto *CI = dyn_cast<CallInst>(User);
  141. if (!CI)
  142. continue;
  143. Subtarget = &TM.getSubtarget<PPCSubtarget>(*CI->getParent()->getParent());
  144. Changed |= lowerMASSVCall(CI, Func, M, Subtarget);
  145. }
  146. }
  147. return Changed;
  148. }
  149. char PPCLowerMASSVEntries::ID = 0;
  150. char &llvm::PPCLowerMASSVEntriesID = PPCLowerMASSVEntries::ID;
  151. INITIALIZE_PASS(PPCLowerMASSVEntries, DEBUG_TYPE, "Lower MASSV entries", false,
  152. false)
  153. ModulePass *llvm::createPPCLowerMASSVEntriesPass() {
  154. return new PPCLowerMASSVEntries();
  155. }