20#define DEBUG_TYPE "coro-suspend-crossing"
23#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
37 dbgs() << Label <<
":";
63 dump(
" Consumes", Block[BBNo].Consumes, RPOT, MST);
64 dump(
" Kills", Block[BBNo].Kills, RPOT, MST);
74 bool const Result = Block[ToIndex].Kills[FromIndex];
76 <<
" crosses suspend point\n");
84 bool Result = Block[ToIndex].Kills[FromIndex] ||
85 (
From == To && Block[ToIndex].KillLoop);
87 <<
" crosses suspend point (path or loop)\n");
91template <
bool Initialize>
92bool SuspendCrossingInfo::computeBlockData(
98 auto &
B = Block[BBNo];
101 if constexpr (!Initialize)
113 auto SavedConsumes =
B.Consumes;
114 auto SavedKills =
B.Kills;
116 for (BasicBlock *PI : predecessors(
B)) {
118 auto &
P = Block[PrevNo];
121 B.Consumes |=
P.Consumes;
127 B.Kills |=
P.Consumes;
133 B.Kills |=
B.Consumes;
143 B.KillLoop |=
B.Kills[BBNo];
147 if constexpr (!Initialize) {
148 B.Changed = (
B.Kills != SavedKills) || (
B.Consumes != SavedConsumes);
149 Changed |=
B.Changed;
160 const size_t N = Mapping.
size();
164 for (
size_t I = 0;
I <
N; ++
I) {
166 B.Consumes.resize(
N);
175 for (
auto *CE : CoroEnds) {
177 assert(CE->getParent()->getFirstInsertionPt() == CE->getIterator() &&
178 CE->getParent()->size() <= 2 &&
"CoroEnd must be in its own BB");
180 getBlockData(CE->getParent()).End =
true;
189 auto &
B = getBlockData(SuspendBlock);
191 B.Kills |=
B.Consumes;
193 for (
auto *CSI : CoroSuspends) {
195 assert(CSI->getParent()->getFirstInsertionPt() == CSI->getIterator() &&
196 CSI->getParent()->size() <= 2 &&
197 "CoroSuspend must be in its own BB");
199 markSuspendBlock(CSI);
200 if (
auto *Save = CSI->getCoroSave())
201 markSuspendBlock(Save);
207 computeBlockData<
true>(RPOT);
208 while (computeBlockData</*Initialize*/ false>(RPOT))
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
size_t blockToIndex(BasicBlock const *BB) const
BasicBlock * indexToBlock(unsigned Index) const
A wrapper class for inspecting calls to intrinsic functions.
Manage lifetime of a slot tracker for printing IR.
int getLocalSlot(const Value *V)
Return the slot number of the specified local value.
void incorporateFunction(const Function &F)
Incorporate the given function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
bool hasPathCrossingSuspendPoint(BasicBlock *From, BasicBlock *To) const
Returns true if there is a path from From to To crossing a suspend point without crossing From a 2nd ...
SuspendCrossingInfo(Function &F, const SmallVectorImpl< AnyCoroSuspendInst * > &CoroSuspends, const SmallVectorImpl< AnyCoroEndInst * > &CoroEnds)
bool hasPathOrLoopCrossingSuspendPoint(BasicBlock *From, BasicBlock *To) const
Returns true if there is a path from From to To crossing a suspend point without crossing From a 2nd ...
StringRef getName() const
Return a constant reference to the value's name.
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.
static void dumpBasicBlockLabel(const BasicBlock *BB, ModuleSlotTracker &MST)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.