[llvm] 1b81964 - [MIBundle] Turn MachineOperandIteratorBase into a forward iterator.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 5 01:09:00 PST 2019
Author: Florian Hahn
Date: 2019-12-05T09:06:22Z
New Revision: 1b81964586b4f0fde94f4d238be659bedd85b627
URL: https://github.com/llvm/llvm-project/commit/1b81964586b4f0fde94f4d238be659bedd85b627
DIFF: https://github.com/llvm/llvm-project/commit/1b81964586b4f0fde94f4d238be659bedd85b627.diff
LOG: [MIBundle] Turn MachineOperandIteratorBase into a forward iterator.
This patch turns MachineOperandIteratorBase into a regular forward
iterator, which can be used with iterator_range.
It also adds mi_bundle_ops and const_mi_bundle_ops that return iterator
ranges over all operands in a bundle and updates a use of the old
iterator.
Reviewers: evandro, t.p.northover, paquette, MatzeB, arsenm
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D70561
Added:
Modified:
llvm/include/llvm/CodeGen/MachineInstrBundle.h
llvm/lib/CodeGen/LiveIntervals.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/MachineInstrBundle.h b/llvm/include/llvm/CodeGen/MachineInstrBundle.h
index a54f2795d911..517f03e60933 100644
--- a/llvm/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/llvm/include/llvm/CodeGen/MachineInstrBundle.h
@@ -90,7 +90,10 @@ inline MachineBasicBlock::const_instr_iterator getBundleEnd(
/// ...
/// }
///
-class MIBundleOperandIteratorBase {
+template <typename ValueT>
+class MIBundleOperandIteratorBase
+ : public iterator_facade_base<MIBundleOperandIteratorBase<ValueT>,
+ std::forward_iterator_tag, ValueT> {
MachineBasicBlock::instr_iterator InstrI, InstrE;
MachineInstr::mop_iterator OpI, OpE;
@@ -99,8 +102,10 @@ class MIBundleOperandIteratorBase {
void advance() {
while (OpI == OpE) {
// Don't advance off the basic block, or into a new bundle.
- if (++InstrI == InstrE || !InstrI->isInsideBundle())
+ if (++InstrI == InstrE || !InstrI->isInsideBundle()) {
+ InstrI = InstrE;
break;
+ }
OpI = InstrI->operands_begin();
OpE = InstrI->operands_end();
}
@@ -120,7 +125,11 @@ class MIBundleOperandIteratorBase {
advance();
}
- MachineOperand &deref() const { return *OpI; }
+ /// Constructor for an iterator past the last iteration: both instruction
+ /// iterators point to the end of the BB and OpI == OpE.
+ explicit MIBundleOperandIteratorBase(MachineBasicBlock::instr_iterator InstrE,
+ MachineInstr::mop_iterator OpE)
+ : InstrI(InstrE), InstrE(InstrE), OpI(OpE), OpE(OpE) {}
public:
/// isValid - Returns true until all the operands have been visited.
@@ -133,6 +142,16 @@ class MIBundleOperandIteratorBase {
advance();
}
+ ValueT &operator*() const { return *OpI; }
+ ValueT *operator->() const { return &*OpI; }
+
+ bool operator==(const MIBundleOperandIteratorBase &Arg) const {
+ // Iterators are equal, if InstrI matches and either OpIs match or OpI ==
+ // OpE match for both. The second condition allows us to construct an 'end'
+ // iterator, without finding the last instruction in a bundle up-front.
+ return InstrI == Arg.InstrI &&
+ (OpI == Arg.OpI || (OpI == OpE && Arg.OpI == Arg.OpE));
+ }
/// getOperandNo - Returns the number of the current operand relative to its
/// instruction.
///
@@ -144,24 +163,55 @@ class MIBundleOperandIteratorBase {
/// MIBundleOperands - Iterate over all operands in a bundle of machine
/// instructions.
///
-class MIBundleOperands : public MIBundleOperandIteratorBase {
+class MIBundleOperands : public MIBundleOperandIteratorBase<MachineOperand> {
+ /// Constructor for an iterator past the last iteration.
+ MIBundleOperands(MachineBasicBlock::instr_iterator InstrE,
+ MachineInstr::mop_iterator OpE)
+ : MIBundleOperandIteratorBase(InstrE, OpE) {}
+
public:
MIBundleOperands(MachineInstr &MI) : MIBundleOperandIteratorBase(MI) {}
- MachineOperand &operator* () const { return deref(); }
- MachineOperand *operator->() const { return &deref(); }
+
+ /// Returns an iterator past the last iteration.
+ static MIBundleOperands end(const MachineBasicBlock &MBB) {
+ return {const_cast<MachineBasicBlock &>(MBB).instr_end(),
+ const_cast<MachineBasicBlock &>(MBB).instr_begin()->operands_end()};
+ }
};
/// ConstMIBundleOperands - Iterate over all operands in a const bundle of
/// machine instructions.
///
-class ConstMIBundleOperands : public MIBundleOperandIteratorBase {
+class ConstMIBundleOperands
+ : public MIBundleOperandIteratorBase<const MachineOperand> {
+
+ /// Constructor for an iterator past the last iteration.
+ ConstMIBundleOperands(MachineBasicBlock::instr_iterator InstrE,
+ MachineInstr::mop_iterator OpE)
+ : MIBundleOperandIteratorBase(InstrE, OpE) {}
+
public:
ConstMIBundleOperands(const MachineInstr &MI)
: MIBundleOperandIteratorBase(const_cast<MachineInstr &>(MI)) {}
- const MachineOperand &operator* () const { return deref(); }
- const MachineOperand *operator->() const { return &deref(); }
+
+ /// Returns an iterator past the last iteration.
+ static ConstMIBundleOperands end(const MachineBasicBlock &MBB) {
+ return {const_cast<MachineBasicBlock &>(MBB).instr_end(),
+ const_cast<MachineBasicBlock &>(MBB).instr_begin()->operands_end()};
+ }
};
+inline iterator_range<ConstMIBundleOperands>
+const_mi_bundle_ops(const MachineInstr &MI) {
+ return make_range(ConstMIBundleOperands(MI),
+ ConstMIBundleOperands::end(*MI.getParent()));
+}
+
+inline iterator_range<MIBundleOperands> mi_bundle_ops(MachineInstr &MI) {
+ return make_range(MIBundleOperands(MI),
+ MIBundleOperands::end(*MI.getParent()));
+}
+
/// VirtRegInfo - Information about a virtual register used by a set of
/// operands.
///
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index 600e7880c702..9c80282bc59e 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -1072,9 +1072,9 @@ class LiveIntervals::HMEditor {
// Kill flags shouldn't be used while live intervals exist, they will be
// reinserted by VirtRegRewriter.
if (MachineInstr *KillMI = LIS.getInstructionFromIndex(OldIdxIn->end))
- for (MIBundleOperands MO(*KillMI); MO.isValid(); ++MO)
- if (MO->isReg() && MO->isUse())
- MO->setIsKill(false);
+ for (MachineOperand &MOP : mi_bundle_ops(*KillMI))
+ if (MOP.isReg() && MOP.isUse())
+ MOP.setIsKill(false);
// Is there a def before NewIdx which is not OldIdx?
LiveRange::iterator Next = std::next(OldIdxIn);
More information about the llvm-commits
mailing list