12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/Transforms/Utils/BypassSlowDivision.h ---------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file contains an optimization for div and rem on architectures that
- // execute short instructions significantly faster than longer instructions.
- // For example, on Intel Atom 32-bit divides are slow enough that during
- // runtime it is profitable to check the value of the operands, and if they are
- // positive and less than 256 use an unsigned 8-bit divide.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
- #define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/DenseMapInfo.h"
- #include "llvm/IR/ValueHandle.h"
- #include <cstdint>
- namespace llvm {
- class BasicBlock;
- class Value;
- struct DivRemMapKey {
- bool SignedOp;
- AssertingVH<Value> Dividend;
- AssertingVH<Value> Divisor;
- DivRemMapKey() = default;
- DivRemMapKey(bool InSignedOp, Value *InDividend, Value *InDivisor)
- : SignedOp(InSignedOp), Dividend(InDividend), Divisor(InDivisor) {}
- };
- template <> struct DenseMapInfo<DivRemMapKey> {
- static bool isEqual(const DivRemMapKey &Val1, const DivRemMapKey &Val2) {
- return Val1.SignedOp == Val2.SignedOp && Val1.Dividend == Val2.Dividend &&
- Val1.Divisor == Val2.Divisor;
- }
- static DivRemMapKey getEmptyKey() {
- return DivRemMapKey(false, nullptr, nullptr);
- }
- static DivRemMapKey getTombstoneKey() {
- return DivRemMapKey(true, nullptr, nullptr);
- }
- static unsigned getHashValue(const DivRemMapKey &Val) {
- return (unsigned)(reinterpret_cast<uintptr_t>(
- static_cast<Value *>(Val.Dividend)) ^
- reinterpret_cast<uintptr_t>(
- static_cast<Value *>(Val.Divisor))) ^
- (unsigned)Val.SignedOp;
- }
- };
- /// This optimization identifies DIV instructions in a BB that can be
- /// profitably bypassed and carried out with a shorter, faster divide.
- ///
- /// This optimization may add basic blocks immediately after BB; for obvious
- /// reasons, you shouldn't pass those blocks to bypassSlowDivision.
- bool bypassSlowDivision(
- BasicBlock *BB, const DenseMap<unsigned int, unsigned int> &BypassWidth);
- } // end namespace llvm
- #endif // LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|