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