convert a bunch of std::strings to use StringRef. This should eliminate
[oota-llvm.git] / include / llvm / Target / TargetInstrInfo.h
index 0bcda44b9706325297b4bf27cb33c3bfe37eef6a..12d6e3b1efe8d1beba3a374f3830043ae75619d7 100644 (file)
@@ -19,7 +19,9 @@
 
 namespace llvm {
 
+class MCAsmInfo;
 class TargetRegisterClass;
+class TargetRegisterInfo;
 class LiveVariables;
 class CalleeSavedInfo;
 class SDNode;
@@ -49,11 +51,40 @@ public:
     DBG_LABEL = 2,
     EH_LABEL = 3,
     GC_LABEL = 4,
-    DECLARE = 5,
+    // FIXME: DECLARE is removed. Readjust enum values ?
+
+    /// 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;
   }
 
@@ -118,7 +151,7 @@ public:
   /// specific location targeting a new destination register.
   virtual void reMaterialize(MachineBasicBlock &MBB,
                              MachineBasicBlock::iterator MI,
-                             unsigned DestReg,
+                             unsigned DestReg, unsigned SubIdx,
                              const MachineInstr *Orig) const = 0;
 
   /// isInvariantLoad - Return true if the specified instruction (which is
@@ -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,25 +211,29 @@ 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
-  ///    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
+  ///    a successor block, it sets TBB to be the branch destination block and
+  ///    a 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 a conditional branch followed by an
+  ///    unconditional branch, 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;
   }
-  
+
   /// RemoveBranch - Remove the branching code at the end of the specific MBB.
   /// This is only invoked in cases where AnalyzeBranch returns success. It
   /// returns the number of instructions that were removed.
@@ -206,13 +241,17 @@ public:
     assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!"); 
     return 0;
   }
-  
-  /// InsertBranch - Insert a branch into the end of the specified
-  /// MachineBasicBlock.  This operands to this method are the same as those
-  /// returned by AnalyzeBranch.  This is invoked in cases where AnalyzeBranch
-  /// 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.
+
+  /// InsertBranch - Insert branch code into the end of the specified
+  /// MachineBasicBlock.  The operands to this method are the same as those
+  /// returned by AnalyzeBranch.  This is only invoked in cases where
+  /// AnalyzeBranch returns success. 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 {
@@ -232,6 +271,11 @@ public:
     return false;
   }
   
+  /// storeRegToStackSlot - Store the specified register of the given register
+  /// class to the specified stack frame index. The store instruction is to be
+  /// added to the given machine basic block before the specified machine
+  /// instruction. If isKill is true, the register operand is the last use and
+  /// must be marked kill.
   virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator MI,
                                    unsigned SrcReg, bool isKill, int FrameIndex,
@@ -239,26 +283,16 @@ public:
     assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!");
   }
 
-  virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
-                              SmallVectorImpl<MachineOperand> &Addr,
-                              const TargetRegisterClass *RC,
-                              SmallVectorImpl<MachineInstr*> &NewMIs) const {
-    assert(0 && "Target didn't implement TargetInstrInfo::storeRegToAddr!");
-  }
-
+  /// loadRegFromStackSlot - Load the specified register of the given register
+  /// class from the specified stack frame index. The load instruction is to be
+  /// added to the given machine basic block before the specified machine
+  /// instruction.
   virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator MI,
                                     unsigned DestReg, int FrameIndex,
                                     const TargetRegisterClass *RC) const {
     assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!");
   }
-
-  virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
-                               SmallVectorImpl<MachineOperand> &Addr,
-                               const TargetRegisterClass *RC,
-                               SmallVectorImpl<MachineInstr*> &NewMIs) const {
-    assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromAddr!");
-  }
   
   /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
   /// saved registers and returns true if it isn't possible / profitable to do
@@ -286,24 +320,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;
+  }
+
+  /// 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;
   }
 
-  /// canFoldMemoryOperand - Returns true if the specified load / store is
+public:
+  /// canFoldMemoryOperand - Returns true for the specified load / store if
   /// folding is possible.
   virtual
   bool canFoldMemoryOperand(const MachineInstr *MI,
@@ -316,7 +368,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;
   }
 
@@ -353,11 +405,8 @@ public:
   /// insertNoop - Insert a noop into the instruction stream at the specified
   /// point.
   virtual void insertNoop(MachineBasicBlock &MBB, 
-                          MachineBasicBlock::iterator MI) const {
-    assert(0 && "Target didn't implement insertNoop!");
-    abort();
-  }
-
+                          MachineBasicBlock::iterator MI) const;
+  
   /// isPredicated - Returns true if the instruction is already predicated.
   ///
   virtual bool isPredicated(const MachineInstr *MI) const {
@@ -390,14 +439,16 @@ public:
     return false;
   }
 
-  /// 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
+  /// 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;
   }
 
+  /// isDeadInstruction - Return true if the instruction is considered dead.
+  /// This allows some late codegen passes to delete them.
+  virtual bool isDeadInstruction(const MachineInstr *MI) const = 0;
+
   /// GetInstSize - Returns the size of the specified Instruction.
   /// 
   virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
@@ -405,10 +456,15 @@ public:
     return 0;
   }
 
-  /// GetFunctionSizeInBytes - Returns the size of the specified MachineFunction.
+  /// GetFunctionSizeInBytes - Returns the size of the specified
+  /// MachineFunction.
   /// 
   virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const = 0;
-
+  
+  /// Measure the specified inline asm to determine an approximation of its
+  /// length.
+  virtual unsigned getInlineAsmLength(const char *Str,
+                                      const MCAsmInfo &MAI) const;
 };
 
 /// TargetInstrInfoImpl - This is the default implementation of
@@ -422,14 +478,16 @@ 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,
                              MachineBasicBlock::iterator MI,
-                             unsigned DestReg,
+                             unsigned DestReg, unsigned SubReg,
                              const MachineInstr *Orig) const;
+  virtual bool isDeadInstruction(const MachineInstr *MI) const;
+
   virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
 };