@@ -178,6 +178,12 @@ class ICFLoopSafetyInfo: public LoopSafetyInfo {
178
178
179
179
struct MustBeExecutedContextExplorer ;
180
180
181
+ // / Enum that allows us to spell out the direction.
182
+ enum class ExplorationDirection {
183
+ BACKWARD = 0 ,
184
+ FORWARD = 1 ,
185
+ };
186
+
181
187
// / Must be executed iterators visit stretches of instructions that are
182
188
// / guaranteed to be executed together, potentially with other instruction
183
189
// / executed in-between.
@@ -282,16 +288,18 @@ struct MustBeExecutedIterator {
282
288
283
289
MustBeExecutedIterator (const MustBeExecutedIterator &Other)
284
290
: Visited(Other.Visited), Explorer(Other.Explorer),
285
- CurInst (Other.CurInst) {}
291
+ CurInst (Other.CurInst), Head(Other.Head), Tail(Other.Tail) {}
286
292
287
293
MustBeExecutedIterator (MustBeExecutedIterator &&Other)
288
294
: Visited(std::move(Other.Visited)), Explorer(Other.Explorer),
289
- CurInst(Other.CurInst) {}
295
+ CurInst(Other.CurInst), Head(Other.Head), Tail(Other.Tail) {}
290
296
291
297
MustBeExecutedIterator &operator =(MustBeExecutedIterator &&Other) {
292
298
if (this != &Other) {
293
299
std::swap (Visited, Other.Visited );
294
300
std::swap (CurInst, Other.CurInst );
301
+ std::swap (Head, Other.Head );
302
+ std::swap (Tail, Other.Tail );
295
303
}
296
304
return *this ;
297
305
}
@@ -315,7 +323,7 @@ struct MustBeExecutedIterator {
315
323
// / Equality and inequality operators. Note that we ignore the history here.
316
324
// /{
317
325
bool operator ==(const MustBeExecutedIterator &Other) const {
318
- return CurInst == Other.CurInst ;
326
+ return CurInst == Other.CurInst && Head == Other. Head && Tail == Other. Tail ;
319
327
}
320
328
321
329
bool operator !=(const MustBeExecutedIterator &Other) const {
@@ -328,17 +336,24 @@ struct MustBeExecutedIterator {
328
336
const Instruction *getCurrentInst () const { return CurInst; }
329
337
330
338
// / Return true if \p I was encountered by this iterator already.
331
- bool count (const Instruction *I) const { return Visited.count (I); }
339
+ bool count (const Instruction *I) const {
340
+ return Visited.count ({I, ExplorationDirection::FORWARD}) ||
341
+ Visited.count ({I, ExplorationDirection::BACKWARD});
342
+ }
332
343
333
344
private:
334
- using VisitedSetTy = DenseSet<const Instruction *>;
345
+ using VisitedSetTy =
346
+ DenseSet<PointerIntPair<const Instruction *, 1 , ExplorationDirection>>;
335
347
336
348
// / Private constructors.
337
349
MustBeExecutedIterator (ExplorerTy &Explorer, const Instruction *I);
338
350
339
351
// / Reset the iterator to its initial state pointing at \p I.
340
352
void reset (const Instruction *I);
341
353
354
+ // / Reset the iterator to point at \p I, keep cached state.
355
+ void resetInstruction (const Instruction *I);
356
+
342
357
// / Try to advance one of the underlying positions (Head or Tail).
343
358
// /
344
359
// / \return The next instruction in the must be executed context, or nullptr
@@ -357,6 +372,11 @@ struct MustBeExecutedIterator {
357
372
// / initially the program point itself.
358
373
const Instruction *CurInst;
359
374
375
+ // / Two positions that mark the program points where this iterator will look
376
+ // / for the next instruction. Note that the current instruction is either the
377
+ // / one pointed to by Head, Tail, or both.
378
+ const Instruction *Head, *Tail;
379
+
360
380
friend struct MustBeExecutedContextExplorer ;
361
381
};
362
382
@@ -379,14 +399,24 @@ struct MustBeExecutedContextExplorer {
379
399
// / \param ExploreInterBlock Flag to indicate if instructions in blocks
380
400
// / other than the parent of PP should be
381
401
// / explored.
402
+ // / \param ExploreCFGForward Flag to indicate if instructions located after
403
+ // / PP in the CFG, e.g., post-dominating PP,
404
+ // / should be explored.
405
+ // / \param ExploreCFGBackward Flag to indicate if instructions located
406
+ // / before PP in the CFG, e.g., dominating PP,
407
+ // / should be explored.
382
408
MustBeExecutedContextExplorer (
383
- bool ExploreInterBlock,
409
+ bool ExploreInterBlock, bool ExploreCFGForward, bool ExploreCFGBackward,
384
410
GetterTy<const LoopInfo> LIGetter =
385
411
[](const Function &) { return nullptr ; },
412
+ GetterTy<const DominatorTree> DTGetter =
413
+ [](const Function &) { return nullptr ; },
386
414
GetterTy<const PostDominatorTree> PDTGetter =
387
415
[](const Function &) { return nullptr ; })
388
- : ExploreInterBlock(ExploreInterBlock), LIGetter(LIGetter),
389
- PDTGetter (PDTGetter), EndIterator(*this , nullptr ) {}
416
+ : ExploreInterBlock(ExploreInterBlock),
417
+ ExploreCFGForward (ExploreCFGForward),
418
+ ExploreCFGBackward(ExploreCFGBackward), LIGetter(LIGetter),
419
+ DTGetter(DTGetter), PDTGetter(PDTGetter), EndIterator(*this , nullptr ) {}
390
420
391
421
// / Clean up the dynamically allocated iterators.
392
422
~MustBeExecutedContextExplorer () {
@@ -464,21 +494,36 @@ struct MustBeExecutedContextExplorer {
464
494
const Instruction *
465
495
getMustBeExecutedNextInstruction (MustBeExecutedIterator &It,
466
496
const Instruction *PP);
497
+ // / Return the previous instr. that is guaranteed to be executed before \p PP.
498
+ // /
499
+ // / \param It The iterator that is used to traverse the must be
500
+ // / executed context.
501
+ // / \param PP The program point for which the previous instr.
502
+ // / that is guaranteed to execute is determined.
503
+ const Instruction *
504
+ getMustBeExecutedPrevInstruction (MustBeExecutedIterator &It,
505
+ const Instruction *PP);
467
506
468
507
// / Find the next join point from \p InitBB in forward direction.
469
508
const BasicBlock *findForwardJoinPoint (const BasicBlock *InitBB);
470
509
510
+ // / Find the next join point from \p InitBB in backward direction.
511
+ const BasicBlock *findBackwardJoinPoint (const BasicBlock *InitBB);
512
+
471
513
// / Parameter that limit the performed exploration. See the constructor for
472
514
// / their meaning.
473
515
// /{
474
516
const bool ExploreInterBlock;
517
+ const bool ExploreCFGForward;
518
+ const bool ExploreCFGBackward;
475
519
// /}
476
520
477
521
private:
478
522
// / Getters for common CFG analyses: LoopInfo, DominatorTree, and
479
523
// / PostDominatorTree.
480
524
// /{
481
525
GetterTy<const LoopInfo> LIGetter;
526
+ GetterTy<const DominatorTree> DTGetter;
482
527
GetterTy<const PostDominatorTree> PDTGetter;
483
528
// /}
484
529
0 commit comments