summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/llvm/Transforms/Utils/BypassSlowDivision.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983e/include/llvm/Transforms/Utils/BypassSlowDivision.h')
-rw-r--r--clang-r353983e/include/llvm/Transforms/Utils/BypassSlowDivision.h69
1 files changed, 69 insertions, 0 deletions
diff --git a/clang-r353983e/include/llvm/Transforms/Utils/BypassSlowDivision.h b/clang-r353983e/include/llvm/Transforms/Utils/BypassSlowDivision.h
new file mode 100644
index 00000000..47105592
--- /dev/null
+++ b/clang-r353983e/include/llvm/Transforms/Utils/BypassSlowDivision.h
@@ -0,0 +1,69 @@
+//===- 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 <cstdint>
+
+namespace llvm {
+
+class BasicBlock;
+class Value;
+
+struct DivRemMapKey {
+ bool SignedOp;
+ Value *Dividend;
+ Value *Divisor;
+
+ 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>(Val.Dividend) ^
+ reinterpret_cast<uintptr_t>(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