Use MachineBasicBlock::transferSuccessors.
[oota-llvm.git] / include / llvm / Target / TargetInstrInfo.h
index 6035f33794b22bd1bd26fd35fe1baa03d0557958..a2dc86f4a3ad08c028c80e1ee4ce8f7985a64c32 100644 (file)
@@ -47,8 +47,11 @@ public:
     PHI = 0,
     INLINEASM = 1,
     LABEL = 2,
-    EXTRACT_SUBREG = 3,
-    INSERT_SUBREG = 4
+    DECLARE = 3,
+    EXTRACT_SUBREG = 4,
+    INSERT_SUBREG = 5,
+    IMPLICIT_DEF = 6,
+    SUBREG_TO_REG = 7
   };
 
   unsigned getNumOpcodes() const { return NumOpcodes; }
@@ -64,20 +67,11 @@ public:
   /// isTriviallyReMaterializable - Return true if the instruction is trivially
   /// rematerializable, meaning it has no side effects and requires no operands
   /// that aren't always available.
-  bool isTriviallyReMaterializable(MachineInstr *MI) const {
+  bool isTriviallyReMaterializable(const MachineInstr *MI) const {
     return MI->getDesc().isRematerializable() &&
            isReallyTriviallyReMaterializable(MI);
   }
 
-  /// hasUnmodelledSideEffects - Returns true if the instruction has side
-  /// effects that are not captured by any operands of the instruction or other
-  /// flags.
-  bool hasUnmodelledSideEffects(MachineInstr *MI) const {
-    const TargetInstrDesc &TID = MI->getDesc();
-    if (TID.hasNoSideEffects()) return false;
-    if (!TID.hasConditionalSideEffects()) return true;
-    return !isReallySideEffectFree(MI); // May have side effects
-  }
 protected:
   /// isReallyTriviallyReMaterializable - For instructions with opcodes for
   /// which the M_REMATERIALIZABLE flag is set, this function tests whether the
@@ -87,19 +81,10 @@ protected:
   /// return false if the instruction has any side effects other than
   /// producing a value, or if it requres any address registers that are not
   /// always available.
-  virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const {
+  virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const {
     return true;
   }
 
-  /// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this
-  /// method is called to determine if the specific instance of this
-  /// instruction has side effects. This is useful in cases of instructions,
-  /// like loads, which generally always have side effects. A load from a
-  /// constant pool doesn't have side effects, though. So we need to
-  /// differentiate it from the general case.
-  virtual bool isReallySideEffectFree(MachineInstr *MI) const {
-    return false;
-  }
 public:
   /// Return true if the instruction is a register to register move
   /// and leave the source and dest operands in the passed parameters.
@@ -127,6 +112,23 @@ public:
     return 0;
   }
 
+  /// reMaterialize - Re-issue the specified 'original' instruction at the
+  /// specific location targeting a new destination register.
+  virtual void reMaterialize(MachineBasicBlock &MBB,
+                             MachineBasicBlock::iterator MI,
+                             unsigned DestReg,
+                             const MachineInstr *Orig) const = 0;
+
+  /// isInvariantLoad - Return true if the specified instruction (which is
+  /// marked mayLoad) is loading from a location whose value is invariant across
+  /// the function.  For example, loading a value from the constant pool or from
+  /// 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 {
+    return false;
+  }
+  
   /// convertToThreeAddress - This method must be implemented by targets that
   /// set the M_CONVERTIBLE_TO_3_ADDR flag.  When this flag is set, the target
   /// may be able to convert a two-address instruction into one or more true
@@ -153,7 +155,18 @@ public:
   /// return a new machine instruction.  If an instruction cannot commute, it
   /// can also return null.
   ///
-  virtual MachineInstr *commuteInstruction(MachineInstr *MI) const = 0;
+  /// If NewMI is true, then a new machine instruction must be created.
+  ///
+  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;
 
   /// 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
@@ -268,7 +281,8 @@ 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(MachineInstr* MI,
+  virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
+                                          MachineInstr* MI,
                                           SmallVectorImpl<unsigned> &Ops,
                                           int FrameIndex) const {
     return 0;
@@ -277,7 +291,8 @@ public:
   /// 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(MachineInstr* MI,
+  virtual MachineInstr* foldMemoryOperand(MachineFunction &MF,
+                                          MachineInstr* MI,
                                           SmallVectorImpl<unsigned> &Ops,
                                           MachineInstr* LoadMI) const {
     return 0;
@@ -376,6 +391,18 @@ public:
     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 {
+    assert(0 && "Target didn't implement TargetInstrInfo::GetInstSize!");
+    return 0;
+  }
+
+  /// GetFunctionSizeInBytes - Returns the size of the specified MachineFunction.
+  /// 
+  virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const = 0;
+
 };
 
 /// TargetInstrInfoImpl - This is the default implementation of
@@ -387,10 +414,17 @@ protected:
   TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes)
   : TargetInstrInfo(desc, NumOpcodes) {}
 public:
-  virtual MachineInstr *commuteInstruction(MachineInstr *MI) const;
+  virtual MachineInstr *commuteInstruction(MachineInstr *MI,
+                                           bool NewMI = false) const;
+  virtual bool CommuteChangesDestination(MachineInstr *MI,
+                                         unsigned &OpIdx) const;
   virtual bool PredicateInstruction(MachineInstr *MI,
                               const std::vector<MachineOperand> &Pred) const;
-  
+  virtual void reMaterialize(MachineBasicBlock &MBB,
+                             MachineBasicBlock::iterator MI,
+                             unsigned DestReg,
+                             const MachineInstr *Orig) const;
+  virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
 };
 
 } // End llvm namespace