File indexing completed on 2026-05-10 08:43:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ANALYSIS_ASSUMEBUNDLEQUERIES_H
0015 #define LLVM_ANALYSIS_ASSUMEBUNDLEQUERIES_H
0016
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/IR/IntrinsicInst.h"
0019
0020 namespace llvm {
0021 class AssumptionCache;
0022 class DominatorTree;
0023 class Instruction;
0024
0025
0026
0027
0028 enum AssumeBundleArg {
0029 ABA_WasOn = 0,
0030 ABA_Argument = 1,
0031 };
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 bool hasAttributeInAssume(AssumeInst &Assume, Value *IsOn, StringRef AttrName,
0042 uint64_t *ArgVal = nullptr);
0043 inline bool hasAttributeInAssume(AssumeInst &Assume, Value *IsOn,
0044 Attribute::AttrKind Kind,
0045 uint64_t *ArgVal = nullptr) {
0046 return hasAttributeInAssume(Assume, IsOn,
0047 Attribute::getNameFromAttrKind(Kind), ArgVal);
0048 }
0049
0050 template<> struct DenseMapInfo<Attribute::AttrKind> {
0051 static Attribute::AttrKind getEmptyKey() {
0052 return Attribute::EmptyKey;
0053 }
0054 static Attribute::AttrKind getTombstoneKey() {
0055 return Attribute::TombstoneKey;
0056 }
0057 static unsigned getHashValue(Attribute::AttrKind AK) {
0058 return hash_combine(AK);
0059 }
0060 static bool isEqual(Attribute::AttrKind LHS, Attribute::AttrKind RHS) {
0061 return LHS == RHS;
0062 }
0063 };
0064
0065
0066
0067
0068 using RetainedKnowledgeKey = std::pair<Value *, Attribute::AttrKind>;
0069
0070 struct MinMax {
0071 uint64_t Min;
0072 uint64_t Max;
0073 };
0074
0075
0076
0077
0078
0079 using Assume2KnowledgeMap = DenseMap<AssumeInst *, MinMax>;
0080
0081 using RetainedKnowledgeMap =
0082 DenseMap<RetainedKnowledgeKey, Assume2KnowledgeMap>;
0083
0084
0085
0086
0087
0088
0089 void fillMapFromAssume(AssumeInst &Assume, RetainedKnowledgeMap &Result);
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 struct RetainedKnowledge {
0100 Attribute::AttrKind AttrKind = Attribute::None;
0101 uint64_t ArgValue = 0;
0102 Value *WasOn = nullptr;
0103 bool operator==(RetainedKnowledge Other) const {
0104 return AttrKind == Other.AttrKind && WasOn == Other.WasOn &&
0105 ArgValue == Other.ArgValue;
0106 }
0107 bool operator!=(RetainedKnowledge Other) const { return !(*this == Other); }
0108
0109
0110 bool operator<(RetainedKnowledge Other) const {
0111 assert(((AttrKind == Other.AttrKind && WasOn == Other.WasOn) ||
0112 AttrKind == Attribute::None || Other.AttrKind == Attribute::None) &&
0113 "This is only intend for use in min/max to select the best for "
0114 "RetainedKnowledge that is otherwise equal");
0115 return ArgValue < Other.ArgValue;
0116 }
0117 operator bool() const { return AttrKind != Attribute::None; }
0118 static RetainedKnowledge none() { return RetainedKnowledge{}; }
0119 };
0120
0121
0122
0123 RetainedKnowledge getKnowledgeFromOperandInAssume(AssumeInst &Assume,
0124 unsigned Idx);
0125
0126
0127
0128 inline RetainedKnowledge getKnowledgeFromUseInAssume(const Use *U) {
0129 return getKnowledgeFromOperandInAssume(*cast<AssumeInst>(U->getUser()),
0130 U->getOperandNo());
0131 }
0132
0133
0134 constexpr StringRef IgnoreBundleTag = "ignore";
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 bool isAssumeWithEmptyBundle(const AssumeInst &Assume);
0145
0146
0147
0148 RetainedKnowledge getKnowledgeFromUse(const Use *U,
0149 ArrayRef<Attribute::AttrKind> AttrKinds);
0150
0151
0152
0153 RetainedKnowledge getKnowledgeForValue(
0154 const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
0155 AssumptionCache *AC = nullptr,
0156 function_ref<bool(RetainedKnowledge, Instruction *,
0157 const CallBase::BundleOpInfo *)>
0158 Filter = [](auto...) { return true; });
0159
0160
0161
0162
0163 RetainedKnowledge getKnowledgeValidInContext(
0164 const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
0165 const Instruction *CtxI, const DominatorTree *DT = nullptr,
0166 AssumptionCache *AC = nullptr);
0167
0168
0169
0170 RetainedKnowledge getKnowledgeFromBundle(AssumeInst &Assume,
0171 const CallBase::BundleOpInfo &BOI);
0172
0173 }
0174
0175 #endif