aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/BypassSlowDivision.cpp
diff options
context:
space:
mode:
authorJakub Staszak <kubastaszak@gmail.com>2012-09-04 20:48:24 +0000
committerJakub Staszak <kubastaszak@gmail.com>2012-09-04 20:48:24 +0000
commit7b2d20d0600ffbc9ae6df67a18b6f6485ebceb54 (patch)
tree00f4b2ed7151361d1216150ff8a2b1c950f448ca /lib/Transforms/Utils/BypassSlowDivision.cpp
parentf2d8190b814697ef8e36f9d839c64c60e78760db (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.cpp67
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;
}