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/KnownBits.h" 20 #include <type_traits> 21 22 namespace llvm { 23 struct SimplifyQuery; 24 KnownBits computeKnownBits(const Value *V, unsigned Depth, 25 const SimplifyQuery &Q); 26 27 template <typename Arg> class WithCache { 28 static_assert(std::is_pointer_v<Arg>, "WithCache requires a pointer type!"); 29 30 using UnderlyingType = std::remove_pointer_t<Arg>; 31 constexpr static bool IsConst = std::is_const_v<Arg>; 32 33 template <typename T, bool Const> 34 using conditionally_const_t = std::conditional_t<Const, const T, T>; 35 36 using PointerType = conditionally_const_t<UnderlyingType *, IsConst>; 37 using ReferenceType = conditionally_const_t<UnderlyingType &, IsConst>; 38 39 // Store the presence of the KnownBits information in one of the bits of 40 // Pointer. 41 // true -> present 42 // false -> absent 43 mutable PointerIntPair<PointerType, 1, bool> Pointer; 44 mutable KnownBits Known; 45 calculateKnownBits(const SimplifyQuery & Q)46 void calculateKnownBits(const SimplifyQuery &Q) const { 47 Known = computeKnownBits(Pointer.getPointer(), 0, Q); 48 Pointer.setInt(true); 49 } 50 51 public: WithCache(PointerType Pointer)52 WithCache(PointerType Pointer) : Pointer(Pointer, false) {} WithCache(PointerType Pointer,const KnownBits & Known)53 WithCache(PointerType Pointer, const KnownBits &Known) 54 : Pointer(Pointer, true), Known(Known) {} 55 getValue()56 [[nodiscard]] PointerType getValue() const { return Pointer.getPointer(); } 57 getKnownBits(const SimplifyQuery & Q)58 [[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const { 59 if (!hasKnownBits()) 60 calculateKnownBits(Q); 61 return Known; 62 } 63 hasKnownBits()64 [[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); } 65 PointerType()66 operator PointerType() const { return Pointer.getPointer(); } 67 PointerType operator->() const { return Pointer.getPointer(); } 68 ReferenceType operator*() const { return *Pointer.getPointer(); } 69 }; 70 } // namespace llvm 71 72 #endif 73