PPCLowerMASSVEntries.cpp 6.4 KB

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