LLVM  15.0.0git
PPCGenScalarMASSEntries.cpp
Go to the documentation of this file.
1 //===-- PPCGenScalarMASSEntries.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 transformation converts standard math functions into their
10 // corresponding MASS (scalar) entries for PowerPC targets.
11 // Following are examples of such conversion:
12 // tanh ---> __xl_tanh_finite
13 // Such lowering is legal under the fast-math option.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "PPC.h"
18 #include "PPCSubtarget.h"
19 #include "PPCTargetMachine.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Module.h"
24 
25 #define DEBUG_TYPE "ppc-gen-scalar-mass"
26 
27 using namespace llvm;
28 
29 namespace {
30 
31 class PPCGenScalarMASSEntries : public ModulePass {
32 public:
33  static char ID;
34 
35  PPCGenScalarMASSEntries() : ModulePass(ID) {
36  ScalarMASSFuncs = {
37 #define TLI_DEFINE_SCALAR_MASS_FUNCS
38 #include "llvm/Analysis/ScalarFuncs.def"
39  };
40  }
41 
42  bool runOnModule(Module &M) override;
43 
44  StringRef getPassName() const override {
45  return "PPC Generate Scalar MASS Entries";
46  }
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
50  }
51 
52 private:
53  std::map<StringRef, StringRef> ScalarMASSFuncs;
54  bool isCandidateSafeToLower(const CallInst &CI) const;
55  bool isFiniteCallSafe(const CallInst &CI) const;
56  bool createScalarMASSCall(StringRef MASSEntry, CallInst &CI,
57  Function &Func) const;
58 };
59 
60 } // namespace
61 
62 // Returns true if 'afn' flag exists on the call instruction with the math
63 // function
64 bool PPCGenScalarMASSEntries::isCandidateSafeToLower(const CallInst &CI) const {
65  // skip functions with no scalar or vector FP type (like cosisin)
66  if (!isa<FPMathOperator>(CI))
67  return false;
68 
69  return CI.hasApproxFunc();
70 }
71 
72 // Returns true if 'nnan', 'ninf' and 'nsz' flags exist on the call instruction
73 // with the math function
74 bool PPCGenScalarMASSEntries::isFiniteCallSafe(const CallInst &CI) const {
75  // skip functions with no scalar or vector FP type (like cosisin)
76  if (!isa<FPMathOperator>(CI))
77  return false;
78 
79  // FIXME: no-errno and trapping-math need to be set for MASS converstion
80  // but they don't have IR representation.
81  return CI.hasNoNaNs() && CI.hasNoInfs() && CI.hasNoSignedZeros();
82 }
83 
84 /// Lowers scalar math functions to scalar MASS functions.
85 /// e.g.: tanh --> __xl_tanh_finite or __xl_tanh
86 /// Both function prototype and its callsite is updated during lowering.
87 bool PPCGenScalarMASSEntries::createScalarMASSCall(StringRef MASSEntry,
88  CallInst &CI,
89  Function &Func) const {
90  if (CI.use_empty())
91  return false;
92 
93  Module *M = Func.getParent();
94  assert(M && "Expecting a valid Module");
95 
96  std::string MASSEntryStr = MASSEntry.str();
97  if (isFiniteCallSafe(CI))
98  MASSEntryStr += "_finite";
99 
100  FunctionCallee FCache = M->getOrInsertFunction(
101  MASSEntryStr, Func.getFunctionType(), Func.getAttributes());
102 
103  CI.setCalledFunction(FCache);
104 
105  return true;
106 }
107 
108 bool PPCGenScalarMASSEntries::runOnModule(Module &M) {
109  bool Changed = false;
110 
111  auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
112  if (!TPC || skipModule(M))
113  return false;
114 
115  for (Function &Func : M) {
116  if (!Func.isDeclaration())
117  continue;
118 
119  auto Iter = ScalarMASSFuncs.find(Func.getName());
120  if (Iter == ScalarMASSFuncs.end())
121  continue;
122 
123  // The call to createScalarMASSCall() invalidates the iterator over users
124  // upon replacing the users. Precomputing the current list of users allows
125  // us to replace all the call sites.
126  SmallVector<User *, 4> TheUsers;
127  for (auto *User : Func.users())
128  TheUsers.push_back(User);
129 
130  for (auto *User : TheUsers)
131  if (auto *CI = dyn_cast_or_null<CallInst>(User)) {
132  if (isCandidateSafeToLower(*CI))
133  Changed |= createScalarMASSCall(Iter->second, *CI, Func);
134  }
135  }
136 
137  return Changed;
138 }
139 
141 
143 
144 INITIALIZE_PASS(PPCGenScalarMASSEntries, DEBUG_TYPE,
145  "Generate Scalar MASS entries", false, false)
146 
148  return new PPCGenScalarMASSEntries();
149 }
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
llvm::Function
Definition: Function.h:60
llvm::CallBase::setCalledFunction
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition: InstrTypes.h:1435
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
Module.h
llvm::Instruction::hasApproxFunc
bool hasApproxFunc() const
Determine whether the approximate-math-functions flag is set.
Definition: Instruction.cpp:284
DEBUG_TYPE
#define DEBUG_TYPE
Definition: PPCGenScalarMASSEntries.cpp:25
PPCSubtarget.h
llvm::User
Definition: User.h:44
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::createPPCGenScalarMASSEntriesPass
ModulePass * createPPCGenScalarMASSEntriesPass()
PPC.h
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:249
llvm::Value::use_empty
bool use_empty() const
Definition: Value.h:344
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::TargetTransformInfoWrapperPass
Wrapper pass for TargetTransformInfo.
Definition: TargetTransformInfo.h:2541
TargetPassConfig.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:58
llvm::ifs::IFSSymbolType::Func
@ Func
llvm::Instruction::hasNoNaNs
bool hasNoNaNs() const
Determine whether the no-NaNs flag is set.
Definition: Instruction.cpp:259
Instructions.h
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::Instruction::hasNoInfs
bool hasNoInfs() const
Determine whether the no-infs flag is set.
Definition: Instruction.cpp:264
llvm::Instruction::hasNoSignedZeros
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
Definition: Instruction.cpp:269
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1461
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
INITIALIZE_PASS
INITIALIZE_PASS(PPCGenScalarMASSEntries, DEBUG_TYPE, "Generate Scalar MASS entries", false, false) ModulePass *llvm
Definition: PPCGenScalarMASSEntries.cpp:144
PPCTargetMachine.h
llvm::PPCGenScalarMASSEntriesID
char & PPCGenScalarMASSEntriesID
Definition: PPCGenScalarMASSEntries.cpp:142
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38