Mesa (master): radeon/llvm: Add custom SDNodes for MAX

Tom Stellard tstellar at kemper.freedesktop.org
Thu May 17 20:21:30 UTC 2012


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

Author: Tom Stellard <thomas.stellard at amd.com>
Date:   Thu May 17 07:35:15 2012 -0400

radeon/llvm: Add custom SDNodes for MAX

We now lower the various intrinsics for max to SDNodes and then use
tablegen patterns to lower the SDNodes to instructions.

---

 src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl |    3 +-
 src/gallium/drivers/radeon/AMDGPUISelLowering.cpp |   45 +++++++++++++++++++++
 src/gallium/drivers/radeon/AMDGPUISelLowering.h   |   21 ++++++++++
 src/gallium/drivers/radeon/AMDGPUInstrInfo.td     |   31 ++++++++++++++
 src/gallium/drivers/radeon/AMDIL.td               |    1 +
 src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp  |    1 +
 src/gallium/drivers/radeon/AMDILISelLowering.h    |    1 +
 src/gallium/drivers/radeon/AMDILInstructions.td   |    1 -
 src/gallium/drivers/radeon/R600Instructions.td    |    9 ++--
 src/gallium/drivers/radeon/SIInstructions.td      |    5 +-
 10 files changed, 108 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl b/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl
index 130eaac..ddff399 100644
--- a/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl
+++ b/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl
@@ -34,7 +34,6 @@ use strict;
 my @F32_MULTICLASSES = qw {
   UnaryIntrinsicFloat
   UnaryIntrinsicFloatScalar
-  BinaryIntrinsicFloat
   TernaryIntrinsicFloat
   BinaryOpMCFloat
 };
@@ -58,7 +57,7 @@ my $FILE_TYPE = $ARGV[0];
 
 open AMDIL, '<', 'AMDILInstructions.td';
 
-my @INST_ENUMS = ('NONE', 'FEQ', 'FGE', 'FLT', 'FNE', 'MOVE_f32', 'MOVE_i32', 'FTOI', 'ITOF', 'CMOVLOG_f32', 'UGT', 'IGE', 'INE', 'UGE', 'IEQ', 'BINARY_OR_i32', 'BINARY_NOT_i32');
+my @INST_ENUMS = ('NONE', 'FEQ', 'FGE', 'FLT', 'FNE', 'MOVE_f32', 'MOVE_i32', 'FTOI', 'ITOF', 'CMOVLOG_f32', 'UGT', 'IGE', 'INE', 'UGE', 'IEQ', 'BINARY_OR_i32', 'BINARY_NOT_i32', 'MIN_f32');
 
 while (<AMDIL>) {
   if ($_ =~ /defm\s+([A-Z_]+)\s+:\s+([A-Za-z0-9]+)</) {
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
index 8d4207f..9d1042e 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AMDGPUISelLowering.h"
+#include "AMDILIntrinsicInfo.h"
 #include "AMDGPUUtil.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 
@@ -20,6 +21,38 @@ using namespace llvm;
 AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
   AMDILTargetLowering(TM)
 {
+  // We need to custom lower some of the intrinsics
+  setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
+}
+
+SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
+    const
+{
+  switch (Op.getOpcode()) {
+  default: return AMDILTargetLowering::LowerOperation(Op, DAG);
+  case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
+  }
+}
+
+SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
+    SelectionDAG &DAG) const
+{
+  unsigned IntrinsicID = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+  DebugLoc DL = Op.getDebugLoc();
+  EVT VT = Op.getValueType();
+
+  switch (IntrinsicID) {
+    default: return Op;
+    case AMDGPUIntrinsic::AMDIL_max:
+      return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
+                                                  Op.getOperand(2));
+    case AMDGPUIntrinsic::AMDGPU_imax:
+      return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1),
+                                                  Op.getOperand(2));
+    case AMDGPUIntrinsic::AMDGPU_umax:
+      return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1),
+                                                  Op.getOperand(2));
+  }
 }
 
 void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI,
@@ -29,3 +62,15 @@ void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI,
   AMDGPU::utilAddLiveIn(MF, MRI, TII, reg, MI->getOperand(0).getReg());
 }
 
+#define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
+
+const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const
+{
+  switch (Opcode) {
+  default: return AMDILTargetLowering::getTargetNodeName(Opcode);
+
+  NODE_NAME_CASE(FMAX)
+  NODE_NAME_CASE(SMAX)
+  NODE_NAME_CASE(UMAX)
+  }
+}
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
index 16adf1b..b67f30b 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
@@ -21,6 +21,9 @@ namespace llvm {
 
 class AMDGPUTargetLowering : public AMDILTargetLowering
 {
+private:
+  SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
+
 protected:
 
   /// addLiveIn - This functions adds reg to the live in list of the entry block
@@ -36,8 +39,26 @@ protected:
 public:
   AMDGPUTargetLowering(TargetMachine &TM);
 
+  virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
+  virtual const char* getTargetNodeName(unsigned Opcode) const;
+
 };
 
+namespace AMDGPUISD
+{
+
+enum
+{
+  AMDGPU_FIRST = AMDILISD::LAST_NON_MEMORY_OPCODE,
+  FMAX,
+  SMAX,
+  UMAX,
+  LAST_AMDGPU_ISD_NUMBER
+};
+
+
+} // End namespace AMDGPUISD
+
 } // End namespace llvm
 
 #endif // AMDGPUISELLOWERING_H
diff --git a/src/gallium/drivers/radeon/AMDGPUInstrInfo.td b/src/gallium/drivers/radeon/AMDGPUInstrInfo.td
new file mode 100644
index 0000000..abb1ebe
--- /dev/null
+++ b/src/gallium/drivers/radeon/AMDGPUInstrInfo.td
@@ -0,0 +1,31 @@
+//===-- AMDGPUInstrInfo.td - AMDGPU DAG nodes --------------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains DAG node defintions for the AMDGPU target.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// AMDGPU DAG Nodes
+//
+
+// out = max(a, b) a and b are floats
+def AMDGPUfmax : SDNode<"AMDGPUISD::FMAX", SDTFPBinOp,
+  [SDNPCommutative, SDNPAssociative]
+>;
+
+// out = max(a, b) a and b are signed ints
+def AMDGPUsmax : SDNode<"AMDGPUISD::SMAX", SDTIntBinOp,
+  [SDNPCommutative, SDNPAssociative]
+>;
+
+// out = max(a, b) a and b are unsigned ints
+def AMDGPUumax : SDNode<"AMDGPUISD::UMAX", SDTIntBinOp,
+  [SDNPCommutative, SDNPAssociative]
+>;
diff --git a/src/gallium/drivers/radeon/AMDIL.td b/src/gallium/drivers/radeon/AMDIL.td
index deee290..28d4182 100644
--- a/src/gallium/drivers/radeon/AMDIL.td
+++ b/src/gallium/drivers/radeon/AMDIL.td
@@ -14,6 +14,7 @@ include "AMDILVersion.td"
 include "R600Schedule.td"
 include "SISchedule.td"
 include "Processors.td"
+include "AMDGPUInstrInfo.td"
 include "AMDGPUIntrinsics.td"
 include "AMDGPURegisterInfo.td"
 include "AMDGPUInstructions.td"
diff --git a/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp b/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
index b889882..a96cc95 100644
--- a/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
+++ b/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
@@ -10,6 +10,7 @@
 // This file defines an instruction selector for the AMDIL target.
 //
 //===----------------------------------------------------------------------===//
+#include "AMDGPUISelLowering.h" // For AMDGPUISD
 #include "AMDILDevices.h"
 #include "AMDILTargetMachine.h"
 #include "AMDILUtilityFunctions.h"
diff --git a/src/gallium/drivers/radeon/AMDILISelLowering.h b/src/gallium/drivers/radeon/AMDILISelLowering.h
index 302f0cb..8463915 100644
--- a/src/gallium/drivers/radeon/AMDILISelLowering.h
+++ b/src/gallium/drivers/radeon/AMDILISelLowering.h
@@ -94,6 +94,7 @@ namespace llvm
       LOOP_ZERO,
       LOOP_CMP,
       ADDADDR,
+      LAST_NON_MEMORY_OPCODE,
       // ATOMIC Operations
       // Global Memory
       ATOM_G_ADD = ISD::FIRST_TARGET_MEMORY_OPCODE,
diff --git a/src/gallium/drivers/radeon/AMDILInstructions.td b/src/gallium/drivers/radeon/AMDILInstructions.td
index db56e21..f03ec6b 100644
--- a/src/gallium/drivers/radeon/AMDILInstructions.td
+++ b/src/gallium/drivers/radeon/AMDILInstructions.td
@@ -261,7 +261,6 @@ defm POW : BinaryIntrinsicFloat<IL_OP_POW, int_AMDIL_pow>;
 let hasIEEEFlag = 1 in {
   let mayLoad = 0, mayStore=0 in {
 defm MIN  : BinaryIntrinsicFloat<IL_OP_MIN, int_AMDIL_min>;
-defm MAX  : BinaryIntrinsicFloat<IL_OP_MAX, int_AMDIL_max>;
 defm MAD  : TernaryIntrinsicFloat<IL_OP_MAD, int_AMDIL_mad>;
   }
 defm MOD  : BinaryOpMCf32<IL_OP_MOD, frem>;
diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td
index fda6b27..ca2af73 100644
--- a/src/gallium/drivers/radeon/R600Instructions.td
+++ b/src/gallium/drivers/radeon/R600Instructions.td
@@ -261,9 +261,8 @@ def MUL_IEEE : R600_2OP <
 
 def MAX : R600_2OP <
   0x3, "MAX",
-  [(set R600_Reg32:$dst, (int_AMDIL_max R600_Reg32:$src0, R600_Reg32:$src1))]> {
-  let AMDILOp = AMDILInst.MAX_f32;
-}
+  [(set R600_Reg32:$dst, (AMDGPUfmax R600_Reg32:$src0, R600_Reg32:$src1))]
+>;
 
 def MIN : R600_2OP <
   0x4, "MIN",
@@ -370,7 +369,7 @@ def SUB_INT : R600_2OP <
 
 def MAX_INT : R600_2OP <
   0x36, "MAX_INT",
-  [(set R600_Reg32:$dst, (int_AMDGPU_imax R600_Reg32:$src0, R600_Reg32:$src1))]>;
+  [(set R600_Reg32:$dst, (AMDGPUsmax R600_Reg32:$src0, R600_Reg32:$src1))]>;
 
 def MIN_INT : R600_2OP <
   0x37, "MIN_INT",
@@ -378,7 +377,7 @@ def MIN_INT : R600_2OP <
 
 def MAX_UINT : R600_2OP <
   0x38, "MAX_UINT",
-  [(set R600_Reg32:$dst, (int_AMDGPU_umax R600_Reg32:$src0, R600_Reg32:$src1))]>;
+  [(set R600_Reg32:$dst, (AMDGPUsmax R600_Reg32:$src0, R600_Reg32:$src1))]>;
 
 def MIN_UINT : R600_2OP <
   0x39, "MIN_UINT",
diff --git a/src/gallium/drivers/radeon/SIInstructions.td b/src/gallium/drivers/radeon/SIInstructions.td
index 313728f..4efc093 100644
--- a/src/gallium/drivers/radeon/SIInstructions.td
+++ b/src/gallium/drivers/radeon/SIInstructions.td
@@ -606,8 +606,9 @@ defm V_MUL_F32 : VOP2_32 <0x00000008, "V_MUL_F32", []>;
 //defm V_MUL_HI_U32_U24 : VOP2_32 <0x0000000c, "V_MUL_HI_U32_U24", []>;
 defm V_MIN_LEGACY_F32 : VOP2_32 <0x0000000d, "V_MIN_LEGACY_F32", []>;
 
-defm V_MAX_LEGACY_F32 : VOP2_32 <0x0000000e, "V_MAX_LEGACY_F32", [],
-                                 AMDILInst.MAX_f32>;
+defm V_MAX_LEGACY_F32 : VOP2_32 <0x0000000e, "V_MAX_LEGACY_F32",
+  [(set VReg_32:$dst, (AMDGPUfmax AllReg_32:$src0, VReg_32:$src1))]
+>;
 defm V_MIN_F32 : VOP2_32 <0x0000000f, "V_MIN_F32", []>;
 defm V_MAX_F32 : VOP2_32 <0x00000010, "V_MAX_F32", []>;
 defm V_MIN_I32 : VOP2_32 <0x00000011, "V_MIN_I32", []>;




More information about the mesa-commit mailing list