LLVM 20.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"
23#include "llvm/IR/Module.h"
24
25#define DEBUG_TYPE "ppc-gen-scalar-mass"
26
27using namespace llvm;
28
29namespace {
30
31class PPCGenScalarMASSEntries : public ModulePass {
32public:
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
52private:
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
64bool 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
74bool 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.
87bool 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
108bool 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(Func.users());
127
128 for (auto *User : TheUsers)
129 if (auto *CI = dyn_cast_or_null<CallInst>(User)) {
130 if (isCandidateSafeToLower(*CI))
131 Changed |= createScalarMASSCall(Iter->second, *CI, Func);
132 }
133 }
134
135 return Changed;
136}
137
138char PPCGenScalarMASSEntries::ID = 0;
139
140char &llvm::PPCGenScalarMASSEntriesID = PPCGenScalarMASSEntries::ID;
141
142INITIALIZE_PASS(PPCGenScalarMASSEntries, DEBUG_TYPE,
143 "Generate Scalar MASS entries", false, false)
144
146 return new PPCGenScalarMASSEntries();
147}
Module.h This file contains the declarations for the Module class.
#define DEBUG_TYPE
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition: InstrTypes.h:1504
This class represents a function call, abstracting a target machine's calling convention.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
bool hasNoNaNs() const LLVM_READONLY
Determine whether the no-NaNs flag is set.
bool hasNoInfs() const LLVM_READONLY
Determine whether the no-infs flag is set.
bool hasNoSignedZeros() const LLVM_READONLY
Determine whether the no-signed-zeros flag is set.
bool hasApproxFunc() const LLVM_READONLY
Determine whether the approximate-math-functions flag is set.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1210
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
Wrapper pass for TargetTransformInfo.
bool use_empty() const
Definition: Value.h:344
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
ModulePass * createPPCGenScalarMASSEntriesPass()
char & PPCGenScalarMASSEntriesID