LLVM 24.0.0git
AssumeBundleQueries.cpp
Go to the documentation of this file.
1//===- AssumeBundleQueries.cpp - tool to query assume bundles ---*- 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
10#include "llvm/ADT/Statistic.h"
13#include "llvm/IR/Instruction.h"
17
18#define DEBUG_TYPE "assume-queries"
19
20using namespace llvm;
21
22STATISTIC(NumAssumeQueries, "Number of Queries into an assume assume bundles");
24 NumUsefullAssumeQueries,
25 "Number of Queries into an assume assume bundles that were satisfied");
26
27DEBUG_COUNTER(AssumeQueryCounter, "assume-queries-counter",
28 "Controls which assumes gets created");
29
30static bool bundleHasArgument(const CallBase::BundleOpInfo &BOI, unsigned Idx) {
31 return BOI.End - BOI.Begin > Idx;
32}
33
35 const CallBase::BundleOpInfo &BOI,
36 unsigned Idx) {
37 assert(bundleHasArgument(BOI, Idx) && "index out of range");
38 return (Assume.op_begin() + BOI.Begin + Idx)->get();
39}
40
42 for (auto &Bundles : Assume.bundle_op_infos()) {
43 std::pair<Value *, Attribute::AttrKind> Key{
44 nullptr, Attribute::getAttrKindFromName(Bundles.Tag->getKey())};
45 if (bundleHasArgument(Bundles, ABA_WasOn))
46 Key.first = getValueFromBundleOpInfo(Assume, Bundles, ABA_WasOn);
47
48 if (Key.first == nullptr && Key.second == Attribute::None)
49 continue;
50 if (!bundleHasArgument(Bundles, ABA_Argument)) {
51 Result[Key][&Assume] = {0, 0};
52 continue;
53 }
54 auto *CI = dyn_cast<ConstantInt>(
55 getValueFromBundleOpInfo(Assume, Bundles, ABA_Argument));
56 if (!CI)
57 continue;
58 uint64_t Val = CI->getZExtValue();
59 auto [It, Inserted] = Result[Key].try_emplace(&Assume);
60 if (Inserted) {
61 It->second = {Val, Val};
62 continue;
63 }
64 auto &MinMax = It->second;
65 MinMax.Min = std::min(Val, MinMax.Min);
66 MinMax.Max = std::max(Val, MinMax.Max);
67 }
68}
69
72 const CallBase::BundleOpInfo &BOI) {
73 RetainedKnowledge Result;
74 if (!DebugCounter::shouldExecute(AssumeQueryCounter))
75 return Result;
76
77 Result.AttrKind = Attribute::getAttrKindFromName(BOI.Tag->getKey());
79 Result.WasOn = getValueFromBundleOpInfo(Assume, BOI, ABA_WasOn);
80 auto GetArgOr = [&](unsigned Idx, uint64_t Default) -> uint64_t {
81 if (auto *ConstInt = dyn_cast<ConstantInt>(
82 getValueFromBundleOpInfo(Assume, BOI, ABA_Argument + Idx)))
83 return ConstInt->getZExtValue();
84 return Default;
85 };
86 if (BOI.End - BOI.Begin > ABA_Argument) {
87 switch (Result.AttrKind) {
88 case Attribute::Alignment:
89 Result.ArgValue = GetArgOr(0, 1);
90 break;
91 case Attribute::Dereferenceable:
92 case Attribute::DereferenceableOrNull:
93 Result.ArgValue = GetArgOr(0, 0);
94 break;
95 case Attribute::None:
96 Result.ArgValue = 0;
97 break;
98 default:
99 llvm_unreachable("Attribute kind does not support argument");
100 }
101 }
102 Result.IRArgValue = bundleHasArgument(BOI, ABA_Argument)
104 : nullptr;
105 if (Result.AttrKind == Attribute::Alignment)
106 if (BOI.End - BOI.Begin > ABA_Argument + 1)
107 Result.ArgValue = MinAlign(Result.ArgValue, GetArgOr(1, 1));
108 return Result;
109}
110
112 return none_of(Assume.bundle_op_infos(),
113 [](const CallBase::BundleOpInfo &BOI) {
114 return BOI.Tag->getKey() != IgnoreBundleTag;
115 });
116}
117
121 AssumptionCache &AC,
123 const CallBase::BundleOpInfo *)>
124 Filter) {
125 NumAssumeQueries++;
126 for (AssumptionCache::ResultElem &Elem : AC.assumptionsFor(V)) {
127 auto *II = cast_or_null<AssumeInst>(Elem.Assume);
128 if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
129 continue;
131 *II, II->bundle_op_info_begin()[Elem.Index])) {
132 if (V != RK.WasOn)
133 continue;
134 if (is_contained(AttrKinds, RK.AttrKind) &&
135 Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
136 NumUsefullAssumeQueries++;
137 return RK;
138 }
139 }
140 }
141
143}
144
146 const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
147 AssumptionCache &AC, const Instruction *CtxI, const DominatorTree *DT) {
148 return getKnowledgeForValue(V, AttrKinds, AC,
149 [&](auto, Instruction *I, auto) {
150 return isValidAssumeForContext(I, CtxI, DT);
151 });
152}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Value * getValueFromBundleOpInfo(AssumeInst &Assume, const CallBase::BundleOpInfo &BOI, unsigned Idx)
static bool bundleHasArgument(const CallBase::BundleOpInfo &BOI, unsigned Idx)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This represents the llvm.assume intrinsic.
A cache of @llvm.assume calls within a function.
MutableArrayRef< ResultElem > assumptionsFor(const Value *V)
Access the list of assumptions which affect this value.
static LLVM_ABI Attribute::AttrKind getAttrKindFromName(StringRef AttrName)
@ None
No attributes have been set.
Definition Attributes.h:127
static bool shouldExecute(CounterInfo &Counter)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
StringRef getKey() const
LLVM Value Representation.
Definition Value.h:75
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI RetainedKnowledge getKnowledgeForValue(const Value *V, ArrayRef< Attribute::AttrKind > AttrKinds, AssumptionCache &AC, function_ref< bool(RetainedKnowledge, Instruction *, const CallBase::BundleOpInfo *)> Filter=[](auto...) { return true;})
Return a valid Knowledge associated to the Value V if its Attribute kind is in AttrKinds and it match...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto cast_or_null(const Y &Val)
Definition Casting.h:714
LLVM_ABI bool isAssumeWithEmptyBundle(const AssumeInst &Assume)
Return true iff the operand bundles of the provided llvm.assume doesn't contain any valuable informat...
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
Definition MathExtras.h:352
LLVM_ABI RetainedKnowledge getKnowledgeFromBundle(AssumeInst &Assume, const CallBase::BundleOpInfo &BOI)
This extracts the Knowledge from an element of an operand bundle.
LLVM_ABI bool isValidAssumeForContext(const Instruction *I, const Instruction *CtxI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
DenseMap< RetainedKnowledgeKey, Assume2KnowledgeMap > RetainedKnowledgeMap
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI RetainedKnowledge getKnowledgeValidInContext(const Value *V, ArrayRef< Attribute::AttrKind > AttrKinds, AssumptionCache &AC, const Instruction *CtxI, const DominatorTree *DT=nullptr)
Return a valid Knowledge associated to the Value V if its Attribute kind is in AttrKinds and the know...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
LLVM_ABI void fillMapFromAssume(AssumeInst &Assume, RetainedKnowledgeMap &Result)
Insert into the map all the informations contained in the operand bundles of the llvm....
Used to keep track of an operand bundle.
StringMapEntry< uint32_t > * Tag
The operand bundle tag, interned by LLVMContextImpl::getOrInsertBundleTag.
uint32_t End
The index in the Use& vector where operands for this operand bundle ends.
uint32_t Begin
The index in the Use& vector where operands for this operand bundle starts.
Represent one information held inside an operand bundle of an llvm.assume.
static RetainedKnowledge none()