Make insert_subreg a two-address instruction, vastly simplifying LowerSubregs pass. Add a new TII, subreg_to_reg, which is like insert_subreg except that it takes an immediate implicit value to insert into rather than a register.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48412 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Target.td b/lib/Target/Target.td
index 9d49bd2..6e2ba91 100644
--- a/lib/Target/Target.td
+++ b/lib/Target/Target.td
@@ -366,6 +366,7 @@
   let AsmString = "";
   let Namespace = "TargetInstrInfo";
   let neverHasSideEffects = 1;
+  let Constraints = "$supersrc = $dst";
 }
 def IMPLICIT_DEF : Instruction {
   let OutOperandList = (ops unknown:$dst);
@@ -374,6 +375,13 @@
   let Namespace = "TargetInstrInfo";
   let neverHasSideEffects = 1;
 }
+def SUBREG_TO_REG : Instruction {
+  let OutOperandList = (ops unknown:$dst);
+  let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
+  let AsmString = "";
+  let Namespace = "TargetInstrInfo";
+  let neverHasSideEffects = 1;
+}
 
 //===----------------------------------------------------------------------===//
 // AsmWriter - This class can be implemented by targets that need to customize
diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td
index 73280f3..d70cc75 100644
--- a/lib/Target/TargetSelectionDAG.td
+++ b/lib/Target/TargetSelectionDAG.td
@@ -918,11 +918,3 @@
 def SDT_dwarf_loc : SDTypeProfile<0, 3,
                       [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
 def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;
-
-//===----------------------------------------------------------------------===//
-// Implict value insert subreg support.
-//
-// These should match the enum TargetInstrInfo::ImplictVal.
-def tii_impl_val_undef : PatLeaf<(i32 0)>;
-def tii_impl_val_zero  : PatLeaf<(i32 1)>;
-
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index bf233bf..7a55d9d 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1529,39 +1529,36 @@
     }
 
     case ISD::ANY_EXTEND: {
+      // Check if the type  extended to supports subregs.
+      if (NVT == MVT::i8)
+        break;
+      
       SDOperand N0 = Node->getOperand(0);
+      // Get the subregsiter index for the type to extend.
+      MVT::ValueType N0VT = N0.getValueType();
+      unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT :
+                      (N0VT == MVT::i16) ? X86::SUBREG_16BIT :
+                        (Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0;
+      
+      // If we don't have a subreg Idx, let generated ISel have a try.
+      if (Idx == 0)
+        break;
+        
+      // If we have an index, generate an insert_subreg into undef.
       AddToISelQueue(N0);
-      if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
-        SDOperand SRIdx;
-        switch(N0.getValueType()) {
-        case MVT::i32:
-          SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
-          break;
-        case MVT::i16:
-          SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
-          break;
-        case MVT::i8:
-          if (Subtarget->is64Bit())
-            SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
-          break;
-        default: assert(0 && "Unknown any_extend!");
-        }
-        if (SRIdx.Val) {
-          SDOperand ImplVal = 
-              CurDAG->getTargetConstant(X86InstrInfo::IMPL_VAL_UNDEF, MVT::i32);
-          SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
-                                                  NVT, ImplVal, N0, SRIdx);
+      SDOperand Undef = 
+                  SDOperand(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0);
+      SDOperand SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32);
+      SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
+                                                NVT, Undef, N0, SRIdx);
 
 #ifndef NDEBUG
-          DOUT << std::string(Indent-2, ' ') << "=> ";
-          DEBUG(ResNode->dump(CurDAG));
-          DOUT << "\n";
-          Indent -= 2;
+      DOUT << std::string(Indent-2, ' ') << "=> ";
+      DEBUG(ResNode->dump(CurDAG));
+      DOUT << "\n";
+      Indent -= 2;
 #endif
-          return ResNode;
-        } // Otherwise let generated ISel handle it.
-      }
-      break;
+      return ResNode;
     }
     
     case ISD::SIGN_EXTEND_INREG: {
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 730f393..59d7afc 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -1202,43 +1202,43 @@
 
 
 // Zero-extension
-def : Pat<(i64 (zext GR32:$src)), (INSERT_SUBREG tii_impl_val_zero, 
-                                            GR32:$src, x86_subreg_32bit)>;
+def : Pat<(i64 (zext GR32:$src)), 
+          (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
 
 // zextload bool -> zextload byte
 def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
 
-def : Pat<(zextloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_zero, 
-                                        (MOV32rm addr:$src), x86_subreg_32bit)>;
+def : Pat<(zextloadi64i32 addr:$src), 
+          (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), x86_subreg_32bit)>;
 
 // extload
 def : Pat<(extloadi64i1 addr:$src),  (MOVZX64rm8  addr:$src)>;
 def : Pat<(extloadi64i8 addr:$src),  (MOVZX64rm8  addr:$src)>;
 def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
-def : Pat<(extloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_undef, 
-                                        (MOV32rm addr:$src), x86_subreg_32bit)>;
+def : Pat<(extloadi64i32 addr:$src), 
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src), 
+                                                  x86_subreg_32bit)>;
 
 // anyext -> zext
 def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8  GR8 :$src)>;
 def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>;
-def : Pat<(i64 (anyext GR32:$src)), (INSERT_SUBREG tii_impl_val_undef, 
-                                        GR32:$src, x86_subreg_32bit)>;
+def : Pat<(i64 (anyext GR32:$src)), 
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
 
 def : Pat<(i64 (anyext (loadi8  addr:$src))), (MOVZX64rm8  addr:$src)>;
 def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>;
-def : Pat<(i64 (anyext (loadi32 addr:$src))), (INSERT_SUBREG tii_impl_val_undef, 
-                                                (MOV32rm addr:$src), 
-                                                  x86_subreg_32bit)>;
+def : Pat<(i64 (anyext (loadi32 addr:$src))), 
+          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src), 
+                                                    x86_subreg_32bit)>;
 
 //===----------------------------------------------------------------------===//
 // Some peepholes
 //===----------------------------------------------------------------------===//
 
-
 // r & (2^32-1) ==> mov32 + implicit zext
 def : Pat<(and GR64:$src, i64immFFFFFFFF), 
-          (INSERT_SUBREG tii_impl_val_zero, 
-            (MOV32rr (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)),
+          (SUBREG_TO_REG (i64 0), 
+            (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)),
             x86_subreg_32bit)>;
 
 // (shl x, 1) ==> (add x, x)
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index ff666ff..650ab41 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -920,10 +920,11 @@
             
       // Build and insert into an implicit UNDEF value. This is OK because
       // well be shifting and then extracting the lower 16-bits. 
+      MachineInstr *Undef = BuildMI(get(X86::IMPLICIT_DEF), leaInReg);
+      
       MachineInstr *Ins = 
        BuildMI(get(X86::INSERT_SUBREG),leaInReg)
-                    .addImm(X86InstrInfo::IMPL_VAL_UNDEF)
-                    .addReg(Src).addImm(X86::SUBREG_16BIT);
+                    .addReg(leaInReg).addReg(Src).addImm(X86::SUBREG_16BIT);
       
       NewMI = BuildMI(get(Opc), leaOutReg)
         .addReg(0).addImm(1 << ShAmt).addReg(leaInReg).addImm(0);
@@ -933,6 +934,7 @@
          .addReg(leaOutReg).addImm(X86::SUBREG_16BIT);
       Ext->copyKillDeadInfo(MI);
       
+      MFI->insert(MBBI, Undef);
       MFI->insert(MBBI, Ins);            // Insert the insert_subreg
       LV.instructionChanged(MI, NewMI);  // Update live variables
       LV.addVirtualRegisterKilled(leaInReg, NewMI);