47 #define DEBUG_TYPE "libcalls-shrinkwrap" 49 STATISTIC(NumWrappedOneCond,
"Number of One-Condition Wrappers Inserted");
50 STATISTIC(NumWrappedTwoCond,
"Number of Two-Condition Wrappers Inserted");
53 class LibCallsShrinkWrapLegacyPass :
public FunctionPass {
56 explicit LibCallsShrinkWrapLegacyPass() :
FunctionPass(ID) {
67 "Conditionally eliminate dead library calls",
false,
71 "Conditionally eliminate dead library
calls",
false, false)
81 for (
auto &CI : WorkList) {
82 LLVM_DEBUG(
dbgs() <<
"CDCE calls: " << CI->getCalledFunction()->getName()
108 auto Cond2 = createCond(BBBuilder, Arg, Cmp2, Val2);
109 auto Cond1 = createCond(BBBuilder, Arg, Cmp, Val);
110 return BBBuilder.
CreateOr(Cond1, Cond2);
126 return createCond(BBBuilder, Arg, Cmp, Val);
136 bool LibCallsShrinkWrap::performCallDomainErrorOnly(
CallInst *CI,
138 Value *Cond =
nullptr;
183 shrinkWrapCI(CI, Cond);
188 bool LibCallsShrinkWrap::performCallRangeErrorOnly(
CallInst *CI,
190 Value *Cond =
nullptr;
207 case LibFunc_sinhl: {
208 Cond = generateTwoRangeCond(CI, Func);
215 Cond = generateOneRangeCond(CI, Func);
221 shrinkWrapCI(CI, Cond);
226 bool LibCallsShrinkWrap::performCallErrors(
CallInst *CI,
228 Value *Cond =
nullptr;
275 Cond = generateCondForPow(CI, Func);
283 assert(Cond &&
"performCallErrors should not see an empty condition");
284 shrinkWrapCI(CI, Cond);
290 void LibCallsShrinkWrap::checkCandidate(
CallInst &CI) {
304 if (!TLI.getLibFunc(*Callee, Func) || !TLI.has(Func))
315 WorkList.push_back(&CI);
319 Value *LibCallsShrinkWrap::generateOneRangeCond(
CallInst *CI,
330 UpperBound = 11356.0f;
341 Value *LibCallsShrinkWrap::generateTwoRangeCond(
CallInst *CI,
343 float UpperBound, LowerBound;
347 LowerBound = -710.0f;
357 LowerBound = -11357.0f;
358 UpperBound = 11357.0f;
361 LowerBound = -745.0f;
365 LowerBound = -103.0f;
369 LowerBound = -11399.0f;
370 UpperBound = 11356.0f;
373 LowerBound = -323.0f;
381 LowerBound = -4950.0f;
382 UpperBound = 4932.0f;
385 LowerBound = -1074.0f;
386 UpperBound = 1023.0f;
389 LowerBound = -149.0f;
393 LowerBound = -16445.0f;
394 UpperBound = 11383.0f;
423 if (Func != LibFunc_pow) {
433 if (
ConstantFP *CF = dyn_cast<ConstantFP>(Base)) {
434 double D = CF->getValueAPF().convertToDouble();
436 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): constant base out of range\n");
454 if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {
478 return BBBuilder.
CreateOr(Cond0, Cond);
480 LLVM_DEBUG(
dbgs() <<
"Not handled pow(): base not from integer convert\n");
485 void LibCallsShrinkWrap::shrinkWrapCI(
CallInst *CI,
Value *Cond) {
486 assert(Cond !=
nullptr &&
"ShrinkWrapCI is not expecting an empty call inst");
495 assert(SuccBB &&
"The split block should have a single successor");
505 bool LibCallsShrinkWrap::perform(
CallInst *CI) {
508 assert(Callee &&
"perform() should apply to a non-empty callee");
509 TLI.getLibFunc(*Callee, Func);
510 assert(Func &&
"perform() is not expecting an empty function");
512 if (performCallDomainErrorOnly(CI, Func) || performCallRangeErrorOnly(CI, Func))
514 return performCallErrors(CI, Func);
517 void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(
AnalysisUsage &AU)
const {
527 LibCallsShrinkWrap CCDCE(TLI, DT);
529 bool Changed = CCDCE.perform();
537 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
538 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
539 auto *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
548 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.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
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...
amdgpu Simplify well known AMD library false Value * Callee
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.
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()
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.
amdgpu Simplify well known AMD library false Value Value * Arg
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
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)
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.
const BasicBlock * getParent() const