1 //===-- LibCallsShrinkWrap.cpp ----------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass shrink-wraps a call to function if the result is not used.
10 // The call can set errno but is otherwise side effect free. For example:
15 // Even if the result of library call is not being used, the compiler cannot
16 // safely delete the call because the function can set errno on error
18 // Note in many functions, the error condition solely depends on the incoming
19 // parameter. In this optimization, we can generate the condition can lead to
20 // the errno to shrink-wrap the call. Since the chances of hitting the error
21 // condition is low, the runtime call is effectively eliminated.
23 // These partially dead calls are usually results of C++ abstraction penalty
24 // exposed by inlining.
26 //===----------------------------------------------------------------------===//
28 #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/Statistic.h"
31 #include "llvm/Analysis/GlobalsModRef.h"
32 #include "llvm/Analysis/TargetLibraryInfo.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/Dominators.h"
35 #include "llvm/IR/Function.h"
36 #include "llvm/IR/IRBuilder.h"
37 #include "llvm/IR/InstVisitor.h"
38 #include "llvm/IR/Instructions.h"
39 #include "llvm/IR/MDBuilder.h"
40 #include "llvm/InitializePasses.h"
41 #include "llvm/Pass.h"
42 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
45 #define DEBUG_TYPE "libcalls-shrinkwrap"
47 STATISTIC(NumWrappedOneCond
, "Number of One-Condition Wrappers Inserted");
48 STATISTIC(NumWrappedTwoCond
, "Number of Two-Condition Wrappers Inserted");
51 class LibCallsShrinkWrapLegacyPass
: public FunctionPass
{
53 static char ID
; // Pass identification, replacement for typeid
54 explicit LibCallsShrinkWrapLegacyPass() : FunctionPass(ID
) {
55 initializeLibCallsShrinkWrapLegacyPassPass(
56 *PassRegistry::getPassRegistry());
58 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
59 bool runOnFunction(Function
&F
) override
;
63 char LibCallsShrinkWrapLegacyPass::ID
= 0;
64 INITIALIZE_PASS_BEGIN(LibCallsShrinkWrapLegacyPass
, "libcalls-shrinkwrap",
65 "Conditionally eliminate dead library calls", false,
67 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass
)
68 INITIALIZE_PASS_END(LibCallsShrinkWrapLegacyPass
, "libcalls-shrinkwrap",
69 "Conditionally eliminate dead library calls", false, false)
72 class LibCallsShrinkWrap
: public InstVisitor
<LibCallsShrinkWrap
> {
74 LibCallsShrinkWrap(const TargetLibraryInfo
&TLI
, DominatorTree
*DT
)
76 void visitCallInst(CallInst
&CI
) { checkCandidate(CI
); }
79 for (auto &CI
: WorkList
) {
80 LLVM_DEBUG(dbgs() << "CDCE calls: " << CI
->getCalledFunction()->getName()
84 LLVM_DEBUG(dbgs() << "Transformed\n");
91 bool perform(CallInst
*CI
);
92 void checkCandidate(CallInst
&CI
);
93 void shrinkWrapCI(CallInst
*CI
, Value
*Cond
);
94 bool performCallDomainErrorOnly(CallInst
*CI
, const LibFunc
&Func
);
95 bool performCallErrors(CallInst
*CI
, const LibFunc
&Func
);
96 bool performCallRangeErrorOnly(CallInst
*CI
, const LibFunc
&Func
);
97 Value
*generateOneRangeCond(CallInst
*CI
, const LibFunc
&Func
);
98 Value
*generateTwoRangeCond(CallInst
*CI
, const LibFunc
&Func
);
99 Value
*generateCondForPow(CallInst
*CI
, const LibFunc
&Func
);
101 // Create an OR of two conditions.
102 Value
*createOrCond(CallInst
*CI
, CmpInst::Predicate Cmp
, float Val
,
103 CmpInst::Predicate Cmp2
, float Val2
) {
104 IRBuilder
<> BBBuilder(CI
);
105 Value
*Arg
= CI
->getArgOperand(0);
106 auto Cond2
= createCond(BBBuilder
, Arg
, Cmp2
, Val2
);
107 auto Cond1
= createCond(BBBuilder
, Arg
, Cmp
, Val
);
108 return BBBuilder
.CreateOr(Cond1
, Cond2
);
111 // Create a single condition using IRBuilder.
112 Value
*createCond(IRBuilder
<> &BBBuilder
, Value
*Arg
, CmpInst::Predicate Cmp
,
114 Constant
*V
= ConstantFP::get(BBBuilder
.getContext(), APFloat(Val
));
115 if (!Arg
->getType()->isFloatTy())
116 V
= ConstantExpr::getFPExtend(V
, Arg
->getType());
117 return BBBuilder
.CreateFCmp(Cmp
, Arg
, V
);
120 // Create a single condition.
121 Value
*createCond(CallInst
*CI
, CmpInst::Predicate Cmp
, float Val
) {
122 IRBuilder
<> BBBuilder(CI
);
123 Value
*Arg
= CI
->getArgOperand(0);
124 return createCond(BBBuilder
, Arg
, Cmp
, Val
);
127 const TargetLibraryInfo
&TLI
;
129 SmallVector
<CallInst
*, 16> WorkList
;
131 } // end anonymous namespace
133 // Perform the transformation to calls with errno set by domain error.
134 bool LibCallsShrinkWrap::performCallDomainErrorOnly(CallInst
*CI
,
135 const LibFunc
&Func
) {
136 Value
*Cond
= nullptr;
139 case LibFunc_acos
: // DomainError: (x < -1 || x > 1)
140 case LibFunc_acosf
: // Same as acos
141 case LibFunc_acosl
: // Same as acos
142 case LibFunc_asin
: // DomainError: (x < -1 || x > 1)
143 case LibFunc_asinf
: // Same as asin
144 case LibFunc_asinl
: // Same as asin
147 Cond
= createOrCond(CI
, CmpInst::FCMP_OLT
, -1.0f
, CmpInst::FCMP_OGT
, 1.0f
);
150 case LibFunc_cos
: // DomainError: (x == +inf || x == -inf)
151 case LibFunc_cosf
: // Same as cos
152 case LibFunc_cosl
: // Same as cos
153 case LibFunc_sin
: // DomainError: (x == +inf || x == -inf)
154 case LibFunc_sinf
: // Same as sin
155 case LibFunc_sinl
: // Same as sin
158 Cond
= createOrCond(CI
, CmpInst::FCMP_OEQ
, INFINITY
, CmpInst::FCMP_OEQ
,
162 case LibFunc_acosh
: // DomainError: (x < 1)
163 case LibFunc_acoshf
: // Same as acosh
164 case LibFunc_acoshl
: // Same as acosh
167 Cond
= createCond(CI
, CmpInst::FCMP_OLT
, 1.0f
);
170 case LibFunc_sqrt
: // DomainError: (x < 0)
171 case LibFunc_sqrtf
: // Same as sqrt
172 case LibFunc_sqrtl
: // Same as sqrt
175 Cond
= createCond(CI
, CmpInst::FCMP_OLT
, 0.0f
);
181 shrinkWrapCI(CI
, Cond
);
185 // Perform the transformation to calls with errno set by range error.
186 bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst
*CI
,
187 const LibFunc
&Func
) {
188 Value
*Cond
= nullptr;
205 case LibFunc_sinhl
: {
206 Cond
= generateTwoRangeCond(CI
, Func
);
209 case LibFunc_expm1
: // RangeError: (709, inf)
210 case LibFunc_expm1f
: // RangeError: (88, inf)
211 case LibFunc_expm1l
: // RangeError: (11356, inf)
213 Cond
= generateOneRangeCond(CI
, Func
);
219 shrinkWrapCI(CI
, Cond
);
223 // Perform the transformation to calls with errno set by combination of errors.
224 bool LibCallsShrinkWrap::performCallErrors(CallInst
*CI
,
225 const LibFunc
&Func
) {
226 Value
*Cond
= nullptr;
229 case LibFunc_atanh
: // DomainError: (x < -1 || x > 1)
230 // PoleError: (x == -1 || x == 1)
231 // Overall Cond: (x <= -1 || x >= 1)
232 case LibFunc_atanhf
: // Same as atanh
233 case LibFunc_atanhl
: // Same as atanh
236 Cond
= createOrCond(CI
, CmpInst::FCMP_OLE
, -1.0f
, CmpInst::FCMP_OGE
, 1.0f
);
239 case LibFunc_log
: // DomainError: (x < 0)
240 // PoleError: (x == 0)
241 // Overall Cond: (x <= 0)
242 case LibFunc_logf
: // Same as log
243 case LibFunc_logl
: // Same as log
244 case LibFunc_log10
: // Same as log
245 case LibFunc_log10f
: // Same as log
246 case LibFunc_log10l
: // Same as log
247 case LibFunc_log2
: // Same as log
248 case LibFunc_log2f
: // Same as log
249 case LibFunc_log2l
: // Same as log
250 case LibFunc_logb
: // Same as log
251 case LibFunc_logbf
: // Same as log
252 case LibFunc_logbl
: // Same as log
255 Cond
= createCond(CI
, CmpInst::FCMP_OLE
, 0.0f
);
258 case LibFunc_log1p
: // DomainError: (x < -1)
259 // PoleError: (x == -1)
260 // Overall Cond: (x <= -1)
261 case LibFunc_log1pf
: // Same as log1p
262 case LibFunc_log1pl
: // Same as log1p
265 Cond
= createCond(CI
, CmpInst::FCMP_OLE
, -1.0f
);
268 case LibFunc_pow
: // DomainError: x < 0 and y is noninteger
269 // PoleError: x == 0 and y < 0
270 // RangeError: overflow or underflow
273 Cond
= generateCondForPow(CI
, Func
);
281 assert(Cond
&& "performCallErrors should not see an empty condition");
282 shrinkWrapCI(CI
, Cond
);
286 // Checks if CI is a candidate for shrinkwrapping and put it into work list if
288 void LibCallsShrinkWrap::checkCandidate(CallInst
&CI
) {
289 if (CI
.isNoBuiltin())
291 // A possible improvement is to handle the calls with the return value being
292 // used. If there is API for fast libcall implementation without setting
293 // errno, we can use the same framework to direct/wrap the call to the fast
294 // API in the error free path, and leave the original call in the slow path.
299 Function
*Callee
= CI
.getCalledFunction();
302 if (!TLI
.getLibFunc(*Callee
, Func
) || !TLI
.has(Func
))
307 // TODO: Handle long double in other formats.
308 Type
*ArgType
= CI
.getArgOperand(0)->getType();
309 if (!(ArgType
->isFloatTy() || ArgType
->isDoubleTy() ||
310 ArgType
->isX86_FP80Ty()))
313 WorkList
.push_back(&CI
);
316 // Generate the upper bound condition for RangeError.
317 Value
*LibCallsShrinkWrap::generateOneRangeCond(CallInst
*CI
,
318 const LibFunc
&Func
) {
321 case LibFunc_expm1
: // RangeError: (709, inf)
324 case LibFunc_expm1f
: // RangeError: (88, inf)
327 case LibFunc_expm1l
: // RangeError: (11356, inf)
328 UpperBound
= 11356.0f
;
331 llvm_unreachable("Unhandled library call!");
335 return createCond(CI
, CmpInst::FCMP_OGT
, UpperBound
);
338 // Generate the lower and upper bound condition for RangeError.
339 Value
*LibCallsShrinkWrap::generateTwoRangeCond(CallInst
*CI
,
340 const LibFunc
&Func
) {
341 float UpperBound
, LowerBound
;
343 case LibFunc_cosh
: // RangeError: (x < -710 || x > 710)
344 case LibFunc_sinh
: // Same as cosh
345 LowerBound
= -710.0f
;
348 case LibFunc_coshf
: // RangeError: (x < -89 || x > 89)
349 case LibFunc_sinhf
: // Same as coshf
353 case LibFunc_coshl
: // RangeError: (x < -11357 || x > 11357)
354 case LibFunc_sinhl
: // Same as coshl
355 LowerBound
= -11357.0f
;
356 UpperBound
= 11357.0f
;
358 case LibFunc_exp
: // RangeError: (x < -745 || x > 709)
359 LowerBound
= -745.0f
;
362 case LibFunc_expf
: // RangeError: (x < -103 || x > 88)
363 LowerBound
= -103.0f
;
366 case LibFunc_expl
: // RangeError: (x < -11399 || x > 11356)
367 LowerBound
= -11399.0f
;
368 UpperBound
= 11356.0f
;
370 case LibFunc_exp10
: // RangeError: (x < -323 || x > 308)
371 LowerBound
= -323.0f
;
374 case LibFunc_exp10f
: // RangeError: (x < -45 || x > 38)
378 case LibFunc_exp10l
: // RangeError: (x < -4950 || x > 4932)
379 LowerBound
= -4950.0f
;
380 UpperBound
= 4932.0f
;
382 case LibFunc_exp2
: // RangeError: (x < -1074 || x > 1023)
383 LowerBound
= -1074.0f
;
384 UpperBound
= 1023.0f
;
386 case LibFunc_exp2f
: // RangeError: (x < -149 || x > 127)
387 LowerBound
= -149.0f
;
390 case LibFunc_exp2l
: // RangeError: (x < -16445 || x > 11383)
391 LowerBound
= -16445.0f
;
392 UpperBound
= 11383.0f
;
395 llvm_unreachable("Unhandled library call!");
399 return createOrCond(CI
, CmpInst::FCMP_OGT
, UpperBound
, CmpInst::FCMP_OLT
,
403 // For pow(x,y), We only handle the following cases:
404 // (1) x is a constant && (x >= 1) && (x < MaxUInt8)
405 // Cond is: (y > 127)
406 // (2) x is a value coming from an integer type.
407 // (2.1) if x's bit_size == 8
408 // Cond: (x <= 0 || y > 128)
409 // (2.2) if x's bit_size is 16
410 // Cond: (x <= 0 || y > 64)
411 // (2.3) if x's bit_size is 32
412 // Cond: (x <= 0 || y > 32)
413 // Support for powl(x,y) and powf(x,y) are TBD.
415 // Note that condition can be more conservative than the actual condition
416 // (i.e. we might invoke the calls that will not set the errno.).
418 Value
*LibCallsShrinkWrap::generateCondForPow(CallInst
*CI
,
419 const LibFunc
&Func
) {
420 // FIXME: LibFunc_powf and powl TBD.
421 if (Func
!= LibFunc_pow
) {
422 LLVM_DEBUG(dbgs() << "Not handled powf() and powl()\n");
426 Value
*Base
= CI
->getArgOperand(0);
427 Value
*Exp
= CI
->getArgOperand(1);
428 IRBuilder
<> BBBuilder(CI
);
430 // Constant Base case.
431 if (ConstantFP
*CF
= dyn_cast
<ConstantFP
>(Base
)) {
432 double D
= CF
->getValueAPF().convertToDouble();
433 if (D
< 1.0f
|| D
> APInt::getMaxValue(8).getZExtValue()) {
434 LLVM_DEBUG(dbgs() << "Not handled pow(): constant base out of range\n");
439 Constant
*V
= ConstantFP::get(CI
->getContext(), APFloat(127.0f
));
440 if (!Exp
->getType()->isFloatTy())
441 V
= ConstantExpr::getFPExtend(V
, Exp
->getType());
442 return BBBuilder
.CreateFCmp(CmpInst::FCMP_OGT
, Exp
, V
);
445 // If the Base value coming from an integer type.
446 Instruction
*I
= dyn_cast
<Instruction
>(Base
);
448 LLVM_DEBUG(dbgs() << "Not handled pow(): FP type base\n");
451 unsigned Opcode
= I
->getOpcode();
452 if (Opcode
== Instruction::UIToFP
|| Opcode
== Instruction::SIToFP
) {
453 unsigned BW
= I
->getOperand(0)->getType()->getPrimitiveSizeInBits();
462 LLVM_DEBUG(dbgs() << "Not handled pow(): type too wide\n");
467 Constant
*V
= ConstantFP::get(CI
->getContext(), APFloat(UpperV
));
468 Constant
*V0
= ConstantFP::get(CI
->getContext(), APFloat(0.0f
));
469 if (!Exp
->getType()->isFloatTy())
470 V
= ConstantExpr::getFPExtend(V
, Exp
->getType());
471 if (!Base
->getType()->isFloatTy())
472 V0
= ConstantExpr::getFPExtend(V0
, Exp
->getType());
474 Value
*Cond
= BBBuilder
.CreateFCmp(CmpInst::FCMP_OGT
, Exp
, V
);
475 Value
*Cond0
= BBBuilder
.CreateFCmp(CmpInst::FCMP_OLE
, Base
, V0
);
476 return BBBuilder
.CreateOr(Cond0
, Cond
);
478 LLVM_DEBUG(dbgs() << "Not handled pow(): base not from integer convert\n");
482 // Wrap conditions that can potentially generate errno to the library call.
483 void LibCallsShrinkWrap::shrinkWrapCI(CallInst
*CI
, Value
*Cond
) {
484 assert(Cond
!= nullptr && "ShrinkWrapCI is not expecting an empty call inst");
485 MDNode
*BranchWeights
=
486 MDBuilder(CI
->getContext()).createBranchWeights(1, 2000);
488 Instruction
*NewInst
=
489 SplitBlockAndInsertIfThen(Cond
, CI
, false, BranchWeights
, DT
);
490 BasicBlock
*CallBB
= NewInst
->getParent();
491 CallBB
->setName("cdce.call");
492 BasicBlock
*SuccBB
= CallBB
->getSingleSuccessor();
493 assert(SuccBB
&& "The split block should have a single successor");
494 SuccBB
->setName("cdce.end");
495 CI
->removeFromParent();
496 CallBB
->getInstList().insert(CallBB
->getFirstInsertionPt(), CI
);
497 LLVM_DEBUG(dbgs() << "== Basic Block After ==");
498 LLVM_DEBUG(dbgs() << *CallBB
->getSinglePredecessor() << *CallBB
499 << *CallBB
->getSingleSuccessor() << "\n");
502 // Perform the transformation to a single candidate.
503 bool LibCallsShrinkWrap::perform(CallInst
*CI
) {
505 Function
*Callee
= CI
->getCalledFunction();
506 assert(Callee
&& "perform() should apply to a non-empty callee");
507 TLI
.getLibFunc(*Callee
, Func
);
508 assert(Func
&& "perform() is not expecting an empty function");
510 if (performCallDomainErrorOnly(CI
, Func
) || performCallRangeErrorOnly(CI
, Func
))
512 return performCallErrors(CI
, Func
);
515 void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(AnalysisUsage
&AU
) const {
516 AU
.addPreserved
<DominatorTreeWrapperPass
>();
517 AU
.addPreserved
<GlobalsAAWrapperPass
>();
518 AU
.addRequired
<TargetLibraryInfoWrapperPass
>();
521 static bool runImpl(Function
&F
, const TargetLibraryInfo
&TLI
,
523 if (F
.hasFnAttribute(Attribute::OptimizeForSize
))
525 LibCallsShrinkWrap
CCDCE(TLI
, DT
);
527 bool Changed
= CCDCE
.perform();
529 // Verify the dominator after we've updated it locally.
530 assert(!DT
|| DT
->verify(DominatorTree::VerificationLevel::Fast
));
534 bool LibCallsShrinkWrapLegacyPass::runOnFunction(Function
&F
) {
535 auto &TLI
= getAnalysis
<TargetLibraryInfoWrapperPass
>().getTLI(F
);
536 auto *DTWP
= getAnalysisIfAvailable
<DominatorTreeWrapperPass
>();
537 auto *DT
= DTWP
? &DTWP
->getDomTree() : nullptr;
538 return runImpl(F
, TLI
, DT
);
542 char &LibCallsShrinkWrapPassID
= LibCallsShrinkWrapLegacyPass::ID
;
544 // Public interface to LibCallsShrinkWrap pass.
545 FunctionPass
*createLibCallsShrinkWrapPass() {
546 return new LibCallsShrinkWrapLegacyPass();
549 PreservedAnalyses
LibCallsShrinkWrapPass::run(Function
&F
,
550 FunctionAnalysisManager
&FAM
) {
551 auto &TLI
= FAM
.getResult
<TargetLibraryAnalysis
>(F
);
552 auto *DT
= FAM
.getCachedResult
<DominatorTreeAnalysis
>(F
);
553 if (!runImpl(F
, TLI
, DT
))
554 return PreservedAnalyses::all();
555 auto PA
= PreservedAnalyses();
556 PA
.preserve
<DominatorTreeAnalysis
>();