41 cl::desc(
"Enable verification of assumption cache"),
45AssumptionCache::getOrInsertAffectedValues(
Value *V) {
48 auto AVI = AffectedValues.
find_as(V);
49 if (AVI != AffectedValues.
end())
52 auto AVIP = AffectedValues.
insert(
54 return AVIP.first->second;
63 auto AddAffected = [&Affected](
Value *V,
unsigned Idx =
65 if (isa<Argument>(V) || isa<GlobalValue>(V)) {
67 }
else if (
auto *
I = dyn_cast<Instruction>(V)) {
74 if (isa<Instruction>(
Op) || isa<Argument>(
Op))
80 for (
unsigned Idx = 0;
Idx != CI->getNumOperandBundles();
Idx++) {
81 if (CI->getOperandBundleAt(
Idx).Inputs.size() >
ABA_WasOn &&
96 auto AddAffectedFromEq = [&AddAffected](
Value *
V) {
114 AddAffectedFromEq(
A);
115 AddAffectedFromEq(
B);
150 AddAffected(
const_cast<Value *
>(
Ptr->stripInBoundsOffsets()));
158 for (
auto &AV : Affected) {
159 auto &AVV = getOrInsertAffectedValues(AV.Assume);
161 return Elem.
Assume == CI && Elem.
Index == AV.Index;
163 AVV.push_back({CI, AV.Index});
171 for (
auto &AV : Affected) {
172 auto AVI = AffectedValues.
find_as(AV.Assume);
173 if (AVI == AffectedValues.
end())
176 bool HasNonnull =
false;
182 HasNonnull |= !!Elem.
Assume;
183 if (HasNonnull && Found)
186 assert(Found &&
"already unregistered or incorrect cache state");
188 AffectedValues.
erase(AVI);
194void AssumptionCache::AffectedValueCallbackVH::deleted() {
195 AC->AffectedValues.erase(getValPtr());
199void AssumptionCache::transferAffectedValuesInCache(
Value *OV,
Value *NV) {
200 auto &NAVV = getOrInsertAffectedValues(NV);
201 auto AVI = AffectedValues.
find(OV);
202 if (AVI == AffectedValues.
end())
205 for (
auto &
A : AVI->second)
208 AffectedValues.
erase(OV);
211void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(
Value *NV) {
212 if (!isa<Instruction>(NV) && !isa<Argument>(NV))
217 AC->transferAffectedValuesInCache(getValPtr(), NV);
223void AssumptionCache::scanFunction() {
224 assert(!Scanned &&
"Tried to scan the function twice!");
225 assert(AssumeHandles.empty() &&
"Already have assumes when scanning!");
231 if (isa<AssumeInst>(&
I))
238 for (
auto &
A : AssumeHandles)
252 "Cannot register @llvm.assume call not in a basic block");
254 "Cannot register @llvm.assume call not in this function");
260 for (
auto &VH : AssumeHandles) {
265 "Cached assumption not inside this function!");
266 assert(
match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
267 "Cached something other than a call to @llvm.assume!");
269 "Cache contains multiple copies of a call!");
288 OS <<
"Cached assumptions for function: " <<
F.getName() <<
"\n";
291 OS <<
" " << *cast<CallInst>(VH)->getArgOperand(0) <<
"\n";
296void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
297 auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
298 if (
I != ACT->AssumptionCaches.end())
299 ACT->AssumptionCaches.erase(
I);
309 if (
I != AssumptionCaches.
end())
312 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
313 auto *
TTI = TTIWP ? &TTIWP->getTTI(
F) :
nullptr;
317 auto IP = AssumptionCaches.
insert(std::make_pair(
318 FunctionCallbackVH(&
F,
this), std::make_unique<AssumptionCache>(
F,
TTI)));
319 assert(IP.second &&
"Scanning function already in the map?");
320 return *IP.first->second;
325 if (
I != AssumptionCaches.
end())
326 return I->second.get();
339 for (
const auto &
I : AssumptionCaches) {
340 for (
auto &VH :
I.second->assumptions())
342 AssumptionSet.
insert(cast<CallInst>(VH));
346 if (
match(&II, m_Intrinsic<Intrinsic::assume>()) &&
347 !AssumptionSet.
count(cast<CallInst>(&II)))
361 "Assumption Cache Tracker",
false,
true)
static void findAffectedValues(CallBase *CI, TargetTransformInfo *TTI, SmallVectorImpl< AssumptionCache::ResultElem > &Affected)
static cl::opt< bool > VerifyAssumptionCache("verify-assumption-cache", cl::Hidden, cl::desc("Enable verification of assumption cache"), cl::init(false))
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
FunctionAnalysisManager FAM
This header defines various interfaces for pass management in LLVM.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
AssumptionCache run(Function &F, FunctionAnalysisManager &)
An immutable pass that tracks lazily created AssumptionCache objects.
~AssumptionCacheTracker() override
AssumptionCache * lookupAssumptionCache(Function &F)
Return the cached assumptions for a function if it has already been scanned.
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
A cache of @llvm.assume calls within a function.
void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
void updateAffectedValues(AssumeInst *CI)
Update the cache of values being affected by this assumption (i.e.
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
void unregisterAssumption(AssumeInst *CI)
Remove an @llvm.assume intrinsic from this function's cache if it has been added to the cache earlier...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_ULT
unsigned less than
bool isFPPredicate() const
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive,...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
ImmutablePass class - This class is used to provide information that does not need to be run.
const BasicBlock * getParent() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
LLVM Value Representation.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
CastClass_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
bool match(Val *V, const Pattern &P)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
CastClass_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op > m_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations.
m_Intrinsic_Ty< Opnd0 >::Ty m_FAbs(const Opnd0 &Op0)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
constexpr StringRef IgnoreBundleTag
Tag in operand bundle indicating that this bundle should be ignored.
void initializeAssumptionCacheTrackerPass(PassRegistry &)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void erase_value(Container &C, ValueType V)
Wrapper function to remove a value from a container:
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
A special type used by analysis passes to provide an address that identifies that particular analysis...
unsigned Index
contains either ExprResultIdx or the index of the operand bundle containing the knowledge.