diff options
author | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-02-17 10:00:11 +0300 |
---|---|---|
committer | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-02-17 10:00:11 +0300 |
commit | 238dcee0609b29afef350ad1ec1f11a5f77f3ddb (patch) | |
tree | 60c8fceccb240051282831ee7c022d5d13176497 /contrib/libs/llvm12/include | |
parent | 6556439410107545365e31cda892ba81dbeb5b2e (diff) | |
download | ydb-238dcee0609b29afef350ad1ec1f11a5f77f3ddb.tar.gz |
intermediate changes
ref:9d0ab25c9bb4423427bb19b3ca25ded76535a4df
Diffstat (limited to 'contrib/libs/llvm12/include')
-rw-r--r-- | contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h index fb36c30de81..b77035f5e93 100644 --- a/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h +++ b/contrib/libs/llvm12/include/llvm/CodeGen/MachineBasicBlock.h @@ -417,6 +417,97 @@ public: /// Remove entry from the livein set and return iterator to the next. livein_iterator removeLiveIn(livein_iterator I); + class liveout_iterator { + public: + using iterator_category = std::input_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = RegisterMaskPair; + using pointer = const RegisterMaskPair *; + using reference = const RegisterMaskPair &; + + liveout_iterator(const MachineBasicBlock &MBB, MCPhysReg ExceptionPointer, + MCPhysReg ExceptionSelector, bool End) + : ExceptionPointer(ExceptionPointer), + ExceptionSelector(ExceptionSelector), BlockI(MBB.succ_begin()), + BlockEnd(MBB.succ_end()) { + if (End) + BlockI = BlockEnd; + else if (BlockI != BlockEnd) { + LiveRegI = (*BlockI)->livein_begin(); + if (!advanceToValidPosition()) + return; + if (LiveRegI->PhysReg == ExceptionPointer || + LiveRegI->PhysReg == ExceptionSelector) + ++(*this); + } + } + + liveout_iterator &operator++() { + do { + ++LiveRegI; + if (!advanceToValidPosition()) + return *this; + } while ((*BlockI)->isEHPad() && + (LiveRegI->PhysReg == ExceptionPointer || + LiveRegI->PhysReg == ExceptionSelector)); + return *this; + } + + liveout_iterator operator++(int) { + liveout_iterator Tmp = *this; + ++(*this); + return Tmp; + } + + reference operator*() const { + return *LiveRegI; + } + + pointer operator->() const { + return &*LiveRegI; + } + + bool operator==(const liveout_iterator &RHS) const { + if (BlockI != BlockEnd) + return BlockI == RHS.BlockI && LiveRegI == RHS.LiveRegI; + return RHS.BlockI == BlockEnd; + } + + bool operator!=(const liveout_iterator &RHS) const { + return !(*this == RHS); + } + private: + bool advanceToValidPosition() { + if (LiveRegI != (*BlockI)->livein_end()) + return true; + + do { + ++BlockI; + } while (BlockI != BlockEnd && (*BlockI)->livein_empty()); + if (BlockI == BlockEnd) + return false; + + LiveRegI = (*BlockI)->livein_begin(); + return true; + } + + MCPhysReg ExceptionPointer, ExceptionSelector; + const_succ_iterator BlockI; + const_succ_iterator BlockEnd; + livein_iterator LiveRegI; + }; + + /// Iterator scanning successor basic blocks' liveins to determine the + /// registers potentially live at the end of this block. There may be + /// duplicates or overlapping registers in the list returned. + liveout_iterator liveout_begin() const; + liveout_iterator liveout_end() const { + return liveout_iterator(*this, 0, 0, true); + } + iterator_range<liveout_iterator> liveouts() const { + return make_range(liveout_begin(), liveout_end()); + } + /// Get the clobber mask for the start of this basic block. Funclets use this /// to prevent register allocation across funclet transitions. const uint32_t *getBeginClobberMask(const TargetRegisterInfo *TRI) const; |