LLVM: lib/Transforms/Coroutines/SuspendCrossingInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
17
18
19
20#define DEBUG_TYPE "coro-suspend-crossing"
21
22namespace llvm {
23#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
27 return;
28 }
29
31}
32
37 dbgs() << Label << ":";
40 if (BV[BBNo]) {
41 dbgs() << " ";
43 }
44 }
45 dbgs() << "\n";
46}
47
49 if (Block.empty())
50 return;
51
54
57
62 dbgs() << ":\n";
63 dump(" Consumes", Block[BBNo].Consumes, RPOT, MST);
64 dump(" Kills", Block[BBNo].Kills, RPOT, MST);
65 }
66 dbgs() << "\n";
67}
68#endif
69
73 size_t const ToIndex = Mapping.blockToIndex(To);
74 bool const Result = Block[ToIndex].Kills[FromIndex];
76 << " crosses suspend point\n");
77 return Result;
78}
79
83 size_t const ToIndex = Mapping.blockToIndex(To);
84 bool Result = Block[ToIndex].Kills[FromIndex] ||
85 (From == To && Block[ToIndex].KillLoop);
87 << " crosses suspend point (path or loop)\n");
88 return Result;
89}
90
91template
92bool SuspendCrossingInfo::computeBlockData(
94 bool Changed = false;
95
98 auto &B = Block[BBNo];
99
100
101 if constexpr (!Initialize)
102
103
105 return !Block[Mapping.blockToIndex(BB)].Changed;
106 })) {
107 B.Changed = false;
108 continue;
109 }
110
111
112
113 auto SavedConsumes = B.Consumes;
114 auto SavedKills = B.Kills;
115
116 for (BasicBlock *PI : predecessors(B)) {
118 auto &P = Block[PrevNo];
119
120
123
124
125
126 if (P.Suspend)
128 }
129
130 if (B.Suspend) {
131
132
134 } else if (B.End) {
135
136
137
138
139 B.Kills.reset();
140 } else {
141
142
143 B.KillLoop |= B.Kills[BBNo];
144 B.Kills.reset(BBNo);
145 }
146
147 if constexpr (!Initialize) {
148 B.Changed = (B.Kills != SavedKills) || (B.Consumes != SavedConsumes);
149 Changed |= B.Changed;
150 }
151 }
152
153 return Changed;
154}
155
159 : Mapping(F) {
160 const size_t N = Mapping.size();
162
163
164 for (size_t I = 0; I < N; ++I) {
169 B.Changed = true;
170 }
171
172
173
174
175 for (auto *CE : CoroEnds) {
176
177 assert(CE->getParent()->getFirstInsertionPt() == CE->getIterator() &&
178 CE->getParent()->size() <= 2 && "CoroEnd must be in its own BB");
179
180 getBlockData(CE->getParent()).End = true;
181 }
182
183
184
185
186
187 auto markSuspendBlock = [&](IntrinsicInst *BarrierInst) {
189 auto &B = getBlockData(SuspendBlock);
190 B.Suspend = true;
192 };
193 for (auto *CSI : CoroSuspends) {
194
195 assert(CSI->getParent()->getFirstInsertionPt() == CSI->getIterator() &&
196 CSI->getParent()->size() <= 2 &&
197 "CoroSuspend must be in its own BB");
198
199 markSuspendBlock(CSI);
200 if (auto *Save = CSI->getCoroSave())
201 markSuspendBlock(Save);
202 }
203
204
205
207 computeBlockData<true>(RPOT);
208 while (computeBlockData</*Initialize*/ false>(RPOT))
209 ;
210
212}
213
214}
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.