Replace M_REMATERIALIZIBLE and the newly-added isOtherReMaterializableLoad
authorDan Gohman <gohman@apple.com>
Tue, 19 Jun 2007 01:48:05 +0000 (01:48 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 19 Jun 2007 01:48:05 +0000 (01:48 +0000)
with a general target hook to identify rematerializable instructions. Some
instructions are only rematerializable with specific operands, such as loads
from constant pools, while others are always rematerializable. This hook
allows both to be identified as being rematerializable with the same
mechanism.

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

17 files changed:
include/llvm/Target/TargetInstrInfo.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/VirtRegMap.cpp
lib/Target/ARM/ARMInstrInfo.cpp
lib/Target/ARM/ARMInstrInfo.h
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/Target.td
lib/Target/X86/X86InstrFPStack.td
lib/Target/X86/X86InstrInfo.cpp
lib/Target/X86/X86InstrInfo.h
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86InstrMMX.td
lib/Target/X86/X86InstrSSE.td
utils/TableGen/CodeGenInstruction.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/InstrInfoEmitter.cpp

index 2a1843f8df7c23bc5982af3c74bd73cda66f8fe2..339b39171fd512d85590cd8cc69be90cac4321fb 100644 (file)
@@ -78,10 +78,6 @@ const unsigned M_VARIABLE_OPS = 1 << 11;
 // 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;
@@ -264,10 +260,6 @@ public:
     return get(Opcode).Flags & M_PREDICABLE;
   }
 
-  bool isReMaterializable(MachineOpCode Opcode) const {
-    return get(Opcode).Flags & M_REMATERIALIZIBLE;
-  }
-
   bool clobbersPredicate(MachineOpCode Opcode) const {
     return get(Opcode).Flags & M_CLOBBERS_PRED;
   }
@@ -309,13 +301,13 @@ public:
     return 0;
   }
 
-  /// isOtherReMaterializableLoad - If the specified machine instruction is a
-  /// direct load that is trivially rematerializable, not counting loads from
-  /// stack slots, return true. If not, return false.  This predicate must
+  /// 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
   /// 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 isOtherReMaterializableLoad(MachineInstr *MI) const {
+  virtual bool isTriviallyReMaterializable(MachineInstr *MI) const {
     return false;
   }
 
index aae27bb882d2511a676e06bbfb5b16fbe58047e5..34134520d65460f6b2c36e001e66eeed5fb1b654 100644 (file)
@@ -336,14 +336,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
   // time we see a vreg.
   if (interval.empty()) {
     // Remember if the definition can be rematerialized. All load's from fixed
-    // stack slots are re-materializable. The target may permit other loads to
-    // be re-materialized as well.
+    // stack slots are re-materializable. The target may permit other
+    // instructions to be re-materialized as well.
     int FrameIdx = 0;
     if (vi.DefInst &&
-        (tii_->isReMaterializable(vi.DefInst->getOpcode()) ||
+        (tii_->isTriviallyReMaterializable(vi.DefInst) ||
          (tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) &&
-          mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx)) ||
-         tii_->isOtherReMaterializableLoad(vi.DefInst)))
+          mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx))))
       interval.remat = vi.DefInst;
 
     // Get the Idx of the defining instructions.
index 95453b0e3d529cc4bcb3eb31dbeb2412f035c4aa..1f9c1649d449f10e7f54f2aa12ff6d79be202fc9 100644 (file)
@@ -663,9 +663,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
 
     // If this instruction is being rematerialized, just remove it!
     int FrameIdx;
-    if ((TID->Flags & M_REMATERIALIZIBLE) ||
-        TII->isLoadFromStackSlot(&MI, FrameIdx) ||
-        TII->isOtherReMaterializableLoad(&MI)) {
+    if (TII->isTriviallyReMaterializable(&MI) ||
+        TII->isLoadFromStackSlot(&MI, FrameIdx)) {
       bool Remove = true;
       for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
         MachineOperand &MO = MI.getOperand(i);
index 1370faba4d7c9e592f4679bb4f9732b602a73f49..a1e02581cd0f066787167a4bb6fb2644e25d44a0 100644 (file)
@@ -130,6 +130,20 @@ unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) con
   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 5b406cb8168f67626f9bbd53f08dd652ef0d3acb..8e6a2fd5ad786f10c7781ccf883a899de423c055 100644 (file)
@@ -87,6 +87,7 @@ public:
                            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 33a41a0607e3b796dd8ddeb8e6a99e71107ad605..5a7b72bdd98acc45f325b134756810d1bd987989 100644 (file)
@@ -670,7 +670,6 @@ def LDR  : AI2<(ops GPR:$dst, addrmode2:$addr),
                [(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", []>;
 
@@ -804,7 +803,6 @@ def MOVr : AI1<(ops GPR:$dst, GPR:$src),
 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)]>;
 
@@ -912,7 +910,6 @@ def  MVNr  : AI<(ops GPR:$dst, GPR:$src),
                 "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)]>;
 
@@ -1183,7 +1180,6 @@ def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
 // 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 996b635338e68140324c01b063bd5a83b871aa71..de71410e0afebfe5c40370b8c7cd6cd9b089c017 100644 (file)
@@ -267,7 +267,6 @@ def tLDRpci : TIs<(ops GPR:$dst, i32imm:$addr),
                   [(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 43e3af8667a61adb2178d6317ffad2efbeb7d04a..2258199ddf071be475f5677ccca1258613b54f56 100644 (file)
@@ -186,7 +186,6 @@ class Instruction {
   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 848d370db4d06969f1e0accd6da7cdc3b2572a2f..48b216a199c7d69ec3d8c9167a0496aa4fe967fc 100644 (file)
@@ -413,12 +413,10 @@ def FSTPrr  : FPI<0xD8, AddRegFrm, (ops RST:$op), "fstp $op">, DD;
 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 c8621ad1b73693712495111097a5c280ed0b66ff..0e02ef0be84d5feeb0bee20222b0702975f5a417 100644 (file)
@@ -112,9 +112,20 @@ unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI,
 }
 
 
-bool X86InstrInfo::isOtherReMaterializableLoad(MachineInstr *MI) const {
+bool X86InstrInfo::isTriviallyReMaterializable(MachineInstr *MI) const {
   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:
@@ -128,6 +139,7 @@ bool X86InstrInfo::isOtherReMaterializableLoad(MachineInstr *MI) const {
   case X86::MOVAPDrm:
   case X86::MMX_MOVD64rm:
   case X86::MMX_MOVQ64rm:
+    // Loads from constant pools are trivially rematerializable.
     return MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate() &&
            MI->getOperand(3).isRegister() && MI->getOperand(4).isConstantPoolIndex() &&
            MI->getOperand(1).getReg() == 0 &&
index 75cce47401dcb0a0cdb66a573c539ab4ef53b233..f3d571a43dd695b4bcc5eca59eec31f5fc0db33c 100644 (file)
@@ -239,7 +239,7 @@ public:
                    unsigned& destReg) const;
   unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
   unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
-  bool isOtherReMaterializableLoad(MachineInstr *MI) const;
+  bool isTriviallyReMaterializable(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 f8eac7e70496f10e14b33824c5bb22c67d8d4e77..a221c42a1bd52e0e44d39db548f0798fe24e65d6 100644 (file)
@@ -617,7 +617,6 @@ def MOV16rr : I<0x89, MRMDestReg, (ops GR16:$dst, GR16:$src),
                 "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)]>;
@@ -627,7 +626,6 @@ def MOV16ri : Ii16<0xB8, AddRegFrm, (ops GR16:$dst, i16imm:$src),
 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)]>;
index 897d8f2aab2e921d734d8b0f5d00d0e37b21e030..cc22f4fb585ef919003ef3683a03f48b9341a417 100644 (file)
@@ -503,14 +503,12 @@ def MMX_MASKMOVQ : MMXI<0xF7, MRMDestMem, (ops VR64:$src, VR64:$mask),
 
 // Alias instructions that map zero vector to pxor.
 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
-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))]>;
-}
+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 8e64f7b1687557b7059e15d887e29444abcd5294..1195114805b76d3941561bfe1eb55378a1b4af43 100644 (file)
@@ -759,7 +759,6 @@ def STMXCSR : PSI<0xAE, MRM3m, (ops i32mem:$dst),
 
 // 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))]>;
@@ -1819,10 +1818,9 @@ def MFENCE : I<0xAE, MRM6m, (ops),
 
 // 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_SETALLONES : PDI<0x76, MRMInitReg, (ops VR128:$dst),
-                         "pcmpeqd $dst, $dst",
-                         [(set VR128:$dst, (v2f64 immAllOnesV))]>;
+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 54d9b3fea7b7f1fb30dc22f6e7c4dbdc4dfc9b95..4f76de8f35c3d1b4ab397d05c51674dd28378fd6 100644 (file)
@@ -91,7 +91,6 @@ namespace llvm {
     bool isConvertibleToThreeAddress;
     bool isCommutable;
     bool isTerminator;
-    bool isReMaterializable;
     bool hasDelaySlot;
     bool usesCustomDAGSchedInserter;
     bool hasVariableNumberOfOperands;
index c54ecd02e489d57945724136eb5af34d062bb621..b02c423ad74c24cd5c24c5bada35da31e7b019ae 100644 (file)
@@ -365,7 +365,6 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
   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 af01e4cd75a14e033cae3a1d2506ee1ff4f6e8b1..bf027dd29a44c0e96ac52deefb5192e72d62deb5 100644 (file)
@@ -240,7 +240,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
   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)