LibCallsShrinkWrap.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. //===-- LibCallsShrinkWrap.cpp ----------------------------------*- C++ -*-===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  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:
  11. // sqrt(val);
  12. // is transformed to
  13. // if (val < 0)
  14. // sqrt(val);
  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
  17. // conditions.
  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.
  22. //
  23. // These partially dead calls are usually results of C++ abstraction penalty
  24. // exposed by inlining.
  25. //
  26. //===----------------------------------------------------------------------===//
  27. #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h"
  28. #include "llvm/ADT/SmallVector.h"
  29. #include "llvm/ADT/Statistic.h"
  30. #include "llvm/Analysis/GlobalsModRef.h"
  31. #include "llvm/Analysis/TargetLibraryInfo.h"
  32. #include "llvm/IR/Constants.h"
  33. #include "llvm/IR/Dominators.h"
  34. #include "llvm/IR/Function.h"
  35. #include "llvm/IR/IRBuilder.h"
  36. #include "llvm/IR/InstVisitor.h"
  37. #include "llvm/IR/Instructions.h"
  38. #include "llvm/IR/MDBuilder.h"
  39. #include "llvm/InitializePasses.h"
  40. #include "llvm/Pass.h"
  41. #include "llvm/Transforms/Utils/BasicBlockUtils.h"
  42. #include <cmath>
  43. using namespace llvm;
  44. #define DEBUG_TYPE "libcalls-shrinkwrap"
  45. STATISTIC(NumWrappedOneCond, "Number of One-Condition Wrappers Inserted");
  46. STATISTIC(NumWrappedTwoCond, "Number of Two-Condition Wrappers Inserted");
  47. namespace {
  48. class LibCallsShrinkWrapLegacyPass : public FunctionPass {
  49. public:
  50. static char ID; // Pass identification, replacement for typeid
  51. explicit LibCallsShrinkWrapLegacyPass() : FunctionPass(ID) {
  52. initializeLibCallsShrinkWrapLegacyPassPass(
  53. *PassRegistry::getPassRegistry());
  54. }
  55. void getAnalysisUsage(AnalysisUsage &AU) const override;
  56. bool runOnFunction(Function &F) override;
  57. };
  58. }
  59. char LibCallsShrinkWrapLegacyPass::ID = 0;
  60. INITIALIZE_PASS_BEGIN(LibCallsShrinkWrapLegacyPass, "libcalls-shrinkwrap",
  61. "Conditionally eliminate dead library calls", false,
  62. false)
  63. INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
  64. INITIALIZE_PASS_END(LibCallsShrinkWrapLegacyPass, "libcalls-shrinkwrap",
  65. "Conditionally eliminate dead library calls", false, false)
  66. namespace {
  67. class LibCallsShrinkWrap : public InstVisitor<LibCallsShrinkWrap> {
  68. public:
  69. LibCallsShrinkWrap(const TargetLibraryInfo &TLI, DominatorTree *DT)
  70. : TLI(TLI), DT(DT){};
  71. void visitCallInst(CallInst &CI) { checkCandidate(CI); }
  72. bool perform() {
  73. bool Changed = false;
  74. for (auto &CI : WorkList) {
  75. LLVM_DEBUG(dbgs() << "CDCE calls: " << CI->getCalledFunction()->getName()
  76. << "\n");
  77. if (perform(CI)) {
  78. Changed = true;
  79. LLVM_DEBUG(dbgs() << "Transformed\n");
  80. }
  81. }
  82. return Changed;
  83. }
  84. private:
  85. bool perform(CallInst *CI);
  86. void checkCandidate(CallInst &CI);
  87. void shrinkWrapCI(CallInst *CI, Value *Cond);
  88. bool performCallDomainErrorOnly(CallInst *CI, const LibFunc &Func);
  89. bool performCallErrors(CallInst *CI, const LibFunc &Func);
  90. bool performCallRangeErrorOnly(CallInst *CI, const LibFunc &Func);
  91. Value *generateOneRangeCond(CallInst *CI, const LibFunc &Func);
  92. Value *generateTwoRangeCond(CallInst *CI, const LibFunc &Func);
  93. Value *generateCondForPow(CallInst *CI, const LibFunc &Func);
  94. // Create an OR of two conditions.
  95. Value *createOrCond(CallInst *CI, CmpInst::Predicate Cmp, float Val,
  96. CmpInst::Predicate Cmp2, float Val2) {
  97. IRBuilder<> BBBuilder(CI);
  98. Value *Arg = CI->getArgOperand(0);
  99. auto Cond2 = createCond(BBBuilder, Arg, Cmp2, Val2);
  100. auto Cond1 = createCond(BBBuilder, Arg, Cmp, Val);
  101. return BBBuilder.CreateOr(Cond1, Cond2);
  102. }
  103. // Create a single condition using IRBuilder.
  104. Value *createCond(IRBuilder<> &BBBuilder, Value *Arg, CmpInst::Predicate Cmp,
  105. float Val) {
  106. Constant *V = ConstantFP::get(BBBuilder.getContext(), APFloat(Val));
  107. if (!Arg->getType()->isFloatTy())
  108. V = ConstantExpr::getFPExtend(V, Arg->getType());
  109. return BBBuilder.CreateFCmp(Cmp, Arg, V);
  110. }
  111. // Create a single condition.
  112. Value *createCond(CallInst *CI, CmpInst::Predicate Cmp, float Val) {
  113. IRBuilder<> BBBuilder(CI);
  114. Value *Arg = CI->getArgOperand(0);
  115. return createCond(BBBuilder, Arg, Cmp, Val);
  116. }
  117. const TargetLibraryInfo &TLI;
  118. DominatorTree *DT;
  119. SmallVector<CallInst *, 16> WorkList;
  120. };
  121. } // end anonymous namespace
  122. // Perform the transformation to calls with errno set by domain error.
  123. bool LibCallsShrinkWrap::performCallDomainErrorOnly(CallInst *CI,
  124. const LibFunc &Func) {
  125. Value *Cond = nullptr;
  126. switch (Func) {
  127. case LibFunc_acos: // DomainError: (x < -1 || x > 1)
  128. case LibFunc_acosf: // Same as acos
  129. case LibFunc_acosl: // Same as acos
  130. case LibFunc_asin: // DomainError: (x < -1 || x > 1)
  131. case LibFunc_asinf: // Same as asin
  132. case LibFunc_asinl: // Same as asin
  133. {
  134. ++NumWrappedTwoCond;
  135. Cond = createOrCond(CI, CmpInst::FCMP_OLT, -1.0f, CmpInst::FCMP_OGT, 1.0f);
  136. break;
  137. }
  138. case LibFunc_cos: // DomainError: (x == +inf || x == -inf)
  139. case LibFunc_cosf: // Same as cos
  140. case LibFunc_cosl: // Same as cos
  141. case LibFunc_sin: // DomainError: (x == +inf || x == -inf)
  142. case LibFunc_sinf: // Same as sin
  143. case LibFunc_sinl: // Same as sin
  144. {
  145. ++NumWrappedTwoCond;
  146. Cond = createOrCond(CI, CmpInst::FCMP_OEQ, INFINITY, CmpInst::FCMP_OEQ,
  147. -INFINITY);
  148. break;
  149. }
  150. case LibFunc_acosh: // DomainError: (x < 1)
  151. case LibFunc_acoshf: // Same as acosh
  152. case LibFunc_acoshl: // Same as acosh
  153. {
  154. ++NumWrappedOneCond;
  155. Cond = createCond(CI, CmpInst::FCMP_OLT, 1.0f);
  156. break;
  157. }
  158. case LibFunc_sqrt: // DomainError: (x < 0)
  159. case LibFunc_sqrtf: // Same as sqrt
  160. case LibFunc_sqrtl: // Same as sqrt
  161. {
  162. ++NumWrappedOneCond;
  163. Cond = createCond(CI, CmpInst::FCMP_OLT, 0.0f);
  164. break;
  165. }
  166. default:
  167. return false;
  168. }
  169. shrinkWrapCI(CI, Cond);
  170. return true;
  171. }
  172. // Perform the transformation to calls with errno set by range error.
  173. bool LibCallsShrinkWrap::performCallRangeErrorOnly(CallInst *CI,
  174. const LibFunc &Func) {
  175. Value *Cond = nullptr;
  176. switch (Func) {
  177. case LibFunc_cosh:
  178. case LibFunc_coshf:
  179. case LibFunc_coshl:
  180. case LibFunc_exp:
  181. case LibFunc_expf:
  182. case LibFunc_expl:
  183. case LibFunc_exp10:
  184. case LibFunc_exp10f:
  185. case LibFunc_exp10l:
  186. case LibFunc_exp2:
  187. case LibFunc_exp2f:
  188. case LibFunc_exp2l:
  189. case LibFunc_sinh:
  190. case LibFunc_sinhf:
  191. case LibFunc_sinhl: {
  192. Cond = generateTwoRangeCond(CI, Func);
  193. break;
  194. }
  195. case LibFunc_expm1: // RangeError: (709, inf)
  196. case LibFunc_expm1f: // RangeError: (88, inf)
  197. case LibFunc_expm1l: // RangeError: (11356, inf)
  198. {
  199. Cond = generateOneRangeCond(CI, Func);
  200. break;
  201. }
  202. default:
  203. return false;
  204. }
  205. shrinkWrapCI(CI, Cond);
  206. return true;
  207. }
  208. // Perform the transformation to calls with errno set by combination of errors.
  209. bool LibCallsShrinkWrap::performCallErrors(CallInst *CI,
  210. const LibFunc &Func) {
  211. Value *Cond = nullptr;
  212. switch (Func) {
  213. case LibFunc_atanh: // DomainError: (x < -1 || x > 1)
  214. // PoleError: (x == -1 || x == 1)
  215. // Overall Cond: (x <= -1 || x >= 1)
  216. case LibFunc_atanhf: // Same as atanh
  217. case LibFunc_atanhl: // Same as atanh
  218. {
  219. ++NumWrappedTwoCond;
  220. Cond = createOrCond(CI, CmpInst::FCMP_OLE, -1.0f, CmpInst::FCMP_OGE, 1.0f);
  221. break;
  222. }
  223. case LibFunc_log: // DomainError: (x < 0)
  224. // PoleError: (x == 0)
  225. // Overall Cond: (x <= 0)
  226. case LibFunc_logf: // Same as log
  227. case LibFunc_logl: // Same as log
  228. case LibFunc_log10: // Same as log
  229. case LibFunc_log10f: // Same as log
  230. case LibFunc_log10l: // Same as log
  231. case LibFunc_log2: // Same as log
  232. case LibFunc_log2f: // Same as log
  233. case LibFunc_log2l: // Same as log
  234. case LibFunc_logb: // Same as log
  235. case LibFunc_logbf: // Same as log
  236. case LibFunc_logbl: // Same as log
  237. {
  238. ++NumWrappedOneCond;
  239. Cond = createCond(CI, CmpInst::FCMP_OLE, 0.0f);
  240. break;
  241. }
  242. case LibFunc_log1p: // DomainError: (x < -1)
  243. // PoleError: (x == -1)
  244. // Overall Cond: (x <= -1)
  245. case LibFunc_log1pf: // Same as log1p
  246. case LibFunc_log1pl: // Same as log1p
  247. {
  248. ++NumWrappedOneCond;
  249. Cond = createCond(CI, CmpInst::FCMP_OLE, -1.0f);
  250. break;
  251. }
  252. case LibFunc_pow: // DomainError: x < 0 and y is noninteger
  253. // PoleError: x == 0 and y < 0
  254. // RangeError: overflow or underflow
  255. case LibFunc_powf:
  256. case LibFunc_powl: {
  257. Cond = generateCondForPow(CI, Func);
  258. if (Cond == nullptr)
  259. return false;
  260. break;
  261. }
  262. default:
  263. return false;
  264. }
  265. assert(Cond && "performCallErrors should not see an empty condition");
  266. shrinkWrapCI(CI, Cond);
  267. return true;
  268. }
  269. // Checks if CI is a candidate for shrinkwrapping and put it into work list if
  270. // true.
  271. void LibCallsShrinkWrap::checkCandidate(CallInst &CI) {
  272. if (CI.isNoBuiltin())
  273. return;
  274. // A possible improvement is to handle the calls with the return value being
  275. // used. If there is API for fast libcall implementation without setting
  276. // errno, we can use the same framework to direct/wrap the call to the fast
  277. // API in the error free path, and leave the original call in the slow path.
  278. if (!CI.use_empty())
  279. return;
  280. LibFunc Func;
  281. Function *Callee = CI.getCalledFunction();
  282. if (!Callee)
  283. return;
  284. if (!TLI.getLibFunc(*Callee, Func) || !TLI.has(Func))
  285. return;
  286. if (CI.arg_empty())
  287. return;
  288. // TODO: Handle long double in other formats.
  289. Type *ArgType = CI.getArgOperand(0)->getType();
  290. if (!(ArgType->isFloatTy() || ArgType->isDoubleTy() ||
  291. ArgType->isX86_FP80Ty()))
  292. return;
  293. WorkList.push_back(&CI);
  294. }
  295. // Generate the upper bound condition for RangeError.
  296. Value *LibCallsShrinkWrap::generateOneRangeCond(CallInst *CI,
  297. const LibFunc &Func) {
  298. float UpperBound;
  299. switch (Func) {
  300. case LibFunc_expm1: // RangeError: (709, inf)
  301. UpperBound = 709.0f;
  302. break;
  303. case LibFunc_expm1f: // RangeError: (88, inf)
  304. UpperBound = 88.0f;
  305. break;
  306. case LibFunc_expm1l: // RangeError: (11356, inf)
  307. UpperBound = 11356.0f;
  308. break;
  309. default:
  310. llvm_unreachable("Unhandled library call!");
  311. }
  312. ++NumWrappedOneCond;
  313. return createCond(CI, CmpInst::FCMP_OGT, UpperBound);
  314. }
  315. // Generate the lower and upper bound condition for RangeError.
  316. Value *LibCallsShrinkWrap::generateTwoRangeCond(CallInst *CI,
  317. const LibFunc &Func) {
  318. float UpperBound, LowerBound;
  319. switch (Func) {
  320. case LibFunc_cosh: // RangeError: (x < -710 || x > 710)
  321. case LibFunc_sinh: // Same as cosh
  322. LowerBound = -710.0f;
  323. UpperBound = 710.0f;
  324. break;
  325. case LibFunc_coshf: // RangeError: (x < -89 || x > 89)
  326. case LibFunc_sinhf: // Same as coshf
  327. LowerBound = -89.0f;
  328. UpperBound = 89.0f;
  329. break;
  330. case LibFunc_coshl: // RangeError: (x < -11357 || x > 11357)
  331. case LibFunc_sinhl: // Same as coshl
  332. LowerBound = -11357.0f;
  333. UpperBound = 11357.0f;
  334. break;
  335. case LibFunc_exp: // RangeError: (x < -745 || x > 709)
  336. LowerBound = -745.0f;
  337. UpperBound = 709.0f;
  338. break;
  339. case LibFunc_expf: // RangeError: (x < -103 || x > 88)
  340. LowerBound = -103.0f;
  341. UpperBound = 88.0f;
  342. break;
  343. case LibFunc_expl: // RangeError: (x < -11399 || x > 11356)
  344. LowerBound = -11399.0f;
  345. UpperBound = 11356.0f;
  346. break;
  347. case LibFunc_exp10: // RangeError: (x < -323 || x > 308)
  348. LowerBound = -323.0f;
  349. UpperBound = 308.0f;
  350. break;
  351. case LibFunc_exp10f: // RangeError: (x < -45 || x > 38)
  352. LowerBound = -45.0f;
  353. UpperBound = 38.0f;
  354. break;
  355. case LibFunc_exp10l: // RangeError: (x < -4950 || x > 4932)
  356. LowerBound = -4950.0f;
  357. UpperBound = 4932.0f;
  358. break;
  359. case LibFunc_exp2: // RangeError: (x < -1074 || x > 1023)
  360. LowerBound = -1074.0f;
  361. UpperBound = 1023.0f;
  362. break;
  363. case LibFunc_exp2f: // RangeError: (x < -149 || x > 127)
  364. LowerBound = -149.0f;
  365. UpperBound = 127.0f;
  366. break;
  367. case LibFunc_exp2l: // RangeError: (x < -16445 || x > 11383)
  368. LowerBound = -16445.0f;
  369. UpperBound = 11383.0f;
  370. break;
  371. default:
  372. llvm_unreachable("Unhandled library call!");
  373. }
  374. ++NumWrappedTwoCond;
  375. return createOrCond(CI, CmpInst::FCMP_OGT, UpperBound, CmpInst::FCMP_OLT,
  376. LowerBound);
  377. }
  378. // For pow(x,y), We only handle the following cases:
  379. // (1) x is a constant && (x >= 1) && (x < MaxUInt8)
  380. // Cond is: (y > 127)
  381. // (2) x is a value coming from an integer type.
  382. // (2.1) if x's bit_size == 8
  383. // Cond: (x <= 0 || y > 128)
  384. // (2.2) if x's bit_size is 16
  385. // Cond: (x <= 0 || y > 64)
  386. // (2.3) if x's bit_size is 32
  387. // Cond: (x <= 0 || y > 32)
  388. // Support for powl(x,y) and powf(x,y) are TBD.
  389. //
  390. // Note that condition can be more conservative than the actual condition
  391. // (i.e. we might invoke the calls that will not set the errno.).
  392. //
  393. Value *LibCallsShrinkWrap::generateCondForPow(CallInst *CI,
  394. const LibFunc &Func) {
  395. // FIXME: LibFunc_powf and powl TBD.
  396. if (Func != LibFunc_pow) {
  397. LLVM_DEBUG(dbgs() << "Not handled powf() and powl()\n");
  398. return nullptr;
  399. }
  400. Value *Base = CI->getArgOperand(0);
  401. Value *Exp = CI->getArgOperand(1);
  402. IRBuilder<> BBBuilder(CI);
  403. // Constant Base case.
  404. if (ConstantFP *CF = dyn_cast<ConstantFP>(Base)) {
  405. double D = CF->getValueAPF().convertToDouble();
  406. if (D < 1.0f || D > APInt::getMaxValue(8).getZExtValue()) {
  407. LLVM_DEBUG(dbgs() << "Not handled pow(): constant base out of range\n");
  408. return nullptr;
  409. }
  410. ++NumWrappedOneCond;
  411. Constant *V = ConstantFP::get(CI->getContext(), APFloat(127.0f));
  412. if (!Exp->getType()->isFloatTy())
  413. V = ConstantExpr::getFPExtend(V, Exp->getType());
  414. return BBBuilder.CreateFCmp(CmpInst::FCMP_OGT, Exp, V);
  415. }
  416. // If the Base value coming from an integer type.
  417. Instruction *I = dyn_cast<Instruction>(Base);
  418. if (!I) {
  419. LLVM_DEBUG(dbgs() << "Not handled pow(): FP type base\n");
  420. return nullptr;
  421. }
  422. unsigned Opcode = I->getOpcode();
  423. if (Opcode == Instruction::UIToFP || Opcode == Instruction::SIToFP) {
  424. unsigned BW = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
  425. float UpperV = 0.0f;
  426. if (BW == 8)
  427. UpperV = 128.0f;
  428. else if (BW == 16)
  429. UpperV = 64.0f;
  430. else if (BW == 32)
  431. UpperV = 32.0f;
  432. else {
  433. LLVM_DEBUG(dbgs() << "Not handled pow(): type too wide\n");
  434. return nullptr;
  435. }
  436. ++NumWrappedTwoCond;
  437. Constant *V = ConstantFP::get(CI->getContext(), APFloat(UpperV));
  438. Constant *V0 = ConstantFP::get(CI->getContext(), APFloat(0.0f));
  439. if (!Exp->getType()->isFloatTy())
  440. V = ConstantExpr::getFPExtend(V, Exp->getType());
  441. if (!Base->getType()->isFloatTy())
  442. V0 = ConstantExpr::getFPExtend(V0, Exp->getType());
  443. Value *Cond = BBBuilder.CreateFCmp(CmpInst::FCMP_OGT, Exp, V);
  444. Value *Cond0 = BBBuilder.CreateFCmp(CmpInst::FCMP_OLE, Base, V0);
  445. return BBBuilder.CreateOr(Cond0, Cond);
  446. }
  447. LLVM_DEBUG(dbgs() << "Not handled pow(): base not from integer convert\n");
  448. return nullptr;
  449. }
  450. // Wrap conditions that can potentially generate errno to the library call.
  451. void LibCallsShrinkWrap::shrinkWrapCI(CallInst *CI, Value *Cond) {
  452. assert(Cond != nullptr && "ShrinkWrapCI is not expecting an empty call inst");
  453. MDNode *BranchWeights =
  454. MDBuilder(CI->getContext()).createBranchWeights(1, 2000);
  455. Instruction *NewInst =
  456. SplitBlockAndInsertIfThen(Cond, CI, false, BranchWeights, DT);
  457. BasicBlock *CallBB = NewInst->getParent();
  458. CallBB->setName("cdce.call");
  459. BasicBlock *SuccBB = CallBB->getSingleSuccessor();
  460. assert(SuccBB && "The split block should have a single successor");
  461. SuccBB->setName("cdce.end");
  462. CI->removeFromParent();
  463. CI->insertInto(CallBB, CallBB->getFirstInsertionPt());
  464. LLVM_DEBUG(dbgs() << "== Basic Block After ==");
  465. LLVM_DEBUG(dbgs() << *CallBB->getSinglePredecessor() << *CallBB
  466. << *CallBB->getSingleSuccessor() << "\n");
  467. }
  468. // Perform the transformation to a single candidate.
  469. bool LibCallsShrinkWrap::perform(CallInst *CI) {
  470. LibFunc Func;
  471. Function *Callee = CI->getCalledFunction();
  472. assert(Callee && "perform() should apply to a non-empty callee");
  473. TLI.getLibFunc(*Callee, Func);
  474. assert(Func && "perform() is not expecting an empty function");
  475. if (performCallDomainErrorOnly(CI, Func) || performCallRangeErrorOnly(CI, Func))
  476. return true;
  477. return performCallErrors(CI, Func);
  478. }
  479. void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
  480. AU.addPreserved<DominatorTreeWrapperPass>();
  481. AU.addPreserved<GlobalsAAWrapperPass>();
  482. AU.addRequired<TargetLibraryInfoWrapperPass>();
  483. }
  484. static bool runImpl(Function &F, const TargetLibraryInfo &TLI,
  485. DominatorTree *DT) {
  486. if (F.hasFnAttribute(Attribute::OptimizeForSize))
  487. return false;
  488. LibCallsShrinkWrap CCDCE(TLI, DT);
  489. CCDCE.visit(F);
  490. bool Changed = CCDCE.perform();
  491. // Verify the dominator after we've updated it locally.
  492. assert(!DT || DT->verify(DominatorTree::VerificationLevel::Fast));
  493. return Changed;
  494. }
  495. bool LibCallsShrinkWrapLegacyPass::runOnFunction(Function &F) {
  496. auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
  497. auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  498. auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
  499. return runImpl(F, TLI, DT);
  500. }
  501. namespace llvm {
  502. char &LibCallsShrinkWrapPassID = LibCallsShrinkWrapLegacyPass::ID;
  503. // Public interface to LibCallsShrinkWrap pass.
  504. FunctionPass *createLibCallsShrinkWrapPass() {
  505. return new LibCallsShrinkWrapLegacyPass();
  506. }
  507. PreservedAnalyses LibCallsShrinkWrapPass::run(Function &F,
  508. FunctionAnalysisManager &FAM) {
  509. auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
  510. auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
  511. if (!runImpl(F, TLI, DT))
  512. return PreservedAnalyses::all();
  513. auto PA = PreservedAnalyses();
  514. PA.preserve<DominatorTreeAnalysis>();
  515. return PA;
  516. }
  517. }