21#include "llvm/IR/IntrinsicsAMDGPU.h"
26#define DEBUG_TYPE "amdgpu-simplifylib"
31 cl::desc(
"Enable pre-link mode optimizations"),
36 cl::desc(
"Comma separated list of functions to replace with native, or all"),
40#define MATH_PI numbers::pi
41#define MATH_E numbers::e
42#define MATH_SQRT2 numbers::sqrt2
43#define MATH_SQRT1_2 numbers::inv_sqrt2
55 bool AllNative =
false;
88 bool evaluateScalarMathFunc(
const FuncInfo &FInfo,
double& Res0,
173char AMDGPUSimplifyLibCalls::ID = 0;
174char AMDGPUUseNativeCalls::ID = 0;
177 "Simplify well-known AMD library calls",
false,
false)
183 "Replace builtin math
calls with that native versions.",
186template <typename IRB>
191 R->setCallingConv(
F->getCallingConv());
195template <
typename IRB>
200 R->setCallingConv(
F->getCallingConv());
359 case AMDGPULibFunc::EI_DIVIDE:
360 case AMDGPULibFunc::EI_COS:
361 case AMDGPULibFunc::EI_EXP:
362 case AMDGPULibFunc::EI_EXP2:
363 case AMDGPULibFunc::EI_EXP10:
364 case AMDGPULibFunc::EI_LOG:
365 case AMDGPULibFunc::EI_LOG2:
366 case AMDGPULibFunc::EI_LOG10:
367 case AMDGPULibFunc::EI_POWR:
368 case AMDGPULibFunc::EI_RECIP:
369 case AMDGPULibFunc::EI_RSQRT:
370 case AMDGPULibFunc::EI_SIN:
371 case AMDGPULibFunc::EI_SINCOS:
372 case AMDGPULibFunc::EI_SQRT:
373 case AMDGPULibFunc::EI_TAN:
394 case AMDGPULibFunc::EI_NCOS:
401 case AMDGPULibFunc::EI_NEXP2:
406 case AMDGPULibFunc::EI_NLOG2:
409 case AMDGPULibFunc::EI_NRSQRT:
411 case AMDGPULibFunc::EI_NSIN:
415 case AMDGPULibFunc::EI_NSQRT:
442bool AMDGPULibCalls::parseFunctionName(
const StringRef &FMangledName,
448 if (
auto Op = dyn_cast<FPMathOperator>(
CI))
452 Attribute Attr =
F->getFnAttribute(
"unsafe-fp-math");
456bool AMDGPULibCalls::useNativeFunc(
const StringRef F)
const {
461 AllNative = useNativeFunc(
"all") ||
467 bool native_sin = useNativeFunc(
"sin");
468 bool native_cos = useNativeFunc(
"cos");
470 if (native_sin && native_cos) {
485 if (sinExpr && cosExpr) {
491 <<
" with native version of sin/cos");
505 if (!parseFunctionName(
Callee->getName(), FInfo) || !FInfo.
isMangled() ||
508 !(AllNative || useNativeFunc(FInfo.
getName()))) {
513 return sincosUseNative(aCI, FInfo);
522 <<
" with native version");
536 if (!
Callee->isDeclaration())
539 assert(
Callee->hasName() &&
"Invalid read_pipe/write_pipe function");
540 auto *M =
Callee->getParent();
541 auto &Ctx = M->getContext();
542 std::string
Name = std::string(
Callee->getName());
544 if (NumArg != 4 && NumArg != 6)
548 if (!isa<ConstantInt>(PacketSize) || !isa<ConstantInt>(PacketAlign))
550 unsigned Size = cast<ConstantInt>(PacketSize)->getZExtValue();
551 Align Alignment = cast<ConstantInt>(PacketAlign)->getAlignValue();
552 if (Alignment !=
Size)
566 for (
unsigned I = 0;
I != PtrArgLoc; ++
I)
578 auto *BCast =
B.CreatePointerCast(PtrArg, PtrTy);
580 for (
unsigned I = 0;
I != PtrArgLoc; ++
I)
582 Args.push_back(BCast);
584 auto *NCI =
B.CreateCall(
F, Args);
611 B.setFastMathFlags(FPOp->getFastMathFlags());
613 switch (
Callee->getIntrinsicID()) {
616 case Intrinsic::amdgcn_wavefrontsize:
621 if (!parseFunctionName(
Callee->getName(), FInfo))
628 if (TDOFold(
CI, FInfo))
638 switch (FInfo.
getId()) {
643 "recip must be an either native or half function");
650 "divide must be an either native or half function");
656 return fold_pow(
CI,
B, FInfo);
675 return fold_sincos(
CI,
B, AA);
682 return fold_read_write_pipe(
CI,
B, FInfo);
697 int const sz = (int)tr.
size();
703 for (
int eltNo = 0; eltNo <
getVecSize(FInfo); ++eltNo) {
705 CV->getElementAsConstant((
unsigned)eltNo));
706 assert(eltval &&
"Non-FP arguments in math function!");
708 for (
int i=0; i < sz; ++i) {
724 for (
unsigned i = 0; i < DVal.
size(); ++i) {
739 if (
ConstantFP *CF = dyn_cast<ConstantFP>(opr0)) {
740 for (
int i = 0; i < sz; ++i) {
741 if (CF->isExactlyValue(tr[i].input)) {
758 if (
ConstantFP *CF = dyn_cast<ConstantFP>(opr0)) {
785 opr1,
"__div2recip");
786 Value *nval =
B.CreateFMul(opr0, nval1,
"__div2mul");
795#if _XOPEN_SOURCE >= 600 || defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L
808 "fold_pow: encounter a wrong function call");
818 CZero = dyn_cast<ConstantAggregateZero>(opr1);
821 CF = dyn_cast<ConstantFP>(opr1);
822 CINT = dyn_cast<ConstantInt>(opr1);
825 assert(VTy &&
"Oprand of vector function should be of vectortype");
826 eltType = VTy->getElementType();
830 CF = CDV ? dyn_cast_or_null<ConstantFP>(CDV->
getSplatValue()) : nullptr;
831 CINT = CDV ? dyn_cast_or_null<ConstantInt>(CDV->
getSplatValue()) : nullptr;
839 int ci_opr1 = (CINT ? (int)CINT->
getSExtValue() : 0x1111111);
841 if ((CF && CF->
isZero()) || (CINT && ci_opr1 == 0) || CZero) {
859 LLVM_DEBUG(
errs() <<
"AMDIC: " << *
CI <<
" ---> " << *opr0 <<
" * " << *opr0
861 Value *nval =
B.CreateFMul(opr0, opr0,
"__pow2");
865 if ((CF && CF->
isExactlyValue(-1.0)) || (CINT && ci_opr1 == -1)) {
872 Value *nval =
B.CreateFDiv(cnval, opr0,
"__powrecip");
886 << FInfo.
getName().c_str() <<
"(" << *opr0 <<
")\n");
887 Value *nval = CreateCallEx(
B,FPExpr, opr0, issqrt ?
"__pow2sqrt"
904 int ival = (int)dval;
905 if ((
double)ival == dval) {
908 ci_opr1 = 0x11111111;
913 unsigned abs_opr1 = (ci_opr1 < 0) ? -ci_opr1 : ci_opr1;
914 if (abs_opr1 <= 12) {
924 Value *valx2 =
nullptr;
926 while (abs_opr1 > 0) {
927 valx2 = valx2 ?
B.CreateFMul(valx2, valx2,
"__powx2") : opr0;
929 nval = nval ?
B.CreateFMul(nval, valx2,
"__powprod") : valx2;
940 nval =
B.CreateFDiv(cnval, nval,
"__1powprod");
943 << ((ci_opr1 < 0) ?
"1/prod(" :
"prod(") << *opr0
956 bool needlog =
false;
957 bool needabs =
false;
958 bool needcopysign =
false;
961 CF = dyn_cast<ConstantFP>(opr0);
968 V =
log2(std::abs(V));
985 "Wrong vector size detected");
992 if (V < 0.0) needcopysign =
true;
993 V =
log2(std::abs(V));
998 for (
unsigned i=0; i < DVal.
size(); ++i) {
1014 if (
const ConstantFP *CF = dyn_cast<ConstantFP>(opr1)) {
1018 if (y != (
double)(int64_t)y)
1028 if (y != (
double)(int64_t)y)
1042 nval = CreateCallEx(
B, AbsExpr, opr0,
"__fabs");
1044 nval = cnval ? cnval : opr0;
1051 nval = CreateCallEx(
B,LogExpr, nval,
"__log2");
1056 opr1 =
B.CreateSIToFP(opr1, nval->
getType(),
"pownI2F");
1058 nval =
B.CreateFMul(opr1, nval,
"__ylogx");
1059 nval = CreateCallEx(
B,ExpExpr, nval,
"__exp2");
1066 if (
const auto *vTy = dyn_cast<FixedVectorType>(rTy))
1071 opr_n =
B.CreateZExtOrBitCast(opr_n, nTy,
"__ytou");
1073 opr_n =
B.CreateFPToSI(opr1, nTy,
"__ytou");
1075 Value *sign =
B.CreateShl(opr_n, size-1,
"__yeven");
1076 sign =
B.CreateAnd(
B.CreateBitCast(opr0, nTy), sign,
"__pow_sign");
1077 nval =
B.CreateOr(
B.CreateBitCast(nval, nTy), sign);
1078 nval =
B.CreateBitCast(nval, opr0->
getType());
1082 <<
"exp2(" << *opr1 <<
" * log2(" << *opr0 <<
"))\n");
1108 Value *nval = CreateCallEx(
B,FPExpr, opr0,
"__rootn2sqrt");
1112 }
else if (ci_opr1 == 3) {
1117 Value *nval = CreateCallEx(
B,FPExpr, opr0,
"__rootn2cbrt");
1121 }
else if (ci_opr1 == -1) {
1128 }
else if (ci_opr1 == -2) {
1134 Value *nval = CreateCallEx(
B,FPExpr, opr0,
"__rootn2rsqrt");
1148 ConstantFP *CF0 = dyn_cast<ConstantFP>(opr0);
1149 ConstantFP *CF1 = dyn_cast<ConstantFP>(opr1);
1150 if ((CF0 && CF0->
isZero()) || (CF1 && CF1->
isZero())) {
1158 LLVM_DEBUG(
errs() <<
"AMDIC: " << *
CI <<
" ---> " << *opr1 <<
" + " << *opr2
1160 Value *nval =
B.CreateFAdd(opr1, opr2,
"fmaadd");
1166 LLVM_DEBUG(
errs() <<
"AMDIC: " << *
CI <<
" ---> " << *opr0 <<
" + " << *opr2
1168 Value *nval =
B.CreateFAdd(opr0, opr2,
"fmaadd");
1172 if (
ConstantFP *CF = dyn_cast<ConstantFP>(opr2)) {
1177 Value *nval =
B.CreateFMul(opr0, opr1,
"fmamul");
1193 return getFunction(M, nf);
1205 <<
"sqrt(" << *opr0 <<
")\n");
1206 Value *nval = CreateCallEx(
B,FPExpr, opr0,
"__sqrt");
1228 int const MaxScan = 30;
1229 bool Changed =
false;
1232 LoadInst *LI = dyn_cast<LoadInst>(CArgVal);
1248 std::string
const PairName = fInfo.
mangle();
1252 CallInst *XI = dyn_cast_or_null<CallInst>(U);
1264 for (
int I = MaxScan;
I > 0 && BBI != CBB->
begin(); --BBI, --
I) {
1265 if (cast<Instruction>(BBI) == XI) {
1288 B.SetInsertPoint(UI);
1296 P =
B.CreateAddrSpaceCast(
Alloc, PTy);
1299 LLVM_DEBUG(
errs() <<
"AMDIC: fold_sincos (" << *
CI <<
", " << *UI <<
") with "
1303 B.SetInsertPoint(&*ItOld);
1331 unsigned N =
ST.getWavefrontSize();
1345 assert(BB &&
"Entry block not found!");
1352 const char *prefix) {
1356 B.SetInsertPoint(&*ItNew);
1358 B.CreateAlloca(RetType,
nullptr, std::string(prefix) + UI->
getName());
1359 Alloc->setAlignment(
1364bool AMDGPULibCalls::evaluateScalarMathFunc(
const FuncInfo &FInfo,
1365 double& Res0,
double& Res1,
1371 double opr0=0.0, opr1=0.0, opr2=0.0;
1372 ConstantFP *fpopr0 = dyn_cast_or_null<ConstantFP>(copr0);
1373 ConstantFP *fpopr1 = dyn_cast_or_null<ConstantFP>(copr1);
1374 ConstantFP *fpopr2 = dyn_cast_or_null<ConstantFP>(copr2);
1393 switch (FInfo.getId()) {
1394 default :
return false;
1402 Res0 = log(opr0 + sqrt(opr0*opr0 - 1.0));
1415 Res0 = log(opr0 + sqrt(opr0*opr0 + 1.0));
1428 Res0 = (log(opr0 + 1.0) - log(opr0 - 1.0))/2.0;
1436 Res0 = (opr0 < 0.0) ? -pow(-opr0, 1.0/3.0) : pow(opr0, 1.0/3.0);
1456 Res0 = pow(2.0, opr0);
1460 Res0 = pow(10.0, opr0);
1464 Res0 = exp(opr0) - 1.0;
1472 Res0 = log(opr0) / log(2.0);
1476 Res0 = log(opr0) / log(10.0);
1480 Res0 = 1.0 / sqrt(opr0);
1522 Res0 = pow(opr0, opr1);
1526 if (
ConstantInt *iopr1 = dyn_cast_or_null<ConstantInt>(copr1)) {
1527 double val = (double)iopr1->getSExtValue();
1528 Res0 = pow(opr0, val);
1535 if (
ConstantInt *iopr1 = dyn_cast_or_null<ConstantInt>(copr1)) {
1536 double val = (double)iopr1->getSExtValue();
1537 Res0 = pow(opr0, 1.0 / val);
1552 Res0 = opr0 * opr1 + opr2;
1560 int numArgs = (int)aCI->
arg_size();
1568 if ((copr0 = dyn_cast<Constant>(aCI->
getArgOperand(0))) ==
nullptr)
1573 if ((copr1 = dyn_cast<Constant>(aCI->
getArgOperand(1))) ==
nullptr) {
1580 if ((copr2 = dyn_cast<Constant>(aCI->
getArgOperand(2))) ==
nullptr)
1587 double DVal0[16], DVal1[16];
1590 if (FuncVecSize == 1) {
1591 if (!evaluateScalarMathFunc(FInfo, DVal0[0],
1592 DVal1[0], copr0, copr1, copr2)) {
1599 for (
int i = 0; i < FuncVecSize; ++i) {
1603 if (!evaluateScalarMathFunc(FInfo, DVal0[i],
1604 DVal1[i], celt0, celt1, celt2)) {
1612 if (FuncVecSize == 1) {
1618 SmallVector <float, 0> FVal0, FVal1;
1619 for (
int i = 0; i < FuncVecSize; ++i)
1623 if (hasTwoResults) {
1624 for (
int i = 0; i < FuncVecSize; ++i)
1632 if (hasTwoResults) {
1639 if (hasTwoResults) {
1642 "math function with ptr arg not supported yet");
1652 return new AMDGPUSimplifyLibCalls(
TM);
1656 return new AMDGPUUseNativeCalls();
1659bool AMDGPUSimplifyLibCalls::runOnFunction(
Function &
F) {
1660 if (skipFunction(
F))
1663 bool Changed =
false;
1664 auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
1667 F.printAsOperand(
dbgs(),
false,
F.getParent());
dbgs() <<
'\n';);
1669 for (
auto &BB :
F) {
1685 if(Simplifier.
fold(CI, AA))
1697 bool Changed =
false;
1701 F.printAsOperand(
dbgs(),
false,
F.getParent());
dbgs() <<
'\n';);
1703 for (
auto &BB :
F) {
1719 if (Simplifier.
fold(CI, AA))
1726bool AMDGPUUseNativeCalls::runOnFunction(
Function &
F) {
1730 bool Changed =
false;
1731 for (
auto &BB :
F) {
1758 bool Changed =
false;
1759 for (
auto &BB :
F) {
static const TableEntry tbl_log[]
static const TableEntry tbl_tgamma[]
static AMDGPULibFunc::EType getArgType(const AMDGPULibFunc &FInfo)
static const TableEntry tbl_expm1[]
static const TableEntry tbl_asinpi[]
static const TableEntry tbl_cos[]
static const TableEntry tbl_exp10[]
static const TableEntry tbl_rsqrt[]
static const TableEntry tbl_atanh[]
static const TableEntry tbl_cosh[]
static const TableEntry tbl_asin[]
static const TableEntry tbl_sinh[]
static const TableEntry tbl_acos[]
static const TableEntry tbl_tan[]
amdgpu Simplify well known AMD library false FunctionCallee Callee
static const TableEntry tbl_cospi[]
static const TableEntry tbl_tanpi[]
static cl::opt< bool > EnablePreLink("amdgpu-prelink", cl::desc("Enable pre-link mode optimizations"), cl::init(false), cl::Hidden)
static bool HasNative(AMDGPULibFunc::EFuncId id)
ArrayRef< TableEntry > TableRef
static int getVecSize(const AMDGPULibFunc &FInfo)
static const TableEntry tbl_sin[]
static const TableEntry tbl_atan[]
static const TableEntry tbl_log2[]
static const TableEntry tbl_acospi[]
amdgpu Simplify well known AMD library calls
static const TableEntry tbl_sqrt[]
static const TableEntry tbl_asinh[]
static TableRef getOptTable(AMDGPULibFunc::EFuncId id)
static const TableEntry tbl_acosh[]
static const TableEntry tbl_exp[]
static const TableEntry tbl_cbrt[]
static const TableEntry tbl_sinpi[]
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
static const TableEntry tbl_atanpi[]
static const TableEntry tbl_erf[]
static const TableEntry tbl_log10[]
static const TableEntry tbl_erfc[]
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)
static const TableEntry tbl_tanh[]
static const TableEntry tbl_exp2[]
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
AMD GCN specific subclass of TargetSubtarget.
typename CallsiteContextGraph< DerivedCCG, FuncTy, CallTy >::FuncInfo FuncInfo
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Replace intrinsics with calls to vector library
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
void replaceCall(Value *With)
AMDGPULibCalls(const TargetMachine *TM_=nullptr)
bool useNative(CallInst *CI)
bool fold(CallInst *CI, AliasAnalysis *AA=nullptr)
bool isUnsafeMath(const CallInst *CI) const
static unsigned getEPtrKindFromAddrSpace(unsigned AS)
Wrapper class for AMDGPULIbFuncImpl.
static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr)
std::string getName() const
Get unmangled name for mangled library function and name for unmangled library function.
static FunctionCallee getOrInsertFunction(llvm::Module *M, const AMDGPULibFunc &fInfo)
void setPrefix(ENamePrefix PFX)
std::string mangle() const
Param * getLeads()
Get leading parameters for mangled lib functions.
ENamePrefix getPrefix() const
unsigned getNumArgs() const
double convertToDouble() const
Converts this APFloat to host double value.
float convertToFloat() const
Converts this APFloat to host float value.
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
bool getValueAsBool() const
Return the attribute's value as a boolean.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
LLVMContext & getContext() const
Get the context in which this basic block lives.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
AttributeList getAttributes() const
Return the parameter attributes for this call.
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
All zero aggregate value.
double getElementAsDouble(unsigned i) const
If this is an sequential container of doubles, return the specified element as a double.
float getElementAsFloat(unsigned i) const
If this is an sequential container of floats, return the specified element as a float.
unsigned getNumElements() const
Return the number of elements in the array or vector.
Constant * getElementAsConstant(unsigned i) const
Return a Constant for a specified index's element.
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
Constant * getSplatValue() const
If this is a splat constant, meaning that all of the elements have the same value,...
static Constant * getSplat(unsigned NumElts, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
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...
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
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...
bool isNegative() const
Return true if the sign bit is set.
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 ...
bool isZero() const
Return true if the value is positive or negative zero.
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
This is an important base class in LLVM.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Utility class for floating point operations which can have information about relaxed accuracy require...
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionType * getFunctionType()
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Type * getParamType(unsigned i) const
Parameter type accessors.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
Module * getParent()
Get the module that this global value is contained inside of...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
bool contains_insensitive(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
StringRef getTargetFeatureString() const
StringRef getTargetCPU() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
void dropAllReferences()
Drop all references to operands.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
unsigned getNumUses() const
This method computes the number of uses of this Value.
StringRef getName() const
Return a constant reference to the value's name.
self_iterator getIterator()
@ FLAT_ADDRESS
Address space for flat memory.
@ PRIVATE_ADDRESS
Address space for private memory.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void initializeAMDGPUUseNativeCallsPass(PassRegistry &)
static double log2(double V)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, AAResults *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 ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void initializeAMDGPUSimplifyLibCallsPass(PassRegistry &)
FunctionPass * createAMDGPUSimplifyLibCallsPass(const TargetMachine *)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionPass * createAMDGPUUseNativeCallsPass()
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This struct is a compact representation of a valid (non-zero power of two) alignment.