LLVM 22.0.0git
DropUnnecessaryAssumes.cpp
Go to the documentation of this file.
1//===------------------------------------------------------------*- 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
15
16using namespace llvm;
17using namespace llvm::PatternMatch;
18
20 // If all the affected uses have only one use (part of the assume), then
21 // the assume does not provide useful information. Note that additional
22 // users may appear as a result of inlining and CSE, so we should only
23 // make this assumption late in the optimization pipeline.
24 // TODO: Handle dead cyclic usages.
25 // TODO: Handle multiple dead assumes on the same value.
26 return all_of(Affected, match_fn(m_OneUse(m_Value())));
27}
28
31 AssumptionCache &AC = FAM.getResult<AssumptionAnalysis>(F);
32 bool Changed = false;
33
34 for (const WeakVH &Elem : AC.assumptions()) {
35 auto *Assume = cast_or_null<AssumeInst>(Elem);
36 if (!Assume)
37 continue;
38
39 if (Assume->hasOperandBundles()) {
40 // Handle operand bundle assumptions.
41 SmallVector<WeakTrackingVH> DeadBundleArgs;
43 unsigned NumBundles = Assume->getNumOperandBundles();
44 for (unsigned I = 0; I != NumBundles; ++I) {
45 auto IsDead = [](OperandBundleUse Bundle) {
46 // "ignore" operand bundles are always dead.
47 if (Bundle.getTagName() == "ignore")
48 return true;
49
50 // Bundles without arguments do not affect any specific values.
51 // Always keep them for now.
52 if (Bundle.Inputs.empty())
53 return false;
54
55 SmallVector<Value *> Affected;
57 Bundle, [&](Value *A) { Affected.push_back(A); });
58
59 return affectedValuesAreEphemeral(Affected);
60 };
61
62 OperandBundleUse Bundle = Assume->getOperandBundleAt(I);
63 if (IsDead(Bundle))
64 append_range(DeadBundleArgs, Bundle.Inputs);
65 else
66 KeptBundles.emplace_back(Bundle);
67 }
68
69 if (KeptBundles.size() != NumBundles) {
70 if (KeptBundles.empty()) {
71 // All operand bundles are dead, remove the whole assume.
72 Assume->eraseFromParent();
73 } else {
74 // Otherwise only drop the dead operand bundles.
75 CallBase *NewAssume =
76 CallBase::Create(Assume, KeptBundles, Assume->getIterator());
78 Assume->eraseFromParent();
79 }
80
82 Changed = true;
83 }
84 continue;
85 }
86
87 Value *Cond = Assume->getArgOperand(0);
88 // Don't drop type tests, which have special semantics.
90 continue;
91
92 SmallVector<Value *> Affected;
93 findValuesAffectedByCondition(Cond, /*IsAssume=*/true,
94 [&](Value *A) { Affected.push_back(A); });
95
96 if (!affectedValuesAreEphemeral(Affected))
97 continue;
98
99 Assume->eraseFromParent();
101 Changed = true;
102 }
103
104 if (Changed) {
107 return PA;
108 }
109 return PreservedAnalyses::all();
110}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool affectedValuesAreEphemeral(ArrayRef< Value * > Affected)
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
bool IsDead
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
static void findValuesAffectedByOperandBundle(OperandBundleUse Bundle, function_ref< void(Value *)> InsertAffected)
Determine which values are affected by this assume operand bundle.
LLVM_ABI void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
MutableArrayRef< WeakVH > assumptions()
Access the list of assumption handles currently tracked for this function.
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static LLVM_ABI CallBase * Create(CallBase *CB, ArrayRef< OperandBundleDef > Bundles, InsertPosition InsertPt=nullptr)
Create a clone of CB with a different set of operand bundles and insert it before InsertPt.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
Definition Value.h:75
A nullable Value handle that is nullable.
Changed
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
MatchFunctor< Val, Pattern > match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1705
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:533
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2116
auto cast_or_null(const Y &Val)
Definition Casting.h:720
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(SmallVectorImpl< WeakTrackingVH > &DeadInsts, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow instructions that are not...
Definition Local.cpp:548
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)
Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
A lightweight accessor for an operand bundle meant to be passed around by value.
ArrayRef< Use > Inputs