@@ -416,6 +416,97 @@ class MachineBasicBlock
416416 // / Remove entry from the livein set and return iterator to the next.
417417 livein_iterator removeLiveIn (livein_iterator I);
418418
419+ class liveout_iterator {
420+ public:
421+ using iterator_category = std::input_iterator_tag;
422+ using difference_type = std::ptrdiff_t ;
423+ using value_type = RegisterMaskPair;
424+ using pointer = const RegisterMaskPair *;
425+ using reference = const RegisterMaskPair &;
426+
427+ liveout_iterator (const MachineBasicBlock &MBB, MCPhysReg ExceptionPointer,
428+ MCPhysReg ExceptionSelector, bool End)
429+ : ExceptionPointer(ExceptionPointer),
430+ ExceptionSelector (ExceptionSelector), BlockI(MBB.succ_begin()),
431+ BlockEnd(MBB.succ_end()) {
432+ if (End)
433+ BlockI = BlockEnd;
434+ else if (BlockI != BlockEnd) {
435+ LiveRegI = (*BlockI)->livein_begin ();
436+ if (!advanceToValidPosition ())
437+ return ;
438+ if (LiveRegI->PhysReg == ExceptionPointer ||
439+ LiveRegI->PhysReg == ExceptionSelector)
440+ ++(*this );
441+ }
442+ }
443+
444+ liveout_iterator &operator ++() {
445+ do {
446+ ++LiveRegI;
447+ if (!advanceToValidPosition ())
448+ return *this ;
449+ } while ((*BlockI)->isEHPad () &&
450+ (LiveRegI->PhysReg == ExceptionPointer ||
451+ LiveRegI->PhysReg == ExceptionSelector));
452+ return *this ;
453+ }
454+
455+ liveout_iterator operator ++(int ) {
456+ liveout_iterator Tmp = *this ;
457+ ++(*this );
458+ return Tmp;
459+ }
460+
461+ reference operator *() const {
462+ return *LiveRegI;
463+ }
464+
465+ pointer operator ->() const {
466+ return &*LiveRegI;
467+ }
468+
469+ bool operator ==(const liveout_iterator &RHS) const {
470+ if (BlockI != BlockEnd)
471+ return BlockI == RHS.BlockI && LiveRegI == RHS.LiveRegI ;
472+ return RHS.BlockI == BlockEnd;
473+ }
474+
475+ bool operator !=(const liveout_iterator &RHS) const {
476+ return !(*this == RHS);
477+ }
478+ private:
479+ bool advanceToValidPosition () {
480+ if (LiveRegI != (*BlockI)->livein_end ())
481+ return true ;
482+
483+ do {
484+ ++BlockI;
485+ } while (BlockI != BlockEnd && (*BlockI)->livein_empty ());
486+ if (BlockI == BlockEnd)
487+ return false ;
488+
489+ LiveRegI = (*BlockI)->livein_begin ();
490+ return true ;
491+ }
492+
493+ MCPhysReg ExceptionPointer, ExceptionSelector;
494+ const_succ_iterator BlockI;
495+ const_succ_iterator BlockEnd;
496+ livein_iterator LiveRegI;
497+ };
498+
499+ // / Iterator scanning successor basic blocks' liveins to determine the
500+ // / registers potentially live at the end of this block. There may be
501+ // / duplicates or overlapping registers in the list returned.
502+ liveout_iterator liveout_begin () const ;
503+ liveout_iterator liveout_end () const {
504+ return liveout_iterator (*this , 0 , 0 , true );
505+ }
506+ iterator_range<liveout_iterator> liveouts () const {
507+ return make_range (liveout_begin (), liveout_end ());
508+ }
509+
419510 // / Get the clobber mask for the start of this basic block. Funclets use this
420511 // / to prevent register allocation across funclet transitions.
421512 const uint32_t *getBeginClobberMask (const TargetRegisterInfo *TRI) const ;
0 commit comments