Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:42

0001 //===- llvm/Transforms/Utils/BypassSlowDivision.h ---------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file contains an optimization for div and rem on architectures that
0010 // execute short instructions significantly faster than longer instructions.
0011 // For example, on Intel Atom 32-bit divides are slow enough that during
0012 // runtime it is profitable to check the value of the operands, and if they are
0013 // positive and less than 256 use an unsigned 8-bit divide.
0014 //
0015 //===----------------------------------------------------------------------===//
0016 
0017 #ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
0018 #define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
0019 
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/ADT/DenseMapInfo.h"
0022 #include "llvm/IR/ValueHandle.h"
0023 #include <cstdint>
0024 
0025 namespace llvm {
0026 
0027 class BasicBlock;
0028 class Value;
0029 
0030 struct DivRemMapKey {
0031   bool SignedOp;
0032   AssertingVH<Value> Dividend;
0033   AssertingVH<Value> Divisor;
0034 
0035   DivRemMapKey() = default;
0036 
0037   DivRemMapKey(bool InSignedOp, Value *InDividend, Value *InDivisor)
0038       : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {}
0039 };
0040 
0041 template <> struct DenseMapInfo<DivRemMapKey> {
0042   static bool isEqual(const DivRemMapKey &Val1, const DivRemMapKey &Val2) {
0043     return Val1.SignedOp == Val2.SignedOp && Val1.Dividend == Val2.Dividend &&
0044            Val1.Divisor == Val2.Divisor;
0045   }
0046 
0047   static DivRemMapKey getEmptyKey() {
0048     return DivRemMapKey(false, nullptr, nullptr);
0049   }
0050 
0051   static DivRemMapKey getTombstoneKey() {
0052     return DivRemMapKey(true, nullptr, nullptr);
0053   }
0054 
0055   static unsigned getHashValue(const DivRemMapKey &Val) {
0056     return (unsigned)(reinterpret_cast<uintptr_t>(
0057                           static_cast<Value *>(Val.Dividend)) ^
0058                       reinterpret_cast<uintptr_t>(
0059                           static_cast<Value *>(Val.Divisor))) ^
0060            (unsigned)Val.SignedOp;
0061   }
0062 };
0063 
0064 /// This optimization identifies DIV instructions in a BB that can be
0065 /// profitably bypassed and carried out with a shorter, faster divide.
0066 ///
0067 /// This optimization may add basic blocks immediately after BB; for obvious
0068 /// reasons, you shouldn't pass those blocks to bypassSlowDivision.
0069 bool bypassSlowDivision(
0070     BasicBlock *BB, const DenseMap<unsigned int, unsigned int> &BypassWidth);
0071 
0072 } // end namespace llvm
0073 
0074 #endif // LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H