LLVM API Documentation
00001 //===- LowerSelect.cpp - Transform select insts to branches ---------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass lowers select instructions into conditional branches for targets 00011 // that do not have conditional moves or that have not implemented the select 00012 // instruction yet. 00013 // 00014 // Note that this pass could be improved. In particular it turns every select 00015 // instruction into a new conditional branch, even though some common cases have 00016 // select instructions on the same predicate next to each other. It would be 00017 // better to use the same branch for the whole group of selects. 00018 // 00019 //===----------------------------------------------------------------------===// 00020 00021 #include "llvm/Transforms/Scalar.h" 00022 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" 00023 #include "llvm/Function.h" 00024 #include "llvm/Instructions.h" 00025 #include "llvm/Pass.h" 00026 #include "llvm/Type.h" 00027 #include "llvm/ADT/Statistic.h" 00028 using namespace llvm; 00029 00030 namespace { 00031 Statistic<> NumLowered("lowerselect","Number of select instructions lowered"); 00032 00033 /// LowerSelect - Turn select instructions into conditional branches. 00034 /// 00035 class LowerSelect : public FunctionPass { 00036 bool OnlyFP; // Only lower FP select instructions? 00037 public: 00038 LowerSelect(bool onlyfp = false) : OnlyFP(onlyfp) {} 00039 00040 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00041 // This certainly destroys the CFG. 00042 // This is a cluster of orthogonal Transforms: 00043 AU.addPreserved<UnifyFunctionExitNodes>(); 00044 AU.addPreservedID(PromoteMemoryToRegisterID); 00045 AU.addPreservedID(LowerSwitchID); 00046 AU.addPreservedID(LowerInvokePassID); 00047 AU.addPreservedID(LowerAllocationsID); 00048 } 00049 00050 bool runOnFunction(Function &F); 00051 }; 00052 00053 RegisterOpt<LowerSelect> 00054 X("lowerselect", "Lower select instructions to branches"); 00055 } 00056 00057 // Publically exposed interface to pass... 00058 const PassInfo *llvm::LowerSelectID = X.getPassInfo(); 00059 //===----------------------------------------------------------------------===// 00060 // This pass converts SelectInst instructions into conditional branch and PHI 00061 // instructions. If the OnlyFP flag is set to true, then only floating point 00062 // select instructions are lowered. 00063 // 00064 FunctionPass *llvm::createLowerSelectPass(bool OnlyFP) { 00065 return new LowerSelect(OnlyFP); 00066 } 00067 00068 00069 bool LowerSelect::runOnFunction(Function &F) { 00070 bool Changed = false; 00071 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 00072 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 00073 if (SelectInst *SI = dyn_cast<SelectInst>(I)) 00074 if (!OnlyFP || SI->getType()->isFloatingPoint()) { 00075 // Split this basic block in half right before the select instruction. 00076 BasicBlock *NewCont = 00077 BB->splitBasicBlock(I, BB->getName()+".selectcont"); 00078 00079 // Make the true block, and make it branch to the continue block. 00080 BasicBlock *NewTrue = new BasicBlock(BB->getName()+".selecttrue", 00081 BB->getParent(), NewCont); 00082 new BranchInst(NewCont, NewTrue); 00083 00084 // Make the unconditional branch in the incoming block be a 00085 // conditional branch on the select predicate. 00086 BB->getInstList().erase(BB->getTerminator()); 00087 new BranchInst(NewTrue, NewCont, SI->getCondition(), BB); 00088 00089 // Create a new PHI node in the cont block with the entries we need. 00090 std::string Name = SI->getName(); SI->setName(""); 00091 PHINode *PN = new PHINode(SI->getType(), Name, NewCont->begin()); 00092 PN->addIncoming(SI->getTrueValue(), NewTrue); 00093 PN->addIncoming(SI->getFalseValue(), BB); 00094 00095 // Use the PHI instead of the select. 00096 SI->replaceAllUsesWith(PN); 00097 NewCont->getInstList().erase(SI); 00098 00099 Changed = true; 00100 break; // This block is done with. 00101 } 00102 } 00103 return Changed; 00104 }