]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- CodeGen/MachineInstBundle.h - MI bundle utilities -------*- C++ -*-===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file provide utility functions to manipulate machine instruction | |
11 | // bundles. | |
12 | // | |
13 | //===----------------------------------------------------------------------===// | |
14 | ||
15 | #ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLE_H | |
16 | #define LLVM_CODEGEN_MACHINEINSTRBUNDLE_H | |
17 | ||
18 | #include "llvm/CodeGen/MachineBasicBlock.h" | |
19 | ||
20 | namespace llvm { | |
21 | ||
22 | /// finalizeBundle - Finalize a machine instruction bundle which includes | |
23 | /// a sequence of instructions starting from FirstMI to LastMI (exclusive). | |
24 | /// This routine adds a BUNDLE instruction to represent the bundle, it adds | |
25 | /// IsInternalRead markers to MachineOperands which are defined inside the | |
26 | /// bundle, and it copies externally visible defs and uses to the BUNDLE | |
27 | /// instruction. | |
28 | void finalizeBundle(MachineBasicBlock &MBB, | |
29 | MachineBasicBlock::instr_iterator FirstMI, | |
30 | MachineBasicBlock::instr_iterator LastMI); | |
31 | ||
32 | /// finalizeBundle - Same functionality as the previous finalizeBundle except | |
33 | /// the last instruction in the bundle is not provided as an input. This is | |
34 | /// used in cases where bundles are pre-determined by marking instructions | |
35 | /// with 'InsideBundle' marker. It returns the MBB instruction iterator that | |
36 | /// points to the end of the bundle. | |
37 | MachineBasicBlock::instr_iterator finalizeBundle(MachineBasicBlock &MBB, | |
38 | MachineBasicBlock::instr_iterator FirstMI); | |
39 | ||
40 | /// finalizeBundles - Finalize instruction bundles in the specified | |
41 | /// MachineFunction. Return true if any bundles are finalized. | |
42 | bool finalizeBundles(MachineFunction &MF); | |
43 | ||
44 | /// getBundleStart - Returns the first instruction in the bundle containing MI. | |
45 | /// | |
46 | inline MachineInstr *getBundleStart(MachineInstr *MI) { | |
47 | MachineBasicBlock::instr_iterator I = MI; | |
970d7e83 | 48 | while (I->isBundledWithPred()) |
223e47cc LB |
49 | --I; |
50 | return I; | |
51 | } | |
52 | ||
53 | inline const MachineInstr *getBundleStart(const MachineInstr *MI) { | |
54 | MachineBasicBlock::const_instr_iterator I = MI; | |
970d7e83 | 55 | while (I->isBundledWithPred()) |
223e47cc LB |
56 | --I; |
57 | return I; | |
58 | } | |
59 | ||
970d7e83 LB |
60 | /// Return an iterator pointing beyond the bundle containing MI. |
61 | inline MachineBasicBlock::instr_iterator | |
62 | getBundleEnd(MachineInstr *MI) { | |
63 | MachineBasicBlock::instr_iterator I = MI; | |
64 | while (I->isBundledWithSucc()) | |
65 | ++I; | |
66 | return ++I; | |
67 | } | |
68 | ||
69 | /// Return an iterator pointing beyond the bundle containing MI. | |
70 | inline MachineBasicBlock::const_instr_iterator | |
71 | getBundleEnd(const MachineInstr *MI) { | |
72 | MachineBasicBlock::const_instr_iterator I = MI; | |
73 | while (I->isBundledWithSucc()) | |
74 | ++I; | |
75 | return ++I; | |
76 | } | |
77 | ||
223e47cc LB |
78 | //===----------------------------------------------------------------------===// |
79 | // MachineOperand iterator | |
80 | // | |
81 | ||
82 | /// MachineOperandIteratorBase - Iterator that can visit all operands on a | |
83 | /// MachineInstr, or all operands on a bundle of MachineInstrs. This class is | |
84 | /// not intended to be used directly, use one of the sub-classes instead. | |
85 | /// | |
86 | /// Intended use: | |
87 | /// | |
88 | /// for (MIBundleOperands MIO(MI); MIO.isValid(); ++MIO) { | |
89 | /// if (!MIO->isReg()) | |
90 | /// continue; | |
91 | /// ... | |
92 | /// } | |
93 | /// | |
94 | class MachineOperandIteratorBase { | |
95 | MachineBasicBlock::instr_iterator InstrI, InstrE; | |
96 | MachineInstr::mop_iterator OpI, OpE; | |
97 | ||
98 | // If the operands on InstrI are exhausted, advance InstrI to the next | |
99 | // bundled instruction with operands. | |
100 | void advance() { | |
101 | while (OpI == OpE) { | |
102 | // Don't advance off the basic block, or into a new bundle. | |
103 | if (++InstrI == InstrE || !InstrI->isInsideBundle()) | |
104 | break; | |
105 | OpI = InstrI->operands_begin(); | |
106 | OpE = InstrI->operands_end(); | |
107 | } | |
108 | } | |
109 | ||
110 | protected: | |
111 | /// MachineOperandIteratorBase - Create an iterator that visits all operands | |
112 | /// on MI, or all operands on every instruction in the bundle containing MI. | |
113 | /// | |
114 | /// @param MI The instruction to examine. | |
115 | /// @param WholeBundle When true, visit all operands on the entire bundle. | |
116 | /// | |
117 | explicit MachineOperandIteratorBase(MachineInstr *MI, bool WholeBundle) { | |
118 | if (WholeBundle) { | |
119 | InstrI = getBundleStart(MI); | |
120 | InstrE = MI->getParent()->instr_end(); | |
121 | } else { | |
122 | InstrI = InstrE = MI; | |
123 | ++InstrE; | |
124 | } | |
125 | OpI = InstrI->operands_begin(); | |
126 | OpE = InstrI->operands_end(); | |
127 | if (WholeBundle) | |
128 | advance(); | |
129 | } | |
130 | ||
131 | MachineOperand &deref() const { return *OpI; } | |
132 | ||
133 | public: | |
134 | /// isValid - Returns true until all the operands have been visited. | |
135 | bool isValid() const { return OpI != OpE; } | |
136 | ||
137 | /// Preincrement. Move to the next operand. | |
138 | void operator++() { | |
139 | assert(isValid() && "Cannot advance MIOperands beyond the last operand"); | |
140 | ++OpI; | |
141 | advance(); | |
142 | } | |
143 | ||
144 | /// getOperandNo - Returns the number of the current operand relative to its | |
145 | /// instruction. | |
146 | /// | |
147 | unsigned getOperandNo() const { | |
148 | return OpI - InstrI->operands_begin(); | |
149 | } | |
150 | ||
151 | /// VirtRegInfo - Information about a virtual register used by a set of operands. | |
152 | /// | |
153 | struct VirtRegInfo { | |
154 | /// Reads - One of the operands read the virtual register. This does not | |
155 | /// include <undef> or <internal> use operands, see MO::readsReg(). | |
156 | bool Reads; | |
157 | ||
158 | /// Writes - One of the operands writes the virtual register. | |
159 | bool Writes; | |
160 | ||
161 | /// Tied - Uses and defs must use the same register. This can be because of | |
162 | /// a two-address constraint, or there may be a partial redefinition of a | |
163 | /// sub-register. | |
164 | bool Tied; | |
165 | }; | |
166 | ||
167 | /// PhysRegInfo - Information about a physical register used by a set of | |
168 | /// operands. | |
169 | struct PhysRegInfo { | |
970d7e83 | 170 | /// Clobbers - Reg or an overlapping register is defined, or a regmask |
223e47cc LB |
171 | /// clobbers Reg. |
172 | bool Clobbers; | |
173 | ||
174 | /// Defines - Reg or a super-register is defined. | |
175 | bool Defines; | |
176 | ||
223e47cc LB |
177 | /// Reads - Read or a super-register is read. |
178 | bool Reads; | |
179 | ||
180 | /// ReadsOverlap - Reg or an overlapping register is read. | |
181 | bool ReadsOverlap; | |
182 | ||
183 | /// DefinesDead - All defs of a Reg or a super-register are dead. | |
184 | bool DefinesDead; | |
185 | ||
186 | /// There is a kill of Reg or a super-register. | |
187 | bool Kills; | |
188 | }; | |
189 | ||
190 | /// analyzeVirtReg - Analyze how the current instruction or bundle uses a | |
191 | /// virtual register. This function should not be called after operator++(), | |
192 | /// it expects a fresh iterator. | |
193 | /// | |
194 | /// @param Reg The virtual register to analyze. | |
195 | /// @param Ops When set, this vector will receive an (MI, OpNum) entry for | |
196 | /// each operand referring to Reg. | |
197 | /// @returns A filled-in RegInfo struct. | |
198 | VirtRegInfo analyzeVirtReg(unsigned Reg, | |
199 | SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops = 0); | |
200 | ||
201 | /// analyzePhysReg - Analyze how the current instruction or bundle uses a | |
202 | /// physical register. This function should not be called after operator++(), | |
203 | /// it expects a fresh iterator. | |
204 | /// | |
205 | /// @param Reg The physical register to analyze. | |
206 | /// @returns A filled-in PhysRegInfo struct. | |
207 | PhysRegInfo analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI); | |
208 | }; | |
209 | ||
210 | /// MIOperands - Iterate over operands of a single instruction. | |
211 | /// | |
212 | class MIOperands : public MachineOperandIteratorBase { | |
213 | public: | |
214 | MIOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, false) {} | |
215 | MachineOperand &operator* () const { return deref(); } | |
216 | MachineOperand *operator->() const { return &deref(); } | |
217 | }; | |
218 | ||
219 | /// ConstMIOperands - Iterate over operands of a single const instruction. | |
220 | /// | |
221 | class ConstMIOperands : public MachineOperandIteratorBase { | |
222 | public: | |
223 | ConstMIOperands(const MachineInstr *MI) | |
224 | : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), false) {} | |
225 | const MachineOperand &operator* () const { return deref(); } | |
226 | const MachineOperand *operator->() const { return &deref(); } | |
227 | }; | |
228 | ||
229 | /// MIBundleOperands - Iterate over all operands in a bundle of machine | |
230 | /// instructions. | |
231 | /// | |
232 | class MIBundleOperands : public MachineOperandIteratorBase { | |
233 | public: | |
234 | MIBundleOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, true) {} | |
235 | MachineOperand &operator* () const { return deref(); } | |
236 | MachineOperand *operator->() const { return &deref(); } | |
237 | }; | |
238 | ||
239 | /// ConstMIBundleOperands - Iterate over all operands in a const bundle of | |
240 | /// machine instructions. | |
241 | /// | |
242 | class ConstMIBundleOperands : public MachineOperandIteratorBase { | |
243 | public: | |
244 | ConstMIBundleOperands(const MachineInstr *MI) | |
245 | : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), true) {} | |
246 | const MachineOperand &operator* () const { return deref(); } | |
247 | const MachineOperand *operator->() const { return &deref(); } | |
248 | }; | |
249 | ||
250 | } // End llvm namespace | |
251 | ||
252 | #endif |