llvm_unreachable->llvm_unreachable(0), LLVM_UNREACHABLE->llvm_unreachable.
[oota-llvm.git] / include / llvm / Target / TargetInstrInfo.h
index a37e9e6bd0739a1db59bcfa99a7bf43034fb088e..00f9f5a5220eb0195bf58dc0d02d44705550b80a 100644 (file)
 #ifndef LLVM_TARGET_TARGETINSTRINFO_H
 #define LLVM_TARGET_TARGETINSTRINFO_H
 
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Target/TargetInstrDesc.h"
 #include "llvm/CodeGen/MachineFunction.h"
 
 namespace llvm {
 
 class TargetRegisterClass;
+class TargetRegisterInfo;
 class LiveVariables;
 class CalleeSavedInfo;
 class SDNode;
@@ -50,10 +52,39 @@ public:
     EH_LABEL = 3,
     GC_LABEL = 4,
     DECLARE = 5,
+
+    /// EXTRACT_SUBREG - This instruction takes two operands: a register
+    /// that has subregisters, and a subregister index. It returns the
+    /// extracted subregister value. This is commonly used to implement
+    /// truncation operations on target architectures which support it.
     EXTRACT_SUBREG = 6,
+
+    /// INSERT_SUBREG - This instruction takes three operands: a register
+    /// that has subregisters, a register providing an insert value, and a
+    /// subregister index. It returns the value of the first register with
+    /// the value of the second register inserted. The first register is
+    /// often defined by an IMPLICIT_DEF, as is commonly used to implement
+    /// anyext operations on target architectures which support it.
     INSERT_SUBREG = 7,
+
+    /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
     IMPLICIT_DEF = 8,
-    SUBREG_TO_REG = 9
+
+    /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except
+    /// that the first operand is an immediate integer constant. This constant
+    /// is often zero, as is commonly used to implement zext operations on
+    /// target architectures which support it, such as with x86-64 (with
+    /// zext from i32 to i64 via implicit zero-extension).
+    SUBREG_TO_REG = 9,
+
+    /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
+    /// register-to-register copy into a specific register class. This is only
+    /// used between instruction selection and MachineInstr creation, before
+    /// virtual registers have been created for all the instructions, and it's
+    /// only needed in cases where the register classes implied by the
+    /// instructions are insufficient. The actual MachineInstrs to perform
+    /// the copy are emitted with the TargetInstrInfo::copyRegToReg hook.
+    COPY_TO_REGCLASS = 10
   };
 
   unsigned getNumOpcodes() const { return NumOpcodes; }
@@ -88,11 +119,11 @@ protected:
   }
 
 public:
-  /// Return true if the instruction is a register to register move
-  /// and leave the source and dest operands in the passed parameters.
+  /// Return true if the instruction is a register to register move and return
+  /// the source and dest operands and their sub-register indices by reference.
   virtual bool isMoveInstr(const MachineInstr& MI,
-                           unsigned& sourceReg,
-                           unsigned& destReg) const {
+                           unsigned& SrcReg, unsigned& DstReg,
+                           unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
     return false;
   }
   
@@ -101,7 +132,8 @@ public:
   /// the destination along with the FrameIndex of the loaded stack slot.  If
   /// not, return 0.  This predicate must return 0 if the instruction has
   /// any side effects other than loading from the stack slot.
-  virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
+  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
+                                       int &FrameIndex) const {
     return 0;
   }
   
@@ -110,7 +142,8 @@ public:
   /// the source reg along with the FrameIndex of the loaded stack slot.  If
   /// not, return 0.  This predicate must return 0 if the instruction has
   /// any side effects other than storing to the stack slot.
-  virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
+  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
+                                      int &FrameIndex) const {
     return 0;
   }
 
@@ -127,7 +160,7 @@ public:
   /// from the argument area of a function if it does not change.  This should
   /// only return true of *all* loads the instruction does are invariant (if it
   /// does multiple loads).
-  virtual bool isInvariantLoad(MachineInstr *MI) const {
+  virtual bool isInvariantLoad(const MachineInstr *MI) const {
     return false;
   }
   
@@ -162,13 +195,11 @@ public:
   virtual MachineInstr *commuteInstruction(MachineInstr *MI,
                                            bool NewMI = false) const = 0;
 
-  /// CommuteChangesDestination - Return true if commuting the specified
-  /// instruction will also changes the destination operand. Also return the
-  /// current operand index of the would be new destination register by
-  /// reference. This can happen when the commutable instruction is also a
-  /// two-address instruction.
-  virtual bool CommuteChangesDestination(MachineInstr *MI,
-                                         unsigned &OpIdx) const = 0;
+  /// findCommutedOpIndices - If specified MI is commutable, return the two
+  /// operand indices that would swap value. Return true if the instruction
+  /// is not in a form which this routine understands.
+  virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
+                                     unsigned &SrcOpIdx2) const = 0;
 
   /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
   /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@@ -180,22 +211,26 @@ public:
   /// 2. If this block ends with only an unconditional branch, it sets TBB to be
   ///    the destination block.
   /// 3. If this block ends with an conditional branch and it falls through to
-  ///    an successor block, it sets TBB to be the branch destination block and a
-  ///    list of operands that evaluate the condition. These
+  ///    an successor block, it sets TBB to be the branch destination block and
+  ///    list of operands that evaluate the condition. These
   ///    operands can be passed to other TargetInstrInfo methods to create new
   ///    branches.
   /// 4. If this block ends with an conditional branch and an unconditional
-  ///    block, it returns the 'true' destination in TBB, the 'false' destination
-  ///    in FBB, and a list of operands that evaluate the condition. These
-  ///    operands can be passed to other TargetInstrInfo methods to create new
-  ///    branches.
+  ///    block, it returns the 'true' destination in TBB, the 'false'
+  ///    destination in FBB, and a list of operands that evaluate the condition.
+  ///    These operands can be passed to other TargetInstrInfo methods to create
+  ///    new branches.
   ///
   /// Note that RemoveBranch and InsertBranch must be implemented to support
   /// cases where this method returns success.
   ///
+  /// If AllowModify is true, then this routine is allowed to modify the basic
+  /// block (e.g. delete instructions after the unconditional branch).
+  ///
   virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
                              MachineBasicBlock *&FBB,
-                             SmallVectorImpl<MachineOperand> &Cond) const {
+                             SmallVectorImpl<MachineOperand> &Cond,
+                             bool AllowModify = false) const {
     return true;
   }
   
@@ -213,6 +248,11 @@ public:
   /// returns success and when an unconditional branch (TBB is non-null, FBB is
   /// null, Cond is empty) needs to be inserted. It returns the number of
   /// instructions inserted.
+  ///
+  /// It is also invoked by tail merging to add unconditional branches in
+  /// cases where AnalyzeBranch doesn't apply because there was no original
+  /// branch to analyze.  At least this much must be implemented, else tail
+  /// merging needs to be disabled.
   virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                             MachineBasicBlock *FBB,
                             const SmallVectorImpl<MachineOperand> &Cond) const {
@@ -303,24 +343,42 @@ public:
   /// operand folded, otherwise NULL is returned. The client is responsible for
   /// removing the old instruction and adding the new one in the instruction
   /// stream.
-  virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
-                                          MachineInstr* MI,
-                                          const SmallVectorImpl<unsigned> &Ops,
-                                          int FrameIndex) const {
-    return 0;
-  }
+  MachineInstr* foldMemoryOperand(MachineFunction &MF,
+                                  MachineInstr* MI,
+                                  const SmallVectorImpl<unsigned> &Ops,
+                                  int FrameIndex) const;
 
   /// foldMemoryOperand - Same as the previous version except it allows folding
   /// of any load and store from / to any address, not just from a specific
   /// stack slot.
-  virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
+  MachineInstr* foldMemoryOperand(MachineFunction &MF,
+                                  MachineInstr* MI,
+                                  const SmallVectorImpl<unsigned> &Ops,
+                                  MachineInstr* LoadMI) const;
+
+protected:
+  /// foldMemoryOperandImpl - Target-dependent implementation for
+  /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+  /// take care of adding a MachineMemOperand to the newly created instruction.
+  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
                                           MachineInstr* MI,
                                           const SmallVectorImpl<unsigned> &Ops,
-                                          MachineInstr* LoadMI) const {
+                                          int FrameIndex) const {
     return 0;
   }
 
-  /// canFoldMemoryOperand - Returns true if the specified load / store is
+  /// foldMemoryOperandImpl - Target-dependent implementation for
+  /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+  /// take care of adding a MachineMemOperand to the newly created instruction.
+  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+                                              MachineInstr* MI,
+                                              const SmallVectorImpl<unsigned> &Ops,
+                                              MachineInstr* LoadMI) const {
+    return 0;
+  }
+
+public:
+  /// canFoldMemoryOperand - Returns true for the specified load / store if
   /// folding is possible.
   virtual
   bool canFoldMemoryOperand(const MachineInstr *MI,
@@ -333,7 +391,7 @@ public:
   /// possible, returns true as well as the new instructions by reference.
   virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
                                 unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
-                                  SmallVectorImpl<MachineInstr*> &NewMIs) const{
+                                 SmallVectorImpl<MachineInstr*> &NewMIs) const{
     return false;
   }
 
@@ -371,8 +429,7 @@ public:
   /// point.
   virtual void insertNoop(MachineBasicBlock &MBB, 
                           MachineBasicBlock::iterator MI) const {
-    assert(0 && "Target didn't implement insertNoop!");
-    abort();
+    llvm_unreachable("Target didn't implement insertNoop!");
   }
 
   /// isPredicated - Returns true if the instruction is already predicated.
@@ -407,21 +464,12 @@ public:
     return false;
   }
 
-  /// IgnoreRegisterClassBarriers - Returns true if pre-register allocation
-  /// live interval splitting pass should ignore barriers of the specified
-  /// register class.
-  virtual bool IgnoreRegisterClassBarriers(const TargetRegisterClass *RC) const{
+  /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine
+  /// instruction that defines the specified register class.
+  virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
     return true;
   }
 
-  /// getPointerRegClass - Returns a TargetRegisterClass used for pointer
-  /// values.
-  virtual const TargetRegisterClass *getPointerRegClass() const {
-    assert(0 && "Target didn't implement getPointerRegClass!");
-    abort();
-    return 0; // Must return a value in order to compile with VS 2005
-  }
-
   /// GetInstSize - Returns the size of the specified Instruction.
   /// 
   virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
@@ -445,8 +493,8 @@ protected:
 public:
   virtual MachineInstr *commuteInstruction(MachineInstr *MI,
                                            bool NewMI = false) const;
-  virtual bool CommuteChangesDestination(MachineInstr *MI,
-                                         unsigned &OpIdx) const;
+  virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
+                                     unsigned &SrcOpIdx2) const;
   virtual bool PredicateInstruction(MachineInstr *MI,
                             const SmallVectorImpl<MachineOperand> &Pred) const;
   virtual void reMaterialize(MachineBasicBlock &MBB,
@@ -456,6 +504,12 @@ public:
   virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
 };
 
+/// getInstrOperandRegClass - Return register class of the operand of an
+/// instruction of the specified TargetInstrDesc.
+const TargetRegisterClass*
+getInstrOperandRegClass(const TargetRegisterInfo *TRI,
+                        const TargetInstrDesc &II, unsigned Op);
+
 } // End llvm namespace
 
 #endif