MachineOperand.h revision d735b8019b0f297d7c14b55adcd887af24d8e602
1//===-- llvm/CodeGen/MachineOperand.h - MachineOperand class ----*- 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 contains the declaration of the MachineOperand class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
15#define LLVM_CODEGEN_MACHINEOPERAND_H
16
17#include "llvm/Support/DataTypes.h"
18#include <cassert>
19#include <iosfwd>
20
21namespace llvm {
22
23class ConstantFP;
24class MachineBasicBlock;
25class GlobalValue;
26class MachineInstr;
27class TargetMachine;
28class MachineRegisterInfo;
29class raw_ostream;
30
31/// MachineOperand class - Representation of each machine instruction operand.
32///
33class MachineOperand {
34public:
35  enum MachineOperandType {
36    MO_Register,                // Register operand.
37    MO_Immediate,               // Immediate Operand
38    MO_FPImmediate,
39    MO_MachineBasicBlock,       // MachineBasicBlock reference
40    MO_FrameIndex,              // Abstract Stack Frame Index
41    MO_ConstantPoolIndex,       // Address of indexed Constant in Constant Pool
42    MO_JumpTableIndex,          // Address of indexed Jump Table for switch
43    MO_ExternalSymbol,          // Name of external global symbol
44    MO_GlobalAddress            // Address of a global value
45  };
46
47private:
48  /// OpKind - Specify what kind of operand this is.  This discriminates the
49  /// union.
50  MachineOperandType OpKind : 8;
51
52  /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
53  /// operands.
54
55  /// IsDef - True if this is a def, false if this is a use of the register.
56  ///
57  bool IsDef : 1;
58
59  /// IsImp - True if this is an implicit def or use, false if it is explicit.
60  ///
61  bool IsImp : 1;
62
63  /// IsKill - True if this instruction is the last use of the register on this
64  /// path through the function.  This is only valid on uses of registers.
65  bool IsKill : 1;
66
67  /// IsDead - True if this register is never used by a subsequent instruction.
68  /// This is only valid on definitions of registers.
69  bool IsDead : 1;
70
71  /// IsEarlyClobber - True if this MO_Register 'def' operand is written to
72  /// by the MachineInstr before all input registers are read.  This is used to
73  /// model the GCC inline asm '&' constraint modifier.
74  bool IsEarlyClobber : 1;
75
76  /// SubReg - Subregister number, only valid for MO_Register.  A value of 0
77  /// indicates the MO_Register has no subReg.
78  unsigned char SubReg;
79
80  /// ParentMI - This is the instruction that this operand is embedded into.
81  /// This is valid for all operand types, when the operand is in an instr.
82  MachineInstr *ParentMI;
83
84  /// Contents union - This contains the payload for the various operand types.
85  union {
86    MachineBasicBlock *MBB;   // For MO_MachineBasicBlock.
87    const ConstantFP *CFP;    // For MO_FPImmediate.
88    int64_t ImmVal;           // For MO_Immediate.
89
90    struct {                  // For MO_Register.
91      unsigned RegNo;
92      MachineOperand **Prev;  // Access list for register.
93      MachineOperand *Next;
94    } Reg;
95
96    /// OffsetedInfo - This struct contains the offset and an object identifier.
97    /// this represent the object as with an optional offset from it.
98    struct {
99      union {
100        int Index;                // For MO_*Index - The index itself.
101        const char *SymbolName;   // For MO_ExternalSymbol.
102        GlobalValue *GV;          // For MO_GlobalAddress.
103      } Val;
104      int Offset;   // An offset from the object.
105    } OffsetedInfo;
106  } Contents;
107
108  explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {}
109public:
110  MachineOperand(const MachineOperand &M) {
111    *this = M;
112  }
113
114  ~MachineOperand() {}
115
116  /// getType - Returns the MachineOperandType for this operand.
117  ///
118  MachineOperandType getType() const { return OpKind; }
119
120  /// getParent - Return the instruction that this operand belongs to.
121  ///
122  MachineInstr *getParent() { return ParentMI; }
123  const MachineInstr *getParent() const { return ParentMI; }
124
125  void print(std::ostream &os, const TargetMachine *TM = 0) const;
126  void print(raw_ostream &os, const TargetMachine *TM = 0) const;
127
128  //===--------------------------------------------------------------------===//
129  // Accessors that tell you what kind of MachineOperand you're looking at.
130  //===--------------------------------------------------------------------===//
131
132  /// isReg - Tests if this is a MO_Register operand.
133  bool isReg() const { return OpKind == MO_Register; }
134  /// isImm - Tests if this is a MO_Immediate operand.
135  bool isImm() const { return OpKind == MO_Immediate; }
136  /// isFPImm - Tests if this is a MO_FPImmediate operand.
137  bool isFPImm() const { return OpKind == MO_FPImmediate; }
138  /// isMBB - Tests if this is a MO_MachineBasicBlock operand.
139  bool isMBB() const { return OpKind == MO_MachineBasicBlock; }
140  /// isFI - Tests if this is a MO_FrameIndex operand.
141  bool isFI() const { return OpKind == MO_FrameIndex; }
142  /// isCPI - Tests if this is a MO_ConstantPoolIndex operand.
143  bool isCPI() const { return OpKind == MO_ConstantPoolIndex; }
144  /// isJTI - Tests if this is a MO_JumpTableIndex operand.
145  bool isJTI() const { return OpKind == MO_JumpTableIndex; }
146  /// isGlobal - Tests if this is a MO_GlobalAddress operand.
147  bool isGlobal() const { return OpKind == MO_GlobalAddress; }
148  /// isSymbol - Tests if this is a MO_ExternalSymbol operand.
149  bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
150
151  //===--------------------------------------------------------------------===//
152  // Accessors for Register Operands
153  //===--------------------------------------------------------------------===//
154
155  /// getReg - Returns the register number.
156  unsigned getReg() const {
157    assert(isReg() && "This is not a register operand!");
158    return Contents.Reg.RegNo;
159  }
160
161  unsigned getSubReg() const {
162    assert(isReg() && "Wrong MachineOperand accessor");
163    return (unsigned)SubReg;
164  }
165
166  bool isUse() const {
167    assert(isReg() && "Wrong MachineOperand accessor");
168    return !IsDef;
169  }
170
171  bool isDef() const {
172    assert(isReg() && "Wrong MachineOperand accessor");
173    return IsDef;
174  }
175
176  bool isImplicit() const {
177    assert(isReg() && "Wrong MachineOperand accessor");
178    return IsImp;
179  }
180
181  bool isDead() const {
182    assert(isReg() && "Wrong MachineOperand accessor");
183    return IsDead;
184  }
185
186  bool isKill() const {
187    assert(isReg() && "Wrong MachineOperand accessor");
188    return IsKill;
189  }
190
191  bool isEarlyClobber() const {
192    assert(isReg() && "Wrong MachineOperand accessor");
193    return IsEarlyClobber;
194  }
195
196  /// getNextOperandForReg - Return the next MachineOperand in the function that
197  /// uses or defines this register.
198  MachineOperand *getNextOperandForReg() const {
199    assert(isReg() && "This is not a register operand!");
200    return Contents.Reg.Next;
201  }
202
203  //===--------------------------------------------------------------------===//
204  // Mutators for Register Operands
205  //===--------------------------------------------------------------------===//
206
207  /// Change the register this operand corresponds to.
208  ///
209  void setReg(unsigned Reg);
210
211  void setSubReg(unsigned subReg) {
212    assert(isReg() && "Wrong MachineOperand accessor");
213    SubReg = (unsigned char)subReg;
214  }
215
216  void setIsUse(bool Val = true) {
217    assert(isReg() && "Wrong MachineOperand accessor");
218    IsDef = !Val;
219  }
220
221  void setIsDef(bool Val = true) {
222    assert(isReg() && "Wrong MachineOperand accessor");
223    IsDef = Val;
224  }
225
226  void setImplicit(bool Val = true) {
227    assert(isReg() && "Wrong MachineOperand accessor");
228    IsImp = Val;
229  }
230
231  void setIsKill(bool Val = true) {
232    assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
233    IsKill = Val;
234  }
235
236  void setIsDead(bool Val = true) {
237    assert(isReg() && IsDef && "Wrong MachineOperand accessor");
238    IsDead = Val;
239  }
240
241  void setIsEarlyClobber(bool Val = true) {
242    assert(isReg() && IsDef && "Wrong MachineOperand accessor");
243    IsEarlyClobber = Val;
244  }
245
246  //===--------------------------------------------------------------------===//
247  // Accessors for various operand types.
248  //===--------------------------------------------------------------------===//
249
250  int64_t getImm() const {
251    assert(isImm() && "Wrong MachineOperand accessor");
252    return Contents.ImmVal;
253  }
254
255  const ConstantFP *getFPImm() const {
256    assert(isFPImm() && "Wrong MachineOperand accessor");
257    return Contents.CFP;
258  }
259
260  MachineBasicBlock *getMBB() const {
261    assert(isMBB() && "Wrong MachineOperand accessor");
262    return Contents.MBB;
263  }
264
265  int getIndex() const {
266    assert((isFI() || isCPI() || isJTI()) &&
267           "Wrong MachineOperand accessor");
268    return Contents.OffsetedInfo.Val.Index;
269  }
270
271  GlobalValue *getGlobal() const {
272    assert(isGlobal() && "Wrong MachineOperand accessor");
273    return Contents.OffsetedInfo.Val.GV;
274  }
275
276  int getOffset() const {
277    assert((isGlobal() || isSymbol() || isCPI()) &&
278           "Wrong MachineOperand accessor");
279    return Contents.OffsetedInfo.Offset;
280  }
281
282  const char *getSymbolName() const {
283    assert(isSymbol() && "Wrong MachineOperand accessor");
284    return Contents.OffsetedInfo.Val.SymbolName;
285  }
286
287  //===--------------------------------------------------------------------===//
288  // Mutators for various operand types.
289  //===--------------------------------------------------------------------===//
290
291  void setImm(int64_t immVal) {
292    assert(isImm() && "Wrong MachineOperand mutator");
293    Contents.ImmVal = immVal;
294  }
295
296  void setOffset(int Offset) {
297    assert((isGlobal() || isSymbol() || isCPI()) &&
298        "Wrong MachineOperand accessor");
299    Contents.OffsetedInfo.Offset = Offset;
300  }
301
302  void setIndex(int Idx) {
303    assert((isFI() || isCPI() || isJTI()) &&
304           "Wrong MachineOperand accessor");
305    Contents.OffsetedInfo.Val.Index = Idx;
306  }
307
308  void setMBB(MachineBasicBlock *MBB) {
309    assert(isMBB() && "Wrong MachineOperand accessor");
310    Contents.MBB = MBB;
311  }
312
313  //===--------------------------------------------------------------------===//
314  // Other methods.
315  //===--------------------------------------------------------------------===//
316
317  /// isIdenticalTo - Return true if this operand is identical to the specified
318  /// operand. Note: This method ignores isKill and isDead properties.
319  bool isIdenticalTo(const MachineOperand &Other) const;
320
321  /// ChangeToImmediate - Replace this operand with a new immediate operand of
322  /// the specified value.  If an operand is known to be an immediate already,
323  /// the setImm method should be used.
324  void ChangeToImmediate(int64_t ImmVal);
325
326  /// ChangeToRegister - Replace this operand with a new register operand of
327  /// the specified value.  If an operand is known to be an register already,
328  /// the setReg method should be used.
329  void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
330                        bool isKill = false, bool isDead = false);
331
332  //===--------------------------------------------------------------------===//
333  // Construction methods.
334  //===--------------------------------------------------------------------===//
335
336  static MachineOperand CreateImm(int64_t Val) {
337    MachineOperand Op(MachineOperand::MO_Immediate);
338    Op.setImm(Val);
339    return Op;
340  }
341
342  static MachineOperand CreateFPImm(const ConstantFP *CFP) {
343    MachineOperand Op(MachineOperand::MO_FPImmediate);
344    Op.Contents.CFP = CFP;
345    return Op;
346  }
347
348  static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
349                                  bool isKill = false, bool isDead = false,
350                                  unsigned SubReg = 0,
351                                  bool isEarlyClobber = false) {
352    MachineOperand Op(MachineOperand::MO_Register);
353    Op.IsDef = isDef;
354    Op.IsImp = isImp;
355    Op.IsKill = isKill;
356    Op.IsDead = isDead;
357    Op.IsEarlyClobber = isEarlyClobber;
358    Op.Contents.Reg.RegNo = Reg;
359    Op.Contents.Reg.Prev = 0;
360    Op.Contents.Reg.Next = 0;
361    Op.SubReg = SubReg;
362    return Op;
363  }
364  static MachineOperand CreateMBB(MachineBasicBlock *MBB) {
365    MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
366    Op.setMBB(MBB);
367    return Op;
368  }
369  static MachineOperand CreateFI(unsigned Idx) {
370    MachineOperand Op(MachineOperand::MO_FrameIndex);
371    Op.setIndex(Idx);
372    return Op;
373  }
374  static MachineOperand CreateCPI(unsigned Idx, int Offset) {
375    MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
376    Op.setIndex(Idx);
377    Op.setOffset(Offset);
378    return Op;
379  }
380  static MachineOperand CreateJTI(unsigned Idx) {
381    MachineOperand Op(MachineOperand::MO_JumpTableIndex);
382    Op.setIndex(Idx);
383    return Op;
384  }
385  static MachineOperand CreateGA(GlobalValue *GV, int Offset) {
386    MachineOperand Op(MachineOperand::MO_GlobalAddress);
387    Op.Contents.OffsetedInfo.Val.GV = GV;
388    Op.setOffset(Offset);
389    return Op;
390  }
391  static MachineOperand CreateES(const char *SymName, int Offset = 0) {
392    MachineOperand Op(MachineOperand::MO_ExternalSymbol);
393    Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
394    Op.setOffset(Offset);
395    return Op;
396  }
397  const MachineOperand &operator=(const MachineOperand &MO) {
398    OpKind   = MO.OpKind;
399    IsDef    = MO.IsDef;
400    IsImp    = MO.IsImp;
401    IsKill   = MO.IsKill;
402    IsDead   = MO.IsDead;
403    IsEarlyClobber = MO.IsEarlyClobber;
404    SubReg   = MO.SubReg;
405    ParentMI = MO.ParentMI;
406    Contents = MO.Contents;
407    return *this;
408  }
409
410  friend class MachineInstr;
411  friend class MachineRegisterInfo;
412private:
413  //===--------------------------------------------------------------------===//
414  // Methods for handling register use/def lists.
415  //===--------------------------------------------------------------------===//
416
417  /// isOnRegUseList - Return true if this operand is on a register use/def list
418  /// or false if not.  This can only be called for register operands that are
419  /// part of a machine instruction.
420  bool isOnRegUseList() const {
421    assert(isReg() && "Can only add reg operand to use lists");
422    return Contents.Reg.Prev != 0;
423  }
424
425  /// AddRegOperandToRegInfo - Add this register operand to the specified
426  /// MachineRegisterInfo.  If it is null, then the next/prev fields should be
427  /// explicitly nulled out.
428  void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);
429
430  void RemoveRegOperandFromRegInfo() {
431    assert(isOnRegUseList() && "Reg operand is not on a use list");
432    // Unlink this from the doubly linked list of operands.
433    MachineOperand *NextOp = Contents.Reg.Next;
434    *Contents.Reg.Prev = NextOp;
435    if (NextOp) {
436      assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");
437      NextOp->Contents.Reg.Prev = Contents.Reg.Prev;
438    }
439    Contents.Reg.Prev = 0;
440    Contents.Reg.Next = 0;
441  }
442};
443
444inline std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {
445  MO.print(OS, 0);
446  return OS;
447}
448
449inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
450  MO.print(OS, 0);
451  return OS;
452}
453
454} // End llvm namespace
455
456#endif
457