[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