47#define DEBUG_TYPE "libcalls-shrinkwrap"
49STATISTIC(NumWrappedOneCond,
"Number of One-Condition Wrappers Inserted");
50STATISTIC(NumWrappedTwoCond,
"Number of Two-Condition Wrappers Inserted");
53class LibCallsShrinkWrap :
public InstVisitor<LibCallsShrinkWrap> {
56 : TLI(TLI), DTU(DTU){};
57 void visitCallInst(CallInst &CI) { checkCandidate(CI); }
60 for (
auto &CI : WorkList) {
61 LLVM_DEBUG(
dbgs() <<
"CDCE calls: " << CI->getCalledFunction()->getName()
72 bool perform(CallInst *CI);
73 void checkCandidate(CallInst &CI);
74 void shrinkWrapCI(CallInst *CI,
Value *
Cond);
75 bool performCallDomainErrorOnly(CallInst *CI,
const LibFunc &Func);
76 bool performCallErrors(CallInst *CI,
const LibFunc &Func);
77 bool performCallRangeErrorOnly(CallInst *CI,
const LibFunc &Func);
78 Value *generateOneRangeCond(CallInst *CI,
const LibFunc &Func);
79 Value *generateTwoRangeCond(CallInst *CI,
const LibFunc &Func);
80 Value *generateCondForPow(CallInst *CI,
const LibFunc &Func);
87 auto Cond2 = createCond(BBBuilder, Arg2, Cmp2, Val2);
88 auto Cond1 = createCond(BBBuilder, Arg, Cmp, Val);
89 return BBBuilder.CreateOr(Cond1, Cond2);
96 return createOrCond(CI, Arg, Cmp, Val, Arg, Cmp2, Val2);
114 return createCond(BBBuilder, Arg, Cmp, Val);
120 return createCond(CI, Arg, Cmp, Val);
123 const TargetLibraryInfo &TLI;
130bool LibCallsShrinkWrap::performCallDomainErrorOnly(
CallInst *CI,
177 shrinkWrapCI(CI,
Cond);
182bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst *CI,
201 case LibFunc_sinhl: {
202 Cond = generateTwoRangeCond(CI, Func);
209 Cond = generateOneRangeCond(CI, Func);
215 shrinkWrapCI(CI,
Cond);
220bool LibCallsShrinkWrap::performCallErrors(CallInst *CI,
269 Cond = generateCondForPow(CI, Func);
277 assert(
Cond &&
"performCallErrors should not see an empty condition");
278 shrinkWrapCI(CI,
Cond);
284void LibCallsShrinkWrap::checkCandidate(CallInst &CI) {
309 WorkList.push_back(&CI);
313Value *LibCallsShrinkWrap::generateOneRangeCond(CallInst *CI,
324 UpperBound = 11356.0f;
335Value *LibCallsShrinkWrap::generateTwoRangeCond(CallInst *CI,
337 float UpperBound, LowerBound;
341 LowerBound = -710.0f;
351 LowerBound = -11357.0f;
352 UpperBound = 11357.0f;
355 LowerBound = -745.0f;
359 LowerBound = -103.0f;
363 LowerBound = -11399.0f;
364 UpperBound = 11356.0f;
367 LowerBound = -323.0f;
375 LowerBound = -4950.0f;
376 UpperBound = 4932.0f;
379 LowerBound = -1074.0f;
380 UpperBound = 1023.0f;
383 LowerBound = -149.0f;
387 LowerBound = -16445.0f;
388 UpperBound = 11383.0f;
414Value *LibCallsShrinkWrap::generateCondForPow(CallInst *CI,
417 if (Func != LibFunc_pow) {
427 double D = CF->getValueAPF().convertToDouble();
429 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): constant base out of range\n");
443 unsigned Opcode =
I->getOpcode();
444 if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {
445 unsigned BW =
I->getOperand(0)->getType()->getPrimitiveSizeInBits();
462 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): base not from integer convert\n");
467void LibCallsShrinkWrap::shrinkWrapCI(CallInst *CI,
Value *
Cond) {
468 assert(
Cond !=
nullptr &&
"ShrinkWrapCI is not expecting an empty call inst");
469 MDNode *BranchWeights =
470 MDBuilder(CI->
getContext()).createUnlikelyBranchWeights();
477 assert(SuccBB &&
"The split block should have a single successor");
487bool LibCallsShrinkWrap::perform(CallInst *CI) {
490 assert(Callee &&
"perform() should apply to a non-empty callee");
492 assert(Func &&
"perform() is not expecting an empty function");
494 if (performCallDomainErrorOnly(CI, Func) || performCallRangeErrorOnly(CI, Func))
496 return performCallErrors(CI, Func);
504 LibCallsShrinkWrap CCDCE(TLI, DTU);
506 bool Changed = CCDCE.perform();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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, AssumptionCache *AC)
This is the interface for a simple mod/ref and alias analysis over globals.
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
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.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI 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
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.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
BasicBlock * GetInsertBlock() const
void setIsFPConstrained(bool IsCon)
Enable/Disable use of constrained floating point math.
LLVMContext & getContext() const
Base class for instruction visitors.
LLVM_ABI void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
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.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
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.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI Constant * ConstantFoldCastInstruction(unsigned opcode, Constant *V, Type *DestTy)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.