[llvm-commits] CVS: llvm/lib/Target/X86/X86InstrFPStack.td X86InstrInfo.cpp X86InstrInfo.h X86InstrInfo.td X86InstrMMX.td X86InstrSSE.td

Dan Gohman djg at cray.com
Thu Jun 21 14:56:21 PDT 2007


> I'm sorry to be such a pain, but this seems like a step backward.   
> We've gone from having an explicit flag in the .td files to having  
> another magic table in the .cpp file (somewhat amusing because  
> 'duplicable' just made the opposite transition).
> 
> How about this proposal (Obviously feel free to pick better names for  
> these things):
> 
> 1. Reintroduce the 'isremat-able' flag, set it to true for all the  
> instructions that are *potentially* rematerializable.
> 2. Add a virtual target hook that can override the flag:  
> "TII::isReallyRematerializable(Machineinstr*)".
> 3. Introduce a new non-virtual method:
>    bool TII::isRematerializable(Machineinstr *MI) {
>      return MI->flags->isrematable && isReallyRematerializable(MI);
>    }

I tried this, and got circular dependencies between libLLVMAnalysis.a,
libLLVMTarget.a, and libLLVMCodeGen.a. I think it's because the actual
code for 3. uses MachineInstr::getOpcode.

> 
> This achieves two things:
> 
> 1. Just looking at the .td file, you can tell which instructions are  
> candidates for remat.
> 2. The isRematerializable predicate is faster for instructions that  
> are not remat-able.
> 3. The isReallyRematerializable only needs to be implemented by  
> targets with instructions that are remat-able only in some cases  
> (like the x86 instructions).
> 
> To me, #1 is the killer feature.  In general, I'd like to move away  
> from having tables (either explicit, like the one in  
> X86RegisterInfo::foldMemoryOperand, or just big switch stmts) to  
> having properties on .td file entries.  That makes it much more clear  
> what is going on when inspecting the .td files.
> 
> I'm sorry I didn't look at your patch when you asked for comments,  
> but does this proposal sound sane?

*shrug*. Adding isReMaterializable flags to all the load instructions in
the X86 files isn't unambiguously prettier though. But I've already
strayed from my tangent here :-}.

Attached is a patch which does points 1 and 2 of what you describe above. 

Dan

-- 
Dan Gohman, Cray Inc.
-------------- next part --------------
Index: include/llvm/Target/TargetInstrInfo.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/Target/TargetInstrInfo.h,v
retrieving revision 1.132
diff -u -r1.132 TargetInstrInfo.h
--- include/llvm/Target/TargetInstrInfo.h
+++ include/llvm/Target/TargetInstrInfo.h
@@ -78,6 +78,10 @@
 // controls execution. It may be set to 'always'.
 const unsigned M_PREDICABLE = 1 << 12;
 
+// M_REMATERIALIZIBLE - Set if this instruction can be trivally re-materialized
+// at any time, e.g. constant generation, load from constant pool.
+const unsigned M_REMATERIALIZIBLE = 1 << 13;
+
 // M_CLOBBERS_PRED - Set if this instruction may clobbers the condition code
 // register and / or registers that are used to predicate instructions.
 const unsigned M_CLOBBERS_PRED = 1 << 14;
@@ -260,6 +264,13 @@
     return get(Opcode).Flags & M_PREDICABLE;
   }
 
+  /// isReMaterializableOpcode - Return true if this opcode can ever be trivially
+  /// rematerializable. Use use isReallyReMaterializable to test the specific
+  /// instructions for trivial rematerializability, considering their operands.
+  bool isReMaterializableOpcode(MachineOpCode Opcode) const {
+    return get(Opcode).Flags & M_REMATERIALIZIBLE;
+  }
+
   bool clobbersPredicate(MachineOpCode Opcode) const {
     return get(Opcode).Flags & M_CLOBBERS_PRED;
   }
@@ -301,14 +312,16 @@
     return 0;
   }
 
-  /// isTriviallyReMaterializable - If the specified machine instruction can
-  /// be trivally re-materialized  at any time, e.g. constant generation or
-  /// loads from constant pools. If not, return false.  This predicate must
+  /// isReallyReMaterializable - For instructions with opcodes for which
+  /// the M_REMATERIALIZABLE flag is set, this function tests whether the
+  /// instruction itself is actually trivially rematerializable, considering
+  /// its operands.  This is used for targets that have instructions that are
+  /// only trivially rematerializable for specific uses.  This predicate must
   /// return false if the instruction has any side effects other than
   /// producing the value from the load, or if it requres any address
   /// registers that are not always available.
-  virtual bool isTriviallyReMaterializable(MachineInstr *MI) const {
-    return false;
+  virtual bool isReallyReMaterializable(MachineInstr *MI) const {
+    return true;
   }
 
   /// convertToThreeAddress - This method must be implemented by targets that
Index: lib/CodeGen/LiveIntervalAnalysis.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp,v
retrieving revision 1.248
diff -u -r1.248 LiveIntervalAnalysis.cpp
--- lib/CodeGen/LiveIntervalAnalysis.cpp
+++ lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -340,7 +340,8 @@
     // instructions to be re-materialized as well.
     int FrameIdx = 0;
     if (vi.DefInst &&
-        (tii_->isTriviallyReMaterializable(vi.DefInst) ||
+        ((tii_->isReMaterializableOpcode(vi.DefInst->getOpcode()) &&
+          tii_->isReallyReMaterializable(vi.DefInst)) ||
          (tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) &&
           mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx))))
       interval.remat = vi.DefInst;
Index: lib/CodeGen/VirtRegMap.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/VirtRegMap.cpp,v
retrieving revision 1.113
diff -u -r1.113 VirtRegMap.cpp
--- lib/CodeGen/VirtRegMap.cpp
+++ lib/CodeGen/VirtRegMap.cpp
@@ -663,7 +663,8 @@
 
     // If this instruction is being rematerialized, just remove it!
     int FrameIdx;
-    if (TII->isTriviallyReMaterializable(&MI) ||
+    if ((TII->isReMaterializableOpcode(MI.getOpcode()) &&
+         TII->isReallyReMaterializable(&MI))  ||
         TII->isLoadFromStackSlot(&MI, FrameIdx)) {
       bool Remove = true;
       for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
Index: lib/Target/Target.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/Target.td,v
retrieving revision 1.105
diff -u -r1.105 Target.td
--- lib/Target/Target.td
+++ lib/Target/Target.td
@@ -186,6 +186,7 @@
   bit isConvertibleToThreeAddress = 0;  // Can this 2-addr instruction promote?
   bit isCommutable = 0;     // Is this 3 operand instruction commutable?
   bit isTerminator = 0;     // Is this part of the terminator for a basic block?
+  bit isReMaterializable = 0; // Is this instruction re-materializable?
   bit isPredicable = 0;     // Is this instruction predicable?
   bit hasDelaySlot = 0;     // Does this instruction have an delay slot?
   bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help.
Index: lib/Target/ARM/ARMInstrInfo.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/ARM/ARMInstrInfo.cpp,v
retrieving revision 1.39
diff -u -r1.39 ARMInstrInfo.cpp
--- lib/Target/ARM/ARMInstrInfo.cpp
+++ lib/Target/ARM/ARMInstrInfo.cpp
@@ -130,20 +130,6 @@
   return 0;
 }
 
-bool ARMInstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const {
-  switch (MI->getOpcode()) {
-  default: break;
-  case ARM::LDRcp:
-  case ARM::MOVi:
-  case ARM::MVNi:
-  case ARM::MOVi2pieces:
-  case ARM::tLDRcp:
-    // These instructions are always trivially rematerializable.
-    return true;
-  }
-  return false;
-}
-
 static unsigned getUnindexedOpcode(unsigned Opc) {
   switch (Opc) {
   default: break;
Index: lib/Target/ARM/ARMInstrInfo.h
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/ARM/ARMInstrInfo.h,v
retrieving revision 1.16
diff -u -r1.16 ARMInstrInfo.h
--- lib/Target/ARM/ARMInstrInfo.h
+++ lib/Target/ARM/ARMInstrInfo.h
@@ -87,7 +87,6 @@
                            unsigned &SrcReg, unsigned &DstReg) const;
   virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
   virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
-  virtual bool isTriviallyReMaterializable(MachineInstr *MI) const;
   
   virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
                                               MachineBasicBlock::iterator &MBBI,
Index: lib/Target/ARM/ARMInstrInfo.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/ARM/ARMInstrInfo.td,v
retrieving revision 1.113
diff -u -r1.113 ARMInstrInfo.td
--- lib/Target/ARM/ARMInstrInfo.td
+++ lib/Target/ARM/ARMInstrInfo.td
@@ -677,6 +677,7 @@
                [(set GPR:$dst, (load addrmode2:$addr))]>;
 
 // Special LDR for loads from non-pc-relative constpools.
+let isReMaterializable = 1 in
 def LDRcp : AI2<(ops GPR:$dst, addrmode2:$addr),
                  "ldr", " $dst, $addr", []>;
 
@@ -810,6 +811,7 @@
 def MOVs : AI1<(ops GPR:$dst, so_reg:$src),
                 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>;
 
+let isReMaterializable = 1 in
 def MOVi : AI1<(ops GPR:$dst, so_imm:$src),
                 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>;
 
@@ -917,6 +919,7 @@
                 "mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>;
 def  MVNs  : AI<(ops GPR:$dst, so_reg:$src),
                 "mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>;
+let isReMaterializable = 1 in
 def  MVNi  : AI<(ops GPR:$dst, so_imm:$imm),
                 "mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>;
 
@@ -1187,6 +1190,7 @@
 // Large immediate handling.
 
 // Two piece so_imms.
+let isReMaterializable = 1 in
 def MOVi2pieces : AI1x2<(ops GPR:$dst, so_imm2part:$src),
                          "mov", " $dst, $src",
                          [(set GPR:$dst, so_imm2part:$src)]>;
Index: lib/Target/ARM/ARMInstrThumb.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/ARM/ARMInstrThumb.td,v
retrieving revision 1.32
diff -u -r1.32 ARMInstrThumb.td
--- lib/Target/ARM/ARMInstrThumb.td
+++ lib/Target/ARM/ARMInstrThumb.td
@@ -267,6 +267,7 @@
                   [(set GPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
 
 // Special LDR for loads from non-pc-relative constpools.
+let isReMaterializable = 1 in
 def tLDRcp  : TIs<(ops GPR:$dst, i32imm:$addr),
                   "ldr $dst, $addr", []>;
 } // isLoad
Index: lib/Target/X86/X86InstrFPStack.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrFPStack.td,v
retrieving revision 1.10
diff -u -r1.10 X86InstrFPStack.td
--- lib/Target/X86/X86InstrFPStack.td
+++ lib/Target/X86/X86InstrFPStack.td
@@ -356,6 +356,7 @@
 // Floating point loads & stores.
 def FpLD32m  : FpI<(ops RFP:$dst, f32mem:$src), ZeroArgFP,
                    [(set RFP:$dst, (extloadf64f32 addr:$src))]>;
+let isReMaterializable = 1 in
 def FpLD64m  : FpI<(ops RFP:$dst, f64mem:$src), ZeroArgFP,
                    [(set RFP:$dst, (loadf64 addr:$src))]>;
 def FpILD16m : FpI<(ops RFP:$dst, i16mem:$src), ZeroArgFP,
@@ -413,10 +414,12 @@
 def FXCH    : FPI<0xC8, AddRegFrm, (ops RST:$op), "fxch $op">, D9;
 
 // Floating point constant loads.
+let isReMaterializable = 1 in {
 def FpLD0 : FpI<(ops RFP:$dst), ZeroArgFP,
                 [(set RFP:$dst, fp64imm0)]>;
 def FpLD1 : FpI<(ops RFP:$dst), ZeroArgFP,
                 [(set RFP:$dst, fp64imm1)]>;
+}
 
 def FLD0 : FPI<0xEE, RawFrm, (ops), "fldz">, D9;
 def FLD1 : FPI<0xE8, RawFrm, (ops), "fld1">, D9;
Index: lib/Target/X86/X86InstrInfo.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrInfo.cpp,v
retrieving revision 1.92
diff -u -r1.92 X86InstrInfo.cpp
--- lib/Target/X86/X86InstrInfo.cpp
+++ lib/Target/X86/X86InstrInfo.cpp
@@ -112,20 +112,11 @@
 }
 
 
-bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const {
+bool X86InstrInfo::isReallyReMaterializable(MachineInstr *MI) const {
+  assert(isReMaterializableOpcode(MI->getOpcode()) &&
+         "Check isReMaterializableOpcode before checking isReallyReMaterializable");
   switch (MI->getOpcode()) {
   default: break;
-  case X86::FpLD0:
-  case X86::FpLD1:
-  case X86::MOV8ri:
-  case X86::MOV16ri:
-  case X86::MOV32ri:
-  case X86::MMX_V_SET0:
-  case X86::MMX_V_SETALLONES:
-  case X86::V_SET0:
-  case X86::V_SETALLONES:
-    // These instructions are always trivially rematerializable.
-    return true;
   case X86::MOV8rm:
   case X86::MOV16rm:
   case X86::MOV16_rm:
@@ -146,7 +137,9 @@
            MI->getOperand(2).getImmedValue() == 1 &&
            MI->getOperand(3).getReg() == 0;
   }
-  return false;
+  // All other isReMaterializable instructions are always trivially
+  // rematerializable.
+  return true;
 }
 
 /// convertToThreeAddress - This method must be implemented by targets that
Index: lib/Target/X86/X86InstrInfo.h
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrInfo.h,v
retrieving revision 1.67
diff -u -r1.67 X86InstrInfo.h
--- lib/Target/X86/X86InstrInfo.h
+++ lib/Target/X86/X86InstrInfo.h
@@ -239,7 +239,7 @@
                    unsigned& destReg) const;
   unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
   unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
-  bool isTriviallyReMaterializable(MachineInstr *MI) const;
+  bool isReallyReMaterializable(MachineInstr *MI) const;
   
   /// convertToThreeAddress - This method must be implemented by targets that
   /// set the M_CONVERTIBLE_TO_3_ADDR flag.  When this flag is set, the target
Index: lib/Target/X86/X86InstrInfo.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrInfo.td,v
retrieving revision 1.308
diff -u -r1.308 X86InstrInfo.td
--- lib/Target/X86/X86InstrInfo.td
+++ lib/Target/X86/X86InstrInfo.td
@@ -617,6 +617,7 @@
                 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32rr : I<0x89, MRMDestReg, (ops GR32:$dst, GR32:$src),
                 "mov{l} {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in {
 def MOV8ri  : Ii8 <0xB0, AddRegFrm, (ops GR8 :$dst, i8imm :$src),
                    "mov{b} {$src, $dst|$dst, $src}",
                    [(set GR8:$dst, imm:$src)]>;
@@ -626,6 +627,7 @@
 def MOV32ri : Ii32<0xB8, AddRegFrm, (ops GR32:$dst, i32imm:$src),
                    "mov{l} {$src, $dst|$dst, $src}",
                    [(set GR32:$dst, imm:$src)]>;
+}
 def MOV8mi  : Ii8 <0xC6, MRM0m, (ops i8mem :$dst, i8imm :$src),
                    "mov{b} {$src, $dst|$dst, $src}",
                    [(store (i8 imm:$src), addr:$dst)]>;
@@ -636,6 +638,7 @@
                    "mov{l} {$src, $dst|$dst, $src}",
                    [(store (i32 imm:$src), addr:$dst)]>;
 
+let isReMaterializable = 1 in {
 def MOV8rm  : I<0x8A, MRMSrcMem, (ops GR8 :$dst, i8mem :$src),
                 "mov{b} {$src, $dst|$dst, $src}",
                 [(set GR8:$dst, (load addr:$src))]>;
@@ -645,6 +648,7 @@
 def MOV32rm : I<0x8B, MRMSrcMem, (ops GR32:$dst, i32mem:$src),
                 "mov{l} {$src, $dst|$dst, $src}",
                 [(set GR32:$dst, (load addr:$src))]>;
+}
 
 def MOV8mr  : I<0x88, MRMDestMem, (ops i8mem :$dst, GR8 :$src),
                 "mov{b} {$src, $dst|$dst, $src}",
@@ -2447,10 +2451,12 @@
                 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32_rr : I<0x89, MRMDestReg, (ops GR32_:$dst, GR32_:$src),
                 "mov{l} {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in {
 def MOV16_rm : I<0x8B, MRMSrcMem, (ops GR16_:$dst, i16mem:$src),
                 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32_rm : I<0x8B, MRMSrcMem, (ops GR32_:$dst, i32mem:$src),
                 "mov{l} {$src, $dst|$dst, $src}", []>;
+}
 def MOV16_mr : I<0x89, MRMDestMem, (ops i16mem:$dst, GR16_:$src),
                 "mov{w} {$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32_mr : I<0x89, MRMDestMem, (ops i32mem:$dst, GR32_:$src),
Index: lib/Target/X86/X86InstrMMX.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrMMX.td,v
retrieving revision 1.33
diff -u -r1.33 X86InstrMMX.td
--- lib/Target/X86/X86InstrMMX.td
+++ lib/Target/X86/X86InstrMMX.td
@@ -178,6 +178,7 @@
 // Data Transfer Instructions
 def MMX_MOVD64rr : MMXI<0x6E, MRMSrcReg, (ops VR64:$dst, GR32:$src),
                         "movd {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in
 def MMX_MOVD64rm : MMXI<0x6E, MRMSrcMem, (ops VR64:$dst, i32mem:$src),
                         "movd {$src, $dst|$dst, $src}", []>;
 def MMX_MOVD64mr : MMXI<0x7E, MRMDestMem, (ops i32mem:$dst, VR64:$src),
@@ -185,6 +186,7 @@
 
 def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (ops VR64:$dst, VR64:$src),
                         "movq {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in
 def MMX_MOVQ64rm : MMXI<0x6F, MRMSrcMem, (ops VR64:$dst, i64mem:$src),
                         "movq {$src, $dst|$dst, $src}",
                         [(set VR64:$dst, (load_mmx addr:$src))]>;
@@ -503,12 +505,14 @@
 
 // Alias instructions that map zero vector to pxor.
 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
-def MMX_V_SET0       : MMXI<0xEF, MRMInitReg, (ops VR64:$dst),
-                            "pxor $dst, $dst",
-                            [(set VR64:$dst, (v1i64 immAllZerosV))]>;
-def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (ops VR64:$dst),
-                            "pcmpeqd $dst, $dst",
-                            [(set VR64:$dst, (v1i64 immAllOnesV))]>;
+let isReMaterializable = 1 in {
+  def MMX_V_SET0       : MMXI<0xEF, MRMInitReg, (ops VR64:$dst),
+                              "pxor $dst, $dst",
+                              [(set VR64:$dst, (v1i64 immAllZerosV))]>;
+  def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (ops VR64:$dst),
+                              "pcmpeqd $dst, $dst",
+                              [(set VR64:$dst, (v1i64 immAllOnesV))]>;
+}
 
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
Index: lib/Target/X86/X86InstrSSE.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrSSE.td,v
retrieving revision 1.184
diff -u -r1.184 X86InstrSSE.td
--- lib/Target/X86/X86InstrSSE.td
+++ lib/Target/X86/X86InstrSSE.td
@@ -260,6 +260,7 @@
 // Move Instructions
 def MOVSSrr : SSI<0x10, MRMSrcReg, (ops FR32:$dst, FR32:$src),
                   "movss {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in
 def MOVSSrm : SSI<0x10, MRMSrcMem, (ops FR32:$dst, f32mem:$src),
                   "movss {$src, $dst|$dst, $src}",
                   [(set FR32:$dst, (loadf32 addr:$src))]>;
@@ -480,6 +481,7 @@
 // Move Instructions
 def MOVAPSrr : PSI<0x28, MRMSrcReg, (ops VR128:$dst, VR128:$src),
                    "movaps {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in
 def MOVAPSrm : PSI<0x28, MRMSrcMem, (ops VR128:$dst, f128mem:$src),
                    "movaps {$src, $dst|$dst, $src}",
                    [(set VR128:$dst, (loadv4f32 addr:$src))]>;
@@ -759,6 +761,7 @@
 
 // Alias instructions that map zero vector to pxor / xorp* for sse.
 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
+let isReMaterializable = 1 in
 def V_SET0 : PSI<0x57, MRMInitReg, (ops VR128:$dst),
                  "xorps $dst, $dst",
                  [(set VR128:$dst, (v4f32 immAllZerosV))]>;
@@ -844,6 +847,7 @@
 // Move Instructions
 def MOVSDrr : SDI<0x10, MRMSrcReg, (ops FR64:$dst, FR64:$src),
                   "movsd {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in
 def MOVSDrm : SDI<0x10, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
                   "movsd {$src, $dst|$dst, $src}",
                   [(set FR64:$dst, (loadf64 addr:$src))]>;
@@ -1065,6 +1069,7 @@
 // Move Instructions
 def MOVAPDrr : PDI<0x28, MRMSrcReg, (ops VR128:$dst, VR128:$src),
                    "movapd {$src, $dst|$dst, $src}", []>;
+let isReMaterializable = 1 in
 def MOVAPDrm : PDI<0x28, MRMSrcMem, (ops VR128:$dst, f128mem:$src),
                    "movapd {$src, $dst|$dst, $src}",
                    [(set VR128:$dst, (loadv2f64 addr:$src))]>;
@@ -1818,9 +1823,10 @@
 
 // Alias instructions that map zero vector to pxor / xorp* for sse.
 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
-def V_SETALLONES : PDI<0x76, MRMInitReg, (ops VR128:$dst),
-                       "pcmpeqd $dst, $dst",
-                       [(set VR128:$dst, (v2f64 immAllOnesV))]>;
+let isReMaterializable = 1 in
+  def V_SETALLONES : PDI<0x76, MRMInitReg, (ops VR128:$dst),
+                         "pcmpeqd $dst, $dst",
+                         [(set VR128:$dst, (v2f64 immAllOnesV))]>;
 
 // FR64 to 128-bit vector conversion.
 def MOVSD2PDrr : SDI<0x10, MRMSrcReg, (ops VR128:$dst, FR64:$src),
Index: lib/Target/X86/X86InstrX86-64.td
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/X86/X86InstrX86-64.td,v
retrieving revision 1.17
diff -u -r1.17 X86InstrX86-64.td
--- lib/Target/X86/X86InstrX86-64.td
+++ lib/Target/X86/X86InstrX86-64.td
@@ -187,6 +187,7 @@
                       "mov{q} {$src, $dst|$dst, $src}",
                       [(set GR64:$dst, i64immSExt32:$src)]>;
 
+let isReMaterializable = 1 in
 def MOV64rm : RI<0x8B, MRMSrcMem, (ops GR64:$dst, i64mem:$src),
                  "mov{q} {$src, $dst|$dst, $src}",
                  [(set GR64:$dst, (load addr:$src))]>;
Index: utils/TableGen/CodeGenInstruction.h
===================================================================
RCS file: /var/cvs/llvm/llvm/utils/TableGen/CodeGenInstruction.h,v
retrieving revision 1.30
diff -u -r1.30 CodeGenInstruction.h
--- utils/TableGen/CodeGenInstruction.h
+++ utils/TableGen/CodeGenInstruction.h
@@ -91,6 +91,7 @@
     bool isConvertibleToThreeAddress;
     bool isCommutable;
     bool isTerminator;
+    bool isReMaterializable;
     bool hasDelaySlot;
     bool usesCustomDAGSchedInserter;
     bool hasVariableNumberOfOperands;
Index: utils/TableGen/CodeGenTarget.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/utils/TableGen/CodeGenTarget.cpp,v
retrieving revision 1.94
diff -u -r1.94 CodeGenTarget.cpp
--- utils/TableGen/CodeGenTarget.cpp
+++ utils/TableGen/CodeGenTarget.cpp
@@ -365,6 +365,7 @@
   isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
   isCommutable = R->getValueAsBit("isCommutable");
   isTerminator = R->getValueAsBit("isTerminator");
+  isReMaterializable = R->getValueAsBit("isReMaterializable");
   hasDelaySlot = R->getValueAsBit("hasDelaySlot");
   usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
   hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
Index: utils/TableGen/InstrInfoEmitter.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/utils/TableGen/InstrInfoEmitter.cpp,v
retrieving revision 1.62
diff -u -r1.62 InstrInfoEmitter.cpp
--- utils/TableGen/InstrInfoEmitter.cpp
+++ utils/TableGen/InstrInfoEmitter.cpp
@@ -240,6 +240,7 @@
   if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR";
   if (Inst.isCommutable) OS << "|M_COMMUTABLE";
   if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
+  if (Inst.isReMaterializable) OS << "|M_REMATERIALIZIBLE";
   if (Inst.clobbersPred) OS << "|M_CLOBBERS_PRED";
   if (Inst.isNotDuplicable) OS << "|M_NOT_DUPLICABLE";
   if (Inst.usesCustomDAGSchedInserter)


More information about the llvm-commits mailing list