Initial support for carrying MachineInstrs in SUnits.
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
index 77e5e76521c0baa9ad3190f9f5e6be60a736c3ec..8efea6244258e3207e47cd326892155196caa852 100644 (file)
 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
 #define LLVM_CODEGEN_MACHINEINSTR_H
 
-#include "llvm/ADT/alist.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/Target/TargetInstrDesc.h"
+#include <list>
 #include <vector>
 
 namespace llvm {
@@ -31,13 +35,13 @@ class MachineFunction;
 //===----------------------------------------------------------------------===//
 /// MachineInstr - Representation of each machine instruction.
 ///
-class MachineInstr {
+class MachineInstr : public ilist_node<MachineInstr> {
   const TargetInstrDesc *TID;           // Instruction descriptor.
   unsigned short NumImplicitOps;        // Number of implicit operands (which
                                         // are determined at construction time).
 
   std::vector<MachineOperand> Operands; // the operands
-  alist<MachineMemOperand> MemOperands; // information on memory references
+  std::list<MachineMemOperand> MemOperands; // information on memory references
   MachineBasicBlock *Parent;            // Pointer to the owning basic block.
 
   // OperandComplete - Return true if it's illegal to add a new operand
@@ -47,8 +51,9 @@ class MachineInstr {
   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
 
   // Intrusive list support
-  friend struct alist_traits<MachineInstr>;
-  friend struct alist_traits<MachineBasicBlock>;
+  friend struct ilist_traits<MachineInstr>;
+  friend struct ilist_traits<MachineBasicBlock>;
+  friend struct ilist_sentinel_traits<MachineInstr>;
   void setParent(MachineBasicBlock *P) { Parent = P; }
 
   /// MachineInstr ctor - This constructor creates a copy of the given
@@ -85,7 +90,7 @@ public:
 
   /// getOpcode - Returns the opcode of this MachineInstr.
   ///
-  int getOpcode() const;
+  int getOpcode() const { return TID->Opcode; }
 
   /// Access to explicit operands of the instruction.
   ///
@@ -105,16 +110,23 @@ public:
   unsigned getNumExplicitOperands() const;
   
   /// Access to memory operands of the instruction
-  alist<MachineMemOperand>::iterator memoperands_begin()
+  std::list<MachineMemOperand>::iterator memoperands_begin()
   { return MemOperands.begin(); }
-  alist<MachineMemOperand>::iterator memoperands_end()
+  std::list<MachineMemOperand>::iterator memoperands_end()
   { return MemOperands.end(); }
-  alist<MachineMemOperand>::const_iterator memoperands_begin() const
+  std::list<MachineMemOperand>::const_iterator memoperands_begin() const
   { return MemOperands.begin(); }
-  alist<MachineMemOperand>::const_iterator memoperands_end() const
+  std::list<MachineMemOperand>::const_iterator memoperands_end() const
   { return MemOperands.end(); }
   bool memoperands_empty() const { return MemOperands.empty(); }
 
+  /// hasOneMemOperand - Return true if this instruction has exactly one
+  /// MachineMemOperand.
+  bool hasOneMemOperand() const {
+    return !memoperands_empty() &&
+           next(memoperands_begin()) == memoperands_end();
+  }
+
   /// isIdenticalTo - Return true if this instruction is identical to (same
   /// opcode and same operands as) the specified instruction.
   bool isIdenticalTo(const MachineInstr *Other) const {
@@ -207,9 +219,9 @@ public:
   /// none is found.
   int findFirstPredOperandIdx() const;
   
-  /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due
-  /// to two addr elimination.
-  bool isRegReDefinedByTwoAddr(unsigned Reg) const;
+  /// isRegReDefinedByTwoAddr - Given the defined register and the operand index,
+  /// check if the register def is a re-definition due to two addr elimination.
+  bool isRegReDefinedByTwoAddr(unsigned Reg, unsigned DefIdx) const;
 
   /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
   ///
@@ -238,6 +250,16 @@ public:
   /// the instruction's location and its intended destination.
   bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore);
 
+  /// isSafeToReMat - Return true if it's safe to rematerialize the specified
+  /// instruction which defined the specified register instead of copying it.
+  bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg);
+
+  /// hasVolatileMemoryRef - Return true if this instruction may have a
+  /// volatile memory reference, or if the information describing the
+  /// memory reference is not available. Return false if it is known to
+  /// have no volatile memory references.
+  bool hasVolatileMemoryRef() const;
+
   //
   // Debugging support
   //
@@ -246,6 +268,11 @@ public:
   }
   void print(std::ostream &OS, const TargetMachine *TM = 0) const;
   void print(std::ostream *OS) const { if (OS) print(*OS); }
+  void print(raw_ostream *OS, const TargetMachine *TM) const {
+    if (OS) print(*OS, TM);
+  }
+  void print(raw_ostream &OS, const TargetMachine *TM = 0) const;
+  void print(raw_ostream *OS) const { if (OS) print(*OS); }
   void dump() const;
 
   //===--------------------------------------------------------------------===//
@@ -304,6 +331,11 @@ inline std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI) {
   return OS;
 }
 
+inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) {
+  MI.print(OS);
+  return OS;
+}
+
 } // End llvm namespace
 
 #endif