diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-02-27 18:09:36 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-02-27 18:09:36 +0000 |
commit | 62c4d9799fa592ae4073d633802013d3aaf08d71 (patch) | |
tree | 2845b1e937adfe795b12027e52a1cc0acc021e5e /include/llvm | |
parent | 3bbf2b6548340bb9218836f991da8c3a4718f6db (diff) | |
download | external_llvm-62c4d9799fa592ae4073d633802013d3aaf08d71.zip external_llvm-62c4d9799fa592ae4073d633802013d3aaf08d71.tar.gz external_llvm-62c4d9799fa592ae4073d633802013d3aaf08d71.tar.bz2 |
Add a MachineOperand iterator class.
The MIOperands iterator can visit operands on a single instruction, or
all operands in a bundle. This simplifies code like the register
allocator that treats bundles as a set of operands.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151529 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/CodeGen/MachineBasicBlock.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 576ce94..1138f92 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -699,6 +699,73 @@ template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > { } }; +//===----------------------------------------------------------------------===// +// MachineOperand iterator +// + +/// MachineOperands - Iterator that can visit all operands on a MachineInstr, +/// or all operands on a bundle of MachineInstrs. +/// +/// Intended use: +/// +/// for (MIOperands MIO(MI, true); MIO.isValid(); ++MIO) { +/// if (!MIO->isReg()) +/// continue; +/// ... +/// } +/// +class MIOperands { + MachineBasicBlock::instr_iterator InstrI, InstrE; + MachineInstr::mop_iterator OpI, OpE; + + // If the operands on InstrI are exhausted, advance InstrI to the next + // bundled instruction with operands. + void advance() { + while (OpI == OpE) { + // Don't advance off the basic block, or into a new bundle. + if (++InstrI == InstrE || !InstrI->isInsideBundle()) + break; + OpI = InstrI->operands_begin(); + OpE = InstrI->operands_end(); + } + } + +public: + /// MIOperands - Create an iterator that visits all operands on MI, or all + /// operands on every instruction in the bundle containing MI. + /// + /// @param MI The instruction to examine. + /// @param WholeBundle When true, visit all operands on the entire bundle. + /// + explicit MIOperands(MachineInstr *MI, bool WholeBundle = false) { + if (WholeBundle) { + InstrI = MI->getBundleStart(); + InstrE = MI->getParent()->instr_end(); + } else { + InstrI = InstrE = MI; + ++InstrE; + } + OpI = InstrI->operands_begin(); + OpE = InstrI->operands_end(); + if (WholeBundle) + advance(); + } + + /// isValid - Returns true until all the operands have been visited. + bool isValid() const { return OpI != OpE; } + + /// Preincrement. Move to the next operand. + MIOperands &operator++() { + assert(isValid() && "Cannot advance MIOperands beyond the last operand"); + ++OpI; + advance(); + return *this; + } + + MachineOperand &operator* () const { return *OpI; } + MachineOperand *operator->() const { return &*OpI; } +}; + } // End llvm namespace #endif |