@@ -178,6 +178,12 @@ class ICFLoopSafetyInfo: public LoopSafetyInfo {
178178
179179struct MustBeExecutedContextExplorer ;
180180
181+ // / Enum that allows us to spell out the direction.
182+ enum class ExplorationDirection {
183+ BACKWARD = 0 ,
184+ FORWARD = 1 ,
185+ };
186+
181187// / Must be executed iterators visit stretches of instructions that are
182188// / guaranteed to be executed together, potentially with other instruction
183189// / executed in-between.
@@ -282,16 +288,18 @@ struct MustBeExecutedIterator {
282288
283289 MustBeExecutedIterator (const MustBeExecutedIterator &Other)
284290 : Visited(Other.Visited), Explorer(Other.Explorer),
285- CurInst (Other.CurInst) {}
291+ CurInst (Other.CurInst), Head(Other.Head), Tail(Other.Tail) {}
286292
287293 MustBeExecutedIterator (MustBeExecutedIterator &&Other)
288294 : Visited(std::move(Other.Visited)), Explorer(Other.Explorer),
289- CurInst(Other.CurInst) {}
295+ CurInst(Other.CurInst), Head(Other.Head), Tail(Other.Tail) {}
290296
291297 MustBeExecutedIterator &operator =(MustBeExecutedIterator &&Other) {
292298 if (this != &Other) {
293299 std::swap (Visited, Other.Visited );
294300 std::swap (CurInst, Other.CurInst );
301+ std::swap (Head, Other.Head );
302+ std::swap (Tail, Other.Tail );
295303 }
296304 return *this ;
297305 }
@@ -315,7 +323,7 @@ struct MustBeExecutedIterator {
315323 // / Equality and inequality operators. Note that we ignore the history here.
316324 // /{
317325 bool operator ==(const MustBeExecutedIterator &Other) const {
318- return CurInst == Other.CurInst ;
326+ return CurInst == Other.CurInst && Head == Other. Head && Tail == Other. Tail ;
319327 }
320328
321329 bool operator !=(const MustBeExecutedIterator &Other) const {
@@ -328,17 +336,24 @@ struct MustBeExecutedIterator {
328336 const Instruction *getCurrentInst () const { return CurInst; }
329337
330338 // / 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+ }
332343
333344private:
334- using VisitedSetTy = DenseSet<const Instruction *>;
345+ using VisitedSetTy =
346+ DenseSet<PointerIntPair<const Instruction *, 1 , ExplorationDirection>>;
335347
336348 // / Private constructors.
337349 MustBeExecutedIterator (ExplorerTy &Explorer, const Instruction *I);
338350
339351 // / Reset the iterator to its initial state pointing at \p I.
340352 void reset (const Instruction *I);
341353
354+ // / Reset the iterator to point at \p I, keep cached state.
355+ void resetInstruction (const Instruction *I);
356+
342357 // / Try to advance one of the underlying positions (Head or Tail).
343358 // /
344359 // / \return The next instruction in the must be executed context, or nullptr
@@ -357,6 +372,11 @@ struct MustBeExecutedIterator {
357372 // / initially the program point itself.
358373 const Instruction *CurInst;
359374
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+
360380 friend struct MustBeExecutedContextExplorer ;
361381};
362382
@@ -379,14 +399,24 @@ struct MustBeExecutedContextExplorer {
379399 // / \param ExploreInterBlock Flag to indicate if instructions in blocks
380400 // / other than the parent of PP should be
381401 // / 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.
382408 MustBeExecutedContextExplorer (
383- bool ExploreInterBlock,
409+ bool ExploreInterBlock, bool ExploreCFGForward, bool ExploreCFGBackward,
384410 GetterTy<const LoopInfo> LIGetter =
385411 [](const Function &) { return nullptr ; },
412+ GetterTy<const DominatorTree> DTGetter =
413+ [](const Function &) { return nullptr ; },
386414 GetterTy<const PostDominatorTree> PDTGetter =
387415 [](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 ) {}
390420
391421 // / Clean up the dynamically allocated iterators.
392422 ~MustBeExecutedContextExplorer () {
@@ -464,21 +494,36 @@ struct MustBeExecutedContextExplorer {
464494 const Instruction *
465495 getMustBeExecutedNextInstruction (MustBeExecutedIterator &It,
466496 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);
467506
468507 // / Find the next join point from \p InitBB in forward direction.
469508 const BasicBlock *findForwardJoinPoint (const BasicBlock *InitBB);
470509
510+ // / Find the next join point from \p InitBB in backward direction.
511+ const BasicBlock *findBackwardJoinPoint (const BasicBlock *InitBB);
512+
471513 // / Parameter that limit the performed exploration. See the constructor for
472514 // / their meaning.
473515 // /{
474516 const bool ExploreInterBlock;
517+ const bool ExploreCFGForward;
518+ const bool ExploreCFGBackward;
475519 // /}
476520
477521private:
478522 // / Getters for common CFG analyses: LoopInfo, DominatorTree, and
479523 // / PostDominatorTree.
480524 // /{
481525 GetterTy<const LoopInfo> LIGetter;
526+ GetterTy<const DominatorTree> DTGetter;
482527 GetterTy<const PostDominatorTree> PDTGetter;
483528 // /}
484529
0 commit comments