Mesa (master): radeon/llvm: Use multiclasses for floating point loads

Tom Stellard tstellar at kemper.freedesktop.org
Wed Jul 11 18:45:59 UTC 2012


Module: Mesa
Branch: master
Commit: 49ae102ee346d4be6a61ebdaba6e5d5ad8469407
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=49ae102ee346d4be6a61ebdaba6e5d5ad8469407

Author: Tom Stellard <thomas.stellard at amd.com>
Date:   Tue Jul 10 11:15:49 2012 -0400

radeon/llvm: Use multiclasses for floating point loads

The original strategy for handling floating point loads, which was to
lower (f32 load) to (f32 bitcast (i32 load)) wasn't really working.  The
main problem was that the DAG legalizer couldn't handle replacing a node
with two results (load) with a node with only one result (bitcast).

---

 src/gallium/drivers/radeon/AMDGPUISelLowering.cpp |   34 -----------------
 src/gallium/drivers/radeon/AMDGPUISelLowering.h   |    1 -
 src/gallium/drivers/radeon/R600CodeEmitter.cpp    |    9 +++-
 src/gallium/drivers/radeon/R600ISelLowering.cpp   |    2 +-
 src/gallium/drivers/radeon/R600Instructions.td    |   42 ++++++++++++++++-----
 src/gallium/drivers/radeon/SIInstrInfo.td         |    5 ++
 src/gallium/drivers/radeon/SIInstructions.td      |    3 +-
 7 files changed, 46 insertions(+), 50 deletions(-)

diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
index ef5715f..b3d27f7 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
@@ -33,9 +33,6 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
   setOperationAction(ISD::FEXP2,  MVT::f32, Legal);
   setOperationAction(ISD::FRINT,  MVT::f32, Legal);
 
-  setOperationAction(ISD::LOAD, MVT::f32, Custom);
-  setOperationAction(ISD::LOAD, MVT::v4f32, Custom);
-
   setOperationAction(ISD::UDIV, MVT::i32, Expand);
   setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
   setOperationAction(ISD::UREM, MVT::i32, Expand);
@@ -47,7 +44,6 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
   switch (Op.getOpcode()) {
   default: return AMDILTargetLowering::LowerOperation(Op, DAG);
   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
-  case ISD::LOAD: return BitcastLOAD(Op, DAG);
   case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
   case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
   }
@@ -130,36 +126,6 @@ SDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
                                                OneSubAC);
 }
 
-/// BitcastLoad - Convert floating point loads to integer loads of the same
-/// type width and the bitcast the result back to a floating point type.
-SDValue AMDGPUTargetLowering::BitcastLOAD(SDValue Op, SelectionDAG &DAG) const
-{
-  DebugLoc DL = Op.getDebugLoc();
-  EVT VT = Op.getValueType();
-  EVT IntVT;
-
-  if (VT == MVT::f32) {
-    IntVT = MVT::i32;
-  } else if (VT == MVT::v4f32) {
-    IntVT = MVT::v4i32;
-  } else {
-    return Op;
-  }
-  LoadSDNode * LD = dyn_cast<LoadSDNode>(Op);
-  assert(LD);
-
-  SDValue NewLoad = DAG.getLoad (LD->getAddressingMode(),
-                                 LD->getExtensionType(), IntVT, DL,
-                                 LD->getChain(), LD->getBasePtr(),
-                                 LD->getOffset(), IntVT,
-                                 LD->getMemOperand());
-
-  SDValue Bitcast = DAG.getNode(ISD::BITCAST, DL, VT, NewLoad);
-  DAG.ReplaceAllUsesWith(Op.getValue(0).getNode(), &Bitcast);
-
-  return Op;
-}
-
 SDValue AMDGPUTargetLowering::LowerSELECT_CC(SDValue Op,
     SelectionDAG &DAG) const
 {
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
index 4d1a312..72342c9 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
@@ -23,7 +23,6 @@ class AMDGPUTargetLowering : public AMDILTargetLowering
 {
 private:
   SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
-  SDValue BitcastLOAD(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
 
diff --git a/src/gallium/drivers/radeon/R600CodeEmitter.cpp b/src/gallium/drivers/radeon/R600CodeEmitter.cpp
index 4c7962b..d882bb1 100644
--- a/src/gallium/drivers/radeon/R600CodeEmitter.cpp
+++ b/src/gallium/drivers/radeon/R600CodeEmitter.cpp
@@ -203,9 +203,12 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
                 emit(inst);
                 break;
               }
-            case AMDGPU::VTX_READ_PARAM_eg:
-            case AMDGPU::VTX_READ_GLOBAL_eg:
-            case AMDGPU::VTX_READ_GLOBAL_128_eg:
+            case AMDGPU::VTX_READ_PARAM_i32_eg:
+            case AMDGPU::VTX_READ_PARAM_f32_eg:
+            case AMDGPU::VTX_READ_GLOBAL_i32_eg:
+            case AMDGPU::VTX_READ_GLOBAL_f32_eg:
+            case AMDGPU::VTX_READ_GLOBAL_v4i32_eg:
+            case AMDGPU::VTX_READ_GLOBAL_v4f32_eg:
               {
                 uint64_t InstWord01 = getBinaryCodeForInstr(MI);
                 uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
diff --git a/src/gallium/drivers/radeon/R600ISelLowering.cpp b/src/gallium/drivers/radeon/R600ISelLowering.cpp
index 00ab751..ee4fea8 100644
--- a/src/gallium/drivers/radeon/R600ISelLowering.cpp
+++ b/src/gallium/drivers/radeon/R600ISelLowering.cpp
@@ -253,7 +253,7 @@ void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBl
           .addReg(AMDGPU::ALU_LITERAL_X)
           .addImm(dword_offset * 4);
 
-  BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::VTX_READ_PARAM_eg))
+  BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDGPU::VTX_READ_PARAM_i32_eg))
           .addOperand(MI->getOperand(0))
           .addReg(PtrReg)
           .addImm(0);
diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td
index a7d29fe..f96bd15 100644
--- a/src/gallium/drivers/radeon/R600Instructions.td
+++ b/src/gallium/drivers/radeon/R600Instructions.td
@@ -1021,14 +1021,6 @@ class VTX_READ_32_eg <bits<8> buffer_id, list<dag> pattern>
   let DATA_FORMAT      = 0xD; // COLOR_32
 }
 
-def VTX_READ_PARAM_eg : VTX_READ_32_eg <0,
-  [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
->;
-
-def VTX_READ_GLOBAL_eg : VTX_READ_32_eg <1,
-  [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
->;
-
 class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
     : VTX_READ_eg <buffer_id, (outs R600_Reg128:$dst), pattern> {
 
@@ -1040,10 +1032,40 @@ class VTX_READ_128_eg <bits<8> buffer_id, list<dag> pattern>
   let DATA_FORMAT      =  0x22; // COLOR_32_32_32_32
 }
 
-def VTX_READ_GLOBAL_128_eg : VTX_READ_128_eg <1,
-  [(set (v4i32 R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
+//===----------------------------------------------------------------------===//
+// VTX Read from parameter memory space
+//===----------------------------------------------------------------------===//
+
+class VTX_READ_PARAM_32_eg <ValueType vt> : VTX_READ_32_eg <0,
+  [(set (vt R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))]
+>;
+
+def VTX_READ_PARAM_i32_eg : VTX_READ_PARAM_32_eg<i32>;
+def VTX_READ_PARAM_f32_eg : VTX_READ_PARAM_32_eg<f32>;
+
+
+//===----------------------------------------------------------------------===//
+// VTX Read from global memory space
+//===----------------------------------------------------------------------===//
+
+// 32-bit reads
+
+class VTX_READ_GLOBAL_eg <ValueType vt> : VTX_READ_32_eg <1,
+  [(set (vt R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))]
 >;
 
+def VTX_READ_GLOBAL_i32_eg : VTX_READ_GLOBAL_eg<i32>;
+def VTX_READ_GLOBAL_f32_eg : VTX_READ_GLOBAL_eg<f32>;
+
+// 128-bit reads
+
+class VTX_READ_GLOBAL_128_eg <ValueType vt> : VTX_READ_128_eg <1,
+  [(set (vt R600_Reg128:$dst), (global_load ADDRVTX_READ:$ptr))]
+>;
+
+def VTX_READ_GLOBAL_v4i32_eg : VTX_READ_GLOBAL_128_eg<v4i32>;
+def VTX_READ_GLOBAL_v4f32_eg : VTX_READ_GLOBAL_128_eg<v4f32>;
+
 }
 
 let Predicates = [isCayman] in {
diff --git a/src/gallium/drivers/radeon/SIInstrInfo.td b/src/gallium/drivers/radeon/SIInstrInfo.td
index be08e8a..aac6443 100644
--- a/src/gallium/drivers/radeon/SIInstrInfo.td
+++ b/src/gallium/drivers/radeon/SIInstrInfo.td
@@ -468,5 +468,10 @@ multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass dstClass,
   >;
 }
 
+multiclass SMRD_32 <bits<5> op, string asm, RegisterClass dstClass> {
+  defm _F32 : SMRD_Helper <op, asm, dstClass, f32>;
+  defm _I32 : SMRD_Helper <op, asm, dstClass, i32>;
+}
+
 include "SIInstrFormats.td"
 include "SIInstructions.td"
diff --git a/src/gallium/drivers/radeon/SIInstructions.td b/src/gallium/drivers/radeon/SIInstructions.td
index a96d783..e832ab5 100644
--- a/src/gallium/drivers/radeon/SIInstructions.td
+++ b/src/gallium/drivers/radeon/SIInstructions.td
@@ -358,7 +358,8 @@ def TBUFFER_LOAD_FORMAT_XYZW : MTBUF_Load_Helper <0x00000003, "TBUFFER_LOAD_FORM
 //def TBUFFER_STORE_FORMAT_XYZ : MTBUF_ <0x00000006, "TBUFFER_STORE_FORMAT_XYZ", []>;
 //def TBUFFER_STORE_FORMAT_XYZW : MTBUF_ <0x00000007, "TBUFFER_STORE_FORMAT_XYZW", []>;
 
-defm S_LOAD_DWORD : SMRD_Helper <0x00000000, "S_LOAD_DWORD", SReg_32, f32>;
+defm S_LOAD_DWORD : SMRD_32 <0x00000000, "S_LOAD_DWORD", SReg_32>;
+
 //def S_LOAD_DWORDX2 : SMRD_DWORDX2 <0x00000001, "S_LOAD_DWORDX2", []>;
 defm S_LOAD_DWORDX4 : SMRD_Helper <0x00000002, "S_LOAD_DWORDX4", SReg_128, v4i32>;
 defm S_LOAD_DWORDX8 : SMRD_Helper <0x00000003, "S_LOAD_DWORDX8", SReg_256, v8i32>;




More information about the mesa-commit mailing list