46 #define DEBUG_TYPE "libcalls-shrinkwrap" 48 STATISTIC(NumWrappedOneCond,
"Number of One-Condition Wrappers Inserted");
49 STATISTIC(NumWrappedTwoCond,
"Number of Two-Condition Wrappers Inserted");
52 class LibCallsShrinkWrapLegacyPass :
public FunctionPass {
55 explicit LibCallsShrinkWrapLegacyPass() :
FunctionPass(ID) {
66 "Conditionally eliminate dead library calls",
false,
70 "Conditionally eliminate dead library
calls",
false, false)
80 for (
auto &CI : WorkList) {
81 LLVM_DEBUG(
dbgs() <<
"CDCE calls: " << CI->getCalledFunction()->getName()
107 auto Cond2 = createCond(BBBuilder, Arg, Cmp2, Val2);
108 auto Cond1 = createCond(BBBuilder, Arg, Cmp, Val);
109 return BBBuilder.
CreateOr(Cond1, Cond2);
125 return createCond(BBBuilder, Arg, Cmp, Val);
135 bool LibCallsShrinkWrap::performCallDomainErrorOnly(
CallInst *CI,
137 Value *Cond =
nullptr;
182 shrinkWrapCI(CI, Cond);
187 bool LibCallsShrinkWrap::performCallRangeErrorOnly(
CallInst *CI,
189 Value *Cond =
nullptr;
206 case LibFunc_sinhl: {
207 Cond = generateTwoRangeCond(CI, Func);
214 Cond = generateOneRangeCond(CI, Func);
220 shrinkWrapCI(CI, Cond);
225 bool LibCallsShrinkWrap::performCallErrors(
CallInst *CI,
227 Value *Cond =
nullptr;
274 Cond = generateCondForPow(CI, Func);
282 assert(Cond &&
"performCallErrors should not see an empty condition");
283 shrinkWrapCI(CI, Cond);
289 void LibCallsShrinkWrap::checkCandidate(
CallInst &CI) {
303 if (!TLI.getLibFunc(*Callee, Func) || !TLI.has(Func))
314 WorkList.push_back(&CI);
318 Value *LibCallsShrinkWrap::generateOneRangeCond(
CallInst *CI,
329 UpperBound = 11356.0f;
340 Value *LibCallsShrinkWrap::generateTwoRangeCond(
CallInst *CI,
342 float UpperBound, LowerBound;
346 LowerBound = -710.0f;
356 LowerBound = -11357.0f;
357 UpperBound = 11357.0f;
360 LowerBound = -745.0f;
364 LowerBound = -103.0f;
368 LowerBound = -11399.0f;
369 UpperBound = 11356.0f;
372 LowerBound = -323.0f;
380 LowerBound = -4950.0f;
381 UpperBound = 4932.0f;
384 LowerBound = -1074.0f;
385 UpperBound = 1023.0f;
388 LowerBound = -149.0f;
392 LowerBound = -16445.0f;
393 UpperBound = 11383.0f;
422 if (Func != LibFunc_pow) {
432 if (
ConstantFP *CF = dyn_cast<ConstantFP>(Base)) {
433 double D = CF->getValueAPF().convertToDouble();
435 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): constant base out of range\n");
453 if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {
477 return BBBuilder.
CreateOr(Cond0, Cond);
479 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): base not from integer convert\n");
484 void LibCallsShrinkWrap::shrinkWrapCI(
CallInst *CI,
Value *Cond) {
485 assert(Cond !=
nullptr &&
"ShrinkWrapCI is not expecting an empty call inst");
494 assert(SuccBB &&
"The split block should have a single successor");
504 bool LibCallsShrinkWrap::perform(
CallInst *CI) {
507 assert(Callee &&
"perform() should apply to a non-empty callee");
508 TLI.getLibFunc(*Callee, Func);
509 assert(Func &&
"perform() is not expecting an empty function");
511 if (performCallDomainErrorOnly(CI, Func) || performCallRangeErrorOnly(CI, Func))
513 return performCallErrors(CI, Func);
516 void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(
AnalysisUsage &AU)
const {
526 LibCallsShrinkWrap CCDCE(TLI, DT);
528 bool Changed = CCDCE.perform();
536 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
537 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
538 auto *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
547 return new LibCallsShrinkWrapLegacyPass();
Legacy wrapper pass to provide the GlobalsAAResult object.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
Base class for instruction visitors.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
This is the interface for a simple mod/ref and alias analysis over globals.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
This class represents a function call, abstracting a target machine's calling convention.
char & LibCallsShrinkWrapPassID
libcalls Conditionally eliminate dead library calls
0 1 0 0 True if ordered and less than
LLVMContext & getContext() const
All values hold a context through their type.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
static bool runImpl(Function &F, const TargetLibraryInfo &TLI, DominatorTree *DT)
LibCallsShrinkWrap(const TargetLibraryInfo &TLI, DominatorTree *DT)
INITIALIZE_PASS_BEGIN(LibCallsShrinkWrapLegacyPass, "libcalls-shrinkwrap", "Conditionally eliminate dead library calls", false, false) INITIALIZE_PASS_END(LibCallsShrinkWrapLegacyPass
Value * getArgOperand(unsigned i) const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
0 1 0 1 True if ordered and less than or equal
void setName(const Twine &Name)
Change the name of the value.
Type * getType() const
All values are typed, get the type of this value.
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void initializeLibCallsShrinkWrapLegacyPassPass(PassRegistry &)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Value * getOperand(unsigned i) const
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
void visitCallInst(CallInst &CI)
Value * CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static bool runOnFunction(Function &F, bool PostInlining)
A set of analyses that are preserved following a run of a transformation pass.
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.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
bool isNoBuiltin() const
Return true if the call should not be treated as a call to a builtin.
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].
Represent the analysis usage information of a pass.
Analysis pass providing a never-invalidated alias analysis result.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
0 0 1 0 True if ordered and greater than
const InstListType & getInstList() const
Return the underlying instruction list container.
Provides information about what library functions are available for the current target.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createLibCallsShrinkWrapPass()
amdgpu Simplify well known AMD library false FunctionCallee Callee
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
bool isX86_FP80Ty() const
Return true if this is x86 long double.
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
unsigned getNumArgOperands() const
iterator insert(iterator where, pointer New)
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Analysis pass providing the TargetLibraryInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
partially inline libcalls
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
0 0 0 1 True if ordered and equal
LLVM Value Representation.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
0 0 1 1 True if ordered and greater than or equal
static Constant * getFPExtend(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
const BasicBlock * getParent() const