PartiallyInlineLibCalls.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //===--- PartiallyInlineLibCalls.cpp - Partially inline libcalls ----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This pass tries to partially inline the fast path of well-known library
  11. // functions, such as using square-root instructions for cases where sqrt()
  12. // does not need to set errno.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "llvm/Analysis/TargetTransformInfo.h"
  16. #include "llvm/IR/IRBuilder.h"
  17. #include "llvm/IR/Intrinsics.h"
  18. #include "llvm/Pass.h"
  19. #include "llvm/Support/CommandLine.h"
  20. #include "llvm/Analysis/TargetLibraryInfo.h"
  21. #include "llvm/Transforms/Scalar.h"
  22. #include "llvm/Transforms/Utils/BasicBlockUtils.h"
  23. using namespace llvm;
  24. #define DEBUG_TYPE "partially-inline-libcalls"
  25. namespace {
  26. class PartiallyInlineLibCalls : public FunctionPass {
  27. public:
  28. static char ID;
  29. PartiallyInlineLibCalls() :
  30. FunctionPass(ID) {
  31. initializePartiallyInlineLibCallsPass(*PassRegistry::getPassRegistry());
  32. }
  33. void getAnalysisUsage(AnalysisUsage &AU) const override;
  34. bool runOnFunction(Function &F) override;
  35. private:
  36. /// Optimize calls to sqrt.
  37. bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
  38. BasicBlock &CurrBB, Function::iterator &BB);
  39. };
  40. char PartiallyInlineLibCalls::ID = 0;
  41. }
  42. INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls",
  43. "Partially inline calls to library functions", false, false)
  44. void PartiallyInlineLibCalls::getAnalysisUsage(AnalysisUsage &AU) const {
  45. AU.addRequired<TargetLibraryInfoWrapperPass>();
  46. AU.addRequired<TargetTransformInfoWrapperPass>();
  47. FunctionPass::getAnalysisUsage(AU);
  48. }
  49. bool PartiallyInlineLibCalls::runOnFunction(Function &F) {
  50. bool Changed = false;
  51. Function::iterator CurrBB;
  52. TargetLibraryInfo *TLI =
  53. &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
  54. const TargetTransformInfo *TTI =
  55. &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
  56. for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) {
  57. CurrBB = BB++;
  58. for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end();
  59. II != IE; ++II) {
  60. CallInst *Call = dyn_cast<CallInst>(&*II);
  61. Function *CalledFunc;
  62. if (!Call || !(CalledFunc = Call->getCalledFunction()))
  63. continue;
  64. // Skip if function either has local linkage or is not a known library
  65. // function.
  66. LibFunc::Func LibFunc;
  67. if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
  68. !TLI->getLibFunc(CalledFunc->getName(), LibFunc))
  69. continue;
  70. switch (LibFunc) {
  71. case LibFunc::sqrtf:
  72. case LibFunc::sqrt:
  73. if (TTI->haveFastSqrt(Call->getType()) &&
  74. optimizeSQRT(Call, CalledFunc, *CurrBB, BB))
  75. break;
  76. continue;
  77. default:
  78. continue;
  79. }
  80. Changed = true;
  81. break;
  82. }
  83. }
  84. return Changed;
  85. }
  86. bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call,
  87. Function *CalledFunc,
  88. BasicBlock &CurrBB,
  89. Function::iterator &BB) {
  90. // There is no need to change the IR, since backend will emit sqrt
  91. // instruction if the call has already been marked read-only.
  92. if (Call->onlyReadsMemory())
  93. return false;
  94. // The call must have the expected result type.
  95. if (!Call->getType()->isFloatingPointTy())
  96. return false;
  97. // Do the following transformation:
  98. //
  99. // (before)
  100. // dst = sqrt(src)
  101. //
  102. // (after)
  103. // v0 = sqrt_noreadmem(src) # native sqrt instruction.
  104. // if (v0 is a NaN)
  105. // v1 = sqrt(src) # library call.
  106. // dst = phi(v0, v1)
  107. //
  108. // Move all instructions following Call to newly created block JoinBB.
  109. // Create phi and replace all uses.
  110. BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode());
  111. IRBuilder<> Builder(JoinBB, JoinBB->begin());
  112. PHINode *Phi = Builder.CreatePHI(Call->getType(), 2);
  113. Call->replaceAllUsesWith(Phi);
  114. // Create basic block LibCallBB and insert a call to library function sqrt.
  115. BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt",
  116. CurrBB.getParent(), JoinBB);
  117. Builder.SetInsertPoint(LibCallBB);
  118. Instruction *LibCall = Call->clone();
  119. Builder.Insert(LibCall);
  120. Builder.CreateBr(JoinBB);
  121. // Add attribute "readnone" so that backend can use a native sqrt instruction
  122. // for this call. Insert a FP compare instruction and a conditional branch
  123. // at the end of CurrBB.
  124. Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
  125. CurrBB.getTerminator()->eraseFromParent();
  126. Builder.SetInsertPoint(&CurrBB);
  127. Value *FCmp = Builder.CreateFCmpOEQ(Call, Call);
  128. Builder.CreateCondBr(FCmp, JoinBB, LibCallBB);
  129. // Add phi operands.
  130. Phi->addIncoming(Call, &CurrBB);
  131. Phi->addIncoming(LibCall, LibCallBB);
  132. BB = JoinBB;
  133. return true;
  134. }
  135. FunctionPass *llvm::createPartiallyInlineLibCallsPass() {
  136. return new PartiallyInlineLibCalls();
  137. }