Add isExtractSubreg property.
[oota-llvm.git] / include / llvm / MC / MCInstrDesc.h
index 9b5415add2413d1fe3783e051ee1841ce544e68d..03b74256850668754b8200583605b7fdd4404a27 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Support/DataTypes.h"
 
 namespace llvm {
@@ -124,7 +125,9 @@ namespace MCID {
     Rematerializable,
     CheapAsAMove,
     ExtraSrcRegAllocReq,
-    ExtraDefRegAllocReq
+    ExtraDefRegAllocReq,
+    RegSequence,
+    ExtractSubreg
   };
 }
 
@@ -145,6 +148,10 @@ public:
   const uint16_t *ImplicitUses;  // Registers implicitly read by this instr
   const uint16_t *ImplicitDefs;  // Registers implicitly defined by this instr
   const MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands
+  uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any
+  // A complex method to determine is a certain is deprecated or not, and return
+  // the reason for deprecation.
+  bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);
 
   /// \brief Returns the value of the specific constraint if
   /// it is set. Returns -1 if it is not set.
@@ -158,6 +165,20 @@ public:
     return -1;
   }
 
+  /// \brief Returns true if a certain instruction is deprecated and if so
+  /// returns the reason in \p Info.
+  bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI,
+                         std::string &Info) const {
+    if (ComplexDeprecationInfo)
+      return ComplexDeprecationInfo(MI, STI, Info);
+    if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) {
+      // FIXME: it would be nice to include the subtarget feature here.
+      Info = "deprecated";
+      return true;
+    }
+    return false;
+  }
+
   /// \brief Return the opcode number for this descriptor.
   unsigned getOpcode() const {
     return Opcode;
@@ -268,8 +289,20 @@ public:
     if (isBranch() || isCall() || isReturn() || isIndirectBranch())
       return true;
     unsigned PC = RI.getProgramCounter();
-    if (PC == 0) return false;
-    return hasDefOfPhysReg(MI, PC, RI);
+    if (PC == 0)
+      return false;
+    if (hasDefOfPhysReg(MI, PC, RI))
+      return true;
+    // A variadic instruction may define PC in the variable operand list.
+    // There's currently no indication of which entries in a variable
+    // list are defs and which are uses. While that's the case, this function
+    // needs to assume they're defs in order to be conservatively correct.
+    for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) {
+      if (MI.getOperand(i).isReg() &&
+          RI.isSubRegisterEq(PC, MI.getOperand(i).getReg()))
+        return true;
+    }
+    return false;
   }
 
   /// \brief Return true if this instruction has a predicate operand
@@ -326,6 +359,33 @@ public:
     return Flags & (1 << MCID::FoldableAsLoad);
   }
 
+  /// \brief Return true if this instruction behaves
+  /// the same way as the generic REG_SEQUENCE instructions.
+  /// E.g., on ARM,
+  /// dX VMOVDRR rY, rZ
+  /// is equivalent to
+  /// dX = REG_SEQUENCE rY, ssub_0, rZ, ssub_1.
+  ///
+  /// Note that for the optimizers to be able to take advantage of
+  /// this property, TargetInstrInfo::getRegSequenceLikeInputs has to be
+  /// override accordingly.
+  bool isRegSequenceLike() const { return Flags & (1 << MCID::RegSequence); }
+
+  /// \brief Return true if this instruction behaves
+  /// the same way as the generic EXTRACT_SUBREG instructions.
+  /// E.g., on ARM,
+  /// rX, rY VMOVRRD dZ
+  /// is equivalent to two EXTRACT_SUBREG:
+  /// rX = EXTRACT_SUBREG dZ, ssub_0
+  /// rY = EXTRACT_SUBREG dZ, ssub_1
+  ///
+  /// Note that for the optimizers to be able to take advantage of
+  /// this property, TargetInstrInfo::getExtractSubregLikeInputs has to be
+  /// override accordingly.
+  bool isExtractSubregLike() const {
+    return Flags & (1 << MCID::ExtractSubreg);
+  }
+
   //===--------------------------------------------------------------------===//
   // Side Effect Analysis
   //===--------------------------------------------------------------------===//
@@ -420,9 +480,12 @@ public:
   }
 
   /// isRematerializable - Returns true if this instruction is a candidate for
-  /// remat.  This flag is deprecated, please don't use it anymore.  If this
-  /// flag is set, the isReallyTriviallyReMaterializable() method is called to
-  /// verify the instruction is really rematable.
+  /// remat. This flag is only used in TargetInstrInfo method
+  /// isTriviallyRematerializable.
+  ///
+  /// If this flag is set, the isReallyTriviallyReMaterializable()
+  /// or isReallyTriviallyReMaterializableGeneric methods are called to verify
+  /// the instruction is really rematable.
   bool isRematerializable() const {
     return Flags & (1 << MCID::Rematerializable);
   }
@@ -433,6 +496,9 @@ public:
   /// where we would like to remat or hoist the instruction, but not if it costs
   /// more than moving the instruction into the appropriate register. Note, we
   /// are not marking copies from and to the same register class with this flag.
+  ///
+  /// This method could be called by interface TargetInstrInfo::isAsCheapAsAMove
+  /// for different subtargets.
   bool isAsCheapAsAMove() const {
     return Flags & (1 << MCID::CheapAsAMove);
   }
@@ -473,7 +539,7 @@ public:
 
   /// \brief Return the number of implicit uses this instruction has.
   unsigned getNumImplicitUses() const {
-    if (ImplicitUses == 0) return 0;
+    if (!ImplicitUses) return 0;
     unsigned i = 0;
     for (; ImplicitUses[i]; ++i) /*empty*/;
     return i;
@@ -495,7 +561,7 @@ public:
 
   /// \brief Return the number of implicit defs this instruct has.
   unsigned getNumImplicitDefs() const {
-    if (ImplicitDefs == 0) return 0;
+    if (!ImplicitDefs) return 0;
     unsigned i = 0;
     for (; ImplicitDefs[i]; ++i) /*empty*/;
     return i;
@@ -513,7 +579,7 @@ public:
   /// \brief Return true if this instruction implicitly
   /// defines the specified physical register.
   bool hasImplicitDefOfPhysReg(unsigned Reg,
-                               const MCRegisterInfo *MRI = 0) const {
+                               const MCRegisterInfo *MRI = nullptr) const {
     if (const uint16_t *ImpDefs = ImplicitDefs)
       for (; *ImpDefs; ++ImpDefs)
         if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))