[llvm-commits] [llvm] r48329 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/LowerSubregs.cpp lib/Target/TargetSelectionDAG.td lib/Target/X86/X86ATTAsmPrinter.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.cpp lib/Target/X86/X86InstrInfo.h lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86IntelAsmPrinter.cpp utils/TableGen/DAGISelEmitter.cpp

Christopher Lamb christopher.lamb at gmail.com
Wed Mar 12 22:47:01 PDT 2008


Author: clamb
Date: Thu Mar 13 00:47:01 2008
New Revision: 48329

URL: http://llvm.org/viewvc/llvm-project?rev=48329&view=rev
Log:
Get rid of a pseudo instruction and replace it with subreg based operation on real instructions, ridding the asm printers of the hack used to do this previously. In the process, update LowerSubregs to be careful about eliminating copies that have side affects. 

Note: the coalescer will have to be careful about this too, when it starts coalescing insert_subreg nodes.


Modified:
    llvm/trunk/include/llvm/Target/TargetInstrInfo.h
    llvm/trunk/lib/CodeGen/LowerSubregs.cpp
    llvm/trunk/lib/Target/TargetSelectionDAG.td
    llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/X86/X86Instr64bit.td
    llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.h
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp
    llvm/trunk/utils/TableGen/DAGISelEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Thu Mar 13 00:47:01 2008
@@ -51,6 +51,15 @@
     EXTRACT_SUBREG = 4,
     INSERT_SUBREG = 5
   };
+  
+  // Target independent implict values for use with subreg insert. All targets
+  // that support insert_subreg support IMPL_VAL_UNDEF. Support for the other 
+  // values is target dependent.
+  enum ImplictVal {
+    IMPL_VAL_UNDEF = 0,
+    IMPL_VAL_ZERO  = 1,
+    LAST_IMPL_VAL  = 3
+  };
 
   unsigned getNumOpcodes() const { return NumOpcodes; }
 
@@ -120,7 +129,6 @@
     return false;
   }
   
-  
   /// convertToThreeAddress - This method must be implemented by targets that
   /// set the M_CONVERTIBLE_TO_3_ADDR flag.  When this flag is set, the target
   /// may be able to convert a two-address instruction into one or more true

Modified: llvm/trunk/lib/CodeGen/LowerSubregs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LowerSubregs.cpp?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LowerSubregs.cpp (original)
+++ llvm/trunk/lib/CodeGen/LowerSubregs.cpp Thu Mar 13 00:47:01 2008
@@ -96,13 +96,10 @@
          (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) &&
           MI->getOperand(3).isImmediate() && "Invalid insert_subreg");
           
+  // Check if we're inserting into an implicit undef value.
+  bool isImplicit = MI->getOperand(1).isImmediate();
   unsigned DstReg = MI->getOperand(0).getReg();
-  unsigned SrcReg = 0;
-  // Check if we're inserting into an implicit value.
-  if (MI->getOperand(1).isImmediate())
-    SrcReg = DstReg;
-  else
-    SrcReg = MI->getOperand(1).getReg();
+  unsigned SrcReg = isImplicit ? DstReg : MI->getOperand(1).getReg();
   unsigned InsReg = MI->getOperand(2).getReg();
   unsigned SubIdx = MI->getOperand(3).getImm();     
 
@@ -118,13 +115,20 @@
 
   DOUT << "subreg: CONVERTING: " << *MI;
        
+  // Check whether the implict subreg copy has side affects or not. Only copies
+  // into an undef value have no side affects, that is they can be eliminated
+  // without changing the semantics of the program.
+  bool copyHasSideAffects = isImplicit? 
+                  MI->getOperand(1).getImm() != TargetInstrInfo::IMPL_VAL_UNDEF
+                  : false; 
+       
   // If the inserted register is already allocated into a subregister
   // of the destination, we copy the subreg into the source
   // However, this is only safe if the insert instruction is the kill
   // of the source register
   bool revCopyOrder = TRI.isSubRegister(DstReg, InsReg);
-  if (revCopyOrder && InsReg != DstSubReg) {
-    if (MI->getOperand(1).isKill()) {
+  if (revCopyOrder && (InsReg != DstSubReg || copyHasSideAffects)) {
+    if (isImplicit || MI->getOperand(1).isKill()) {
       DstSubReg = TRI.getSubReg(SrcReg, SubIdx);
       // Insert sub-register copy
       const TargetRegisterClass *TRC1 = 0;
@@ -144,7 +148,7 @@
     }
   }
 #ifndef NDEBUG
-  if (InsReg == DstSubReg) {
+  if (InsReg == DstSubReg && !copyHasSideAffects) {
      DOUT << "subreg: Eliminated subreg copy\n";
   }
 #endif
@@ -174,7 +178,7 @@
   }
 #endif
 
-  if (!revCopyOrder && InsReg != DstSubReg) {
+  if (!revCopyOrder && (InsReg != DstSubReg || copyHasSideAffects)) {
     // Insert sub-register copy
     const TargetRegisterClass *TRC1 = 0;
     if (TargetRegisterInfo::isPhysicalRegister(InsReg)) {

Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/lib/Target/TargetSelectionDAG.td Thu Mar 13 00:47:01 2008
@@ -919,5 +919,10 @@
                       [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)>;
 

Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Thu Mar 13 00:47:01 2008
@@ -637,14 +637,6 @@
 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
 
-  // See if a truncate instruction can be turned into a nop.
-  switch (MI->getOpcode()) {
-  default: break;
-  case X86::PsMOVZX64rr32:
-    O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
-    break;
-  }
-
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);
 }

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Thu Mar 13 00:47:01 2008
@@ -1533,14 +1533,9 @@
       AddToISelQueue(N0);
       if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
         SDOperand SRIdx;
-        SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF, 
-                                                      MVT::i32);
         switch(N0.getValueType()) {
         case MVT::i32:
           SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
-          // x86-64 zero extends 32-bit inserts int 64-bit registers
-          if (Subtarget->is64Bit())
-            ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32);
           break;
         case MVT::i16:
           SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
@@ -1552,6 +1547,8 @@
         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);
 

Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Thu Mar 13 00:47:01 2008
@@ -1089,22 +1089,6 @@
 // Alias Instructions
 //===----------------------------------------------------------------------===//
 
-// Zero-extension
-// TODO: Remove this after proper i32 -> i64 zext support.
-def PsMOVZX64rr32: I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
-                     "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
-                     [(set GR64:$dst, (zext GR32:$src))]>;
-def PsMOVZX64rm32: I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
-                     "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
-                     [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
-
-/// PsAND64rrFFFFFFFF - r = r & (2^32-1)
-def PsAND64rrFFFFFFFF
-  : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
-  "mov{l}\t{${src:subreg32}, ${dst:subreg32}|${dst:subreg32}, ${src:subreg32}}",
-      [(set GR64:$dst, (and GR64:$src, i64immFFFFFFFF))]>;
-
-
 // Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
 // equivalent due to implicit zero-extending, and it sometimes has a smaller
 // encoding.
@@ -1220,27 +1204,48 @@
 def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)),
           (TEST64rr GR64:$src1, GR64:$src1)>;
 
+
+
+// Zero-extension
+def : Pat<(i64 (zext GR32:$src)), (INSERT_SUBREG tii_impl_val_zero, 
+                                            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)>;
+
 // 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), (PsMOVZX64rm32 addr:$src)>;
+def : Pat<(extloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_undef, 
+                                        (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)), (PsMOVZX64rr32 GR32:$src)>;
+def : Pat<(i64 (anyext GR32:$src)), (INSERT_SUBREG tii_impl_val_undef, 
+                                        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))), (PsMOVZX64rm32 addr:$src)>;
+def : Pat<(i64 (anyext (loadi32 addr:$src))), (INSERT_SUBREG tii_impl_val_undef, 
+                                                (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)),
+            x86_subreg_32bit)>;
+
 // (shl x, 1) ==> (add x, x)
 def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
 

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Thu Mar 13 00:47:01 2008
@@ -392,7 +392,6 @@
     { X86::PSHUFDri,        X86::PSHUFDmi },
     { X86::PSHUFHWri,       X86::PSHUFHWmi },
     { X86::PSHUFLWri,       X86::PSHUFLWmi },
-    { X86::PsMOVZX64rr32,   X86::PsMOVZX64rm32 },
     { X86::RCPPSr,          X86::RCPPSm },
     { X86::RCPPSr_Int,      X86::RCPPSm_Int },
     { X86::RSQRTPSr,        X86::RSQRTPSm },
@@ -922,8 +921,9 @@
       // Build and insert into an implicit UNDEF value. This is OK because
       // well be shifting and then extracting the lower 16-bits. 
       MachineInstr *Ins = 
-       BuildMI(get(X86::INSERT_SUBREG),leaInReg).addImm(X86::IMPL_VAL_UNDEF)
-         .addReg(Src).addImm(X86::SUBREG_16BIT);
+       BuildMI(get(X86::INSERT_SUBREG),leaInReg)
+                    .addImm(X86InstrInfo::IMPL_VAL_UNDEF)
+                    .addReg(Src).addImm(X86::SUBREG_16BIT);
       
       NewMI = BuildMI(get(Opc), leaOutReg)
         .addReg(0).addImm(1 << ShAmt).addReg(leaInReg).addImm(0);

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Thu Mar 13 00:47:01 2008
@@ -45,15 +45,7 @@
     COND_S  = 15,
     COND_INVALID
   };
-  
-  // X86 specific implict values used for subregister inserts. 
-  // This can be used to model the fact that x86-64 by default
-  // inserts 32-bit values into 64-bit registers implicitly containing zeros.
-  enum ImplicitVal {
-    IMPL_VAL_UNDEF = 0,
-    IMPL_VAL_ZERO  = 1
-  };
-  
+    
   // Turn condition code into conditional branch opcode.
   unsigned GetCondBranchFromCond(CondCode CC);
   

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Mar 13 00:47:01 2008
@@ -161,10 +161,6 @@
 // Branch targets have OtherVT type.
 def brtarget : Operand<OtherVT>;
 
-// These should match the enum X86::ImplicitVal
-def x86_impl_val_undef : PatLeaf<(i32 0)>;
-def x86_impl_val_zero  : PatLeaf<(i32 1)>;
-
 //===----------------------------------------------------------------------===//
 // X86 Complex Pattern Definitions.
 //

Modified: llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86IntelAsmPrinter.cpp Thu Mar 13 00:47:01 2008
@@ -314,14 +314,6 @@
 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
 
-  // See if a truncate instruction can be turned into a nop.
-  switch (MI->getOpcode()) {
-  default: break;
-  case X86::PsMOVZX64rr32:
-    O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
-    break;
-  }
-
   // Call the autogenerated instruction printer routines.
   printInstruction(MI);
 }

Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=48329&r1=48328&r2=48329&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Thu Mar 13 00:47:01 2008
@@ -975,9 +975,9 @@
         }
       }
 
-      // Generate MemOperandSDNodes nodes for each memory accesses covered by this
-      // pattern.
-      if (isRoot) {
+      // Generate MemOperandSDNodes nodes for each memory accesses covered by 
+      // this pattern.
+      if (II.isSimpleLoad | II.mayLoad | II.mayStore) {
         std::vector<std::string>::const_iterator mi, mie;
         for (mi = LSI.begin(), mie = LSI.end(); mi != mie; ++mi) {
           emitCode("SDOperand LSI_" + *mi + " = "
@@ -1880,14 +1880,9 @@
      << "  SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n"
      << "  AddToISelQueue(N1);\n"
      << "  SDOperand Ops[] = { N0, N1, Tmp };\n"
-     << "  if (N0.getOpcode() == ISD::UNDEF) {\n"
-     << "    return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n"
-     << "                                 N.getValueType(), Ops+1, 2);\n"
-     << "  } else {\n"
-     << "    AddToISelQueue(N0);\n"
-     << "    return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n"
-     << "                                 N.getValueType(), Ops, 3);\n"
-     << "  }\n"
+     << "  AddToISelQueue(N0);\n"
+     << "  return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n"
+     << "                               N.getValueType(), Ops, 3);\n"
      << "}\n\n";
 
   OS << "// The main instruction selector code.\n"





More information about the llvm-commits mailing list