Implicit def instructions, e.g. X86::IMPLICIT_DEF_GR32, are always re-materializable and they should not be spilled.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44960 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 0761e05..3496b6f 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -613,8 +613,10 @@
     return false;
 
   isLoad = false;
-  if (tii_->isTriviallyReMaterializable(MI)) {
-    isLoad = MI->getInstrDescriptor()->Flags & M_LOAD_FLAG;
+  const TargetInstrDescriptor *TID = MI->getInstrDescriptor();
+  if ((TID->Flags & M_IMPLICIT_DEF_FLAG) ||
+      tii_->isTriviallyReMaterializable(MI)) {
+    isLoad = TID->Flags & M_LOAD_FLAG;
     return true;
   }
 
@@ -677,6 +679,15 @@
                                          bool isSS, int Slot, unsigned Reg) {
   unsigned MRInfo = 0;
   const TargetInstrDescriptor *TID = MI->getInstrDescriptor();
+  // If it is an implicit def instruction, just delete it.
+  if (TID->Flags & M_IMPLICIT_DEF_FLAG) {
+    RemoveMachineInstrFromMaps(MI);
+    vrm.RemoveMachineInstrFromMaps(MI);
+    MI->eraseFromParent();
+    ++numFolds;
+    return true;
+  }
+
   SmallVector<unsigned, 2> FoldOps;
   for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
     unsigned OpIdx = Ops[i];
@@ -852,7 +863,8 @@
       } else {
         CanFold = canFoldMemoryOperand(MI, Ops);
       }
-    } else CanFold = false;
+    } else
+      CanFold = false;
 
     // Create a new virtual register for the spill interval.
     bool CreatedNewVReg = false;
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 53c36f3..fd28698 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -646,6 +646,7 @@
 //===----------------------------------------------------------------------===//
 //  Miscellaneous Instructions.
 //
+let isImplicitDef = 1 in
 def IMPLICIT_DEF_GPR : 
 PseudoInst<(outs GPR:$rD), (ins pred:$p),
            "@ IMPLICIT_DEF_GPR $rD",
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index 5b7a403..b3fe2ff 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -251,12 +251,14 @@
 // FP <-> GPR Copies.  Int <-> FP Conversions.
 //
 
+let isImplicitDef = 1 in {
 def IMPLICIT_DEF_SPR : PseudoInst<(outs SPR:$rD), (ins pred:$p),
                                   "@ IMPLICIT_DEF_SPR $rD",
                                   [(set SPR:$rD, (undef))]>;
 def IMPLICIT_DEF_DPR : PseudoInst<(outs DPR:$rD), (ins pred:$p),
                                   "@ IMPLICIT_DEF_DPR $rD",
                                   [(set DPR:$rD, (undef))]>;
+}
 
 def FMRS   : ASI<(outs GPR:$dst), (ins SPR:$src),
                  "fmrs", " $dst, $src",
diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td
index da24e70..14a9849 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.td
+++ b/lib/Target/Alpha/AlphaInstrInfo.td
@@ -141,12 +141,14 @@
 
 //Pseudo ops for selection
 
+let isImplicitDef = 1 in {
 def IDEF_I : PseudoInstAlpha<(outs GPRC:$RA), (ins), ";#idef $RA",
              [(set GPRC:$RA, (undef))], s_pseudo>;
 def IDEF_F32 : PseudoInstAlpha<(outs F4RC:$RA), (ins), ";#idef $RA",
              [(set F4RC:$RA, (undef))], s_pseudo>;
 def IDEF_F64 : PseudoInstAlpha<(outs F8RC:$RA), (ins), ";#idef $RA",
              [(set F8RC:$RA, (undef))], s_pseudo>;
+}
 
 def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
 
diff --git a/lib/Target/IA64/IA64InstrInfo.td b/lib/Target/IA64/IA64InstrInfo.td
index 8801a72..7df8fd8 100644
--- a/lib/Target/IA64/IA64InstrInfo.td
+++ b/lib/Target/IA64/IA64InstrInfo.td
@@ -457,6 +457,7 @@
 // TODO: support postincrement (reg, imm9) loads+stores - this needs more
 // tablegen support
 
+let isImplicitDef = 1 in {
 def IDEF : PseudoInstIA64<(outs variable_ops), (ins), "// IDEF">;
 
 def IDEF_GR_D : PseudoInstIA64_DAG<(outs GR:$reg), (ins), "// $reg = IDEF",
@@ -465,6 +466,7 @@
     [(set FP:$reg, (undef))]>;
 def IDEF_PR_D : PseudoInstIA64_DAG<(outs PR:$reg), (ins), "// $reg = IDEF",
     [(set PR:$reg, (undef))]>;
+}
 
 def IUSE : PseudoInstIA64<(outs), (ins variable_ops), "// IUSE">;
 def ADJUSTCALLSTACKUP : PseudoInstIA64<(outs), (ins variable_ops),
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index d74ca54..4d09e8b 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -356,6 +356,7 @@
                                       [(callseq_end imm:$amt1, imm:$amt2)]>;
 }
 
+let isImplicitDef = 1 in
 def IMPLICIT_DEF_CPURegs : PseudoInstMips<(outs CPURegs:$dst), (ins),
                                           "!IMPLICIT_DEF $dst",
                                           [(set CPURegs:$dst, (undef))]>;
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 6a53a76..2aea254 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -334,6 +334,7 @@
                        [(set GPRC:$result,
                              (PPCdynalloc GPRC:$negsize, iaddr:$fpsi))]>;
                          
+let isImplicitDef = 1 in {
 def IMPLICIT_DEF_GPRC: Pseudo<(outs GPRC:$rD), (ins),
                               "${:comment}IMPLICIT_DEF_GPRC $rD",
                               [(set GPRC:$rD, (undef))]>;
@@ -343,6 +344,7 @@
 def IMPLICIT_DEF_F4  : Pseudo<(outs F4RC:$rD), (ins),
                               "${:comment} IMPLICIT_DEF_F4 $rD",
                               [(set F4RC:$rD, (undef))]>;
+}
 
 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded by the
 // scheduler into a branch sequence.
diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td
index 354e360..c0b0460 100644
--- a/lib/Target/Sparc/SparcInstrInfo.td
+++ b/lib/Target/Sparc/SparcInstrInfo.td
@@ -212,6 +212,8 @@
                             "!ADJCALLSTACKUP $amt1",
                             [(callseq_end imm:$amt1, imm:$amt2)]>;
 }
+
+let isImplicitDef = 1 in {
 def IMPLICIT_DEF_Int : Pseudo<(outs IntRegs:$dst), (ins),
                               "!IMPLICIT_DEF $dst",
                               [(set IntRegs:$dst, (undef))]>;
@@ -219,6 +221,7 @@
                               [(set FPRegs:$dst, (undef))]>;
 def IMPLICIT_DEF_DFP : Pseudo<(outs DFPRegs:$dst), (ins), "!IMPLICIT_DEF $dst",
                               [(set DFPRegs:$dst, (undef))]>;
+}
                               
 // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the 
 // fpmover pass.
diff --git a/lib/Target/Target.td b/lib/Target/Target.td
index 4c28f99..4c278bb 100644
--- a/lib/Target/Target.td
+++ b/lib/Target/Target.td
@@ -192,6 +192,7 @@
   bit isCall       = 0;     // Is this instruction a call instruction?
   bit isLoad       = 0;     // Is this instruction a load instruction?
   bit isStore      = 0;     // Is this instruction a store instruction?
+  bit isImplicitDef = 0;    // Is this instruction an implicit def instruction?
   bit isTwoAddress = 0;     // Is this a two address instruction?
   bit isConvertibleToThreeAddress = 0;  // Can this 2-addr instruction promote?
   bit isCommutable = 0;     // Is this 3 operand instruction commutable?
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index a92ff50..75be11b 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -262,6 +262,7 @@
 }
 def IMPLICIT_USE     : I<0, Pseudo, (outs), (ins variable_ops),
                          "#IMPLICIT_USE", []>;
+let isImplicitDef = 1 in {
 def IMPLICIT_DEF     : I<0, Pseudo, (outs variable_ops), (ins),
                           "#IMPLICIT_DEF", []>;
 def IMPLICIT_DEF_GR8  : I<0, Pseudo, (outs GR8:$dst), (ins),
@@ -273,6 +274,7 @@
 def IMPLICIT_DEF_GR32  : I<0, Pseudo, (outs GR32:$dst), (ins),
                          "#IMPLICIT_DEF $dst",
                          [(set GR32:$dst, (undef))]>;
+}
 
 // Nop
 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td
index c892c34..08fa0df 100644
--- a/lib/Target/X86/X86InstrMMX.td
+++ b/lib/Target/X86/X86InstrMMX.td
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 // Some 'special' instructions
+let isImplicitDef = 1 in
 def IMPLICIT_DEF_VR64 : I<0, Pseudo, (outs VR64:$dst), (ins),
                           "#IMPLICIT_DEF $dst",
                           [(set VR64:$dst, (v8i8 (undef)))]>,
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index a196dce..26767a5 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -42,6 +42,7 @@
 // SSE 'Special' Instructions
 //===----------------------------------------------------------------------===//
 
+let isImplicitDef = 1 in
 def IMPLICIT_DEF_VR128 : I<0, Pseudo, (outs VR128:$dst), (ins),
                            "#IMPLICIT_DEF $dst",
                            [(set VR128:$dst, (v4f32 (undef)))]>,
diff --git a/lib/Target/X86/X86InstrX86-64.td b/lib/Target/X86/X86InstrX86-64.td
index 2d9ca97..6dea840 100644
--- a/lib/Target/X86/X86InstrX86-64.td
+++ b/lib/Target/X86/X86InstrX86-64.td
@@ -80,6 +80,7 @@
 // Instruction list...
 //
 
+let isImplicitDef = 1 in
 def IMPLICIT_DEF_GR64  : I<0, Pseudo, (outs GR64:$dst), (ins),
                          "#IMPLICIT_DEF $dst",
                          [(set GR64:$dst, (undef))]>;