LLVM  14.0.0git
PPCLowerMASSVEntries.cpp
Go to the documentation of this file.
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 
16 #include "PPC.h"
17 #include "PPCSubtarget.h"
18 #include "PPCTargetMachine.h"
19 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Module.h"
24 
25 #define DEBUG_TYPE "ppc-lower-massv-entries"
26 
27 using namespace llvm;
28 
29 namespace {
30 
31 static StringRef MASSVFuncs[] = {
32 #define TLI_DEFINE_MASSV_VECFUNCS_NAMES
33 #include "llvm/Analysis/VecFuncs.def"
34 };
35 
36 class PPCLowerMASSVEntries : public ModulePass {
37 public:
38  static char ID;
39 
40  PPCLowerMASSVEntries() : ModulePass(ID) {}
41 
42  bool runOnModule(Module &M) override;
43 
44  StringRef getPassName() const override { return "PPC Lower MASS Entries"; }
45 
46  void getAnalysisUsage(AnalysisUsage &AU) const override {
48  }
49 
50 private:
51  static bool isMASSVFunc(StringRef Name);
52  static StringRef getCPUSuffix(const PPCSubtarget *Subtarget);
53  static std::string createMASSVFuncName(Function &Func,
54  const PPCSubtarget *Subtarget);
55  bool handlePowSpecialCases(CallInst *CI, Function &Func, Module &M);
56  bool lowerMASSVCall(CallInst *CI, Function &Func, Module &M,
57  const PPCSubtarget *Subtarget);
58 };
59 
60 } // namespace
61 
62 /// Checks if the specified function name represents an entry in the MASSV
63 /// library.
64 bool PPCLowerMASSVEntries::isMASSVFunc(StringRef Name) {
65  return llvm::is_contained(MASSVFuncs, Name);
66 }
67 
68 // FIXME:
69 /// Returns a string corresponding to the specified PowerPC subtarget. e.g.:
70 /// "_P8" for Power8, "_P9" for Power9. The string is used as a suffix while
71 /// generating subtarget-specific MASSV library functions. Current support
72 /// includes minimum subtarget Power8 for Linux and Power7 for AIX.
73 StringRef PPCLowerMASSVEntries::getCPUSuffix(const PPCSubtarget *Subtarget) {
74  // Assume generic when Subtarget is unavailable.
75  if (!Subtarget)
76  return "";
77  // TODO: add _P10 enties to Linux MASS lib and remove the check for AIX
78  if (Subtarget->isAIXABI() && Subtarget->hasP10Vector())
79  return "_P10";
80  if (Subtarget->hasP9Vector())
81  return "_P9";
82  if (Subtarget->hasP8Vector())
83  return "_P8";
84  if (Subtarget->isAIXABI())
85  return "_P7";
86 
88  "Mininum subtarget for -vector-library=MASSV option is Power8 on Linux "
89  "and Power7 on AIX when vectorization is not disabled.");
90 }
91 
92 /// Creates PowerPC subtarget-specific name corresponding to the specified
93 /// generic MASSV function, and the PowerPC subtarget.
94 std::string
95 PPCLowerMASSVEntries::createMASSVFuncName(Function &Func,
96  const PPCSubtarget *Subtarget) {
97  StringRef Suffix = getCPUSuffix(Subtarget);
98  auto GenericName = Func.getName().str();
99  std::string MASSVEntryName = GenericName + Suffix.str();
100  return MASSVEntryName;
101 }
102 
103 /// If there are proper fast-math flags, this function creates llvm.pow
104 /// intrinsics when the exponent is 0.25 or 0.75.
105 bool PPCLowerMASSVEntries::handlePowSpecialCases(CallInst *CI, Function &Func,
106  Module &M) {
107  if (Func.getName() != "__powf4" && Func.getName() != "__powd2")
108  return false;
109 
110  if (Constant *Exp = dyn_cast<Constant>(CI->getArgOperand(1)))
111  if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(Exp->getSplatValue())) {
112  // If the argument is 0.75 or 0.25 it is cheaper to turn it into pow
113  // intrinsic so that it could be optimzed as sequence of sqrt's.
114  if (!CI->hasNoInfs() || !CI->hasApproxFunc())
115  return false;
116 
117  if (!CFP->isExactlyValue(0.75) && !CFP->isExactlyValue(0.25))
118  return false;
119 
120  if (CFP->isExactlyValue(0.25) && !CI->hasNoSignedZeros())
121  return false;
122 
123  CI->setCalledFunction(
124  Intrinsic::getDeclaration(&M, Intrinsic::pow, CI->getType()));
125  return true;
126  }
127 
128  return false;
129 }
130 
131 /// Lowers generic MASSV entries to PowerPC subtarget-specific MASSV entries.
132 /// e.g.: __sind2_massv --> __sind2_P9 for a Power9 subtarget.
133 /// Both function prototypes and their callsites are updated during lowering.
134 bool PPCLowerMASSVEntries::lowerMASSVCall(CallInst *CI, Function &Func,
135  Module &M,
136  const PPCSubtarget *Subtarget) {
137  if (CI->use_empty())
138  return false;
139 
140  // Handling pow(x, 0.25), pow(x, 0.75), powf(x, 0.25), powf(x, 0.75)
141  if (handlePowSpecialCases(CI, Func, M))
142  return true;
143 
144  std::string MASSVEntryName = createMASSVFuncName(Func, Subtarget);
145  FunctionCallee FCache = M.getOrInsertFunction(
146  MASSVEntryName, Func.getFunctionType(), Func.getAttributes());
147 
148  CI->setCalledFunction(FCache);
149 
150  return true;
151 }
152 
153 bool PPCLowerMASSVEntries::runOnModule(Module &M) {
154  bool Changed = false;
155 
156  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
157  if (!TPC)
158  return Changed;
159 
160  auto &TM = TPC->getTM<PPCTargetMachine>();
161  const PPCSubtarget *Subtarget;
162 
163  for (Function &Func : M) {
164  if (!Func.isDeclaration())
165  continue;
166 
167  if (!isMASSVFunc(Func.getName()))
168  continue;
169 
170  // Call to lowerMASSVCall() invalidates the iterator over users upon
171  // replacing the users. Precomputing the current list of users allows us to
172  // replace all the call sites.
173  SmallVector<User *, 4> MASSVUsers(Func.users());
174 
175  for (auto *User : MASSVUsers) {
176  auto *CI = dyn_cast<CallInst>(User);
177  if (!CI)
178  continue;
179 
180  Subtarget = &TM.getSubtarget<PPCSubtarget>(*CI->getParent()->getParent());
181  Changed |= lowerMASSVCall(CI, Func, M, Subtarget);
182  }
183  }
184 
185  return Changed;
186 }
187 
188 char PPCLowerMASSVEntries::ID = 0;
189 
191 
192 INITIALIZE_PASS(PPCLowerMASSVEntries, DEBUG_TYPE, "Lower MASSV entries", false,
193  false)
194 
196  return new PPCLowerMASSVEntries();
197 }
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1399
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::BasicBlock::getParent
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:107
llvm::Function
Definition: Function.h:62
llvm::CallBase::setCalledFunction
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition: InstrTypes.h:1434
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1177
llvm::PPCSubtarget::hasP8Vector
bool hasP8Vector() const
Definition: PPCSubtarget.h:281
llvm::PPCSubtarget::hasP9Vector
bool hasP9Vector() const
Definition: PPCSubtarget.h:284
Module.h
llvm::Instruction::hasApproxFunc
bool hasApproxFunc() const
Determine whether the approximate-math-functions flag is set.
Definition: Instruction.cpp:285
STLExtras.h
PPCSubtarget.h
llvm::PPCSubtarget
Definition: PPCSubtarget.h:71
llvm::User
Definition: User.h:44
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::ConstantFP
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:257
PPC.h
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:244
DEBUG_TYPE
#define DEBUG_TYPE
Definition: PPCLowerMASSVEntries.cpp:25
llvm::Value::use_empty
bool use_empty() const
Definition: Value.h:344
llvm::PPCSubtarget::isAIXABI
bool isAIXABI() const
Definition: PPCSubtarget.h:365
llvm::createPPCLowerMASSVEntriesPass
ModulePass * createPPCLowerMASSVEntriesPass()
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::TargetTransformInfoWrapperPass
Wrapper pass for TargetTransformInfo.
Definition: TargetTransformInfo.h:2474
INITIALIZE_PASS
INITIALIZE_PASS(PPCLowerMASSVEntries, DEBUG_TYPE, "Lower MASSV entries", false, false) ModulePass *llvm
Definition: PPCLowerMASSVEntries.cpp:192
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1714
TargetPassConfig.h
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
llvm::ifs::IFSSymbolType::Func
@ Func
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::PPCTargetMachine
Common code between 32-bit and 64-bit PowerPC targets.
Definition: PPCTargetMachine.h:25
llvm::PPCLowerMASSVEntriesID
char & PPCLowerMASSVEntriesID
Definition: PPCLowerMASSVEntries.cpp:190
Instructions.h
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1343
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
TargetTransformInfo.h
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::codeview::CompileSym3Flags::Exp
@ Exp
llvm::Instruction::hasNoInfs
bool hasNoInfs() const
Determine whether the no-infs flag is set.
Definition: Instruction.cpp:265
llvm::Instruction::hasNoSignedZeros
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
Definition: Instruction.cpp:270
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1478
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
PPCTargetMachine.h
llvm::PPCSubtarget::hasP10Vector
bool hasP10Vector() const
Definition: PPCSubtarget.h:286
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38