Skip to content

Commit cb53056

Browse files
committed
Add WithCache
1 parent 15b683a commit cb53056

File tree

6 files changed

+144
-38
lines changed

6 files changed

+144
-38
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "llvm/ADT/ArrayRef.h"
1818
#include "llvm/ADT/SmallSet.h"
1919
#include "llvm/Analysis/SimplifyQuery.h"
20-
#include "llvm/Analysis/CachedBitsValue.h"
20+
#include "llvm/Analysis/WithCache.h"
2121
#include "llvm/IR/Constants.h"
2222
#include "llvm/IR/DataLayout.h"
2323
#include "llvm/IR/FMF.h"
@@ -114,8 +114,8 @@ KnownBits analyzeKnownBitsFromAndXorOr(
114114
bool UseInstrInfo = true);
115115

116116
/// Return true if LHS and RHS have no common bits set.
117-
bool haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
118-
const CachedBitsConstValue &RHSCache,
117+
bool haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
118+
const WithCache<const Value *> &RHSCache,
119119
const SimplifyQuery &SQ);
120120

121121
/// Return true if the given value is known to have exactly one bit set when
@@ -855,9 +855,12 @@ OverflowResult computeOverflowForUnsignedMul(const Value *LHS, const Value *RHS,
855855
const SimplifyQuery &SQ);
856856
OverflowResult computeOverflowForSignedMul(const Value *LHS, const Value *RHS,
857857
const SimplifyQuery &SQ);
858-
OverflowResult computeOverflowForUnsignedAdd(const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
859-
const SimplifyQuery &SQ);
860-
OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
858+
OverflowResult
859+
computeOverflowForUnsignedAdd(const WithCache<const Value *> &LHS,
860+
const WithCache<const Value *> &RHS,
861+
const SimplifyQuery &SQ);
862+
OverflowResult computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
863+
const WithCache<const Value *> &RHS,
861864
const SimplifyQuery &SQ);
862865
/// This version also leverages the sign bit of Add if known.
863866
OverflowResult computeOverflowForSignedAdd(const AddOperator *Add,
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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/IR/Value.h"
18+
#include "llvm/Support/KnownBits.h"
19+
#include <type_traits>
20+
21+
namespace llvm {
22+
struct SimplifyQuery;
23+
}
24+
25+
llvm::KnownBits computeKnownBits(const llvm::Value *V, unsigned Depth,
26+
const llvm::SimplifyQuery &Q);
27+
28+
namespace llvm {
29+
template <typename Arg> class WithCache {
30+
static_assert(std::is_pointer_v<Arg>, "WithCache requires a pointer type!");
31+
32+
using UnderlyingType = std::remove_pointer_t<Arg>;
33+
constexpr static bool IsConst = std::is_const_v<Arg>;
34+
35+
template <typename T, bool Const>
36+
using conditionally_const_t = std::conditional_t<Const, const T, T>;
37+
38+
using PointerType = conditionally_const_t<UnderlyingType *, IsConst>;
39+
using ReferenceType = conditionally_const_t<UnderlyingType &, IsConst>;
40+
41+
template <typename T>
42+
constexpr static bool PointerConvertible =
43+
std::is_convertible_v<T, UnderlyingType>;
44+
45+
// Store the presence of the KnownBits information in one of the bits of
46+
// Pointer.
47+
// true -> present
48+
// false -> absent
49+
mutable PointerIntPair<PointerType, 1, bool> Pointer;
50+
mutable KnownBits Known;
51+
52+
void calculateKnownBits(const SimplifyQuery &Q) const {
53+
Known = computeKnownBits(Pointer.getPointer(), 0, Q);
54+
Pointer.setInt(true);
55+
}
56+
57+
public:
58+
WithCache() = default;
59+
WithCache(PointerType Pointer) : Pointer(Pointer, false) {}
60+
WithCache(PointerType Pointer, const KnownBits &Known)
61+
: Pointer(Pointer, true), Known(Known) {}
62+
63+
template <typename T, std::enable_if_t<PointerConvertible<T>, int> = 0>
64+
WithCache(const T &Value) : Pointer(static_cast<PointerType>(Value), false) {}
65+
66+
template <typename T, std::enable_if_t<PointerConvertible<T>, int> = 0>
67+
WithCache(const T &Value, const KnownBits &Known)
68+
: Pointer(static_cast<PointerType>(Value), true), Known(Known) {}
69+
70+
[[nodiscard]] PointerType getValue() { return Pointer.getPointer(); }
71+
[[nodiscard]] PointerType getValue() const { return Pointer.getPointer(); }
72+
73+
[[nodiscard]] const KnownBits &getKnownBits(const SimplifyQuery &Q) const {
74+
if (!hasKnownBits())
75+
calculateKnownBits(Q);
76+
return Known;
77+
}
78+
79+
[[nodiscard]] KnownBits &getKnownBits(const SimplifyQuery &Q) {
80+
if (!hasKnownBits())
81+
calculateKnownBits(Q);
82+
return Known;
83+
}
84+
85+
[[nodiscard]] bool hasKnownBits() const { return Pointer.getInt(); }
86+
87+
operator PointerType() { return Pointer.getPointer(); }
88+
PointerType operator->() { return Pointer.getPointer(); }
89+
ReferenceType operator*() { return *Pointer.getPointer(); }
90+
91+
operator PointerType() const { return Pointer.getPointer(); }
92+
PointerType operator->() const { return Pointer.getPointer(); }
93+
ReferenceType operator*() const { return *Pointer.getPointer(); }
94+
};
95+
} // namespace llvm
96+
97+
#endif

llvm/include/llvm/Transforms/InstCombine/InstCombiner.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,18 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
510510
SQ.getWithInstruction(CxtI));
511511
}
512512

513-
OverflowResult computeOverflowForUnsignedAdd(const CachedBitsConstValue &LHS,
514-
const CachedBitsConstValue &RHS,
515-
const Instruction *CxtI) const {
513+
OverflowResult
514+
computeOverflowForUnsignedAdd(const WithCache<const Value *> &LHS,
515+
const WithCache<const Value *> &RHS,
516+
const Instruction *CxtI) const {
516517
return llvm::computeOverflowForUnsignedAdd(LHS, RHS,
517518
SQ.getWithInstruction(CxtI));
518519
}
519520

520-
OverflowResult computeOverflowForSignedAdd(const CachedBitsConstValue &LHS,
521-
const CachedBitsConstValue &RHS,
522-
const Instruction *CxtI) const {
521+
OverflowResult
522+
computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
523+
const WithCache<const Value *> &RHS,
524+
const Instruction *CxtI) const {
523525
return llvm::computeOverflowForSignedAdd(LHS, RHS,
524526
SQ.getWithInstruction(CxtI));
525527
}

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "llvm/Analysis/AliasAnalysis.h"
2626
#include "llvm/Analysis/AssumeBundleQueries.h"
2727
#include "llvm/Analysis/AssumptionCache.h"
28-
#include "llvm/Analysis/CachedBitsValue.h"
2928
#include "llvm/Analysis/ConstantFolding.h"
3029
#include "llvm/Analysis/GuardUtils.h"
3130
#include "llvm/Analysis/InstructionSimplify.h"
@@ -34,6 +33,7 @@
3433
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
3534
#include "llvm/Analysis/TargetLibraryInfo.h"
3635
#include "llvm/Analysis/VectorUtils.h"
36+
#include "llvm/Analysis/WithCache.h"
3737
#include "llvm/IR/Argument.h"
3838
#include "llvm/IR/Attributes.h"
3939
#include "llvm/IR/BasicBlock.h"
@@ -202,8 +202,8 @@ KnownBits llvm::computeKnownBits(const Value *V, const APInt &DemandedElts,
202202
SimplifyQuery(DL, DT, AC, safeCxtI(V, CxtI), UseInstrInfo));
203203
}
204204

205-
bool llvm::haveNoCommonBitsSet(const CachedBitsConstValue &LHSCache,
206-
const CachedBitsConstValue &RHSCache,
205+
bool llvm::haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
206+
const WithCache<const Value *> &RHSCache,
207207
const SimplifyQuery &SQ) {
208208
const Value *LHS = LHSCache.getValue();
209209
const Value *RHS = RHSCache.getValue();
@@ -6258,11 +6258,12 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
62586258
}
62596259

62606260
/// Combine constant ranges from computeConstantRange() and computeKnownBits().
6261-
static ConstantRange computeConstantRangeIncludingKnownBits(
6262-
const CachedBitsConstValue &V, bool ForSigned, const SimplifyQuery &SQ) {
6263-
ConstantRange CR1 = ConstantRange::fromKnownBits(
6264-
V.getKnownBits(SQ),
6265-
ForSigned);
6261+
static ConstantRange
6262+
computeConstantRangeIncludingKnownBits(const WithCache<const Value *> &V,
6263+
bool ForSigned,
6264+
const SimplifyQuery &SQ) {
6265+
ConstantRange CR1 =
6266+
ConstantRange::fromKnownBits(V.getKnownBits(SQ), ForSigned);
62666267
ConstantRange CR2 = computeConstantRange(V, ForSigned, SQ.IIQ.UseInstrInfo);
62676268
ConstantRange::PreferredRangeType RangeType =
62686269
ForSigned ? ConstantRange::Signed : ConstantRange::Unsigned;
@@ -6318,19 +6319,21 @@ OverflowResult llvm::computeOverflowForSignedMul(const Value *LHS,
63186319
return OverflowResult::MayOverflow;
63196320
}
63206321

6321-
OverflowResult llvm::computeOverflowForUnsignedAdd(
6322-
const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
6323-
const SimplifyQuery &SQ) {
6324-
ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
6325-
LHS, /*ForSigned=*/false, SQ);
6326-
ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
6327-
RHS, /*ForSigned=*/false, SQ);
6322+
OverflowResult
6323+
llvm::computeOverflowForUnsignedAdd(const WithCache<const Value *> &LHS,
6324+
const WithCache<const Value *> &RHS,
6325+
const SimplifyQuery &SQ) {
6326+
ConstantRange LHSRange =
6327+
computeConstantRangeIncludingKnownBits(LHS, /*ForSigned=*/false, SQ);
6328+
ConstantRange RHSRange =
6329+
computeConstantRangeIncludingKnownBits(RHS, /*ForSigned=*/false, SQ);
63286330
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
63296331
}
63306332

6331-
static OverflowResult computeOverflowForSignedAdd(
6332-
const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
6333-
const AddOperator *Add, const SimplifyQuery &SQ) {
6333+
static OverflowResult
6334+
computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
6335+
const WithCache<const Value *> &RHS,
6336+
const AddOperator *Add, const SimplifyQuery &SQ) {
63346337
if (Add && Add->hasNoSignedWrap()) {
63356338
return OverflowResult::NeverOverflows;
63366339
}
@@ -6946,9 +6949,10 @@ OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
69466949
Add, SQ);
69476950
}
69486951

6949-
OverflowResult llvm::computeOverflowForSignedAdd(
6950-
const CachedBitsConstValue &LHS, const CachedBitsConstValue &RHS,
6951-
const SimplifyQuery &SQ) {
6952+
OverflowResult
6953+
llvm::computeOverflowForSignedAdd(const WithCache<const Value *> &LHS,
6954+
const WithCache<const Value *> &RHS,
6955+
const SimplifyQuery &SQ) {
69526956
return ::computeOverflowForSignedAdd(LHS, RHS, nullptr, SQ);
69536957
}
69546958

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1566,7 +1566,7 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
15661566
return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
15671567

15681568
// A+B --> A|B iff A and B have no bits set in common.
1569-
CachedBitsConstValue LHSCache(LHS), RHSCache(RHS);
1569+
WithCache<const Value *> LHSCache(LHS), RHSCache(RHS);
15701570
if (haveNoCommonBitsSet(LHSCache, RHSCache, SQ.getWithInstruction(&I)))
15711571
return BinaryOperator::CreateOr(LHS, RHS);
15721572

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,15 +295,15 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
295295

296296
Instruction *transformSExtICmp(ICmpInst *Cmp, SExtInst &Sext);
297297

298-
bool willNotOverflowSignedAdd(const CachedBitsConstValue &LHS,
299-
const CachedBitsConstValue &RHS,
298+
bool willNotOverflowSignedAdd(const WithCache<const Value *> &LHS,
299+
const WithCache<const Value *> &RHS,
300300
const Instruction &CxtI) const {
301301
return computeOverflowForSignedAdd(LHS, RHS, &CxtI) ==
302302
OverflowResult::NeverOverflows;
303303
}
304304

305-
bool willNotOverflowUnsignedAdd(const CachedBitsConstValue &LHS,
306-
const CachedBitsConstValue &RHS,
305+
bool willNotOverflowUnsignedAdd(const WithCache<const Value *> &LHS,
306+
const WithCache<const Value *> &RHS,
307307
const Instruction &CxtI) const {
308308
return computeOverflowForUnsignedAdd(LHS, RHS, &CxtI) ==
309309
OverflowResult::NeverOverflows;

0 commit comments

Comments
 (0)