15 #define DEBUG_TYPE "amdgpu-simplifylib" 40 cl::desc(
"Enable pre-link mode optimizations"),
45 cl::desc(
"Comma separated list of functions to replace with native, or all"),
49 #define MATH_PI 3.14159265358979323846264338327950288419716939937511 50 #define MATH_E 2.71828182845904523536028747135266249775724709369996 51 #define MATH_SQRT2 1.41421356237309504880168872420969807856967187537695 53 #define MATH_LOG2E 1.4426950408889634073599246810018921374266459541529859 54 #define MATH_LOG10E 0.4342944819032518276511289189166050822943970058036665 56 #define MATH_LOG2_10 3.3219280948873623478703194294893901758648313930245806 58 #define MATH_RLOG2_10 0.3010299956639811952137388947244930267681898814621085 60 #define MATH_RLOG2_E 0.6931471805599453094172321214581765680755001343602552 70 bool AllNative =
false;
79 bool replaceWithNative(
CallInst *
CI,
const FuncInfo &FInfo);
81 bool parseFunctionName(
const StringRef& FMangledName,
82 FuncInfo *FInfo=
nullptr );
84 bool TDOFold(
CallInst *CI,
const FuncInfo &FInfo);
104 bool sincosUseNative(
CallInst *aCI,
const FuncInfo &FInfo);
107 bool evaluateScalarMathFunc(FuncInfo &FInfo,
double& Res0,
109 bool evaluateCall(
CallInst *aCI, FuncInfo &FInfo);
210 "Simplify well-known AMD library calls",
false,
false)
213 "Simplify well-known AMD library
calls",
false, false)
216 "Replace builtin math calls with that native versions.",
219 template <typename IRB>
222 CallInst *R = B.CreateCall(Callee, Arg, Name);
223 if (
Function*
F = dyn_cast<Function>(Callee))
228 template <
typename IRB>
232 if (
Function*
F = dyn_cast<Function>(Callee))
420 TableRef(
const TableEntry (&tbl)[
N]) : size(N), table(&tbl[0]) {}
475 Constant *AMDGPULibCalls::getFunction(
Module *M,
const FuncInfo& fInfo) {
483 bool AMDGPULibCalls::parseFunctionName(
const StringRef& FMangledName,
489 if (
auto Op = dyn_cast<FPMathOperator>(CI))
497 bool AMDGPULibCalls::useNativeFunc(
const StringRef F)
const {
503 AllNative = useNativeFunc(
"all") ||
508 bool AMDGPULibCalls::sincosUseNative(
CallInst *aCI,
const FuncInfo &FInfo) {
509 bool native_sin = useNativeFunc(
"sin");
510 bool native_cos = useNativeFunc(
"cos");
512 if (native_sin && native_cos) {
522 Constant *sinExpr = getFunction(M, nf);
526 Constant *cosExpr = getFunction(M, nf);
527 if (sinExpr && cosExpr) {
533 <<
" with native version of sin/cos");
550 !(AllNative || useNativeFunc(FInfo.
getName()))) {
555 return sincosUseNative(aCI, FInfo);
564 <<
" with native version");
578 if (!Callee->isDeclaration())
581 assert(Callee->
hasName() &&
"Invalid read_pipe/write_pipe function");
582 auto *M = Callee->getParent();
586 if (NumArg != 4 && NumArg != 6)
590 if (!isa<ConstantInt>(PacketSize) || !isa<ConstantInt>(PacketAlign))
592 unsigned Size = cast<ConstantInt>(PacketSize)->getZExtValue();
593 unsigned Align = cast<ConstantInt>(PacketAlign)->getZExtValue();
608 for (
unsigned I = 0;
I != PtrArgLoc; ++
I)
622 for (
unsigned I = 0;
I != PtrArgLoc; ++
I)
641 if (Callee == 0)
return false;
644 if (!parseFunctionName(Callee->
getName(), &FInfo))
659 if (
const FPMathOperator *FPOp = dyn_cast<const FPMathOperator>(CI))
662 if (TDOFold(CI, FInfo))
672 switch (FInfo.
getId()) {
677 "recip must be an either native or half function");
684 "divide must be an either native or half function");
690 return fold_pow(CI, B, FInfo);
709 return fold_sincos(CI, B, AA);
716 return fold_read_write_pipe(CI, B, FInfo);
731 int const sz = (int)tr.
size;
732 const TableEntry *
const ftbl = tr.
table;
738 for (
int eltNo = 0; eltNo <
getVecSize(FInfo); ++eltNo) {
740 CV->getElementAsConstant((
unsigned)eltNo));
741 assert(eltval &&
"Non-FP arguments in math function!");
743 for (
int i=0; i < sz; ++i) {
759 for (
unsigned i = 0; i < DVal.
size(); ++i) {
768 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *nval <<
"\n");
774 if (
ConstantFP *CF = dyn_cast<ConstantFP>(opr0)) {
775 for (
int i = 0; i < sz; ++i) {
776 if (CF->isExactlyValue(ftbl[i].input)) {
778 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *nval <<
"\n");
789 bool AMDGPULibCalls::replaceWithNative(
CallInst *CI,
const FuncInfo &FInfo) {
798 if (
Constant *FPExpr = getFunction(M, nf)) {
814 if (
ConstantFP *CF = dyn_cast<ConstantFP>(opr0)) {
821 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *nval <<
"\n");
841 opr1,
"__div2recip");
851 #if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L 854 return log(V) / 0.693147180559945309417;
860 const FuncInfo &FInfo) {
864 "fold_pow: encounter a wrong function call");
881 assert(VTy &&
"Oprand of vector function should be of vectortype");
886 CF = CDV ? dyn_cast_or_null<ConstantFP>(CDV->
getSplatValue()) :
nullptr;
887 CINT = CDV ? dyn_cast_or_null<ConstantInt>(CDV->
getSplatValue()) :
nullptr;
895 int ci_opr1 = (CINT ? (int)CINT->
getSExtValue() : 0x1111111);
897 if ((CF && CF->
isZero()) || (CINT && ci_opr1 == 0) || CZero) {
909 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr0 <<
"\n");
915 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr0 <<
" * " << *opr0
921 if ((CF && CF->
isExactlyValue(-1.0)) || (CINT && ci_opr1 == -1)) {
923 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> 1 / " << *opr0 <<
"\n");
937 if (
Constant *FPExpr = getFunction(M,
941 << FInfo.
getName().c_str() <<
"(" << *opr0 <<
")\n");
942 Value *nval = CreateCallEx(B,FPExpr, opr0, issqrt ?
"__pow2sqrt" 959 int ival = (int)dval;
960 if ((
double)ival == dval) {
963 ci_opr1 = 0x11111111;
968 unsigned abs_opr1 = (ci_opr1 < 0) ? -ci_opr1 : ci_opr1;
969 if (abs_opr1 <= 12) {
979 Value *valx2 =
nullptr;
981 while (abs_opr1 > 0) {
982 valx2 = valx2 ? B.
CreateFMul(valx2, valx2,
"__powx2") : opr0;
984 nval = nval ? B.
CreateFMul(nval, valx2,
"__powprod") : valx2;
995 nval = B.
CreateFDiv(cnval, nval,
"__1powprod");
998 << ((ci_opr1 < 0) ?
"1/prod(" :
"prod(") << *opr0
1011 bool needlog =
false;
1012 bool needabs =
false;
1013 bool needcopysign =
false;
1040 "Wrong vector size detected");
1047 if (V < 0.0) needcopysign =
true;
1053 for (
unsigned i=0; i < DVal.size(); ++i) {
1069 if (
const ConstantFP *CF = dyn_cast<ConstantFP>(opr1)) {
1073 if (y != (
double)(int64_t)y)
1081 ? (
double)CDV->getElementAsFloat(i)
1082 : CDV->getElementAsDouble(i);
1083 if (y != (
double)(int64_t)y)
1097 nval = CreateCallEx(B, AbsExpr, opr0,
"__fabs");
1099 nval = cnval ? cnval : opr0;
1106 nval = CreateCallEx(B,LogExpr, nval,
"__log2");
1114 nval = CreateCallEx(B,ExpExpr, nval,
"__exp2");
1121 if (
const VectorType *vTy = dyn_cast<VectorType>(rTy))
1137 <<
"exp2(" << *opr1 <<
" * log2(" << *opr0 <<
"))\n");
1144 const FuncInfo &FInfo) {
1154 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr0 <<
"\n");
1159 std::vector<const Type*> ParamsTys;
1160 ParamsTys.push_back(opr0->
getType());
1164 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> sqrt(" << *opr0 <<
")\n");
1165 Value *nval = CreateCallEx(B,FPExpr, opr0,
"__rootn2sqrt");
1169 }
else if (ci_opr1 == 3) {
1173 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> cbrt(" << *opr0 <<
")\n");
1174 Value *nval = CreateCallEx(B,FPExpr, opr0,
"__rootn2cbrt");
1178 }
else if (ci_opr1 == -1) {
1179 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> 1.0 / " << *opr0 <<
"\n");
1185 }
else if (ci_opr1 == -2) {
1186 std::vector<const Type*> ParamsTys;
1187 ParamsTys.push_back(opr0->
getType());
1193 Value *nval = CreateCallEx(B,FPExpr, opr0,
"__rootn2rsqrt");
1202 const FuncInfo &FInfo) {
1209 if ((CF0 && CF0->
isZero()) || (CF1 && CF1->isZero())) {
1211 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr2 <<
"\n");
1217 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr1 <<
" + " << *opr2
1223 if (CF1 && CF1->isExactlyValue(1.0f)) {
1225 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr0 <<
" + " << *opr2
1231 if (
ConstantFP *CF = dyn_cast<ConstantFP>(opr2)) {
1234 LLVM_DEBUG(
errs() <<
"AMDIC: " << *CI <<
" ---> " << *opr0 <<
" * " 1246 Constant* AMDGPULibCalls::getNativeFunction(
Module* M,
const FuncInfo& FInfo) {
1249 FuncInfo nf = FInfo;
1251 return getFunction(M, nf);
1256 const FuncInfo &FInfo) {
1259 if (
Constant *FPExpr = getNativeFunction(
1263 <<
"sqrt(" << *opr0 <<
")\n");
1264 Value *nval = CreateCallEx(B,FPExpr, opr0,
"__sqrt");
1286 int const MaxScan = 30;
1304 std::string
const PairName = fInfo.
mangle();
1308 CallInst *XI = dyn_cast_or_null<CallInst>(U);
1309 if (!XI || XI == CI || XI->
getParent() != CBB)
1320 for (
int I = MaxScan;
I > 0 && BBI != CBB->
begin(); --BBI, --
I) {
1321 if (cast<Instruction>(BBI) == XI) {
1329 if (!UI)
return false;
1337 Function *Fsincos = dyn_cast_or_null<Function>(getFunction(M, nf));
1338 if (!Fsincos)
return false;
1341 AllocaInst *Alloc = insertAlloca(UI, B,
"__sincos_");
1353 LLVM_DEBUG(
errs() <<
"AMDIC: fold_sincos (" << *CI <<
", " << *UI <<
") with " 1377 assert(BB &&
"Entry block not found!");
1384 const char *prefix) {
1390 std::string(prefix) + UI->
getName());
1396 bool AMDGPULibCalls::evaluateScalarMathFunc(FuncInfo &FInfo,
1397 double& Res0,
double& Res1,
1403 double opr0=0.0, opr1=0.0, opr2=0.0;
1404 ConstantFP *fpopr0 = dyn_cast_or_null<ConstantFP>(copr0);
1405 ConstantFP *fpopr1 = dyn_cast_or_null<ConstantFP>(copr1);
1406 ConstantFP *fpopr2 = dyn_cast_or_null<ConstantFP>(copr2);
1415 ? fpopr1->getValueAPF().convertToDouble()
1416 : (double)fpopr1->getValueAPF().convertToFloat();
1421 ? fpopr2->getValueAPF().convertToDouble()
1422 : (double)fpopr2->getValueAPF().convertToFloat();
1425 switch (FInfo.getId()) {
1426 default :
return false;
1434 Res0 =
log(opr0 +
sqrt(opr0*opr0 - 1.0));
1447 Res0 =
log(opr0 +
sqrt(opr0*opr0 + 1.0));
1460 Res0 = (
log(opr0 + 1.0) -
log(opr0 - 1.0))/2.0;
1468 Res0 = (opr0 < 0.0) ? -
pow(-opr0, 1.0/3.0) :
pow(opr0, 1.0/3.0);
1488 Res0 =
pow(2.0, opr0);
1492 Res0 =
pow(10.0, opr0);
1496 Res0 =
exp(opr0) - 1.0;
1504 Res0 =
log(opr0) /
log(2.0);
1508 Res0 =
log(opr0) /
log(10.0);
1512 Res0 = 1.0 /
sqrt(opr0);
1554 Res0 =
pow(opr0, opr1);
1558 if (
ConstantInt *iopr1 = dyn_cast_or_null<ConstantInt>(copr1)) {
1559 double val = (double)iopr1->getSExtValue();
1560 Res0 =
pow(opr0, val);
1567 if (
ConstantInt *iopr1 = dyn_cast_or_null<ConstantInt>(copr1)) {
1568 double val = (double)iopr1->getSExtValue();
1569 Res0 =
pow(opr0, 1.0 / val);
1584 Res0 = opr0 * opr1 + opr2;
1591 bool AMDGPULibCalls::evaluateCall(
CallInst *aCI, FuncInfo &FInfo) {
1600 if ((copr0 = dyn_cast<Constant>(aCI->
getArgOperand(0))) ==
nullptr)
1605 if ((copr1 = dyn_cast<Constant>(aCI->
getArgOperand(1))) ==
nullptr) {
1612 if ((copr2 = dyn_cast<Constant>(aCI->
getArgOperand(2))) ==
nullptr)
1619 double DVal0[16], DVal1[16];
1622 if (!evaluateScalarMathFunc(FInfo, DVal0[0],
1623 DVal1[0], copr0, copr1, copr2)) {
1632 Constant *celt1 = CDV1 ? CDV1->getElementAsConstant(i) :
nullptr;
1633 Constant *celt2 = CDV2 ? CDV2->getElementAsConstant(i) :
nullptr;
1634 if (!evaluateScalarMathFunc(FInfo, DVal0[i],
1635 DVal1[i], celt0, celt1, celt2)) {
1654 if (hasTwoResults) {
1663 if (hasTwoResults) {
1670 if (hasTwoResults) {
1673 "math function with ptr arg not supported yet");
1683 return new AMDGPUSimplifyLibCalls(Opt);
1687 return new AMDGPUUseNativeCalls();
1711 if (skipFunction(F))
1714 bool Changed =
false;
1715 auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
1723 for (
auto &BB : F) {
1732 if (Callee == 0)
continue;
1736 if(Simplifier.fold(CI, AA))
1744 if (skipFunction(F) ||
UseNative.empty())
1747 bool Changed =
false;
1748 for (
auto &BB : F) {
1757 if (Callee == 0)
continue;
1759 if(Simplifier.useNative(CI))
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double, and whose elements are just simple data values (i.e.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static const TableEntry tbl_sqrt[]
static const TableEntry tbl_log10[]
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
void dropAllReferences()
Drop all references to operands.
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
This class represents lattice values for constants.
Type * getParamType(unsigned i) const
Parameter type accessors.
Constant * getElementAsConstant(unsigned i) const
Return a Constant for a specified index's element.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
A Module instance is used to store all the information related to an LLVM module. ...
void setAlignment(unsigned Align)
static const TableEntry tbl_cospi[]
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
static const TableEntry tbl_cbrt[]
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr)
void push_back(const T &Elt)
void initializeAMDGPUSimplifyLibCallsPass(PassRegistry &)
This class represents a function call, abstracting a target machine's calling convention.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
bool isUnsafeMath(const CallInst *CI) const
float convertToFloat() const
Address space for private memory.
LLVMContext & getContext() const
All values hold a context through their type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
An instruction for reading from memory.
static const TableEntry tbl_erf[]
static IntegerType * getInt64Ty(LLVMContext &C)
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
void setPrefix(ENamePrefix PFX)
LLVMContext & getContext() const
Get the context in which this basic block lives.
static const TableEntry tbl_acosh[]
iterator begin()
Instruction iterator methods.
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * getArgOperand(unsigned i) const
static const TableEntry tbl_atanh[]
std::string getName() const
Get unmangled name for mangled library function and name for unmangled library function.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
bool hasAttributes() const
Return true if the builder has IR-level attributes.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, AliasAnalysis *AA=nullptr, bool *IsLoadCSE=nullptr, unsigned *NumScanedInst=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
LLVMContext & getContext() const
Get the global data context.
bool isIntegerTy() const
True if this is an instance of IntegerType.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Param * getLeads()
Get leading parameters for mangled lib functions.
void setCalledFunction(Value *Fn)
Sets the function called, including updating the function type.
static const TableEntry tbl_sinh[]
unsigned getNumArgs() const
INITIALIZE_PASS_BEGIN(AMDGPUSimplifyLibCalls, "amdgpu-simplifylib", "Simplify well-known AMD library calls", false, false) INITIALIZE_PASS_END(AMDGPUSimplifyLibCalls
All zero aggregate value.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
Type * getType() const
All values are typed, get the type of this value.
amdgpu Simplify well known AMD library false
static const TableEntry tbl_sinpi[]
bool isNegative() const
Return true if the sign bit is set.
static const TableEntry tbl_asinh[]
static const TableEntry tbl_tanpi[]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Value * CreateSIToFP(Value *V, Type *DestTy, const Twine &Name="")
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Value * CreateZExtOrBitCast(Value *V, Type *DestTy, const Twine &Name="")
amdgpu Simplify well known AMD library false Value * Callee
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
static const TableEntry tbl_log2[]
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
static AMDGPULibFunc::EType getArgType(const AMDGPULibFunc &FInfo)
const BasicBlock & getEntryBlock() const
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
TableRef(const TableEntry(&tbl)[N])
Type * getReturnType() const
Returns the type of the ret val.
bool fold(CallInst *CI, AliasAnalysis *AA=nullptr)
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Value * CreateFMul(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
static const TableEntry tbl_exp2[]
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM Basic Block Representation.
static Function * getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
Constant * getSplatValue() const
If this is a splat constant, meaning that all of the elements have the same value, return that value.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
Address space for flat memory.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ConstantFP - Floating Point Values [float, double].
static cl::opt< bool > EnablePreLink("amdgpu-prelink", cl::desc("Enable pre-link mode optimizations"), cl::init(false), cl::Hidden)
double convertToDouble() const
float getElementAsFloat(unsigned i) const
If this is an sequential container of floats, return the specified element as a float.
static const TableEntry tbl_atan[]
static const TableEntry tbl_sin[]
Represent the analysis usage information of a pass.
static const TableEntry tbl_rsqrt[]
static const TableEntry tbl_acospi[]
void setCallingConv(CallingConv::ID CC)
FunctionPass class - This class is used to implement most global optimizations.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Wrapper class for AMDGPULIbFuncImpl.
static const TableEntry tbl_expm1[]
self_iterator getIterator()
static int getVecSize(const AMDGPULibFunc &FInfo)
static Constant * getSplat(unsigned NumElts, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
static double log2(double V)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static unsigned getEPtrKindFromAddrSpace(unsigned AS)
void initializeAMDGPUUseNativeCallsPass(PassRegistry &)
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
static const TableEntry tbl_atanpi[]
const APFloat & getValueAPF() const
static const TableEntry tbl_exp10[]
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
static const TableEntry tbl_asinpi[]
static bool setFastFlags(Function &F, const TargetOptions &Options)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
ENamePrefix getPrefix() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Utility class for floating point operations which can have information about relaxed accuracy require...
Module.h This file contains the declarations for the Module class.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
AttributeList getAttributes() const
Return the parameter attributes for this call.
static const TableEntry tbl_log[]
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Class to represent vector types.
static Function * getOrInsertFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
static const TableEntry tbl_cosh[]
iterator_range< user_iterator > users()
InstListType::iterator iterator
Instruction iterators...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
amdgpu Simplify well known AMD library false Value Value * Arg
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
unsigned getNumUses() const
This method computes the number of uses of this Value.
unsigned getNumArgOperands() const
static const TableEntry tbl_exp[]
StringRef getValueAsString() const
Return the attribute's value as a string.
static const TableEntry tbl_tanh[]
bool isZero() const
Return true if the value is positive or negative zero.
double getElementAsDouble(unsigned i) const
If this is an sequential container of doubles, return the specified element as a double.
StringRef getName() const
Return a constant reference to the value's name.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
const Function * getParent() const
Return the enclosing method, or null if none.
static TableRef getOptTable(AMDGPULibFunc::EFuncId id)
FunctionPass * createAMDGPUSimplifyLibCallsPass(const TargetOptions &)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
static const TableEntry tbl_asin[]
Value * CreateFPToSI(Value *V, Type *DestTy, const Twine &Name="")
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
static cl::list< std::string > UseNative("amdgpu-use-native", cl::desc("Comma separated list of functions to replace with native, or all"), cl::CommaSeparated, cl::ValueOptional, cl::Hidden)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
static const TableEntry tbl_tan[]
static const TableEntry tbl_cos[]
Value * CreateFAdd(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
static bool HasNative(AMDGPULibFunc::EFuncId id)
Value * CreateFDiv(Value *L, Value *R, const Twine &Name="", MDNode *FPMD=nullptr)
const std::string to_string(const T &Value)
void replaceCall(Value *With)
void addAttributes(unsigned i, const AttrBuilder &Attrs)
adds the attributes to the list of attributes.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass * createAMDGPUUseNativeCallsPass()
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
amdgpu Simplify well known AMD library calls
static VectorType * get(Type *ElementType, unsigned NumElements)
This static method is the primary way to construct an VectorType.
static const TableEntry tbl_erfc[]
void setFastMathFlags(FastMathFlags NewFMF)
Set the fast-math flags to be used with generated fp-math operators.
BasicBlock::iterator GetInsertPoint() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
std::string mangle() const
Type * getElementType() const
bool isExactlyValue(const APFloat &V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
StringRef - Represent a constant reference to a string, i.e.
unsigned getNumElements() const
Return the number of elements in the array or vector.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
static Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static const TableEntry tbl_tgamma[]
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool useNative(CallInst *CI)
static const TableEntry tbl_acos[]
const BasicBlock * getParent() const
an instruction to allocate memory on the stack