From: Jakob Stoklund Olesen Date: Mon, 27 Feb 2012 18:09:36 +0000 (+0000) Subject: Add a MachineOperand iterator class. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=62c4d9799fa592ae4073d633802013d3aaf08d71;p=oota-llvm.git 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 --- diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 576ce944469..1138f92bf86 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -699,6 +699,73 @@ template <> struct GraphTraits > { } }; +//===----------------------------------------------------------------------===// +// 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