blob: 7ffdad597a9b8f8c16d33543ff04a8a0f62b565c [file] [log] [blame]
Preston Gurdcdf540d2012-09-04 18:22:17 +00001//===-- 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 Carruthed0881b2012-12-03 16:50:05 +000018#include "llvm/Transforms/Utils/BypassSlowDivision.h"
19#include "llvm/ADT/DenseMap.h"
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +000020#include "llvm/ADT/SmallPtrSet.h"
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +000021#include "llvm/Analysis/ValueTracking.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000022#include "llvm/IR/Function.h"
23#include "llvm/IR/IRBuilder.h"
24#include "llvm/IR/Instructions.h"
Craig Topperb45eabc2017-04-26 16:39:58 +000025#include "llvm/Support/KnownBits.h"
Justin Lebar0ede5fb2016-10-28 21:43:54 +000026#include "llvm/Transforms/Utils/Local.h"
Preston Gurdcdf540d2012-09-04 18:22:17 +000027
28using namespace llvm;
29
Chandler Carruth964daaa2014-04-22 02:55:47 +000030#define DEBUG_TYPE "bypass-slow-division"
31
Benjamin Kramer1f66f882012-09-10 11:52:08 +000032namespace {
Preston Gurdcdf540d2012-09-04 18:22:17 +000033 struct DivOpInfo {
34 bool SignedOp;
35 Value *Dividend;
36 Value *Divisor;
37
38 DivOpInfo(bool InSignedOp, Value *InDividend, Value *InDivisor)
39 : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {}
40 };
41
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +000042 struct QuotRemPair {
43 Value *Quotient;
44 Value *Remainder;
Preston Gurdcdf540d2012-09-04 18:22:17 +000045
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +000046 QuotRemPair(Value *InQuotient, Value *InRemainder)
47 : Quotient(InQuotient), Remainder(InRemainder) {}
48 };
49
50 /// A quotient and remainder, plus a BB from which they logically "originate".
51 /// If you use Quotient or Remainder in a Phi node, you should use BB as its
52 /// corresponding predecessor.
53 struct QuotRemWithBB {
54 BasicBlock *BB = nullptr;
55 Value *Quotient = nullptr;
56 Value *Remainder = nullptr;
Preston Gurdcdf540d2012-09-04 18:22:17 +000057 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000058}
Preston Gurdcdf540d2012-09-04 18:22:17 +000059
Benjamin Kramer1f66f882012-09-10 11:52:08 +000060namespace llvm {
Preston Gurdcdf540d2012-09-04 18:22:17 +000061 template<>
62 struct DenseMapInfo<DivOpInfo> {
63 static bool isEqual(const DivOpInfo &Val1, const DivOpInfo &Val2) {
64 return Val1.SignedOp == Val2.SignedOp &&
65 Val1.Dividend == Val2.Dividend &&
66 Val1.Divisor == Val2.Divisor;
67 }
68
69 static DivOpInfo getEmptyKey() {
Craig Topperf40110f2014-04-25 05:29:35 +000070 return DivOpInfo(false, nullptr, nullptr);
Preston Gurdcdf540d2012-09-04 18:22:17 +000071 }
72
73 static DivOpInfo getTombstoneKey() {
Craig Topperf40110f2014-04-25 05:29:35 +000074 return DivOpInfo(true, nullptr, nullptr);
Preston Gurdcdf540d2012-09-04 18:22:17 +000075 }
76
77 static unsigned getHashValue(const DivOpInfo &Val) {
78 return (unsigned)(reinterpret_cast<uintptr_t>(Val.Dividend) ^
79 reinterpret_cast<uintptr_t>(Val.Divisor)) ^
Jakub Staszak46beca62012-09-04 20:48:24 +000080 (unsigned)Val.SignedOp;
Preston Gurdcdf540d2012-09-04 18:22:17 +000081 }
82 };
83
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +000084 typedef DenseMap<DivOpInfo, QuotRemPair> DivCacheTy;
85 typedef DenseMap<unsigned, unsigned> BypassWidthsTy;
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +000086 typedef SmallPtrSet<Instruction *, 4> VisitedSetTy;
Alexander Kornienkof00654e2015-06-23 09:49:53 +000087}
Preston Gurdcdf540d2012-09-04 18:22:17 +000088
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +000089namespace {
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +000090enum ValueRange {
91 /// Operand definitely fits into BypassType. No runtime checks are needed.
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +000092 VALRNG_KNOWN_SHORT,
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +000093 /// A runtime check is required, as value range is unknown.
94 VALRNG_UNKNOWN,
95 /// Operand is unlikely to fit into BypassType. The bypassing should be
96 /// disabled.
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +000097 VALRNG_LIKELY_LONG
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +000098};
99
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000100class FastDivInsertionTask {
101 bool IsValidTask = false;
102 Instruction *SlowDivOrRem = nullptr;
103 IntegerType *BypassType = nullptr;
104 BasicBlock *MainBB = nullptr;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000105
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000106 bool isHashLikeValue(Value *V, VisitedSetTy &Visited);
107 ValueRange getValueRange(Value *Op, VisitedSetTy &Visited);
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000108 QuotRemWithBB createSlowBB(BasicBlock *Successor);
109 QuotRemWithBB createFastBB(BasicBlock *Successor);
110 QuotRemPair createDivRemPhiNodes(QuotRemWithBB &LHS, QuotRemWithBB &RHS,
111 BasicBlock *PhiBB);
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000112 Value *insertOperandRuntimeCheck(Value *Op1, Value *Op2);
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000113 Optional<QuotRemPair> insertFastDivAndRem();
114
115 bool isSignedOp() {
116 return SlowDivOrRem->getOpcode() == Instruction::SDiv ||
117 SlowDivOrRem->getOpcode() == Instruction::SRem;
118 }
119 bool isDivisionOp() {
120 return SlowDivOrRem->getOpcode() == Instruction::SDiv ||
121 SlowDivOrRem->getOpcode() == Instruction::UDiv;
122 }
123 Type *getSlowType() { return SlowDivOrRem->getType(); }
124
125public:
126 FastDivInsertionTask(Instruction *I, const BypassWidthsTy &BypassWidths);
127 Value *getReplacement(DivCacheTy &Cache);
128};
129} // anonymous namespace
130
131FastDivInsertionTask::FastDivInsertionTask(Instruction *I,
132 const BypassWidthsTy &BypassWidths) {
133 switch (I->getOpcode()) {
134 case Instruction::UDiv:
135 case Instruction::SDiv:
136 case Instruction::URem:
137 case Instruction::SRem:
138 SlowDivOrRem = I;
139 break;
140 default:
141 // I is not a div/rem operation.
142 return;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000143 }
144
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000145 // Skip division on vector types. Only optimize integer instructions.
146 IntegerType *SlowType = dyn_cast<IntegerType>(SlowDivOrRem->getType());
147 if (!SlowType)
148 return;
Justin Lebar28605732016-11-16 00:44:47 +0000149
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000150 // Skip if this bitwidth is not bypassed.
151 auto BI = BypassWidths.find(SlowType->getBitWidth());
152 if (BI == BypassWidths.end())
153 return;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000154
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000155 // Get type for div/rem instruction with bypass bitwidth.
156 IntegerType *BT = IntegerType::get(I->getContext(), BI->second);
157 BypassType = BT;
158
159 // The original basic block.
160 MainBB = I->getParent();
161
162 // The instruction is indeed a slow div or rem operation.
163 IsValidTask = true;
164}
165
166/// Reuses previously-computed dividend or remainder from the current BB if
167/// operands and operation are identical. Otherwise calls insertFastDivAndRem to
168/// perform the optimization and caches the resulting dividend and remainder.
169/// If no replacement can be generated, nullptr is returned.
170Value *FastDivInsertionTask::getReplacement(DivCacheTy &Cache) {
171 // First, make sure that the task is valid.
172 if (!IsValidTask)
173 return nullptr;
174
175 // Then, look for a value in Cache.
176 Value *Dividend = SlowDivOrRem->getOperand(0);
177 Value *Divisor = SlowDivOrRem->getOperand(1);
178 DivOpInfo Key(isSignedOp(), Dividend, Divisor);
179 auto CacheI = Cache.find(Key);
180
181 if (CacheI == Cache.end()) {
182 // If previous instance does not exist, try to insert fast div.
183 Optional<QuotRemPair> OptResult = insertFastDivAndRem();
184 // Bail out if insertFastDivAndRem has failed.
185 if (!OptResult)
186 return nullptr;
187 CacheI = Cache.insert({Key, *OptResult}).first;
188 }
189
190 QuotRemPair &Value = CacheI->second;
191 return isDivisionOp() ? Value.Quotient : Value.Remainder;
192}
193
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000194/// \brief Check if a value looks like a hash.
195///
196/// The routine is expected to detect values computed using the most common hash
197/// algorithms. Typically, hash computations end with one of the following
198/// instructions:
199///
200/// 1) MUL with a constant wider than BypassType
201/// 2) XOR instruction
202///
203/// And even if we are wrong and the value is not a hash, it is still quite
204/// unlikely that such values will fit into BypassType.
205///
206/// To detect string hash algorithms like FNV we have to look through PHI-nodes.
207/// It is implemented as a depth-first search for values that look neither long
208/// nor hash-like.
209bool FastDivInsertionTask::isHashLikeValue(Value *V, VisitedSetTy &Visited) {
210 Instruction *I = dyn_cast<Instruction>(V);
211 if (!I)
212 return false;
213
214 switch (I->getOpcode()) {
215 case Instruction::Xor:
216 return true;
217 case Instruction::Mul: {
218 // After Constant Hoisting pass, long constants may be represented as
219 // bitcast instructions. As a result, some constants may look like an
220 // instruction at first, and an additional check is necessary to find out if
221 // an operand is actually a constant.
222 Value *Op1 = I->getOperand(1);
223 ConstantInt *C = dyn_cast<ConstantInt>(Op1);
224 if (!C && isa<BitCastInst>(Op1))
225 C = dyn_cast<ConstantInt>(cast<BitCastInst>(Op1)->getOperand(0));
226 return C && C->getValue().getMinSignedBits() > BypassType->getBitWidth();
227 }
228 case Instruction::PHI: {
229 // Stop IR traversal in case of a crazy input code. This limits recursion
230 // depth.
231 if (Visited.size() >= 16)
232 return false;
233 // Do not visit nodes that have been visited already. We return true because
234 // it means that we couldn't find any value that doesn't look hash-like.
235 if (Visited.find(I) != Visited.end())
236 return true;
237 Visited.insert(I);
238 return llvm::all_of(cast<PHINode>(I)->incoming_values(), [&](Value *V) {
239 // Ignore undef values as they probably don't affect the division
240 // operands.
241 return getValueRange(V, Visited) == VALRNG_LIKELY_LONG ||
242 isa<UndefValue>(V);
243 });
244 }
245 default:
246 return false;
247 }
248}
249
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000250/// Check if an integer value fits into our bypass type.
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000251ValueRange FastDivInsertionTask::getValueRange(Value *V,
252 VisitedSetTy &Visited) {
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000253 unsigned ShortLen = BypassType->getBitWidth();
254 unsigned LongLen = V->getType()->getIntegerBitWidth();
255
256 assert(LongLen > ShortLen && "Value type must be wider than BypassType");
257 unsigned HiBits = LongLen - ShortLen;
258
259 const DataLayout &DL = SlowDivOrRem->getModule()->getDataLayout();
Craig Topperb45eabc2017-04-26 16:39:58 +0000260 KnownBits Known(LongLen);
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000261
Craig Topperb45eabc2017-04-26 16:39:58 +0000262 computeKnownBits(V, Known, DL);
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000263
Craig Topperb45eabc2017-04-26 16:39:58 +0000264 if (Known.Zero.countLeadingOnes() >= HiBits)
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000265 return VALRNG_KNOWN_SHORT;
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000266
Craig Topperb45eabc2017-04-26 16:39:58 +0000267 if (Known.One.countLeadingZeros() < HiBits)
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000268 return VALRNG_LIKELY_LONG;
269
270 // Long integer divisions are often used in hashtable implementations. It's
271 // not worth bypassing such divisions because hash values are extremely
272 // unlikely to have enough leading zeros. The call below tries to detect
273 // values that are unlikely to fit BypassType (including hashes).
274 if (isHashLikeValue(V, Visited))
275 return VALRNG_LIKELY_LONG;
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000276
277 return VALRNG_UNKNOWN;
278}
279
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000280/// Add new basic block for slow div and rem operations and put it before
281/// SuccessorBB.
282QuotRemWithBB FastDivInsertionTask::createSlowBB(BasicBlock *SuccessorBB) {
283 QuotRemWithBB DivRemPair;
284 DivRemPair.BB = BasicBlock::Create(MainBB->getParent()->getContext(), "",
285 MainBB->getParent(), SuccessorBB);
286 IRBuilder<> Builder(DivRemPair.BB, DivRemPair.BB->begin());
287
288 Value *Dividend = SlowDivOrRem->getOperand(0);
289 Value *Divisor = SlowDivOrRem->getOperand(1);
290
291 if (isSignedOp()) {
292 DivRemPair.Quotient = Builder.CreateSDiv(Dividend, Divisor);
293 DivRemPair.Remainder = Builder.CreateSRem(Dividend, Divisor);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000294 } else {
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000295 DivRemPair.Quotient = Builder.CreateUDiv(Dividend, Divisor);
296 DivRemPair.Remainder = Builder.CreateURem(Dividend, Divisor);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000297 }
Preston Gurdcdf540d2012-09-04 18:22:17 +0000298
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000299 Builder.CreateBr(SuccessorBB);
300 return DivRemPair;
301}
Preston Gurdcdf540d2012-09-04 18:22:17 +0000302
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000303/// Add new basic block for fast div and rem operations and put it before
304/// SuccessorBB.
305QuotRemWithBB FastDivInsertionTask::createFastBB(BasicBlock *SuccessorBB) {
306 QuotRemWithBB DivRemPair;
307 DivRemPair.BB = BasicBlock::Create(MainBB->getParent()->getContext(), "",
308 MainBB->getParent(), SuccessorBB);
309 IRBuilder<> Builder(DivRemPair.BB, DivRemPair.BB->begin());
Preston Gurdcdf540d2012-09-04 18:22:17 +0000310
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000311 Value *Dividend = SlowDivOrRem->getOperand(0);
312 Value *Divisor = SlowDivOrRem->getOperand(1);
313 Value *ShortDivisorV =
314 Builder.CreateCast(Instruction::Trunc, Divisor, BypassType);
315 Value *ShortDividendV =
316 Builder.CreateCast(Instruction::Trunc, Dividend, BypassType);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000317
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000318 // udiv/urem because this optimization only handles positive numbers.
319 Value *ShortQV = Builder.CreateUDiv(ShortDividendV, ShortDivisorV);
320 Value *ShortRV = Builder.CreateURem(ShortDividendV, ShortDivisorV);
321 DivRemPair.Quotient =
322 Builder.CreateCast(Instruction::ZExt, ShortQV, getSlowType());
323 DivRemPair.Remainder =
324 Builder.CreateCast(Instruction::ZExt, ShortRV, getSlowType());
325 Builder.CreateBr(SuccessorBB);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000326
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000327 return DivRemPair;
328}
329
330/// Creates Phi nodes for result of Div and Rem.
331QuotRemPair FastDivInsertionTask::createDivRemPhiNodes(QuotRemWithBB &LHS,
332 QuotRemWithBB &RHS,
333 BasicBlock *PhiBB) {
334 IRBuilder<> Builder(PhiBB, PhiBB->begin());
335 PHINode *QuoPhi = Builder.CreatePHI(getSlowType(), 2);
336 QuoPhi->addIncoming(LHS.Quotient, LHS.BB);
337 QuoPhi->addIncoming(RHS.Quotient, RHS.BB);
338 PHINode *RemPhi = Builder.CreatePHI(getSlowType(), 2);
339 RemPhi->addIncoming(LHS.Remainder, LHS.BB);
340 RemPhi->addIncoming(RHS.Remainder, RHS.BB);
341 return QuotRemPair(QuoPhi, RemPhi);
342}
343
344/// Creates a runtime check to test whether both the divisor and dividend fit
345/// into BypassType. The check is inserted at the end of MainBB. True return
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000346/// value means that the operands fit. Either of the operands may be NULL if it
347/// doesn't need a runtime check.
348Value *FastDivInsertionTask::insertOperandRuntimeCheck(Value *Op1, Value *Op2) {
349 assert((Op1 || Op2) && "Nothing to check");
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000350 IRBuilder<> Builder(MainBB, MainBB->end());
Justin Lebar28605732016-11-16 00:44:47 +0000351
352 Value *OrV;
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000353 if (Op1 && Op2)
354 OrV = Builder.CreateOr(Op1, Op2);
Justin Lebar28605732016-11-16 00:44:47 +0000355 else
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000356 OrV = Op1 ? Op1 : Op2;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000357
358 // BitMask is inverted to check if the operands are
359 // larger than the bypass type
360 uint64_t BitMask = ~BypassType->getBitMask();
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000361 Value *AndV = Builder.CreateAnd(OrV, BitMask);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000362
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000363 // Compare operand values
364 Value *ZeroV = ConstantInt::getSigned(getSlowType(), 0);
365 return Builder.CreateICmpEQ(AndV, ZeroV);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000366}
367
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000368/// Substitutes the div/rem instruction with code that checks the value of the
369/// operands and uses a shorter-faster div/rem instruction when possible.
370Optional<QuotRemPair> FastDivInsertionTask::insertFastDivAndRem() {
371 Value *Dividend = SlowDivOrRem->getOperand(0);
372 Value *Divisor = SlowDivOrRem->getOperand(1);
Preston Gurdcdf540d2012-09-04 18:22:17 +0000373
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000374 if (isa<ConstantInt>(Divisor)) {
375 // Keep division by a constant for DAGCombiner.
376 return None;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000377 }
378
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000379 VisitedSetTy SetL;
380 ValueRange DividendRange = getValueRange(Dividend, SetL);
381 if (DividendRange == VALRNG_LIKELY_LONG)
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000382 return None;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000383
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000384 VisitedSetTy SetR;
385 ValueRange DivisorRange = getValueRange(Divisor, SetR);
386 if (DivisorRange == VALRNG_LIKELY_LONG)
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000387 return None;
388
Nikolai Bozhenovfca527a2017-04-02 13:14:30 +0000389 bool DividendShort = (DividendRange == VALRNG_KNOWN_SHORT);
390 bool DivisorShort = (DivisorRange == VALRNG_KNOWN_SHORT);
Nikolai Bozhenov4a04fb9e2017-03-02 22:12:15 +0000391
392 if (DividendShort && DivisorShort) {
393 // If both operands are known to be short then just replace the long
394 // division with a short one in-place.
395
396 IRBuilder<> Builder(SlowDivOrRem);
397 Value *TruncDividend = Builder.CreateTrunc(Dividend, BypassType);
398 Value *TruncDivisor = Builder.CreateTrunc(Divisor, BypassType);
399 Value *TruncDiv = Builder.CreateUDiv(TruncDividend, TruncDivisor);
400 Value *TruncRem = Builder.CreateURem(TruncDividend, TruncDivisor);
401 Value *ExtDiv = Builder.CreateZExt(TruncDiv, getSlowType());
402 Value *ExtRem = Builder.CreateZExt(TruncRem, getSlowType());
403 return QuotRemPair(ExtDiv, ExtRem);
404 } else if (DividendShort && !isSignedOp()) {
405 // If the division is unsigned and Dividend is known to be short, then
406 // either
407 // 1) Divisor is less or equal to Dividend, and the result can be computed
408 // with a short division.
409 // 2) Divisor is greater than Dividend. In this case, no division is needed
410 // at all: The quotient is 0 and the remainder is equal to Dividend.
411 //
412 // So instead of checking at runtime whether Divisor fits into BypassType,
413 // we emit a runtime check to differentiate between these two cases. This
414 // lets us entirely avoid a long div.
415
416 // Split the basic block before the div/rem.
417 BasicBlock *SuccessorBB = MainBB->splitBasicBlock(SlowDivOrRem);
418 // Remove the unconditional branch from MainBB to SuccessorBB.
419 MainBB->getInstList().back().eraseFromParent();
420 QuotRemWithBB Long;
421 Long.BB = MainBB;
422 Long.Quotient = ConstantInt::get(getSlowType(), 0);
423 Long.Remainder = Dividend;
424 QuotRemWithBB Fast = createFastBB(SuccessorBB);
425 QuotRemPair Result = createDivRemPhiNodes(Fast, Long, SuccessorBB);
426 IRBuilder<> Builder(MainBB, MainBB->end());
427 Value *CmpV = Builder.CreateICmpUGE(Dividend, Divisor);
428 Builder.CreateCondBr(CmpV, Fast.BB, SuccessorBB);
429 return Result;
430 } else {
431 // General case. Create both slow and fast div/rem pairs and choose one of
432 // them at runtime.
433
434 // Split the basic block before the div/rem.
435 BasicBlock *SuccessorBB = MainBB->splitBasicBlock(SlowDivOrRem);
436 // Remove the unconditional branch from MainBB to SuccessorBB.
437 MainBB->getInstList().back().eraseFromParent();
438 QuotRemWithBB Fast = createFastBB(SuccessorBB);
439 QuotRemWithBB Slow = createSlowBB(SuccessorBB);
440 QuotRemPair Result = createDivRemPhiNodes(Fast, Slow, SuccessorBB);
441 Value *CmpV = insertOperandRuntimeCheck(DividendShort ? nullptr : Dividend,
442 DivisorShort ? nullptr : Divisor);
443 IRBuilder<> Builder(MainBB, MainBB->end());
444 Builder.CreateCondBr(CmpV, Fast.BB, Slow.BB);
445 return Result;
446 }
Preston Gurdcdf540d2012-09-04 18:22:17 +0000447}
448
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000449/// This optimization identifies DIV/REM instructions in a BB that can be
450/// profitably bypassed and carried out with a shorter, faster divide.
451bool llvm::bypassSlowDivision(BasicBlock *BB,
452 const BypassWidthsTy &BypassWidths) {
453 DivCacheTy PerBBDivCache;
Preston Gurdcdf540d2012-09-04 18:22:17 +0000454
455 bool MadeChange = false;
Eric Christopher49a7d6c2016-01-04 23:18:58 +0000456 Instruction* Next = &*BB->begin();
457 while (Next != nullptr) {
458 // We may add instructions immediately after I, but we want to skip over
459 // them.
460 Instruction* I = Next;
461 Next = Next->getNextNode();
Preston Gurdcdf540d2012-09-04 18:22:17 +0000462
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000463 FastDivInsertionTask Task(I, BypassWidths);
464 if (Value *Replacement = Task.getReplacement(PerBBDivCache)) {
465 I->replaceAllUsesWith(Replacement);
466 I->eraseFromParent();
467 MadeChange = true;
468 }
Preston Gurdcdf540d2012-09-04 18:22:17 +0000469 }
470
Justin Lebar0ede5fb2016-10-28 21:43:54 +0000471 // Above we eagerly create divs and rems, as pairs, so that we can efficiently
472 // create divrem machine instructions. Now erase any unused divs / rems so we
473 // don't leave extra instructions sitting around.
Nikolai Bozhenovd4b12b32017-03-02 22:05:07 +0000474 for (auto &KV : PerBBDivCache)
475 for (Value *V : {KV.second.Quotient, KV.second.Remainder})
476 RecursivelyDeleteTriviallyDeadInstructions(V);
Justin Lebar0ede5fb2016-10-28 21:43:54 +0000477
Preston Gurdcdf540d2012-09-04 18:22:17 +0000478 return MadeChange;
479}