[llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt PPCInstrInfo.td PPCISelLowering.cpp PPCISelLowering.h PPCHazardRecognizers.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Jul 10 13:57:12 PDT 2006



Changes in directory llvm/lib/Target/PowerPC:

README.txt updated: 1.92 -> 1.93
PPCInstrInfo.td updated: 1.237 -> 1.238
PPCISelLowering.cpp updated: 1.197 -> 1.198
PPCISelLowering.h updated: 1.50 -> 1.51
PPCHazardRecognizers.cpp updated: 1.12 -> 1.13
---
Log message:

Implement Regression/CodeGen/PowerPC/bswap-load-store.ll by folding bswaps
into i16/i32 load/stores.


---
Diffs of the changes:  (+103 -6)

 PPCHazardRecognizers.cpp |    4 +++
 PPCISelLowering.cpp      |   59 +++++++++++++++++++++++++++++++++++++++++++++++
 PPCISelLowering.h        |   14 ++++++++++-
 PPCInstrInfo.td          |   27 +++++++++++++++++++++
 README.txt               |    5 ---
 5 files changed, 103 insertions(+), 6 deletions(-)


Index: llvm/lib/Target/PowerPC/README.txt
diff -u llvm/lib/Target/PowerPC/README.txt:1.92 llvm/lib/Target/PowerPC/README.txt:1.93
--- llvm/lib/Target/PowerPC/README.txt:1.92	Wed May 17 14:02:25 2006
+++ llvm/lib/Target/PowerPC/README.txt	Mon Jul 10 15:56:58 2006
@@ -3,7 +3,6 @@
 TODO:
 * gpr0 allocation
 * implement do-loop -> bdnz transform
-* implement powerpc-64 for darwin
 
 ===-------------------------------------------------------------------------===
 
@@ -238,10 +237,6 @@
 
 ===-------------------------------------------------------------------------===
 
-Generate lwbrx and other byteswapping load/store instructions when reasonable.
-
-===-------------------------------------------------------------------------===
-
 Compile this:
 
 int foo(int a) {


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.237 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.238
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.237	Tue Jun 27 13:36:44 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Mon Jul 10 15:56:58 2006
@@ -37,6 +37,13 @@
   SDTCisVT<1, i32>, SDTCisVT<2, OtherVT>
 ]>;
 
+def SDT_PPClbrx : SDTypeProfile<1, 3, [
+  SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>
+]>;
+def SDT_PPCstbrx : SDTypeProfile<0, 4, [
+  SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>
+]>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific DAG Nodes.
 //
@@ -88,6 +95,9 @@
 def PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr,
                            [SDNPHasChain, SDNPOptInFlag]>;
 
+def PPClbrx       : SDNode<"PPCISD::LBRX", SDT_PPClbrx, [SDNPHasChain]>;
+def PPCstbrx      : SDNode<"PPCISD::STBRX", SDT_PPCstbrx, [SDNPHasChain]>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific transformation functions and pattern fragments.
 //
@@ -464,6 +474,15 @@
 def LWZX : XForm_1<31,  23, (ops GPRC:$rD, memrr:$src),
                    "lwzx $rD, $src", LdStGeneral,
                    [(set GPRC:$rD, (load xaddr:$src))]>;
+                   
+                   
+def LHBRX : XForm_1<31, 790, (ops GPRC:$rD, memrr:$src),
+                   "lhbrx $rD, $src", LdStGeneral,
+                   [(set GPRC:$rD, (PPClbrx xaddr:$src,srcvalue:$dummy, i16))]>;
+def LWBRX : XForm_1<31,  534, (ops GPRC:$rD, memrr:$src),
+                   "lwbrx $rD, $src", LdStGeneral,
+                   [(set GPRC:$rD, (PPClbrx xaddr:$src,srcvalue:$dummy, i32))]>;
+
 }
 
 let PPC970_Unit = 1 in {  // FXU Operations.
@@ -517,6 +536,14 @@
 def STWUX : XForm_8<31, 183, (ops GPRC:$rS, GPRC:$rA, GPRC:$rB),
                    "stwux $rS, $rA, $rB", LdStGeneral,
                    []>;
+def STHBRX: XForm_8<31, 918, (ops GPRC:$rS, memrr:$dst),
+                   "sthbrx $rS, $dst", LdStGeneral,
+                   [(PPCstbrx GPRC:$rS, xaddr:$dst, srcvalue:$dummy, i16)]>, 
+                   PPC970_DGroup_Cracked;
+def STWBRX: XForm_8<31, 662, (ops GPRC:$rS, memrr:$dst),
+                   "stwbrx $rS, $dst", LdStGeneral,
+                   [(PPCstbrx GPRC:$rS, xaddr:$dst, srcvalue:$dummy, i32)]>,
+                   PPC970_DGroup_Cracked;
 }
 let PPC970_Unit = 1 in {  // FXU Operations.
 def SRAWI : XForm_10<31, 824, (ops GPRC:$rA, GPRC:$rS, u5imm:$SH), 


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.197 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.198
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.197	Tue Jun 27 15:14:52 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Mon Jul 10 15:56:58 2006
@@ -266,6 +266,7 @@
   setTargetDAGCombine(ISD::SINT_TO_FP);
   setTargetDAGCombine(ISD::STORE);
   setTargetDAGCombine(ISD::BR_CC);
+  setTargetDAGCombine(ISD::BSWAP);
   
   computeRegisterProperties();
 }
@@ -296,6 +297,8 @@
   case PPCISD::MFCR:          return "PPCISD::MFCR";
   case PPCISD::VCMP:          return "PPCISD::VCMP";
   case PPCISD::VCMPo:         return "PPCISD::VCMPo";
+  case PPCISD::LBRX:          return "PPCISD::LBRX";
+  case PPCISD::STBRX:         return "PPCISD::STBRX";
   case PPCISD::COND_BRANCH:   return "PPCISD::COND_BRANCH";
   }
 }
@@ -2344,6 +2347,56 @@
       DCI.AddToWorklist(Val.Val);
       return Val;
     }
+    
+    // Turn STORE (BSWAP) -> sthbrx/stwbrx.
+    if (N->getOperand(1).getOpcode() == ISD::BSWAP &&
+        N->getOperand(1).Val->hasOneUse() &&
+        (N->getOperand(1).getValueType() == MVT::i32 ||
+         N->getOperand(1).getValueType() == MVT::i16)) {
+      SDOperand BSwapOp = N->getOperand(1).getOperand(0);
+      // Do an any-extend to 32-bits if this is a half-word input.
+      if (BSwapOp.getValueType() == MVT::i16)
+        BSwapOp = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BSwapOp);
+
+      return DAG.getNode(PPCISD::STBRX, MVT::Other, N->getOperand(0), BSwapOp,
+                         N->getOperand(2), N->getOperand(3),
+                         DAG.getValueType(N->getOperand(1).getValueType()));
+    }
+    break;
+  case ISD::BSWAP:
+    // Turn BSWAP (LOAD) -> lhbrx/lwbrx.
+    if (N->getOperand(0).getOpcode() == ISD::LOAD &&
+        N->getOperand(0).hasOneUse() &&
+        (N->getValueType(0) == MVT::i32 || N->getValueType(0) == MVT::i16)) {
+      SDOperand Load = N->getOperand(0);
+      // Create the byte-swapping load.
+      std::vector<MVT::ValueType> VTs;
+      VTs.push_back(MVT::i32);
+      VTs.push_back(MVT::Other);
+      std::vector<SDOperand> Ops;
+      Ops.push_back(Load.getOperand(0));   // Chain
+      Ops.push_back(Load.getOperand(1));   // Ptr
+      Ops.push_back(Load.getOperand(2));   // SrcValue
+      Ops.push_back(DAG.getValueType(N->getValueType(0))); // VT
+      SDOperand BSLoad = DAG.getNode(PPCISD::LBRX, VTs, Ops);
+
+      // If this is an i16 load, insert the truncate.  
+      SDOperand ResVal = BSLoad;
+      if (N->getValueType(0) == MVT::i16)
+        ResVal = DAG.getNode(ISD::TRUNCATE, MVT::i16, BSLoad);
+      
+      // First, combine the bswap away.  This makes the value produced by the
+      // load dead.
+      DCI.CombineTo(N, ResVal);
+
+      // Next, combine the load away, we give it a bogus result value but a real
+      // chain result.  The result value is dead because the bswap is dead.
+      DCI.CombineTo(Load.Val, ResVal, BSLoad.getValue(1));
+      
+      // Return N so it doesn't get rechecked!
+      return SDOperand(N, 0);
+    }
+    
     break;
   case PPCISD::VCMP: {
     // If a VCMPo node already exists with exactly the same operands as this
@@ -2477,6 +2530,12 @@
   KnownOne = 0;
   switch (Op.getOpcode()) {
   default: break;
+  case PPCISD::LBRX: {
+    // lhbrx is known to have the top bits cleared out.
+    if (cast<VTSDNode>(Op.getOperand(3))->getVT() == MVT::i16)
+      KnownZero = 0xFFFF0000;
+    break;
+  }
   case ISD::INTRINSIC_WO_CHAIN: {
     switch (cast<ConstantSDNode>(Op.getOperand(0))->getValue()) {
     default: break;


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.50 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.51
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.50	Wed May 17 14:00:46 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Mon Jul 10 15:56:58 2006
@@ -111,7 +111,19 @@
       /// condition register to branch on, OPC is the branch opcode to use (e.g.
       /// PPC::BLE), DESTBB is the destination block to branch to, and INFLAG is
       /// an optional input flag argument.
-      COND_BRANCH
+      COND_BRANCH,
+      
+      /// CHAIN = STBRX CHAIN, GPRC, Ptr, SRCVALUE, Type - This is a 
+      /// byte-swapping store instruction.  It byte-swaps the low "Type" bits of
+      /// the GPRC input, then stores it through Ptr.  Type can be either i16 or
+      /// i32.
+      STBRX, 
+      
+      /// GPRC, CHAIN = LBRX CHAIN, Ptr, SRCVALUE, Type - This is a 
+      /// byte-swapping load instruction.  It loads "Type" bits, byte swaps it,
+      /// then puts it in the bottom bits of the GPRC.  TYPE can be either i16
+      /// or i32.
+      LBRX
     };
   }
 


Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.12 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.13
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.12	Tue Mar 21 23:30:33 2006
+++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp	Mon Jul 10 15:56:58 2006
@@ -178,6 +178,7 @@
     case PPC::LHZ:
     case PPC::LHZX:
     case PPC::LVEHX:
+    case PPC::LHBRX:
       LoadSize = 2;
       break;
     case PPC::LFS:
@@ -188,6 +189,7 @@
     case PPC::LWA:
     case PPC::LWAX:
     case PPC::LVEWX:
+    case PPC::LWBRX:
       LoadSize = 4;
       break;
     case PPC::LFD:
@@ -233,6 +235,7 @@
     case PPC::STHX:
     case PPC::STH:
     case PPC::STVEHX:
+    case PPC::STHBRX:
       ThisStoreSize = 2;
       break;
     case PPC::STFS:
@@ -243,6 +246,7 @@
     case PPC::STW:
     case PPC::STVEWX:
     case PPC::STFIWX:
+    case PPC::STWBRX:
       ThisStoreSize = 4;
       break;
     case PPC::STD_32:






More information about the llvm-commits mailing list