Go to the documentation of this file.
41 cl::desc(
"Enable verification of assumption cache"),
45 AssumptionCache::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)) {
66 Affected.push_back({V, Idx});
67 }
else if (
auto *
I = dyn_cast<Instruction>(V)) {
68 Affected.push_back({
I, Idx});
74 if (isa<Instruction>(
Op) || isa<Argument>(
Op))
75 Affected.push_back({
Op, Idx});
80 for (
unsigned Idx = 0; Idx != CI->getNumOperandBundles(); Idx++) {
81 if (CI->getOperandBundleAt(Idx).Inputs.size() >
ABA_WasOn &&
83 AddAffected(CI->getOperandBundleAt(Idx).Inputs[
ABA_WasOn], Idx);
96 auto AddAffectedFromEq = [&AddAffected](
Value *V) {
114 AddAffectedFromEq(A);
115 AddAffectedFromEq(
B);
140 for (
auto &AV : Affected) {
141 auto &AVV = getOrInsertAffectedValues(AV.Assume);
143 return Elem.
Assume == CI && Elem.
Index == AV.Index;
145 AVV.push_back({CI, AV.Index});
153 for (
auto &AV : Affected) {
154 auto AVI = AffectedValues.
find_as(AV.Assume);
155 if (AVI == AffectedValues.
end())
158 bool HasNonnull =
false;
164 HasNonnull |= !!Elem.
Assume;
165 if (HasNonnull && Found)
168 assert(Found &&
"already unregistered or incorrect cache state");
170 AffectedValues.
erase(AVI);
176 void AssumptionCache::AffectedValueCallbackVH::deleted() {
177 AC->AffectedValues.erase(getValPtr());
181 void AssumptionCache::transferAffectedValuesInCache(
Value *OV,
Value *
NV) {
182 auto &NAVV = getOrInsertAffectedValues(
NV);
183 auto AVI = AffectedValues.
find(OV);
184 if (AVI == AffectedValues.
end())
187 for (
auto &A : AVI->second)
190 AffectedValues.
erase(OV);
193 void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(
Value *
NV) {
194 if (!isa<Instruction>(
NV) && !isa<Argument>(
NV))
199 AC->transferAffectedValuesInCache(getValPtr(),
NV);
205 void AssumptionCache::scanFunction() {
206 assert(!Scanned &&
"Tried to scan the function twice!");
207 assert(AssumeHandles.empty() &&
"Already have assumes when scanning!");
213 if (isa<AssumeInst>(&
I))
220 for (
auto &A : AssumeHandles)
234 "Cannot register @llvm.assume call not in a basic block");
236 "Cannot register @llvm.assume call not in this function");
242 for (
auto &VH : AssumeHandles) {
247 "Cached assumption not inside this function!");
248 assert(
match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
249 "Cached something other than a call to @llvm.assume!");
251 "Cache contains multiple copies of a call!");
270 OS <<
"Cached assumptions for function: " <<
F.getName() <<
"\n";
273 OS <<
" " << *cast<CallInst>(VH)->getArgOperand(0) <<
"\n";
278 void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
279 auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
280 if (
I != ACT->AssumptionCaches.end())
281 ACT->AssumptionCaches.erase(
I);
291 if (
I != AssumptionCaches.
end())
294 auto *TTIWP = getAnalysisIfAvailable<TargetTransformInfoWrapperPass>();
295 auto *
TTI = TTIWP ? &TTIWP->getTTI(
F) :
nullptr;
299 auto IP = AssumptionCaches.
insert(std::make_pair(
300 FunctionCallbackVH(&
F,
this), std::make_unique<AssumptionCache>(
F,
TTI)));
301 assert(
IP.second &&
"Scanning function already in the map?");
302 return *
IP.first->second;
307 if (
I != AssumptionCaches.
end())
308 return I->second.get();
321 for (
const auto &
I : AssumptionCaches) {
322 for (
auto &VH :
I.second->assumptions())
324 AssumptionSet.
insert(cast<CallInst>(VH));
328 if (
match(&II, m_Intrinsic<Intrinsic::assume>()) &&
329 !AssumptionSet.
count(cast<CallInst>(&II)))
343 "Assumption Cache Tracker",
false,
true)
A set of analyses that are preserved following a run of a transformation pass.
Analysis pass providing the TargetTransformInfo.
This is an optimization pass for GlobalISel generic memory operations.
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 registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
const Function * getParent() const
Return the enclosing method, or null if none.
ImmutablePass class - This class is used to provide information that does not need to be run.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
constexpr StringRef IgnoreBundleTag
Tag in operand bundle indicating that this bundle should be ignored.
FunctionAnalysisManager FAM
bool erase(const KeyT &Val)
This represents the llvm.assume intrinsic.
unsigned Index
contains either ExprResultIdx or the index of the operand bundle containing the knowledge.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static cl::opt< bool > VerifyAssumptionCache("verify-assumption-cache", cl::Hidden, cl::desc("Enable verification of assumption cache"), cl::init(false))
DiagnosticInfoOptimizationBase::Argument NV
BinaryOp_match< ValTy, cst_pred_ty< is_all_ones >, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
CastClass_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
LLVM Basic Block Representation.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool match(Val *V, const Pattern &P)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
void initializeAssumptionCacheTrackerPass(PassRegistry &)
AssumptionCache * lookupAssumptionCache(Function &F)
Return the cached assumptions for a function if it has already been scanned.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
void erase_value(Container &C, ValueType V)
Wrapper function to remove a value from a container:
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
AssumptionCache run(Function &F, FunctionAnalysisManager &)
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive,...
A function analysis which provides an AssumptionCache.
A special type used by analysis passes to provide an address that identifies that particular analysis...
initializer< Ty > init(const Ty &Val)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
iterator find(const_arg_type_t< KeyT > Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
An immutable pass that tracks lazily created AssumptionCache objects.
SmallVector< MachineOperand, 4 > Cond
A cache of @llvm.assume calls within a function.
@ ICMP_ULT
unsigned less than
static const Function * getParent(const Value *V)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op > m_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations.
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
CastClass_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
static void findAffectedValues(CallBase *CI, TargetTransformInfo *TTI, SmallVectorImpl< AssumptionCache::ResultElem > &Affected)
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
const BasicBlock * getParent() const
void unregisterAssumption(AssumeInst *CI)
Remove an @llvm.assume intrinsic from this function's cache if it has been added to the cache earlier...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
A container for analyses that lazily runs them and caches their results.
void updateAffectedValues(AssumeInst *CI)
Update the cache of values being affected by this assumption (i.e.
~AssumptionCacheTracker() override
LLVM Value Representation.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator insert(iterator I, T &&Elt)