LLVM API Documentation
00001 //===- SimplifyHalfPowrLibCalls.cpp - Optimize specific half_powr calls ---===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a simple pass that applies an experimental 00011 // transformation on calls to specific functions. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #define DEBUG_TYPE "simplify-libcalls-halfpowr" 00016 #include "llvm/Transforms/Scalar.h" 00017 #include "llvm/Instructions.h" 00018 #include "llvm/Intrinsics.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Pass.h" 00021 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 00022 #include "llvm/Transforms/Utils/Cloning.h" 00023 #include "llvm/Target/TargetData.h" 00024 #include "llvm/ADT/STLExtras.h" 00025 #include "llvm/Support/Compiler.h" 00026 #include "llvm/Support/Debug.h" 00027 #include "llvm/Config/config.h" 00028 using namespace llvm; 00029 00030 namespace { 00031 /// This pass optimizes well half_powr function calls. 00032 /// 00033 class VISIBILITY_HIDDEN SimplifyHalfPowrLibCalls : public FunctionPass { 00034 const TargetData *TD; 00035 public: 00036 static char ID; // Pass identification 00037 SimplifyHalfPowrLibCalls() : FunctionPass(&ID) {} 00038 00039 bool runOnFunction(Function &F); 00040 00041 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00042 AU.addRequired<TargetData>(); 00043 } 00044 00045 Instruction * 00046 InlineHalfPowrs(const std::vector<Instruction *> &HalfPowrs, 00047 Instruction *InsertPt); 00048 }; 00049 char SimplifyHalfPowrLibCalls::ID = 0; 00050 } // end anonymous namespace. 00051 00052 static RegisterPass<SimplifyHalfPowrLibCalls> 00053 X("simplify-libcalls-halfpowr", "Simplify half_powr library calls"); 00054 00055 // Public interface to the Simplify HalfPowr LibCalls pass. 00056 FunctionPass *llvm::createSimplifyHalfPowrLibCallsPass() { 00057 return new SimplifyHalfPowrLibCalls(); 00058 } 00059 00060 /// InlineHalfPowrs - Inline a sequence of adjacent half_powr calls, rearranging 00061 /// their control flow to better facilitate subsequent optimization. 00062 Instruction * 00063 SimplifyHalfPowrLibCalls::InlineHalfPowrs(const std::vector<Instruction *> &HalfPowrs, 00064 Instruction *InsertPt) { 00065 std::vector<BasicBlock *> Bodies; 00066 BasicBlock *NewBlock = 0; 00067 00068 for (unsigned i = 0, e = HalfPowrs.size(); i != e; ++i) { 00069 CallInst *Call = cast<CallInst>(HalfPowrs[i]); 00070 Function *Callee = Call->getCalledFunction(); 00071 00072 // Minimally sanity-check the CFG of half_powr to ensure that it contains 00073 // the the kind of code we expect. If we're running this pass, we have 00074 // reason to believe it will be what we expect. 00075 Function::iterator I = Callee->begin(); 00076 BasicBlock *Prologue = I++; 00077 if (I == Callee->end()) break; 00078 BasicBlock *SubnormalHandling = I++; 00079 if (I == Callee->end()) break; 00080 BasicBlock *Body = I++; 00081 if (I != Callee->end()) break; 00082 if (SubnormalHandling->getSinglePredecessor() != Prologue) 00083 break; 00084 BranchInst *PBI = dyn_cast<BranchInst>(Prologue->getTerminator()); 00085 if (!PBI || !PBI->isConditional()) 00086 break; 00087 BranchInst *SNBI = dyn_cast<BranchInst>(SubnormalHandling->getTerminator()); 00088 if (!SNBI || SNBI->isConditional()) 00089 break; 00090 if (!isa<ReturnInst>(Body->getTerminator())) 00091 break; 00092 00093 Instruction *NextInst = next(BasicBlock::iterator(Call)); 00094 00095 // Inline the call, taking care of what code ends up where. 00096 NewBlock = SplitBlock(NextInst->getParent(), NextInst, this); 00097 00098 bool B = InlineFunction(Call, 0, TD); 00099 assert(B && "half_powr didn't inline?"); B=B; 00100 00101 BasicBlock *NewBody = NewBlock->getSinglePredecessor(); 00102 assert(NewBody); 00103 Bodies.push_back(NewBody); 00104 } 00105 00106 if (!NewBlock) 00107 return InsertPt; 00108 00109 // Put the code for all the bodies into one block, to facilitate 00110 // subsequent optimization. 00111 (void)SplitEdge(NewBlock->getSinglePredecessor(), NewBlock, this); 00112 for (unsigned i = 0, e = Bodies.size(); i != e; ++i) { 00113 BasicBlock *Body = Bodies[i]; 00114 Instruction *FNP = Body->getFirstNonPHI(); 00115 // Splice the insts from body into NewBlock. 00116 NewBlock->getInstList().splice(NewBlock->begin(), Body->getInstList(), 00117 FNP, Body->getTerminator()); 00118 } 00119 00120 return NewBlock->begin(); 00121 } 00122 00123 /// runOnFunction - Top level algorithm. 00124 /// 00125 bool SimplifyHalfPowrLibCalls::runOnFunction(Function &F) { 00126 TD = &getAnalysis<TargetData>(); 00127 00128 bool Changed = false; 00129 std::vector<Instruction *> HalfPowrs; 00130 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { 00131 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 00132 // Look for calls. 00133 bool IsHalfPowr = false; 00134 if (CallInst *CI = dyn_cast<CallInst>(I)) { 00135 // Look for direct calls and calls to non-external functions. 00136 Function *Callee = CI->getCalledFunction(); 00137 if (Callee && Callee->hasExternalLinkage()) { 00138 // Look for calls with well-known names. 00139 const char *CalleeName = Callee->getNameStart(); 00140 if (strcmp(CalleeName, "__half_powrf4") == 0) 00141 IsHalfPowr = true; 00142 } 00143 } 00144 if (IsHalfPowr) 00145 HalfPowrs.push_back(I); 00146 // We're looking for sequences of up to three such calls, which we'll 00147 // simplify as a group. 00148 if ((!IsHalfPowr && !HalfPowrs.empty()) || HalfPowrs.size() == 3) { 00149 I = InlineHalfPowrs(HalfPowrs, I); 00150 E = I->getParent()->end(); 00151 HalfPowrs.clear(); 00152 Changed = true; 00153 } 00154 } 00155 assert(HalfPowrs.empty() && "Block had no terminator!"); 00156 } 00157 00158 return Changed; 00159 }
This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.