@@ -144,21 +144,28 @@ template <typename ContextT> class GenericCycleInfoCompute {
144
144
};
145
145
146
146
template <typename ContextT>
147
- auto GenericCycleInfo<ContextT>::getTopLevelParentCycle(
148
- const BlockT *Block) const -> CycleT * {
147
+ auto GenericCycleInfo<ContextT>::getTopLevelParentCycle(BlockT *Block)
148
+ -> CycleT * {
149
+ auto Cycle = BlockMapTopLevel.find (Block);
150
+ if (Cycle != BlockMapTopLevel.end ())
151
+ return Cycle->second ;
152
+
149
153
auto MapIt = BlockMap.find (Block);
150
154
if (MapIt == BlockMap.end ())
151
155
return nullptr ;
152
156
153
157
auto *C = MapIt->second ;
154
158
while (C->ParentCycle )
155
159
C = C->ParentCycle ;
160
+ BlockMapTopLevel.try_emplace (Block, C);
156
161
return C;
157
162
}
158
163
159
164
template <typename ContextT>
160
- void GenericCycleInfo<ContextT>::moveToNewParent(CycleT *NewParent,
161
- CycleT *Child) {
165
+ void GenericCycleInfo<ContextT>::moveTopLevelCycleToNewParent(CycleT *NewParent,
166
+ CycleT *Child) {
167
+ assert ((!Child->ParentCycle && !NewParent->ParentCycle ) &&
168
+ " NewParent and Child must be both top level cycle!\n " );
162
169
auto &CurrentContainer =
163
170
Child->ParentCycle ? Child->ParentCycle ->Children : TopLevelCycles;
164
171
auto Pos = llvm::find_if (CurrentContainer, [=](const auto &Ptr ) -> bool {
@@ -169,6 +176,13 @@ void GenericCycleInfo<ContextT>::moveToNewParent(CycleT *NewParent,
169
176
*Pos = std::move (CurrentContainer.back ());
170
177
CurrentContainer.pop_back ();
171
178
Child->ParentCycle = NewParent;
179
+
180
+ NewParent->Blocks .insert (NewParent->Blocks .end (), Child->block_begin (),
181
+ Child->block_end ());
182
+
183
+ for (auto &It : BlockMapTopLevel)
184
+ if (It.second == Child)
185
+ It.second = NewParent;
172
186
}
173
187
174
188
// / \brief Main function of the cycle info computations.
@@ -240,10 +254,7 @@ void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
240
254
<< " discovered child cycle "
241
255
<< Info.Context .print (BlockParent->getHeader ()) << " \n " );
242
256
// Make BlockParent the child of NewCycle.
243
- Info.moveToNewParent (NewCycle.get (), BlockParent);
244
- NewCycle->Blocks .insert (NewCycle->Blocks .end (),
245
- BlockParent->block_begin (),
246
- BlockParent->block_end ());
257
+ Info.moveTopLevelCycleToNewParent (NewCycle.get (), BlockParent);
247
258
248
259
for (auto *ChildEntry : BlockParent->entries ())
249
260
ProcessPredecessors (ChildEntry);
@@ -257,6 +268,7 @@ void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
257
268
assert (!is_contained (NewCycle->Blocks , Block));
258
269
NewCycle->Blocks .push_back (Block);
259
270
ProcessPredecessors (Block);
271
+ Info.BlockMapTopLevel .try_emplace (Block, NewCycle.get ());
260
272
}
261
273
} while (!Worklist.empty ());
262
274
@@ -336,6 +348,7 @@ void GenericCycleInfoCompute<ContextT>::dfs(BlockT *EntryBlock) {
336
348
template <typename ContextT> void GenericCycleInfo<ContextT>::clear() {
337
349
TopLevelCycles.clear ();
338
350
BlockMap.clear ();
351
+ BlockMapTopLevel.clear ();
339
352
}
340
353
341
354
// / \brief Compute the cycle info for a function.
0 commit comments