| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 1 | //===-- BypassSlowDivision.cpp - Bypass slow division ---------------------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file contains an optimization for div and rem on architectures that | 
|  | 11 | // execute short instructions significantly faster than longer instructions. | 
|  | 12 | // For example, on Intel Atom 32-bit divides are slow enough that during | 
|  | 13 | // runtime it is profitable to check the value of the operands, and if they are | 
|  | 14 | // positive and less than 256 use an unsigned 8-bit divide. | 
|  | 15 | // | 
|  | 16 | //===----------------------------------------------------------------------===// | 
|  | 17 |  | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 18 | #include "llvm/Transforms/Utils/BypassSlowDivision.h" | 
|  | 19 | #include "llvm/ADT/DenseMap.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 20 | #include "llvm/IR/Function.h" | 
|  | 21 | #include "llvm/IR/IRBuilder.h" | 
|  | 22 | #include "llvm/IR/Instructions.h" | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 23 |  | 
|  | 24 | using namespace llvm; | 
|  | 25 |  | 
| Chandler Carruth | 964daaa | 2014-04-22 02:55:47 +0000 | [diff] [blame] | 26 | #define DEBUG_TYPE "bypass-slow-division" | 
|  | 27 |  | 
| Benjamin Kramer | 1f66f88 | 2012-09-10 11:52:08 +0000 | [diff] [blame] | 28 | namespace { | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 29 | struct DivOpInfo { | 
|  | 30 | bool SignedOp; | 
|  | 31 | Value *Dividend; | 
|  | 32 | Value *Divisor; | 
|  | 33 |  | 
|  | 34 | DivOpInfo(bool InSignedOp, Value *InDividend, Value *InDivisor) | 
|  | 35 | : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {} | 
|  | 36 | }; | 
|  | 37 |  | 
|  | 38 | struct DivPhiNodes { | 
|  | 39 | PHINode *Quotient; | 
|  | 40 | PHINode *Remainder; | 
|  | 41 |  | 
|  | 42 | DivPhiNodes(PHINode *InQuotient, PHINode *InRemainder) | 
|  | 43 | : Quotient(InQuotient), Remainder(InRemainder) {} | 
|  | 44 | }; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 45 | } | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 46 |  | 
| Benjamin Kramer | 1f66f88 | 2012-09-10 11:52:08 +0000 | [diff] [blame] | 47 | namespace llvm { | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 48 | template<> | 
|  | 49 | struct DenseMapInfo<DivOpInfo> { | 
|  | 50 | static bool isEqual(const DivOpInfo &Val1, const DivOpInfo &Val2) { | 
|  | 51 | return Val1.SignedOp == Val2.SignedOp && | 
|  | 52 | Val1.Dividend == Val2.Dividend && | 
|  | 53 | Val1.Divisor == Val2.Divisor; | 
|  | 54 | } | 
|  | 55 |  | 
|  | 56 | static DivOpInfo getEmptyKey() { | 
| Craig Topper | f40110f | 2014-04-25 05:29:35 +0000 | [diff] [blame] | 57 | return DivOpInfo(false, nullptr, nullptr); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 58 | } | 
|  | 59 |  | 
|  | 60 | static DivOpInfo getTombstoneKey() { | 
| Craig Topper | f40110f | 2014-04-25 05:29:35 +0000 | [diff] [blame] | 61 | return DivOpInfo(true, nullptr, nullptr); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 62 | } | 
|  | 63 |  | 
|  | 64 | static unsigned getHashValue(const DivOpInfo &Val) { | 
|  | 65 | return (unsigned)(reinterpret_cast<uintptr_t>(Val.Dividend) ^ | 
|  | 66 | reinterpret_cast<uintptr_t>(Val.Divisor)) ^ | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 67 | (unsigned)Val.SignedOp; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 68 | } | 
|  | 69 | }; | 
|  | 70 |  | 
|  | 71 | typedef DenseMap<DivOpInfo, DivPhiNodes> DivCacheTy; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 72 | } | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 73 |  | 
|  | 74 | // insertFastDiv - Substitutes the div/rem instruction with code that checks the | 
|  | 75 | // value of the operands and uses a shorter-faster div/rem instruction when | 
|  | 76 | // possible and the longer-slower div/rem instruction otherwise. | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 77 | static bool insertFastDiv(Instruction *I, IntegerType *BypassType, | 
|  | 78 | bool UseDivOp, bool UseSignedOp, | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 79 | DivCacheTy &PerBBDivCache) { | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 80 | Function *F = I->getParent()->getParent(); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 81 | // Get instruction operands | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 82 | Value *Dividend = I->getOperand(0); | 
|  | 83 | Value *Divisor = I->getOperand(1); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 84 |  | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 85 | if (isa<ConstantInt>(Divisor) || | 
|  | 86 | (isa<ConstantInt>(Dividend) && isa<ConstantInt>(Divisor))) { | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 87 | // Operations with immediate values should have | 
|  | 88 | // been solved and replaced during compile time. | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 89 | return false; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 90 | } | 
|  | 91 |  | 
|  | 92 | // Basic Block is split before divide | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 93 | BasicBlock *MainBB = &*I->getParent(); | 
|  | 94 | BasicBlock *SuccessorBB = MainBB->splitBasicBlock(I); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 95 |  | 
|  | 96 | // Add new basic block for slow divide operation | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 97 | BasicBlock *SlowBB = | 
|  | 98 | BasicBlock::Create(F->getContext(), "", MainBB->getParent(), SuccessorBB); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 99 | SlowBB->moveBefore(SuccessorBB); | 
|  | 100 | IRBuilder<> SlowBuilder(SlowBB, SlowBB->begin()); | 
|  | 101 | Value *SlowQuotientV; | 
|  | 102 | Value *SlowRemainderV; | 
|  | 103 | if (UseSignedOp) { | 
|  | 104 | SlowQuotientV = SlowBuilder.CreateSDiv(Dividend, Divisor); | 
|  | 105 | SlowRemainderV = SlowBuilder.CreateSRem(Dividend, Divisor); | 
|  | 106 | } else { | 
|  | 107 | SlowQuotientV = SlowBuilder.CreateUDiv(Dividend, Divisor); | 
|  | 108 | SlowRemainderV = SlowBuilder.CreateURem(Dividend, Divisor); | 
|  | 109 | } | 
|  | 110 | SlowBuilder.CreateBr(SuccessorBB); | 
|  | 111 |  | 
|  | 112 | // Add new basic block for fast divide operation | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 113 | BasicBlock *FastBB = | 
|  | 114 | BasicBlock::Create(F->getContext(), "", MainBB->getParent(), SuccessorBB); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 115 | FastBB->moveBefore(SlowBB); | 
|  | 116 | IRBuilder<> FastBuilder(FastBB, FastBB->begin()); | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 117 | Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor, | 
|  | 118 | BypassType); | 
|  | 119 | Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend, | 
|  | 120 | BypassType); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 121 |  | 
|  | 122 | // udiv/urem because optimization only handles positive numbers | 
|  | 123 | Value *ShortQuotientV = FastBuilder.CreateExactUDiv(ShortDividendV, | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 124 | ShortDivisorV); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 125 | Value *ShortRemainderV = FastBuilder.CreateURem(ShortDividendV, | 
|  | 126 | ShortDivisorV); | 
|  | 127 | Value *FastQuotientV = FastBuilder.CreateCast(Instruction::ZExt, | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 128 | ShortQuotientV, | 
|  | 129 | Dividend->getType()); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 130 | Value *FastRemainderV = FastBuilder.CreateCast(Instruction::ZExt, | 
|  | 131 | ShortRemainderV, | 
|  | 132 | Dividend->getType()); | 
|  | 133 | FastBuilder.CreateBr(SuccessorBB); | 
|  | 134 |  | 
|  | 135 | // Phi nodes for result of div and rem | 
|  | 136 | IRBuilder<> SuccessorBuilder(SuccessorBB, SuccessorBB->begin()); | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 137 | PHINode *QuoPhi = SuccessorBuilder.CreatePHI(I->getType(), 2); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 138 | QuoPhi->addIncoming(SlowQuotientV, SlowBB); | 
|  | 139 | QuoPhi->addIncoming(FastQuotientV, FastBB); | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 140 | PHINode *RemPhi = SuccessorBuilder.CreatePHI(I->getType(), 2); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 141 | RemPhi->addIncoming(SlowRemainderV, SlowBB); | 
|  | 142 | RemPhi->addIncoming(FastRemainderV, FastBB); | 
|  | 143 |  | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 144 | // Replace I with appropriate phi node | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 145 | if (UseDivOp) | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 146 | I->replaceAllUsesWith(QuoPhi); | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 147 | else | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 148 | I->replaceAllUsesWith(RemPhi); | 
|  | 149 | I->eraseFromParent(); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 150 |  | 
|  | 151 | // Combine operands into a single value with OR for value testing below | 
|  | 152 | MainBB->getInstList().back().eraseFromParent(); | 
|  | 153 | IRBuilder<> MainBuilder(MainBB, MainBB->end()); | 
|  | 154 | Value *OrV = MainBuilder.CreateOr(Dividend, Divisor); | 
|  | 155 |  | 
|  | 156 | // BitMask is inverted to check if the operands are | 
|  | 157 | // larger than the bypass type | 
|  | 158 | uint64_t BitMask = ~BypassType->getBitMask(); | 
|  | 159 | Value *AndV = MainBuilder.CreateAnd(OrV, BitMask); | 
|  | 160 |  | 
|  | 161 | // Compare operand values and branch | 
| Preston Gurd | 485296d | 2013-03-04 18:13:57 +0000 | [diff] [blame] | 162 | Value *ZeroV = ConstantInt::getSigned(Dividend->getType(), 0); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 163 | Value *CmpV = MainBuilder.CreateICmpEQ(AndV, ZeroV); | 
|  | 164 | MainBuilder.CreateCondBr(CmpV, FastBB, SlowBB); | 
|  | 165 |  | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 166 | // Cache phi nodes to be used later in place of other instances | 
|  | 167 | // of div or rem with the same sign, dividend, and divisor | 
|  | 168 | DivOpInfo Key(UseSignedOp, Dividend, Divisor); | 
|  | 169 | DivPhiNodes Value(QuoPhi, RemPhi); | 
|  | 170 | PerBBDivCache.insert(std::pair<DivOpInfo, DivPhiNodes>(Key, Value)); | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 171 | return true; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 172 | } | 
|  | 173 |  | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 174 | // reuseOrInsertFastDiv - Reuses previously computed dividend or remainder from | 
|  | 175 | // the current BB if operands and operation are identical. Otherwise calls | 
|  | 176 | // insertFastDiv to perform the optimization and caches the resulting dividend | 
|  | 177 | // and remainder. | 
|  | 178 | static bool reuseOrInsertFastDiv(Instruction *I, IntegerType *BypassType, | 
|  | 179 | bool UseDivOp, bool UseSignedOp, | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 180 | DivCacheTy &PerBBDivCache) { | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 181 | // Get instruction operands | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 182 | DivOpInfo Key(UseSignedOp, I->getOperand(0), I->getOperand(1)); | 
| Jakub Staszak | e535c1a | 2012-09-04 23:11:11 +0000 | [diff] [blame] | 183 | DivCacheTy::iterator CacheI = PerBBDivCache.find(Key); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 184 |  | 
|  | 185 | if (CacheI == PerBBDivCache.end()) { | 
|  | 186 | // If previous instance does not exist, insert fast div | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 187 | return insertFastDiv(I, BypassType, UseDivOp, UseSignedOp, PerBBDivCache); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 188 | } | 
|  | 189 |  | 
|  | 190 | // Replace operation value with previously generated phi node | 
| Jakub Staszak | e535c1a | 2012-09-04 23:11:11 +0000 | [diff] [blame] | 191 | DivPhiNodes &Value = CacheI->second; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 192 | if (UseDivOp) { | 
|  | 193 | // Replace all uses of div instruction with quotient phi node | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 194 | I->replaceAllUsesWith(Value.Quotient); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 195 | } else { | 
|  | 196 | // Replace all uses of rem instruction with remainder phi node | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 197 | I->replaceAllUsesWith(Value.Remainder); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 198 | } | 
|  | 199 |  | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 200 | // Remove redundant operation | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 201 | I->eraseFromParent(); | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 202 | return true; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 203 | } | 
|  | 204 |  | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 205 | // bypassSlowDivision - This optimization identifies DIV instructions in a BB | 
|  | 206 | // that can be profitably bypassed and carried out with a shorter, faster | 
|  | 207 | // divide. | 
|  | 208 | bool llvm::bypassSlowDivision( | 
|  | 209 | BasicBlock *BB, const DenseMap<unsigned int, unsigned int> &BypassWidths) { | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 210 | DivCacheTy DivCache; | 
|  | 211 |  | 
|  | 212 | bool MadeChange = false; | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 213 | Instruction* Next = &*BB->begin(); | 
|  | 214 | while (Next != nullptr) { | 
|  | 215 | // We may add instructions immediately after I, but we want to skip over | 
|  | 216 | // them. | 
|  | 217 | Instruction* I = Next; | 
|  | 218 | Next = Next->getNextNode(); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 219 |  | 
|  | 220 | // Get instruction details | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 221 | unsigned Opcode = I->getOpcode(); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 222 | bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv; | 
|  | 223 | bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem; | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 224 | bool UseSignedOp = Opcode == Instruction::SDiv || | 
|  | 225 | Opcode == Instruction::SRem; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 226 |  | 
|  | 227 | // Only optimize div or rem ops | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 228 | if (!UseDivOp && !UseRemOp) | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 229 | continue; | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 230 |  | 
| Preston Gurd | 5509e3d | 2012-10-03 16:11:44 +0000 | [diff] [blame] | 231 | // Skip division on vector types, only optimize integer instructions | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 232 | if (!I->getType()->isIntegerTy()) | 
| Jakub Staszak | 46beca6 | 2012-09-04 20:48:24 +0000 | [diff] [blame] | 233 | continue; | 
|  | 234 |  | 
| Preston Gurd | 0d67f51 | 2012-10-04 21:33:40 +0000 | [diff] [blame] | 235 | // Get bitwidth of div/rem instruction | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 236 | IntegerType *T = cast<IntegerType>(I->getType()); | 
| Preston Gurd | 485296d | 2013-03-04 18:13:57 +0000 | [diff] [blame] | 237 | unsigned int bitwidth = T->getBitWidth(); | 
| Preston Gurd | 5509e3d | 2012-10-03 16:11:44 +0000 | [diff] [blame] | 238 |  | 
| Preston Gurd | 0d67f51 | 2012-10-04 21:33:40 +0000 | [diff] [blame] | 239 | // Continue if bitwidth is not bypassed | 
|  | 240 | DenseMap<unsigned int, unsigned int>::const_iterator BI = BypassWidths.find(bitwidth); | 
|  | 241 | if (BI == BypassWidths.end()) | 
| Preston Gurd | 5509e3d | 2012-10-03 16:11:44 +0000 | [diff] [blame] | 242 | continue; | 
|  | 243 |  | 
| Preston Gurd | 0d67f51 | 2012-10-04 21:33:40 +0000 | [diff] [blame] | 244 | // Get type for div/rem instruction with bypass bitwidth | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 245 | IntegerType *BT = IntegerType::get(I->getContext(), BI->second); | 
| Preston Gurd | 5509e3d | 2012-10-03 16:11:44 +0000 | [diff] [blame] | 246 |  | 
| Eric Christopher | 49a7d6c | 2016-01-04 23:18:58 +0000 | [diff] [blame] | 247 | MadeChange |= reuseOrInsertFastDiv(I, BT, UseDivOp, UseSignedOp, DivCache); | 
| Preston Gurd | cdf540d | 2012-09-04 18:22:17 +0000 | [diff] [blame] | 248 | } | 
|  | 249 |  | 
|  | 250 | return MadeChange; | 
|  | 251 | } |