diff options
Diffstat (limited to 'lib/Target/Mips/MipsOptimizeMathLibCalls.cpp')
-rw-r--r-- | lib/Target/Mips/MipsOptimizeMathLibCalls.cpp | 175 |
1 files changed, 0 insertions, 175 deletions
diff --git a/lib/Target/Mips/MipsOptimizeMathLibCalls.cpp b/lib/Target/Mips/MipsOptimizeMathLibCalls.cpp deleted file mode 100644 index de3f09c..0000000 --- a/lib/Target/Mips/MipsOptimizeMathLibCalls.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//===---- MipsOptimizeMathLibCalls.cpp - Optimize math lib calls. ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass does an IR transformation which enables the backend to emit native -// math instructions. -// -//===----------------------------------------------------------------------===// - -#include "MipsTargetMachine.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetLibraryInfo.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" - -using namespace llvm; - -static cl::opt<bool> DisableOpt("disable-mips-math-optimization", - cl::init(false), - cl::desc("MIPS: Disable math lib call " - "optimization."), cl::Hidden); - -namespace { - class MipsOptimizeMathLibCalls : public FunctionPass { - public: - static char ID; - - MipsOptimizeMathLibCalls(MipsTargetMachine &TM_) : - FunctionPass(ID), TM(TM_) {} - - virtual const char *getPassName() const { - return "MIPS: Optimize calls to math library functions."; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - - virtual bool runOnFunction(Function &F); - - private: - /// Optimize calls to sqrt. - bool optimizeSQRT(CallInst *Call, Function *CalledFunc, - BasicBlock &CurrBB, - Function::iterator &BB); - - const TargetMachine &TM; - }; - - char MipsOptimizeMathLibCalls::ID = 0; -} - -FunctionPass *llvm::createMipsOptimizeMathLibCalls(MipsTargetMachine &TM) { - return new MipsOptimizeMathLibCalls(TM); -} - -void MipsOptimizeMathLibCalls::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<TargetLibraryInfo>(); - FunctionPass::getAnalysisUsage(AU); -} - -bool MipsOptimizeMathLibCalls::runOnFunction(Function &F) { - if (DisableOpt) - return false; - - const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); - - if (Subtarget.inMips16Mode()) - return false; - - bool Changed = false; - Function::iterator CurrBB; - const TargetLibraryInfo *LibInfo = &getAnalysis<TargetLibraryInfo>(); - - for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) { - CurrBB = BB++; - - for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end(); - II != IE; ++II) { - CallInst *Call = dyn_cast<CallInst>(&*II); - Function *CalledFunc; - - if (!Call || !(CalledFunc = Call->getCalledFunction())) - continue; - - LibFunc::Func LibFunc; - Attribute A = CalledFunc->getAttributes() - .getAttribute(AttributeSet::FunctionIndex, "use-soft-float"); - - // Skip if function has "use-soft-float" attribute. - if ((A.isStringAttribute() && (A.getValueAsString() == "true")) || - TM.Options.UseSoftFloat) - continue; - - // Skip if function either has local linkage or is not a known library - // function. - if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || - !LibInfo->getLibFunc(CalledFunc->getName(), LibFunc)) - continue; - - switch (LibFunc) { - case LibFunc::sqrtf: - case LibFunc::sqrt: - if (optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) - break; - continue; - default: - continue; - } - - Changed = true; - break; - } - } - - return Changed; -} - -bool MipsOptimizeMathLibCalls::optimizeSQRT(CallInst *Call, - Function *CalledFunc, - BasicBlock &CurrBB, - Function::iterator &BB) { - // There is no need to change the IR, since backend will emit sqrt - // instruction if the call has already been marked read-only. - if (Call->onlyReadsMemory()) - return false; - - // Do the following transformation: - // - // (before) - // dst = sqrt(src) - // - // (after) - // v0 = sqrt_noreadmem(src) # native sqrt instruction. - // if (v0 is a NaN) - // v1 = sqrt(src) # library call. - // dst = phi(v0, v1) - // - - // Move all instructions following Call to newly created block JoinBB. - // Create phi and replace all uses. - BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode(), this); - IRBuilder<> Builder(JoinBB, JoinBB->begin()); - PHINode *Phi = Builder.CreatePHI(Call->getType(), 2); - Call->replaceAllUsesWith(Phi); - - // Create basic block LibCallBB and insert a call to library function sqrt. - BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt", - CurrBB.getParent(), JoinBB); - Builder.SetInsertPoint(LibCallBB); - Instruction *LibCall = Call->clone(); - Builder.Insert(LibCall); - Builder.CreateBr(JoinBB); - - // Add attribute "readnone" so that backend can use a native sqrt instruction - // for this call. Insert a FP compare instruction and a conditional branch - // at the end of CurrBB. - Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); - CurrBB.getTerminator()->eraseFromParent(); - Builder.SetInsertPoint(&CurrBB); - Value *FCmp = Builder.CreateFCmpOEQ(Call, Call); - Builder.CreateCondBr(FCmp, JoinBB, LibCallBB); - - // Add phi operands. - Phi->addIncoming(Call, &CurrBB); - Phi->addIncoming(LibCall, LibCallBB); - - BB = JoinBB; - return true; -} |