18 #define DEBUG_TYPE "bypass-slow-division"
33 DivOpInfo(
bool InSignedOp,
Value *InDividend,
Value *InDivisor)
34 : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {}
42 : Quotient(InQuotient), Remainder(InRemainder) {}
49 static bool isEqual(
const DivOpInfo &Val1,
const DivOpInfo &Val2) {
50 return Val1.SignedOp == Val2.SignedOp &&
51 Val1.Dividend == Val2.Dividend &&
52 Val1.Divisor == Val2.Divisor;
56 return DivOpInfo(
false, 0, 0);
60 return DivOpInfo(
true, 0, 0);
64 return (
unsigned)(
reinterpret_cast<uintptr_t
>(Val.Dividend) ^
65 reinterpret_cast<uintptr_t>(Val.Divisor)) ^
66 (
unsigned)Val.SignedOp;
88 if (isa<ConstantInt>(Divisor) ||
89 (isa<ConstantInt>(Dividend) && isa<ConstantInt>(Divisor))) {
97 BasicBlock *SuccessorBB = I->splitBasicBlock(J);
105 Value *SlowQuotientV;
106 Value *SlowRemainderV;
108 SlowQuotientV = SlowBuilder.
CreateSDiv(Dividend, Divisor);
109 SlowRemainderV = SlowBuilder.CreateSRem(Dividend, Divisor);
111 SlowQuotientV = SlowBuilder.
CreateUDiv(Dividend, Divisor);
112 SlowRemainderV = SlowBuilder.CreateURem(Dividend, Divisor);
114 SlowBuilder.CreateBr(SuccessorBB);
121 Value *ShortDivisorV = FastBuilder.CreateCast(Instruction::Trunc, Divisor,
123 Value *ShortDividendV = FastBuilder.CreateCast(Instruction::Trunc, Dividend,
127 Value *ShortQuotientV = FastBuilder.CreateExactUDiv(ShortDividendV,
129 Value *ShortRemainderV = FastBuilder.CreateURem(ShortDividendV,
131 Value *FastQuotientV = FastBuilder.CreateCast(Instruction::ZExt,
134 Value *FastRemainderV = FastBuilder.CreateCast(Instruction::ZExt,
137 FastBuilder.CreateBr(SuccessorBB);
141 PHINode *QuoPhi = SuccessorBuilder.CreatePHI(Instr->
getType(), 2);
142 QuoPhi->addIncoming(SlowQuotientV, SlowBB);
143 QuoPhi->addIncoming(FastQuotientV, FastBB);
144 PHINode *RemPhi = SuccessorBuilder.CreatePHI(Instr->
getType(), 2);
158 Value *OrV = MainBuilder.CreateOr(Dividend, Divisor);
163 Value *AndV = MainBuilder.CreateAnd(OrV, BitMask);
167 Value *CmpV = MainBuilder.CreateICmpEQ(AndV, ZeroV);
168 MainBuilder.CreateCondBr(CmpV, FastBB, SlowBB);
175 DivOpInfo Key(UseSignedOp, Dividend, Divisor);
176 DivPhiNodes
Value(QuoPhi, RemPhi);
177 PerBBDivCache.
insert(std::pair<DivOpInfo, DivPhiNodes>(Key, Value));
196 if (CacheI == PerBBDivCache.
end()) {
198 return insertFastDiv(F, I, J, BypassType, UseDivOp, UseSignedOp,
203 DivPhiNodes &
Value = CacheI->second;
206 J->replaceAllUsesWith(Value.Quotient);
209 J->replaceAllUsesWith(Value.Remainder);
227 bool MadeChange =
false;
231 unsigned Opcode = J->getOpcode();
232 bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv;
233 bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem;
234 bool UseSignedOp = Opcode == Instruction::SDiv ||
235 Opcode == Instruction::SRem;
238 if (!UseDivOp && !UseRemOp)
242 if (!J->getType()->isIntegerTy())
251 if (BI == BypassWidths.
end())
258 UseSignedOp, DivCache);
void addIncoming(Value *V, BasicBlock *BB)
LLVMContext & getContext() const
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)
X86 bit-test instructions.
static DivOpInfo getEmptyKey()
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void replaceAllUsesWith(Value *V)
static DivOpInfo getTombstoneKey()
LLVM Basic Block Representation.
const InstListType & getInstList() const
Return the underlying instruction list container.
Value * getOperand(unsigned i) const
Integer representation type.
static bool reuseOrInsertFastDiv(Function &F, Function::iterator &I, BasicBlock::iterator &J, IntegerType *BypassType, bool UseDivOp, bool UseSignedOp, DivCacheTy &PerBBDivCache)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
Get or create an IntegerType instance.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Get a ConstantInt for a specific signed value.
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
DenseMap< DivOpInfo, DivPhiNodes > DivCacheTy
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
bool bypassSlowDivision(Function &F, Function::iterator &I, const DenseMap< unsigned int, unsigned int > &BypassWidth)
static bool isEqual(const DivOpInfo &Val1, const DivOpInfo &Val2)
static unsigned getHashValue(const DivOpInfo &Val)
LLVM Value Representation.
iterator find(const KeyT &Val)
void moveBefore(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it into the function that MovePos lives ...