1234285Sdim//===-- CodeGen/MachineInstBundle.h - MI bundle utilities -------*- C++ -*-===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim//
10234285Sdim// This file provide utility functions to manipulate machine instruction
11234285Sdim// bundles.
12234285Sdim//
13234285Sdim//===----------------------------------------------------------------------===//
14234285Sdim
15234285Sdim#ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
16234285Sdim#define LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
17234285Sdim
18234285Sdim#include "llvm/CodeGen/MachineBasicBlock.h"
19234285Sdim
20234285Sdimnamespace llvm {
21234285Sdim
22234285Sdim/// finalizeBundle - Finalize a machine instruction bundle which includes
23234285Sdim/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
24234285Sdim/// This routine adds a BUNDLE instruction to represent the bundle, it adds
25234285Sdim/// IsInternalRead markers to MachineOperands which are defined inside the
26234285Sdim/// bundle, and it copies externally visible defs and uses to the BUNDLE
27234285Sdim/// instruction.
28234285Sdimvoid finalizeBundle(MachineBasicBlock &MBB,
29234285Sdim                    MachineBasicBlock::instr_iterator FirstMI,
30234285Sdim                    MachineBasicBlock::instr_iterator LastMI);
31234285Sdim
32234285Sdim/// finalizeBundle - Same functionality as the previous finalizeBundle except
33234285Sdim/// the last instruction in the bundle is not provided as an input. This is
34234285Sdim/// used in cases where bundles are pre-determined by marking instructions
35234285Sdim/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
36234285Sdim/// points to the end of the bundle.
37234285SdimMachineBasicBlock::instr_iterator finalizeBundle(MachineBasicBlock &MBB,
38234285Sdim                    MachineBasicBlock::instr_iterator FirstMI);
39234285Sdim
40234285Sdim/// finalizeBundles - Finalize instruction bundles in the specified
41234285Sdim/// MachineFunction. Return true if any bundles are finalized.
42234285Sdimbool finalizeBundles(MachineFunction &MF);
43234285Sdim
44234285Sdim/// getBundleStart - Returns the first instruction in the bundle containing MI.
45234285Sdim///
46239462Sdiminline MachineInstr *getBundleStart(MachineInstr *MI) {
47234285Sdim  MachineBasicBlock::instr_iterator I = MI;
48249423Sdim  while (I->isBundledWithPred())
49234285Sdim    --I;
50234285Sdim  return I;
51234285Sdim}
52234285Sdim
53239462Sdiminline const MachineInstr *getBundleStart(const MachineInstr *MI) {
54234285Sdim  MachineBasicBlock::const_instr_iterator I = MI;
55249423Sdim  while (I->isBundledWithPred())
56234285Sdim    --I;
57234285Sdim  return I;
58234285Sdim}
59234285Sdim
60249423Sdim/// Return an iterator pointing beyond the bundle containing MI.
61249423Sdiminline MachineBasicBlock::instr_iterator
62249423SdimgetBundleEnd(MachineInstr *MI) {
63249423Sdim  MachineBasicBlock::instr_iterator I = MI;
64249423Sdim  while (I->isBundledWithSucc())
65249423Sdim    ++I;
66249423Sdim  return ++I;
67249423Sdim}
68249423Sdim
69249423Sdim/// Return an iterator pointing beyond the bundle containing MI.
70249423Sdiminline MachineBasicBlock::const_instr_iterator
71249423SdimgetBundleEnd(const MachineInstr *MI) {
72249423Sdim  MachineBasicBlock::const_instr_iterator I = MI;
73249423Sdim  while (I->isBundledWithSucc())
74249423Sdim    ++I;
75249423Sdim  return ++I;
76249423Sdim}
77249423Sdim
78234285Sdim//===----------------------------------------------------------------------===//
79234285Sdim// MachineOperand iterator
80234285Sdim//
81234285Sdim
82234285Sdim/// MachineOperandIteratorBase - Iterator that can visit all operands on a
83234285Sdim/// MachineInstr, or all operands on a bundle of MachineInstrs.  This class is
84234285Sdim/// not intended to be used directly, use one of the sub-classes instead.
85234285Sdim///
86234285Sdim/// Intended use:
87234285Sdim///
88234285Sdim///   for (MIBundleOperands MIO(MI); MIO.isValid(); ++MIO) {
89234285Sdim///     if (!MIO->isReg())
90234285Sdim///       continue;
91234285Sdim///     ...
92234285Sdim///   }
93234285Sdim///
94234285Sdimclass MachineOperandIteratorBase {
95234285Sdim  MachineBasicBlock::instr_iterator InstrI, InstrE;
96234285Sdim  MachineInstr::mop_iterator OpI, OpE;
97234285Sdim
98234285Sdim  // If the operands on InstrI are exhausted, advance InstrI to the next
99234285Sdim  // bundled instruction with operands.
100234285Sdim  void advance() {
101234285Sdim    while (OpI == OpE) {
102234285Sdim      // Don't advance off the basic block, or into a new bundle.
103234285Sdim      if (++InstrI == InstrE || !InstrI->isInsideBundle())
104234285Sdim        break;
105234285Sdim      OpI = InstrI->operands_begin();
106234285Sdim      OpE = InstrI->operands_end();
107234285Sdim    }
108234285Sdim  }
109234285Sdim
110234285Sdimprotected:
111234285Sdim  /// MachineOperandIteratorBase - Create an iterator that visits all operands
112234285Sdim  /// on MI, or all operands on every instruction in the bundle containing MI.
113234285Sdim  ///
114234285Sdim  /// @param MI The instruction to examine.
115234285Sdim  /// @param WholeBundle When true, visit all operands on the entire bundle.
116234285Sdim  ///
117234285Sdim  explicit MachineOperandIteratorBase(MachineInstr *MI, bool WholeBundle) {
118234285Sdim    if (WholeBundle) {
119234285Sdim      InstrI = getBundleStart(MI);
120234285Sdim      InstrE = MI->getParent()->instr_end();
121234285Sdim    } else {
122234285Sdim      InstrI = InstrE = MI;
123234285Sdim      ++InstrE;
124234285Sdim    }
125234285Sdim    OpI = InstrI->operands_begin();
126234285Sdim    OpE = InstrI->operands_end();
127234285Sdim    if (WholeBundle)
128234285Sdim      advance();
129234285Sdim  }
130234285Sdim
131234285Sdim  MachineOperand &deref() const { return *OpI; }
132234285Sdim
133234285Sdimpublic:
134234285Sdim  /// isValid - Returns true until all the operands have been visited.
135234285Sdim  bool isValid() const { return OpI != OpE; }
136234285Sdim
137234285Sdim  /// Preincrement.  Move to the next operand.
138234285Sdim  void operator++() {
139234285Sdim    assert(isValid() && "Cannot advance MIOperands beyond the last operand");
140234285Sdim    ++OpI;
141234285Sdim    advance();
142234285Sdim  }
143234285Sdim
144234285Sdim  /// getOperandNo - Returns the number of the current operand relative to its
145234285Sdim  /// instruction.
146234285Sdim  ///
147234285Sdim  unsigned getOperandNo() const {
148234285Sdim    return OpI - InstrI->operands_begin();
149234285Sdim  }
150234285Sdim
151243830Sdim  /// VirtRegInfo - Information about a virtual register used by a set of operands.
152234285Sdim  ///
153243830Sdim  struct VirtRegInfo {
154234285Sdim    /// Reads - One of the operands read the virtual register.  This does not
155234285Sdim    /// include <undef> or <internal> use operands, see MO::readsReg().
156234285Sdim    bool Reads;
157234285Sdim
158234285Sdim    /// Writes - One of the operands writes the virtual register.
159234285Sdim    bool Writes;
160234285Sdim
161234285Sdim    /// Tied - Uses and defs must use the same register. This can be because of
162234285Sdim    /// a two-address constraint, or there may be a partial redefinition of a
163234285Sdim    /// sub-register.
164234285Sdim    bool Tied;
165234285Sdim  };
166234285Sdim
167243830Sdim  /// PhysRegInfo - Information about a physical register used by a set of
168243830Sdim  /// operands.
169243830Sdim  struct PhysRegInfo {
170249423Sdim    /// Clobbers - Reg or an overlapping register is defined, or a regmask
171243830Sdim    /// clobbers Reg.
172243830Sdim    bool Clobbers;
173243830Sdim
174243830Sdim    /// Defines - Reg or a super-register is defined.
175243830Sdim    bool Defines;
176243830Sdim
177243830Sdim    /// Reads - Read or a super-register is read.
178243830Sdim    bool Reads;
179243830Sdim
180243830Sdim    /// ReadsOverlap - Reg or an overlapping register is read.
181243830Sdim    bool ReadsOverlap;
182243830Sdim
183243830Sdim    /// DefinesDead - All defs of a Reg or a super-register are dead.
184243830Sdim    bool DefinesDead;
185243830Sdim
186243830Sdim    /// There is a kill of Reg or a super-register.
187243830Sdim    bool Kills;
188243830Sdim  };
189243830Sdim
190234285Sdim  /// analyzeVirtReg - Analyze how the current instruction or bundle uses a
191234285Sdim  /// virtual register.  This function should not be called after operator++(),
192234285Sdim  /// it expects a fresh iterator.
193234285Sdim  ///
194234285Sdim  /// @param Reg The virtual register to analyze.
195234285Sdim  /// @param Ops When set, this vector will receive an (MI, OpNum) entry for
196234285Sdim  ///            each operand referring to Reg.
197234285Sdim  /// @returns A filled-in RegInfo struct.
198243830Sdim  VirtRegInfo analyzeVirtReg(unsigned Reg,
199234285Sdim                 SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops = 0);
200243830Sdim
201243830Sdim  /// analyzePhysReg - Analyze how the current instruction or bundle uses a
202243830Sdim  /// physical register.  This function should not be called after operator++(),
203243830Sdim  /// it expects a fresh iterator.
204243830Sdim  ///
205243830Sdim  /// @param Reg The physical register to analyze.
206243830Sdim  /// @returns A filled-in PhysRegInfo struct.
207243830Sdim  PhysRegInfo analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI);
208234285Sdim};
209234285Sdim
210234285Sdim/// MIOperands - Iterate over operands of a single instruction.
211234285Sdim///
212234285Sdimclass MIOperands : public MachineOperandIteratorBase {
213234285Sdimpublic:
214234285Sdim  MIOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, false) {}
215234285Sdim  MachineOperand &operator* () const { return deref(); }
216234285Sdim  MachineOperand *operator->() const { return &deref(); }
217234285Sdim};
218234285Sdim
219234285Sdim/// ConstMIOperands - Iterate over operands of a single const instruction.
220234285Sdim///
221234285Sdimclass ConstMIOperands : public MachineOperandIteratorBase {
222234285Sdimpublic:
223234285Sdim  ConstMIOperands(const MachineInstr *MI)
224234285Sdim    : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), false) {}
225234285Sdim  const MachineOperand &operator* () const { return deref(); }
226234285Sdim  const MachineOperand *operator->() const { return &deref(); }
227234285Sdim};
228234285Sdim
229234285Sdim/// MIBundleOperands - Iterate over all operands in a bundle of machine
230234285Sdim/// instructions.
231234285Sdim///
232234285Sdimclass MIBundleOperands : public MachineOperandIteratorBase {
233234285Sdimpublic:
234234285Sdim  MIBundleOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, true) {}
235234285Sdim  MachineOperand &operator* () const { return deref(); }
236234285Sdim  MachineOperand *operator->() const { return &deref(); }
237234285Sdim};
238234285Sdim
239234285Sdim/// ConstMIBundleOperands - Iterate over all operands in a const bundle of
240234285Sdim/// machine instructions.
241234285Sdim///
242234285Sdimclass ConstMIBundleOperands : public MachineOperandIteratorBase {
243234285Sdimpublic:
244234285Sdim  ConstMIBundleOperands(const MachineInstr *MI)
245234285Sdim    : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), true) {}
246234285Sdim  const MachineOperand &operator* () const { return deref(); }
247234285Sdim  const MachineOperand *operator->() const { return &deref(); }
248234285Sdim};
249234285Sdim
250234285Sdim} // End llvm namespace
251234285Sdim
252234285Sdim#endif
253