1 //===- llvm/Transforms/Utils/BypassSlowDivision.h ---------------*- C++ -*-===// 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 18 #ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H 19 #define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H 20 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/DenseMapInfo.h" 23 #include <cstdint> 24 25 namespace llvm { 26 27 class BasicBlock; 28 class Value; 29 30 struct DivRemMapKey { 31 bool SignedOp; 32 Value *Dividend; 33 Value *Divisor; 34 DivRemMapKeyDivRemMapKey35 DivRemMapKey(bool InSignedOp, Value *InDividend, Value *InDivisor) 36 : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {} 37 }; 38 39 template <> struct DenseMapInfo<DivRemMapKey> { 40 static bool isEqual(const DivRemMapKey &Val1, const DivRemMapKey &Val2) { 41 return Val1.SignedOp == Val2.SignedOp && Val1.Dividend == Val2.Dividend && 42 Val1.Divisor == Val2.Divisor; 43 } 44 45 static DivRemMapKey getEmptyKey() { 46 return DivRemMapKey(false, nullptr, nullptr); 47 } 48 49 static DivRemMapKey getTombstoneKey() { 50 return DivRemMapKey(true, nullptr, nullptr); 51 } 52 53 static unsigned getHashValue(const DivRemMapKey &Val) { 54 return (unsigned)(reinterpret_cast<uintptr_t>(Val.Dividend) ^ 55 reinterpret_cast<uintptr_t>(Val.Divisor)) ^ 56 (unsigned)Val.SignedOp; 57 } 58 }; 59 60 /// This optimization identifies DIV instructions in a BB that can be 61 /// profitably bypassed and carried out with a shorter, faster divide. 62 /// 63 /// This optimization may add basic blocks immediately after BB; for obvious 64 /// reasons, you shouldn't pass those blocks to bypassSlowDivision. 65 bool bypassSlowDivision( 66 BasicBlock *BB, const DenseMap<unsigned int, unsigned int> &BypassWidth); 67 68 } // end namespace llvm 69 70 #endif // LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H 71