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