Add TargetInstrInfo::isCoalescableInstr. It returns true if the specified
authorEvan Cheng <evan.cheng@apple.com>
Tue, 12 Jan 2010 00:09:37 +0000 (00:09 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 12 Jan 2010 00:09:37 +0000 (00:09 +0000)
instruction is copy like where the source and destination registers can
overlap. This is to be used by the coalescable to coalesce the source and
destination registers of instructions like X86::MOVSX64rr32. Apparently
some crazy people believe the coalescer is too simple.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93210 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetInstrInfo.h
lib/Target/X86/X86InstrInfo.cpp
lib/Target/X86/X86InstrInfo.h

index c57a2d4c236f746d79069b65b8e85412aab6f3b6..6172fcfa64c2067ae5e9a034a0f22950e5b3298f 100644 (file)
@@ -149,6 +149,19 @@ public:
     return false;
   }
 
+  /// isCoalescableInstr - Return true if the instruction is "coalescable". That
+  /// is, it's like a copy where it's legal for the source to overlap the
+  /// destination. e.g. X86::MOVSX64rr32.
+  virtual bool isCoalescableInstr(const MachineInstr &MI, bool &isCopy,
+                               unsigned &SrcReg, unsigned &DstReg,
+                               unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
+    if (isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
+      isCopy = true;
+      return true;
+    }
+    return false;
+  }
+
   /// isIdentityCopy - Return true if the instruction is a copy (or
   /// extract_subreg, insert_subreg, subreg_to_reg) where the source and
   /// destination registers are the same.
index 9600cffa91fd49205966521a2d2d6bef44b7a460..52077cfd79d24bc45f0f1b3b75f46e8b911421d4 100644 (file)
@@ -712,6 +712,59 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
   }
 }
 
+bool
+X86InstrInfo::isCoalescableInstr(const MachineInstr &MI, bool &isCopy,
+                               unsigned &SrcReg, unsigned &DstReg,
+                               unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
+  switch (MI.getOpcode()) {
+  default: break;
+  case X86::MOVSX16rr8:
+  case X86::MOVZX16rr8:
+  case X86::MOVSX32rr8:
+  case X86::MOVZX32rr8:
+  case X86::MOVSX64rr8:
+  case X86::MOVZX64rr8:
+  case X86::MOVSX32rr16:
+  case X86::MOVZX32rr16:
+  case X86::MOVSX64rr16:
+  case X86::MOVZX64rr16:
+  case X86::MOVSX64rr32:
+  case X86::MOVZX64rr32: {
+    if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg())
+      // Be conservative.
+      return false;
+    isCopy = false;
+    SrcReg = MI.getOperand(1).getReg();
+    DstReg = MI.getOperand(0).getReg();
+    DstSubIdx = 0;
+    switch (MI.getOpcode()) {
+    default:
+      llvm_unreachable(0);
+      break;
+    case X86::MOVSX16rr8:
+    case X86::MOVZX16rr8:
+    case X86::MOVSX32rr8:
+    case X86::MOVZX32rr8:
+    case X86::MOVSX64rr8:
+    case X86::MOVZX64rr8:
+      SrcSubIdx = 1;
+      break;
+    case X86::MOVSX32rr16:
+    case X86::MOVZX32rr16:
+    case X86::MOVSX64rr16:
+    case X86::MOVZX64rr16:
+      SrcSubIdx = 3;
+      break;
+    case X86::MOVSX64rr32:
+    case X86::MOVZX64rr32:
+      SrcSubIdx = 4;
+      break;
+    }
+  }
+  }
+  return isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
+}
+
 /// isFrameOperand - Return true and the FrameIndex if the specified
 /// operand and follow operands form a reference to the stack frame.
 bool X86InstrInfo::isFrameOperand(const MachineInstr *MI, unsigned int Op,
index b83441d89effdf4bec3bd2d99f73ec97966eb7c3..6ae7808e2dd840d551af6fefe92197b175d704d9 100644 (file)
@@ -448,6 +448,14 @@ public:
                            unsigned &SrcReg, unsigned &DstReg,
                            unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
 
+  /// isCoalescableInstr - Return true if the instruction is "coalescable". That
+  /// is, it's like a copy where it's legal for the source to overlap the
+  /// destination. e.g. X86::MOVSX64rr32.
+  virtual bool isCoalescableInstr(const MachineInstr &MI, bool &isCopy,
+                                unsigned &SrcReg, unsigned &DstReg,
+                                unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+
+
   unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
   /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination
   /// stack locations as well.  This uses a heuristic so it isn't