X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FUtils%2FLowerSwitch.cpp;h=1910fd9e5205a589f7884a1b309f02b83bcca041;hp=6a6833fa78d4bb7c4058808156e3277fc89351a5;hb=90c579de5a383cee278acc3f7e7b9d0a656e6a35;hpb=3e15bf33e024b9df9e89351a165acfdb1dde51ed diff --git a/lib/Transforms/Utils/LowerSwitch.cpp b/lib/Transforms/Utils/LowerSwitch.cpp index 6a6833fa78d..1910fd9e520 100644 --- a/lib/Transforms/Utils/LowerSwitch.cpp +++ b/lib/Transforms/Utils/LowerSwitch.cpp @@ -2,14 +2,14 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// The LowerSwitch transformation rewrites switch statements with a sequence of -// branches, which allows targets to get away with not implementing the switch -// statement until it is convenient. +// The LowerSwitch transformation rewrites switch instructions with a sequence +// of branches, which allows targets to get away with not implementing the +// switch instruction until it is convenient. // //===----------------------------------------------------------------------===// @@ -18,9 +18,12 @@ #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" #include "llvm/Pass.h" -#include "llvm/Support/Debug.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include using namespace llvm; @@ -28,10 +31,10 @@ namespace { /// LowerSwitch Pass - Replace all SwitchInst instructions with chained branch /// instructions. Note that this cannot be a BasicBlock pass because it /// modifies the CFG! - class VISIBILITY_HIDDEN LowerSwitch : public FunctionPass { + class LowerSwitch : public FunctionPass { public: - static const char ID; // Pass identifcation, replacement for typeid - LowerSwitch() : FunctionPass((intptr_t) &ID) {} + static char ID; // Pass identification, replacement for typeid + LowerSwitch() : FunctionPass(ID) {} virtual bool runOnFunction(Function &F); @@ -39,9 +42,7 @@ namespace { // This is a cluster of orthogonal Transforms AU.addPreserved(); AU.addPreservedID(PromoteMemoryToRegisterID); - AU.addPreservedID(LowerSelectID); AU.addPreservedID(LowerInvokePassID); - AU.addPreservedID(LowerAllocationsID); } struct CaseRange { @@ -77,14 +78,14 @@ namespace { return CI1->getValue().slt(CI2->getValue()); } }; - - const char LowerSwitch::ID = 0; - RegisterPass - X("lowerswitch", "Lower SwitchInst's to branches"); } +char LowerSwitch::ID = 0; +static RegisterPass +X("lowerswitch", "Lower SwitchInst's to branches"); + // Publically exposed interface to pass... -const PassInfo *llvm::LowerSwitchID = X.getPassInfo(); +char &llvm::LowerSwitchID = LowerSwitch::ID; // createLowerSwitchPass - Interface to this file... FunctionPass *llvm::createLowerSwitchPass() { return new LowerSwitch(); @@ -107,8 +108,10 @@ bool LowerSwitch::runOnFunction(Function &F) { // operator<< - Used for debugging purposes. // -static std::ostream& operator<<(std::ostream &O, - const LowerSwitch::CaseVector &C) { +static raw_ostream& operator<<(raw_ostream &O, + const LowerSwitch::CaseVector &C) ATTRIBUTE_USED; +static raw_ostream& operator<<(raw_ostream &O, + const LowerSwitch::CaseVector &C) { O << "["; for (LowerSwitch::CaseVector::const_iterator B = C.begin(), @@ -120,11 +123,6 @@ static std::ostream& operator<<(std::ostream &O, return O << "]"; } -static OStream& operator<<(OStream &O, const LowerSwitch::CaseVector &C) { - if (O.stream()) *O.stream() << C; - return O; -} - // switchConvert - Convert the switch statement into a binary lookup of // the case values. The function recursively builds this tree. // @@ -139,16 +137,14 @@ BasicBlock* LowerSwitch::switchConvert(CaseItr Begin, CaseItr End, unsigned Mid = Size / 2; std::vector LHS(Begin, Begin + Mid); - DOUT << "LHS: " << LHS << "\n"; + DEBUG(dbgs() << "LHS: " << LHS << "\n"); std::vector RHS(Begin + Mid, End); - DOUT << "RHS: " << RHS << "\n"; + DEBUG(dbgs() << "RHS: " << RHS << "\n"); CaseRange& Pivot = *(Begin + Mid); - DEBUG( DOUT << "Pivot ==> " - << cast(Pivot.Low)->getValue().toStringSigned(10) - << " -" - << cast(Pivot.High)->getValue().toStringSigned(10) - << "\n"); + DEBUG(dbgs() << "Pivot ==> " + << cast(Pivot.Low)->getValue() << " -" + << cast(Pivot.High)->getValue() << "\n"); BasicBlock* LBranch = switchConvert(LHS.begin(), LHS.end(), Val, OrigBlock, Default); @@ -158,13 +154,14 @@ BasicBlock* LowerSwitch::switchConvert(CaseItr Begin, CaseItr End, // Create a new node that checks if the value is < pivot. Go to the // left branch if it is and right branch if not. Function* F = OrigBlock->getParent(); - BasicBlock* NewNode = new BasicBlock("NodeBlock"); + BasicBlock* NewNode = BasicBlock::Create(Val->getContext(), "NodeBlock"); Function::iterator FI = OrigBlock; F->getBasicBlockList().insert(++FI, NewNode); - ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_SLT, Val, Pivot.Low, "Pivot"); + ICmpInst* Comp = new ICmpInst(ICmpInst::ICMP_SLT, + Val, Pivot.Low, "Pivot"); NewNode->getInstList().push_back(Comp); - new BranchInst(LBranch, RBranch, Comp, NewNode); + BranchInst::Create(LBranch, RBranch, Comp, NewNode); return NewNode; } @@ -179,7 +176,7 @@ BasicBlock* LowerSwitch::newLeafBlock(CaseRange& Leaf, Value* Val, BasicBlock* Default) { Function* F = OrigBlock->getParent(); - BasicBlock* NewLeaf = new BasicBlock("LeafBlock"); + BasicBlock* NewLeaf = BasicBlock::Create(Val->getContext(), "LeafBlock"); Function::iterator FI = OrigBlock; F->getBasicBlockList().insert(++FI, NewLeaf); @@ -187,33 +184,33 @@ BasicBlock* LowerSwitch::newLeafBlock(CaseRange& Leaf, Value* Val, ICmpInst* Comp = NULL; if (Leaf.Low == Leaf.High) { // Make the seteq instruction... - Comp = new ICmpInst(ICmpInst::ICMP_EQ, Val, Leaf.Low, - "SwitchLeaf", NewLeaf); + Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_EQ, Val, + Leaf.Low, "SwitchLeaf"); } else { // Make range comparison if (cast(Leaf.Low)->isMinValue(true /*isSigned*/)) { // Val >= Min && Val <= Hi --> Val <= Hi - Comp = new ICmpInst(ICmpInst::ICMP_SLE, Val, Leaf.High, - "SwitchLeaf", NewLeaf); + Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_SLE, Val, Leaf.High, + "SwitchLeaf"); } else if (cast(Leaf.Low)->isZero()) { // Val >= 0 && Val <= Hi --> Val <=u Hi - Comp = new ICmpInst(ICmpInst::ICMP_ULE, Val, Leaf.High, - "SwitchLeaf", NewLeaf); + Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Val, Leaf.High, + "SwitchLeaf"); } else { // Emit V-Lo <=u Hi-Lo Constant* NegLo = ConstantExpr::getNeg(Leaf.Low); - Instruction* Add = BinaryOperator::createAdd(Val, NegLo, + Instruction* Add = BinaryOperator::CreateAdd(Val, NegLo, Val->getName()+".off", NewLeaf); Constant *UpperBound = ConstantExpr::getAdd(NegLo, Leaf.High); - Comp = new ICmpInst(ICmpInst::ICMP_ULE, Add, UpperBound, - "SwitchLeaf", NewLeaf); + Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Add, UpperBound, + "SwitchLeaf"); } } // Make the conditional branch... BasicBlock* Succ = Leaf.BB; - new BranchInst(Succ, Default, Comp, NewLeaf); + BranchInst::Create(Succ, Default, Comp, NewLeaf); // If there were any PHI nodes in this successor, rewrite one entry // from OrigBlock to come from NewLeaf. @@ -243,11 +240,11 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) { Cases.push_back(CaseRange(SI->getSuccessorValue(i), SI->getSuccessorValue(i), SI->getSuccessor(i))); - sort(Cases.begin(), Cases.end(), CaseCmp()); + std::sort(Cases.begin(), Cases.end(), CaseCmp()); // Merge case into clusters if (Cases.size()>=2) - for (CaseItr I=Cases.begin(), J=++(Cases.begin()), E=Cases.end(); J!=E; ) { + for (CaseItr I=Cases.begin(), J=llvm::next(Cases.begin()); J!=Cases.end(); ) { int64_t nextValue = cast(J->Low)->getSExtValue(); int64_t currentValue = cast(I->High)->getSExtValue(); BasicBlock* nextBB = J->BB; @@ -284,17 +281,17 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI) { // If there is only the default destination, don't bother with the code below. if (SI->getNumOperands() == 2) { - new BranchInst(SI->getDefaultDest(), CurBlock); + BranchInst::Create(SI->getDefaultDest(), CurBlock); CurBlock->getInstList().erase(SI); return; } // Create a new, empty default block so that the new hierarchy of // if-then statements go to this and the PHI nodes are happy. - BasicBlock* NewDefault = new BasicBlock("NewDefault"); + BasicBlock* NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault"); F->getBasicBlockList().insert(Default, NewDefault); - new BranchInst(Default, NewDefault); + BranchInst::Create(Default, NewDefault); // If there is an entry in any PHI nodes for the default edge, make sure // to update them as well. @@ -309,15 +306,16 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI) { CaseVector Cases; unsigned numCmps = Clusterify(Cases, SI); - DOUT << "Clusterify finished. Total clusters: " << Cases.size() - << ". Total compares: " << numCmps << "\n"; - DOUT << "Cases: " << Cases << "\n"; + DEBUG(dbgs() << "Clusterify finished. Total clusters: " << Cases.size() + << ". Total compares: " << numCmps << "\n"); + DEBUG(dbgs() << "Cases: " << Cases << "\n"); + (void)numCmps; BasicBlock* SwitchBlock = switchConvert(Cases.begin(), Cases.end(), Val, OrigBlock, NewDefault); // Branch to our shiny new if-then stuff... - new BranchInst(SwitchBlock, OrigBlock); + BranchInst::Create(SwitchBlock, OrigBlock); // We are now done with the switch instruction, delete it. CurBlock->getInstList().erase(SI);