diff options
author | Owen Anderson <resistor@mac.com> | 2014-03-13 23:12:04 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2014-03-13 23:12:04 +0000 |
commit | bf63022492e54c8abe7c8d8c8448661342294f46 (patch) | |
tree | afd0498b2b0da324ad89111ea83faf705400dec9 /include | |
parent | d3fc1be4f634df136220ffc6e2ec381ae3f55c31 (diff) | |
download | llvm-bf63022492e54c8abe7c8d8c8448661342294f46.tar.gz llvm-bf63022492e54c8abe7c8d8c8448661342294f46.tar.bz2 llvm-bf63022492e54c8abe7c8d8c8448661342294f46.tar.xz |
Phase 2 of the great MachineRegisterInfo cleanup. This time, we're changing
operator* on the by-operand iterators to return a MachineOperand& rather than
a MachineInstr&. At this point they almost behave like normal iterators!
Again, this requires making some existing loops more verbose, but should pave
the way for the big range-based for-loop cleanups in the future.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203865 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/CodeGen/MachineRegisterInfo.h | 128 |
1 files changed, 113 insertions, 15 deletions
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 7167595ec7..dd9e2803bd 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -203,10 +203,17 @@ public: template<bool Uses, bool Defs, bool SkipDebug, bool ByOperand, bool ByInstr, bool ByBundle> class defusechain_iterator; + template<bool Uses, bool Defs, bool SkipDebug, + bool ByOperand, bool ByInstr, bool ByBundle> + class defusechain_instr_iterator; // Make it a friend so it can access getNextOperandForReg(). template<bool, bool, bool, bool, bool, bool> friend class defusechain_iterator; + template<bool, bool, bool, bool, bool, bool> + friend class defusechain_instr_iterator; + + /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified /// register. @@ -219,7 +226,7 @@ public: /// reg_instr_iterator/reg_instr_begin/reg_instr_end - Walk all defs and uses /// of the specified register, stepping by MachineInstr. - typedef defusechain_iterator<true,true,false,false,true,false> + typedef defusechain_instr_iterator<true,true,false,false,true,false> reg_instr_iterator; reg_instr_iterator reg_instr_begin(unsigned RegNo) const { return reg_instr_iterator(getRegUseDefListHead(RegNo)); @@ -228,7 +235,7 @@ public: /// reg_bundle_iterator/reg_bundle_begin/reg_bundle_end - Walk all defs and uses /// of the specified register, stepping by bundle. - typedef defusechain_iterator<true,true,false,false,false,true> + typedef defusechain_instr_iterator<true,true,false,false,false,true> reg_bundle_iterator; reg_bundle_iterator reg_bundle_begin(unsigned RegNo) const { return reg_bundle_iterator(getRegUseDefListHead(RegNo)); @@ -251,7 +258,7 @@ public: /// reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk /// all defs and uses of the specified register, stepping by MachineInstr, /// skipping those marked as Debug. - typedef defusechain_iterator<true,true,true,false,true,false> + typedef defusechain_instr_iterator<true,true,true,false,true,false> reg_instr_nodbg_iterator; reg_instr_nodbg_iterator reg_instr_nodbg_begin(unsigned RegNo) const { return reg_instr_nodbg_iterator(getRegUseDefListHead(RegNo)); @@ -263,7 +270,7 @@ public: /// reg_bundle_nodbg_iterator/reg_bundle_nodbg_begin/reg_bundle_nodbg_end - Walk /// all defs and uses of the specified register, stepping by bundle, /// skipping those marked as Debug. - typedef defusechain_iterator<true,true,true,false,false,true> + typedef defusechain_instr_iterator<true,true,true,false,false,true> reg_bundle_nodbg_iterator; reg_bundle_nodbg_iterator reg_bundle_nodbg_begin(unsigned RegNo) const { return reg_bundle_nodbg_iterator(getRegUseDefListHead(RegNo)); @@ -288,7 +295,7 @@ public: /// def_instr_iterator/def_instr_begin/def_instr_end - Walk all defs of the /// specified register, stepping by MachineInst. - typedef defusechain_iterator<false,true,false,false,true,false> + typedef defusechain_instr_iterator<false,true,false,false,true,false> def_instr_iterator; def_instr_iterator def_instr_begin(unsigned RegNo) const { return def_instr_iterator(getRegUseDefListHead(RegNo)); @@ -297,7 +304,7 @@ public: /// def_bundle_iterator/def_bundle_begin/def_bundle_end - Walk all defs of the /// specified register, stepping by bundle. - typedef defusechain_iterator<false,true,false,false,false,true> + typedef defusechain_instr_iterator<false,true,false,false,false,true> def_bundle_iterator; def_bundle_iterator def_bundle_begin(unsigned RegNo) const { return def_bundle_iterator(getRegUseDefListHead(RegNo)); @@ -327,7 +334,7 @@ public: /// use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the /// specified register, stepping by MachineInstr. - typedef defusechain_iterator<true,false,false,false,true,false> + typedef defusechain_instr_iterator<true,false,false,false,true,false> use_instr_iterator; use_instr_iterator use_instr_begin(unsigned RegNo) const { return use_instr_iterator(getRegUseDefListHead(RegNo)); @@ -336,7 +343,7 @@ public: /// use_bundle_iterator/use_bundle_begin/use_bundle_end - Walk all uses of the /// specified register, stepping by bundle. - typedef defusechain_iterator<true,false,false,false,false,true> + typedef defusechain_instr_iterator<true,false,false,false,false,true> use_bundle_iterator; use_bundle_iterator use_bundle_begin(unsigned RegNo) const { return use_bundle_iterator(getRegUseDefListHead(RegNo)); @@ -368,7 +375,7 @@ public: /// use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk /// all uses of the specified register, stepping by MachineInstr, skipping /// those marked as Debug. - typedef defusechain_iterator<true,false,true,false,true,false> + typedef defusechain_instr_iterator<true,false,true,false,true,false> use_instr_nodbg_iterator; use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const { return use_instr_nodbg_iterator(getRegUseDefListHead(RegNo)); @@ -380,7 +387,7 @@ public: /// use_bundle_nodbg_iterator/use_bundle_nodbg_begin/use_bundle_nodbg_end - Walk /// all uses of the specified register, stepping by bundle, skipping /// those marked as Debug. - typedef defusechain_iterator<true,false,true,false,false,true> + typedef defusechain_instr_iterator<true,false,true,false,false,true> use_bundle_nodbg_iterator; use_bundle_nodbg_iterator use_bundle_nodbg_begin(unsigned RegNo) const { return use_bundle_nodbg_iterator(getRegUseDefListHead(RegNo)); @@ -743,11 +750,6 @@ public: defusechain_iterator tmp = *this; ++*this; return tmp; } - MachineOperand &getOperand() const { - assert(Op && "Cannot dereference end iterator!"); - return *Op; - } - /// getOperandNo - Return the operand # of this MachineOperand in its /// MachineInstr. unsigned getOperandNo() const { @@ -756,6 +758,102 @@ public: } // Retrieve a reference to the current operand. + MachineOperand &operator*() const { + assert(Op && "Cannot dereference end iterator!"); + return *Op; + } + + MachineOperand *operator->() const { + assert(Op && "Cannot dereference end iterator!"); + return Op; + } + }; + + /// defusechain_iterator - This class provides iterator support for machine + /// operands in the function that use or define a specific register. If + /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it + /// returns defs. If neither are true then you are silly and it always + /// returns end(). If SkipDebug is true it skips uses marked Debug + /// when incrementing. + template<bool ReturnUses, bool ReturnDefs, bool SkipDebug, + bool ByOperand, bool ByInstr, bool ByBundle> + class defusechain_instr_iterator + : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> { + MachineOperand *Op; + explicit defusechain_instr_iterator(MachineOperand *op) : Op(op) { + // If the first node isn't one we're interested in, advance to one that + // we are interested in. + if (op) { + if ((!ReturnUses && op->isUse()) || + (!ReturnDefs && op->isDef()) || + (SkipDebug && op->isDebug())) + advance(); + } + } + friend class MachineRegisterInfo; + + void advance() { + assert(Op && "Cannot increment end iterator!"); + Op = getNextOperandForReg(Op); + + // All defs come before the uses, so stop def_iterator early. + if (!ReturnUses) { + if (Op) { + if (Op->isUse()) + Op = 0; + else + assert(!Op->isDebug() && "Can't have debug defs"); + } + } else { + // If this is an operand we don't care about, skip it. + while (Op && ((!ReturnDefs && Op->isDef()) || + (SkipDebug && Op->isDebug()))) + Op = getNextOperandForReg(Op); + } + } + public: + typedef std::iterator<std::forward_iterator_tag, + MachineInstr, ptrdiff_t>::reference reference; + typedef std::iterator<std::forward_iterator_tag, + MachineInstr, ptrdiff_t>::pointer pointer; + + defusechain_instr_iterator(const defusechain_instr_iterator &I) : Op(I.Op){} + defusechain_instr_iterator() : Op(0) {} + + bool operator==(const defusechain_instr_iterator &x) const { + return Op == x.Op; + } + bool operator!=(const defusechain_instr_iterator &x) const { + return !operator==(x); + } + + /// atEnd - return true if this iterator is equal to reg_end() on the value. + bool atEnd() const { return Op == 0; } + + // Iterator traversal: forward iteration only + defusechain_instr_iterator &operator++() { // Preincrement + assert(Op && "Cannot increment end iterator!"); + if (ByOperand) + advance(); + else if (ByInstr) { + MachineInstr *P = Op->getParent(); + do { + advance(); + } while (Op && Op->getParent() == P); + } else if (ByBundle) { + MachineInstr *P = getBundleStart(Op->getParent()); + do { + advance(); + } while (Op && getBundleStart(Op->getParent()) == P); + } + + return *this; + } + defusechain_instr_iterator operator++(int) { // Postincrement + defusechain_instr_iterator tmp = *this; ++*this; return tmp; + } + + // Retrieve a reference to the current operand. MachineInstr &operator*() const { assert(Op && "Cannot dereference end iterator!"); return *Op->getParent(); |