diff options
author | Jakub Staszak <kubastaszak@gmail.com> | 2012-09-04 20:48:24 +0000 |
---|---|---|
committer | Jakub Staszak <kubastaszak@gmail.com> | 2012-09-04 20:48:24 +0000 |
commit | 7b2d20d0600ffbc9ae6df67a18b6f6485ebceb54 (patch) | |
tree | 00f4b2ed7151361d1216150ff8a2b1c950f448ca /lib/Transforms/Utils/BypassSlowDivision.cpp | |
parent | f2d8190b814697ef8e36f9d839c64c60e78760db (diff) |
Return false if BypassSlowDivision doesn't change anything.
Also a few minor changes:
- use pre-inc instead of post-inc
- use isa instead of dyn_cast
- 80 col
- trailing spaces
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163164 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/BypassSlowDivision.cpp')
-rw-r--r-- | lib/Transforms/Utils/BypassSlowDivision.cpp | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/lib/Transforms/Utils/BypassSlowDivision.cpp b/lib/Transforms/Utils/BypassSlowDivision.cpp index 1c58bec925..af0633c512 100644 --- a/lib/Transforms/Utils/BypassSlowDivision.cpp +++ b/lib/Transforms/Utils/BypassSlowDivision.cpp @@ -61,7 +61,7 @@ namespace llvm { static unsigned getHashValue(const DivOpInfo &Val) { return (unsigned)(reinterpret_cast<uintptr_t>(Val.Dividend) ^ reinterpret_cast<uintptr_t>(Val.Divisor)) ^ - (unsigned)Val.SignedOp; + (unsigned)Val.SignedOp; } }; @@ -71,31 +71,29 @@ namespace llvm { // insertFastDiv - Substitutes the div/rem instruction with code that checks the // value of the operands and uses a shorter-faster div/rem instruction when // possible and the longer-slower div/rem instruction otherwise. -static void insertFastDiv(Function &F, +static bool insertFastDiv(Function &F, Function::iterator &I, BasicBlock::iterator &J, IntegerType *BypassType, bool UseDivOp, bool UseSignedOp, - DivCacheTy &PerBBDivCache) -{ + DivCacheTy &PerBBDivCache) { // Get instruction operands Instruction *Instr = J; Value *Dividend = Instr->getOperand(0); Value *Divisor = Instr->getOperand(1); - if (dyn_cast<ConstantInt>(Divisor) != 0 || - (dyn_cast<ConstantInt>(Dividend) != 0 && - dyn_cast<ConstantInt>(Divisor) != 0)) { + if (isa<ConstantInt>(Divisor) || + (isa<ConstantInt>(Dividend) && isa<ConstantInt>(Divisor))) { // Operations with immediate values should have // been solved and replaced during compile time. - return; + return false; } // Basic Block is split before divide BasicBlock *MainBB = I; BasicBlock *SuccessorBB = I->splitBasicBlock(J); - I++; //advance iterator I to successorBB + ++I; //advance iterator I to successorBB // Add new basic block for slow divide operation BasicBlock *SlowBB = BasicBlock::Create(F.getContext(), "", @@ -118,17 +116,19 @@ static void insertFastDiv(Function &F, MainBB->getParent(), SuccessorBB); FastBB->moveBefore(SlowBB); IRBuilder<> FastBuilder(FastBB, FastBB->begin()); - Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor, BypassType); - Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend, BypassType); + Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor, + BypassType); + Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend, + BypassType); // udiv/urem because optimization only handles positive numbers Value *ShortQuotientV = FastBuilder.CreateExactUDiv(ShortDividendV, - ShortDivisorV); + ShortDivisorV); Value *ShortRemainderV = FastBuilder.CreateURem(ShortDividendV, ShortDivisorV); Value *FastQuotientV = FastBuilder.CreateCast(Instruction::ZExt, - ShortQuotientV, - Dividend->getType()); + ShortQuotientV, + Dividend->getType()); Value *FastRemainderV = FastBuilder.CreateCast(Instruction::ZExt, ShortRemainderV, Dividend->getType()); @@ -144,11 +144,10 @@ static void insertFastDiv(Function &F, RemPhi->addIncoming(FastRemainderV, FastBB); // Replace Instr with appropriate phi node - if (UseDivOp) { + if (UseDivOp) Instr->replaceAllUsesWith(QuoPhi); - } else { + else Instr->replaceAllUsesWith(RemPhi); - } Instr->eraseFromParent(); // Combine operands into a single value with OR for value testing below @@ -174,19 +173,19 @@ static void insertFastDiv(Function &F, DivOpInfo Key(UseSignedOp, Dividend, Divisor); DivPhiNodes Value(QuoPhi, RemPhi); PerBBDivCache.insert(std::pair<DivOpInfo, DivPhiNodes>(Key, Value)); + return true; } // reuseOrInsertFastDiv - Reuses previously computed dividend or remainder if // operands and operation are identical. Otherwise call insertFastDiv to perform // the optimization and cache the resulting dividend and remainder. -static void reuseOrInsertFastDiv(Function &F, +static bool reuseOrInsertFastDiv(Function &F, Function::iterator &I, BasicBlock::iterator &J, IntegerType *BypassType, bool UseDivOp, bool UseSignedOp, - DivCacheTy &PerBBDivCache) -{ + DivCacheTy &PerBBDivCache) { // Get instruction operands Instruction *Instr = J; DivOpInfo Key(UseSignedOp, Instr->getOperand(0), Instr->getOperand(1)); @@ -194,8 +193,8 @@ static void reuseOrInsertFastDiv(Function &F, if (CacheI == PerBBDivCache.end()) { // If previous instance does not exist, insert fast div - insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp, PerBBDivCache); - return; + return insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp, + PerBBDivCache); } // Replace operation value with previously generated phi node @@ -209,18 +208,18 @@ static void reuseOrInsertFastDiv(Function &F, } // Advance to next operation - J++; + ++J; // Remove redundant operation Instr->eraseFromParent(); + return true; } // bypassSlowDivision - This optimization identifies DIV instructions that can // be profitably bypassed and carried out with a shorter, faster divide. bool bypassSlowDivision(Function &F, Function::iterator &I, - const llvm::DenseMap<Type *, Type *> &BypassTypeMap) -{ + const llvm::DenseMap<Type *, Type *> &BypassTypeMap) { DivCacheTy DivCache; bool MadeChange = false; @@ -230,20 +229,22 @@ bool bypassSlowDivision(Function &F, unsigned Opcode = J->getOpcode(); bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv; bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem; - bool UseSignedOp = Opcode == Instruction::SDiv || Opcode == Instruction::SRem; + bool UseSignedOp = Opcode == Instruction::SDiv || + Opcode == Instruction::SRem; // Only optimize div or rem ops - if (!UseDivOp && !UseRemOp) { + if (!UseDivOp && !UseRemOp) continue; - } + // Continue if div/rem type is not bypassed - DenseMap<Type *, Type *>::const_iterator BT = BypassTypeMap.find(J->getType()); - if (BT == BypassTypeMap.end()) { + DenseMap<Type *, Type *>::const_iterator BT = + BypassTypeMap.find(J->getType()); + if (BT == BypassTypeMap.end()) continue; - } - IntegerType *BypassType = (IntegerType *)BT->second; - reuseOrInsertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp, DivCache); + IntegerType *BypassType = cast<IntegerType>(BT->second); + MadeChange |= reuseOrInsertFastDiv(F, I, J, BypassType, UseDivOp, + UseSignedOp, DivCache); MadeChange = true; } |