Implement the sadd_with_overflow intrinsic. This is converted into
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
index 06d15ab3a39a4f2591ce570a9d6f65ef54090aef..0cdad848b9ac13a39511ae7934790d5d235c9436 100644 (file)
 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
 #define LLVM_CODEGEN_MACHINEINSTR_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 {
@@ -25,34 +30,36 @@ namespace llvm {
 class TargetInstrDesc;
 class TargetInstrInfo;
 class TargetRegisterInfo;
-
-template <typename T> struct ilist_traits;
-template <typename T> struct ilist;
+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
-  std::vector<MachineMemOperand> MemOperands;// information on memory references
-  MachineInstr *Prev, *Next;            // Links for MBB's intrusive list.
+  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
   bool OperandsComplete() const;
 
-  MachineInstr(const MachineInstr&);
+  MachineInstr(const MachineInstr&);   // DO NOT IMPLEMENT
   void operator=(const MachineInstr&); // DO NOT IMPLEMENT
 
   // Intrusive list support
   friend struct ilist_traits<MachineInstr>;
   friend struct ilist_traits<MachineBasicBlock>;
+  friend struct ilist_sentinel_traits<MachineInstr>;
   void setParent(MachineBasicBlock *P) { Parent = P; }
-public:
+
+  /// MachineInstr ctor - This constructor creates a copy of the given
+  /// MachineInstr in the given MachineFunction.
+  MachineInstr(MachineFunction &, const MachineInstr &);
+
   /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
   /// TID NULL and no operands.
   MachineInstr();
@@ -70,6 +77,10 @@ public:
 
   ~MachineInstr();
 
+  // MachineInstrs are pool-allocated and owned by MachineFunction.
+  friend class MachineFunction;
+
+public:
   const MachineBasicBlock* getParent() const { return Parent; }
   MachineBasicBlock* getParent() { return Parent; }
   
@@ -79,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.
   ///
@@ -99,15 +110,21 @@ public:
   unsigned getNumExplicitOperands() const;
   
   /// Access to memory operands of the instruction
-  unsigned getNumMemOperands() const { return (unsigned)MemOperands.size(); }
-
-  const MachineMemOperand& getMemOperand(unsigned i) const {
-    assert(i < getNumMemOperands() && "getMemOperand() out of range!");
-    return MemOperands[i];
-  }
-  MachineMemOperand& getMemOperand(unsigned i) {
-    assert(i < getNumMemOperands() && "getMemOperand() out of range!");
-    return MemOperands[i];
+  std::list<MachineMemOperand>::iterator memoperands_begin()
+  { return MemOperands.begin(); }
+  std::list<MachineMemOperand>::iterator memoperands_end()
+  { return MemOperands.end(); }
+  std::list<MachineMemOperand>::const_iterator memoperands_begin() const
+  { return MemOperands.begin(); }
+  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
@@ -122,19 +139,13 @@ public:
     return true;
   }
 
-  /// clone - Create a copy of 'this' instruction that is identical in
-  /// all ways except the the instruction has no parent, prev, or next.
-  MachineInstr* clone() const { return new MachineInstr(*this); }
-  
   /// removeFromParent - This method unlinks 'this' from the containing basic
   /// block, and returns it, but does not delete it.
   MachineInstr *removeFromParent();
   
   /// eraseFromParent - This method unlinks 'this' from the containing basic
   /// block and deletes it.
-  void eraseFromParent() {
-    delete removeFromParent();
-  }
+  void eraseFromParent();
 
   /// isLabel - Returns true if the MachineInstr represents a label.
   ///
@@ -208,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.
   ///
@@ -237,7 +248,17 @@ public:
   /// isSafeToMove - Return true if it is safe to move this instruction. If
   /// SawStore is set to true, it means that there is a store (or call) between
   /// the instruction's location and its intended destination.
-  bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore);
+  bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore) const;
+
+  /// 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) const;
+
+  /// 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
@@ -247,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;
 
   //===--------------------------------------------------------------------===//
@@ -270,9 +296,11 @@ public:
 
   /// addMemOperand - Add a MachineMemOperand to the machine instruction,
   /// referencing arbitrary storage.
-  void addMemOperand(const MachineMemOperand &MO) {
-    MemOperands.push_back(MO);
-  }
+  void addMemOperand(MachineFunction &MF,
+                     const MachineMemOperand &MO);
+
+  /// clearMemOperands - Erase all of this MachineInstr's MachineMemOperands.
+  void clearMemOperands(MachineFunction &MF);
 
 private:
   /// getRegInfo - If this instruction is embedded into a MachineFunction,
@@ -303,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