[Mesa-dev] [PATCH] [WIP]radeon/llvm: Loads from globaladdr ptr turned into const buf read

Vincent Lejeune vljn at ovi.com
Thu Dec 20 10:37:07 PST 2012


---
 lib/Target/AMDGPU/AMDGPUISelLowering.cpp |  1 +
 lib/Target/AMDGPU/AMDGPUISelLowering.h   |  1 +
 lib/Target/AMDGPU/AMDGPUMCInstLower.cpp  |  6 ++++
 lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp  | 49 ++++++++++++++++++++++++-
 lib/Target/AMDGPU/R600ISelLowering.cpp   | 61 +++++++++++++++++++++++++++++---
 lib/Target/AMDGPU/R600Instructions.td    | 18 ++++++++++
 6 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 665cb59..4963ad7 100644
--- a/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -398,6 +398,7 @@ const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const {
   NODE_NAME_CASE(INTERP)
   NODE_NAME_CASE(INTERP_P0)
   NODE_NAME_CASE(EXPORT)
+  NODE_NAME_CASE(CONST_ADDRESS)
   NODE_NAME_CASE(REGISTER_LOAD)
   NODE_NAME_CASE(REGISTER_STORE)
   }
diff --git a/lib/Target/AMDGPU/AMDGPUISelLowering.h b/lib/Target/AMDGPU/AMDGPUISelLowering.h
index 602a933..4b3a066 100644
--- a/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -122,6 +122,7 @@ enum {
   INTERP,
   INTERP_P0,
   EXPORT,
+  CONST_ADDRESS,
   REGISTER_LOAD,
   REGISTER_STORE,
   LAST_AMDGPU_ISD_NUMBER
diff --git a/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp b/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp
index de4053e..fc40e94 100644
--- a/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp
+++ b/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp
@@ -50,6 +50,12 @@ void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
     case MachineOperand::MO_Register:
       MCOp = MCOperand::CreateReg(MO.getReg());
       break;
+    case MachineOperand::MO_GlobalAddress: {
+      unsigned Offset = MO.getOffset();
+
+      MCOp = MCOperand::CreateReg(AMDGPU::R600_KC0_CReg32RegClass.getRegister(Offset));
+    }
+      break;
     }
     OutMI.addOperand(MCOp);
   }
diff --git a/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp b/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp
index b3403e2..034d075 100644
--- a/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp
+++ b/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp
@@ -168,6 +168,27 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) {
     }
     break;
   }
+  case AMDGPUISD::CONST_ADDRESS: {
+    EVT OpVT = N->getValueType(0);
+    unsigned int NewOpc = AMDGPU::CONST_COPY;
+    SDValue TZero = CurDAG->getTargetConstant(0, MVT::i32);
+    SDValue TOne = CurDAG->getTargetConstant(1, MVT::i32);
+    SDValue Args[11] = {
+        TOne,
+        TZero,
+        TZero,
+        TZero,
+        N->getOperand(0),
+        TZero,
+        TZero,
+        TZero,
+        TOne,
+        CurDAG->getRegister(AMDGPU::PRED_SEL_OFF, MVT::i32),
+        TZero
+    };
+
+    return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Args, 11);
+  }
   case ISD::ConstantFP:
   case ISD::Constant: {
     const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
@@ -260,7 +281,33 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) {
     break;
   }
   }
-  return SelectCode(N);
+  SDNode *Result = SelectCode(N);
+
+  const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
+  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
+    const R600InstrInfo *TII = static_cast<const R600InstrInfo*>(TM.getInstrInfo());
+    if (Result && TII->isALUInstr(Result->getMachineOpcode())) {
+      std::vector<SDValue> Ops;
+      MachineSDNode *PotentialGlue = 0;
+      for(SDNode::op_iterator I = Result->op_begin(), E = Result->op_end();
+          I != E; ++I) {
+        SDValue Value = *I;
+        if (Value.getOpcode() == AMDGPUISD::CONST_ADDRESS) {
+          if (!dyn_cast<ConstantSDNode>(Value.getOperand(1))) {
+            PotentialGlue = CurDAG->getMachineNode(AMDGPU::MOVA_INT, Value.getDebugLoc(), MVT::Glue, Value.getOperand(1));
+          }
+          Ops.push_back(Value.getOperand(0));
+        } else {
+          Ops.push_back(Value);
+        }
+      }
+      if (PotentialGlue)
+        Ops.push_back(SDValue(PotentialGlue, 0));
+      CurDAG->MorphNodeTo(Result, Result->getOpcode(), Result->getVTList(), Ops.data(), Ops.size());
+    }
+  }
+
+  return Result;
 }
 
 bool AMDGPUDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) {
diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp
index 370bc5a..672397c 100644
--- a/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -99,12 +99,12 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
   setOperationAction(ISD::VSELECT, MVT::v4i32, Expand);
 
   // Legalize loads and stores to the private address space.
-  setOperationAction(ISD::LOAD, MVT::f32, Custom);
-  setOperationAction(ISD::LOAD, MVT::i32, Custom);
+  setOperationAction(ISD::LOAD, MVT::v4f32, Custom);
+  /*setOperationAction(ISD::LOAD, MVT::i32, Custom);
   setOperationAction(ISD::LOAD, MVT::v2f32, Custom);
   setOperationAction(ISD::LOAD, MVT::v2i32, Custom);
   setOperationAction(ISD::LOAD, MVT::v4f32, Custom);
-  setOperationAction(ISD::LOAD, MVT::v4i32, Custom);
+  setOperationAction(ISD::LOAD, MVT::v4i32, Custom);*/
   setLoadExtAction(ISD::EXTLOAD, MVT::v4i8, Custom);
   setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom);
   setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i8, Custom);
@@ -954,6 +954,39 @@ SDValue R600TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
   return Cond;
 }
 
+static
+const GlobalValue *SelectAddr(SDValue Addr, unsigned &Offset, SDValue &BaseReg) {
+  switch (Addr.getOpcode()) {
+  case ISD::GlobalAddress: {
+    GlobalAddressSDNode * G = dyn_cast<GlobalAddressSDNode>(Addr);
+    Offset = G->getOffset();
+    return G->getGlobal();
+  }
+  case ISD::ADD: {
+    const GlobalValue *Result;
+    SDValue NoOpValue;
+    if (Result = SelectAddr(Addr.getOperand(0), Offset, NoOpValue)) {
+      ConstantSDNode *Const = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
+      if (Const) {
+        Offset += Const->getZExtValue();
+      } else {
+        BaseReg = Addr.getOperand(1);
+      }
+    } else if (Result = SelectAddr(Addr.getOperand(1), Offset, NoOpValue)) {
+      ConstantSDNode *Const = dyn_cast<ConstantSDNode>(Addr.getOperand(0));
+      if (Const) {
+        Offset += Const->getZExtValue();
+      } else {
+        BaseReg = Addr.getOperand(0);
+      }
+    }
+    return Result;
+  }
+  default:
+    return NULL;
+  }
+}
+
 SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const
 {
   EVT VT = Op.getValueType();
@@ -963,8 +996,26 @@ SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const
   SDValue Ptr = Op.getOperand(1);
   SDValue LoweredLoad;
 
-  if (LoadNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) {
-    return SDValue();
+  if (LoadNode->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS) {
+    unsigned Offset;
+    SDValue BaseReg;
+    const GlobalValue *GV = SelectAddr(Op.getOperand(1), Offset, BaseReg);
+    if (BaseReg.getNode()) {
+      BaseReg = DAG.getNode(ISD::SRL, DL, MVT::i32, BaseReg, DAG.getConstant(2, MVT::i32));
+    } else {
+      BaseReg = DAG.getConstant(0, MVT::i32);
+    }
+    SDValue Slots[4];
+    for (unsigned i = 0; i < 4; i++) {
+      SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, MVT::f32, Offset / 4 + i);
+      Slots[i] = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::f32,
+        TGA, BaseReg);
+    }
+    SDValue MergedValues[2] = {
+        DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, Slots, 4),
+        Chain
+    };
+    return DAG.getMergeValues(MergedValues, 2, DL);
   }
 
   if (VT.isVector()) {
diff --git a/lib/Target/AMDGPU/R600Instructions.td b/lib/Target/AMDGPU/R600Instructions.td
index 6c0ed1d..6898439 100644
--- a/lib/Target/AMDGPU/R600Instructions.td
+++ b/lib/Target/AMDGPU/R600Instructions.td
@@ -439,6 +439,14 @@ def INTERP_P0: SDNode<"AMDGPUISD::INTERP_P0",
   SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisInt<1>]>
   >;
 
+def CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS",
+  SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisInt<1>, SDTCisInt<2>]>,
+  [SDNPMayLoad]
+>;
+
+def MOVA_INT : InstR600 <0xCC, (outs), (ins R600_Reg32:$src0), "MOVA_INT", [],
+AnyALU>;
+
 //===----------------------------------------------------------------------===//
 // Interpolation Instructions
 //===----------------------------------------------------------------------===//
@@ -1624,6 +1632,16 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
       "RETURN", [(IL_retflag)]>;
 }
 
+
+//===----------------------------------------------------------------------===//
+// Constant Buffer Addressing Support
+//===----------------------------------------------------------------------===//
+
+def CONST_COPY : R600_1OP <0x19, "CONST_COPY", []>
+{
+  let mayLoad = 1;
+}
+
 //===----------------------------------------------------------------------===//
 // ISel Patterns
 //===----------------------------------------------------------------------===//
-- 
1.8.0.2



More information about the mesa-dev mailing list