From 1f152baef8d052825385d3577b789fc03a79e72b Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 27 Feb 2012 18:09:36 +0000 Subject: [PATCH] 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. llvm-svn: 151529 --- llvm/include/llvm/CodeGen/MachineBasicBlock.h | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h index 576ce944469e..1138f92bf865 100644 --- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/llvm/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 -- GitLab