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/Function.h" 00023 #include "llvm/Instructions.h" 00024 #include "llvm/Pass.h" 00025 #include "llvm/Type.h" 00026 #include "llvm/ADT/Statistic.h" 00027 using namespace llvm; 00028 00029 namespace { 00030 Statistic<> NumLowered("lowerselect","Number of select instructions lowered"); 00031 00032 /// LowerSelect - Turn select instructions into conditional branches. 00033 /// 00034 class LowerSelect : public FunctionPass { 00035 bool OnlyFP; // Only lower FP select instructions? 00036 public: 00037 LowerSelect(bool onlyfp = false) : OnlyFP(onlyfp) {} 00038 00039 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00040 // Doesn't really preserve anything. It can certainly destroy the CFG. 00041 } 00042 00043 bool runOnFunction(Function &F); 00044 }; 00045 00046 RegisterOpt<LowerSelect> 00047 X("lowerselect", "Lower select instructions to branches"); 00048 } 00049 00050 //===----------------------------------------------------------------------===// 00051 // This pass converts SelectInst instructions into conditional branch and PHI 00052 // instructions. If the OnlyFP flag is set to true, then only floating point 00053 // select instructions are lowered. 00054 // 00055 FunctionPass *llvm::createLowerSelectPass(bool OnlyFP) { 00056 return new LowerSelect(OnlyFP); 00057 } 00058 00059 00060 bool LowerSelect::runOnFunction(Function &F) { 00061 bool Changed = false; 00062 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 00063 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { 00064 if (SelectInst *SI = dyn_cast<SelectInst>(I)) 00065 if (!OnlyFP || SI->getType()->isFloatingPoint()) { 00066 // Split this basic block in half right before the select instruction. 00067 BasicBlock *NewCont = 00068 BB->splitBasicBlock(I, BB->getName()+".selectcont"); 00069 00070 // Make the true block, and make it branch to the continue block. 00071 BasicBlock *NewTrue = new BasicBlock(BB->getName()+".selecttrue", 00072 BB->getParent(), NewCont); 00073 new BranchInst(NewCont, NewTrue); 00074 00075 // Make the unconditional branch in the incoming block be a 00076 // conditional branch on the select predicate. 00077 BB->getInstList().erase(BB->getTerminator()); 00078 new BranchInst(NewTrue, NewCont, SI->getCondition(), BB); 00079 00080 // Create a new PHI node in the cont block with the entries we need. 00081 std::string Name = SI->getName(); SI->setName(""); 00082 PHINode *PN = new PHINode(SI->getType(), Name, NewCont->begin()); 00083 PN->addIncoming(SI->getTrueValue(), NewTrue); 00084 PN->addIncoming(SI->getFalseValue(), BB); 00085 00086 // Use the PHI instead of the select. 00087 SI->replaceAllUsesWith(PN); 00088 NewCont->getInstList().erase(SI); 00089 00090 Changed = true; 00091 break; // This block is done with. 00092 } 00093 } 00094 return Changed; 00095 }