48#define DEBUG_TYPE "libcalls-shrinkwrap"
50STATISTIC(NumWrappedOneCond,
"Number of One-Condition Wrappers Inserted");
51STATISTIC(NumWrappedTwoCond,
"Number of Two-Condition Wrappers Inserted");
54class LibCallsShrinkWrap :
public InstVisitor<LibCallsShrinkWrap> {
61 for (
auto &CI : WorkList) {
62 LLVM_DEBUG(
dbgs() <<
"CDCE calls: " << CI->getCalledFunction()->getName()
88 auto Cond2 = createCond(BBBuilder,
Arg, Cmp2, Val2);
89 auto Cond1 = createCond(BBBuilder,
Arg, Cmp, Val);
90 return BBBuilder.CreateOr(Cond1, Cond2);
97 if (!
Arg->getType()->isFloatTy())
106 return createCond(BBBuilder,
Arg, Cmp, Val);
116bool LibCallsShrinkWrap::performCallDomainErrorOnly(
CallInst *CI,
163 shrinkWrapCI(CI,
Cond);
168bool LibCallsShrinkWrap::performCallRangeErrorOnly(
CallInst *CI,
187 case LibFunc_sinhl: {
188 Cond = generateTwoRangeCond(CI, Func);
195 Cond = generateOneRangeCond(CI, Func);
201 shrinkWrapCI(CI,
Cond);
206bool LibCallsShrinkWrap::performCallErrors(
CallInst *CI,
255 Cond = generateCondForPow(CI, Func);
263 assert(
Cond &&
"performCallErrors should not see an empty condition");
264 shrinkWrapCI(CI,
Cond);
270void LibCallsShrinkWrap::checkCandidate(
CallInst &CI) {
284 if (!TLI.getLibFunc(*
Callee, Func) || !TLI.has(Func))
295 WorkList.push_back(&CI);
310 UpperBound = 11356.0f;
323 float UpperBound, LowerBound;
327 LowerBound = -710.0f;
337 LowerBound = -11357.0f;
338 UpperBound = 11357.0f;
341 LowerBound = -745.0f;
345 LowerBound = -103.0f;
349 LowerBound = -11399.0f;
350 UpperBound = 11356.0f;
353 LowerBound = -323.0f;
361 LowerBound = -4950.0f;
362 UpperBound = 4932.0f;
365 LowerBound = -1074.0f;
366 UpperBound = 1023.0f;
369 LowerBound = -149.0f;
373 LowerBound = -16445.0f;
374 UpperBound = 11383.0f;
403 if (Func != LibFunc_pow) {
414 double D = CF->getValueAPF().convertToDouble();
416 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): constant base out of range\n");
422 if (!
Exp->getType()->isFloatTy())
433 unsigned Opcode =
I->getOpcode();
434 if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {
435 unsigned BW =
I->getOperand(0)->getType()->getPrimitiveSizeInBits();
451 if (!
Exp->getType()->isFloatTy())
453 if (!
Base->getType()->isFloatTy())
460 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): base not from integer convert\n");
466 assert(
Cond !=
nullptr &&
"ShrinkWrapCI is not expecting an empty call inst");
475 assert(SuccBB &&
"The split block should have a single successor");
485bool LibCallsShrinkWrap::perform(
CallInst *CI) {
488 assert(
Callee &&
"perform() should apply to a non-empty callee");
489 TLI.getLibFunc(*
Callee, Func);
490 assert(Func &&
"perform() is not expecting an empty function");
492 if (performCallDomainErrorOnly(CI, Func) || performCallRangeErrorOnly(CI, Func))
494 return performCallErrors(CI, Func);
499 if (
F.hasFnAttribute(Attribute::OptimizeForSize))
501 LibCallsShrinkWrap CCDCE(TLI, DT);
503 bool Changed = CCDCE.perform();
506 assert(!DT || DT->
verify(DominatorTree::VerificationLevel::Fast));
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runImpl(Function &F, const TargetLowering &TLI)
This is the interface for a simple mod/ref and alias analysis over globals.
static bool runImpl(Function &F, const TargetLibraryInfo &TLI, DominatorTree *DT)
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
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
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
static Constant * getFPExtend(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ConstantFP - Floating Point Values [float, double].
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...
This is an important base class in LLVM.
Analysis pass which computes a DominatorTree.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
LLVMContext & getContext() const
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Base class for instruction visitors.
RetTy visitCallInst(CallInst &I)
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
const BasicBlock * getParent() const
SymbolTableList< Instruction >::iterator insertInto(BasicBlock *ParentBB, SymbolTableList< Instruction >::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isX86_FP80Ty() const
Return true if this is x86 long double.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void setName(const Twine &Name)
Change the name of the value.
LLVMContext & getContext() const
All values hold a context through their type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...