26 #define DEBUG_TYPE "bypass-slow-division"
34 DivOpInfo(
bool InSignedOp,
Value *InDividend,
Value *InDivisor)
35 : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {}
43 : Quotient(InQuotient), Remainder(InRemainder) {}
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;
57 return DivOpInfo(
false,
nullptr,
nullptr);
61 return DivOpInfo(
true,
nullptr,
nullptr);
65 return (
unsigned)(
reinterpret_cast<uintptr_t
>(Val.Dividend) ^
66 reinterpret_cast<uintptr_t>(Val.Divisor)) ^
67 (
unsigned)Val.SignedOp;
89 if (isa<ConstantInt>(Divisor) ||
90 (isa<ConstantInt>(Dividend) && isa<ConstantInt>(Divisor))) {
98 BasicBlock *SuccessorBB = I->splitBasicBlock(J);
106 Value *SlowQuotientV;
107 Value *SlowRemainderV;
109 SlowQuotientV = SlowBuilder.
CreateSDiv(Dividend, Divisor);
110 SlowRemainderV = SlowBuilder.CreateSRem(Dividend, Divisor);
112 SlowQuotientV = SlowBuilder.
CreateUDiv(Dividend, Divisor);
113 SlowRemainderV = SlowBuilder.CreateURem(Dividend, Divisor);
115 SlowBuilder.CreateBr(SuccessorBB);
122 Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor,
124 Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend,
128 Value *ShortQuotientV = FastBuilder.CreateExactUDiv(ShortDividendV,
130 Value *ShortRemainderV = FastBuilder.CreateURem(ShortDividendV,
132 Value *FastQuotientV = FastBuilder.CreateCast(Instruction::ZExt,
135 Value *FastRemainderV = FastBuilder.CreateCast(Instruction::ZExt,
138 FastBuilder.CreateBr(SuccessorBB);
142 PHINode *QuoPhi = SuccessorBuilder.CreatePHI(Instr->
getType(), 2);
143 QuoPhi->addIncoming(SlowQuotientV, SlowBB);
144 QuoPhi->addIncoming(FastQuotientV, FastBB);
145 PHINode *RemPhi = SuccessorBuilder.CreatePHI(Instr->
getType(), 2);
159 Value *OrV = MainBuilder.CreateOr(Dividend, Divisor);
164 Value *AndV = MainBuilder.CreateAnd(OrV, BitMask);
168 Value *CmpV = MainBuilder.CreateICmpEQ(AndV, ZeroV);
169 MainBuilder.CreateCondBr(CmpV, FastBB, SlowBB);
176 DivOpInfo Key(UseSignedOp, Dividend, Divisor);
177 DivPhiNodes
Value(QuoPhi, RemPhi);
178 PerBBDivCache.
insert(std::pair<DivOpInfo, DivPhiNodes>(Key, Value));
197 if (CacheI == PerBBDivCache.
end()) {
199 return insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp,
204 DivPhiNodes &
Value = CacheI->second;
207 J->replaceAllUsesWith(Value.Quotient);
210 J->replaceAllUsesWith(Value.Remainder);
228 bool MadeChange =
false;
232 unsigned Opcode = J->getOpcode();
233 bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
234 bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem;
235 bool UseSignedOp = Opcode == Instruction::SDiv ||
236 Opcode == Instruction::SRem;
239 if (!UseDivOp && !UseRemOp)
243 if (!J->getType()->isIntegerTy())
252 if (BI == BypassWidths.
end())
259 UseSignedOp, DivCache);
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
const Function * getParent() const
Return the enclosing method, or null if none.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
static bool insertFastDiv(Function &F, Function::iterator &I, BasicBlock::iterator &J, IntegerType *BypassType, bool UseDivOp, bool UseSignedOp, DivCacheTy &PerBBDivCache)
iterator begin()
Instruction iterator methods.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static DivOpInfo getEmptyKey()
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static DivOpInfo getTombstoneKey()
LLVM Basic Block Representation.
const InstListType & getInstList() const
Return the underlying instruction list container.
Value * getOperand(unsigned i) const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Class to represent integer types.
static bool reuseOrInsertFastDiv(Function &F, Function::iterator &I, BasicBlock::iterator &J, IntegerType *BypassType, bool UseDivOp, bool UseSignedOp, DivCacheTy &PerBBDivCache)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Type * getType() const
All values are typed, get the type of this value.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Value * CreateSDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
uint64_t getBitMask() const
getBitMask - Return a bitmask with ones set for all of the bits that can be set by an unsigned versio...
DenseMap< DivOpInfo, DivPhiNodes > DivCacheTy
iterator find(const KeyT &Val)
bool bypassSlowDivision(Function &F, Function::iterator &I, const DenseMap< unsigned int, unsigned int > &BypassWidth)
This optimization identifies DIV instructions that can be profitably bypassed and carried out with a ...
static bool isEqual(const DivOpInfo &Val1, const DivOpInfo &Val2)
static unsigned getHashValue(const DivOpInfo &Val)
LLVM Value Representation.
void moveBefore(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it into the function that MovePos lives ...