xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/WithCache.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- llvm/Analysis/WithCache.h - KnownBits cache for pointers -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Store a pointer to any type along with the KnownBits information for it
10 // that is computed lazily (if required).
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ANALYSIS_WITHCACHE_H
15 #define LLVM_ANALYSIS_WITHCACHE_H
16 
17 #include "llvm/ADT/PointerIntPair.h"
18 #include "llvm/IR/Value.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/KnownBits.h"
21 #include <type_traits>
22 
23 namespace llvm {
24 struct SimplifyQuery;
25 LLVM_ABI KnownBits computeKnownBits(const Value *V, const SimplifyQuery &Q,
26                                     unsigned Depth);
27 
28 template <typename Arg> class WithCache {
29   static_assert(std::is_pointer_v<Arg>, "WithCache requires a pointer type!");
30 
31   using UnderlyingType = std::remove_pointer_t<Arg>;
32   constexpr static bool IsConst = std::is_const_v<Arg>;
33 
34   template <typename T, bool Const>
35   using conditionally_const_t = std::conditional_t<Const, const T, T>;
36 
37   using PointerType = conditionally_const_t<UnderlyingType *, IsConst>;
38   using ReferenceType = conditionally_const_t<UnderlyingType &, IsConst>;
39 
40   // Store the presence of the KnownBits information in one of the bits of
41   // Pointer.
42   // true  -> present
43   // false -> absent
44   mutable PointerIntPair<PointerType, 1, bool> Pointer;
45   mutable KnownBits Known;
46 
calculateKnownBits(const SimplifyQuery & Q)47   void calculateKnownBits(const SimplifyQuery &Q) const {
48     Known = computeKnownBits(Pointer.getPointer(), Q, 0);
49     Pointer.setInt(true);
50   }
51 
52 public:
WithCache(PointerType Pointer)53   WithCache(PointerType Pointer) : Pointer(Pointer, false) {}
WithCache(PointerType Pointer,const KnownBits & Known)54   WithCache(PointerType Pointer, const KnownBits &Known)
55       : Pointer(Pointer, true), Known(Known) {}
56 
getValue()57   [[nodiscard]] PointerType getValue() const { return Pointer.getPointer(); }
58 
getKnownBits(const SimplifyQuery & Q)59   [[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
60     if (!hasKnownBits())
61       calculateKnownBits(Q);
62     return Known;
63   }
64 
hasKnownBits()65   [[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
66 
PointerType()67   operator PointerType() const { return Pointer.getPointer(); }
68   PointerType operator->() const { return Pointer.getPointer(); }
69   ReferenceType operator*() const { return *Pointer.getPointer(); }
70 };
71 } // namespace llvm
72 
73 #endif
74