LLVM 19.0.0git
R600ISelDAGToDAG.cpp
Go to the documentation of this file.
1//===-- R600ISelDAGToDAG.cpp - A dag to dag inst selector for R600 --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//==-----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines an instruction selector for the R600 subtarget.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPU.h"
15#include "AMDGPUISelDAGToDAG.h"
17#include "R600.h"
18#include "R600Subtarget.h"
20
21namespace {
22class R600DAGToDAGISel : public AMDGPUDAGToDAGISel {
23 const R600Subtarget *Subtarget = nullptr;
24
25 bool isConstantLoad(const MemSDNode *N, int cbID) const;
26 bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue &IntPtr);
27 bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg,
29
30public:
31 R600DAGToDAGISel() = delete;
32
33 explicit R600DAGToDAGISel(TargetMachine &TM, CodeGenOptLevel OptLevel)
34 : AMDGPUDAGToDAGISel(TM, OptLevel) {}
35
36 void Select(SDNode *N) override;
37
38 bool SelectADDRIndirect(SDValue Addr, SDValue &Base,
39 SDValue &Offset) override;
40 bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
41 SDValue &Offset) override;
42
43 bool runOnMachineFunction(MachineFunction &MF) override;
44
45 void PreprocessISelDAG() override {}
46
47protected:
48 // Include the pieces autogenerated from the target description.
49#include "R600GenDAGISel.inc"
50};
51} // namespace
52
53bool R600DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
54 Subtarget = &MF.getSubtarget<R600Subtarget>();
56}
57
58bool R600DAGToDAGISel::isConstantLoad(const MemSDNode *N, int CbId) const {
59 if (!N->readMem())
60 return false;
61 if (CbId == -1)
62 return N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
63 N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT;
64
65 return N->getAddressSpace() == AMDGPUAS::CONSTANT_BUFFER_0 + CbId;
66}
67
68bool R600DAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr,
69 SDValue &IntPtr) {
70 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) {
71 IntPtr =
72 CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, SDLoc(Addr), true);
73 return true;
74 }
75 return false;
76}
77
78bool R600DAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr,
79 SDValue &BaseReg,
80 SDValue &Offset) {
81 if (!isa<ConstantSDNode>(Addr)) {
82 BaseReg = Addr;
83 Offset = CurDAG->getIntPtrConstant(0, SDLoc(Addr), true);
84 return true;
85 }
86 return false;
87}
88
89void R600DAGToDAGISel::Select(SDNode *N) {
90 unsigned int Opc = N->getOpcode();
91 if (N->isMachineOpcode()) {
92 N->setNodeId(-1);
93 return; // Already selected.
94 }
95
96 switch (Opc) {
97 default:
98 break;
101 case ISD::BUILD_VECTOR: {
102 EVT VT = N->getValueType(0);
103 unsigned NumVectorElts = VT.getVectorNumElements();
104 unsigned RegClassID;
105 // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG
106 // that adds a 128 bits reg copy when going through TwoAddressInstructions
107 // pass. We want to avoid 128 bits copies as much as possible because they
108 // can't be bundled by our scheduler.
109 switch (NumVectorElts) {
110 case 2:
111 RegClassID = R600::R600_Reg64RegClassID;
112 break;
113 case 4:
115 RegClassID = R600::R600_Reg128VerticalRegClassID;
116 else
117 RegClassID = R600::R600_Reg128RegClassID;
118 break;
119 default:
120 llvm_unreachable("Do not know how to lower this BUILD_VECTOR");
121 }
122 SelectBuildVector(N, RegClassID);
123 return;
124 }
125 }
126
127 SelectCode(N);
128}
129
130bool R600DAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
131 SDValue &Offset) {
133 SDLoc DL(Addr);
134
135 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
136 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
137 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
138 } else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) &&
139 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(0)))) {
140 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
141 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
142 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) &&
143 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) {
144 Base = Addr.getOperand(0);
145 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
146 } else {
147 Base = Addr;
148 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32);
149 }
150
151 return true;
152}
153
154bool R600DAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
155 SDValue &Offset) {
156 ConstantSDNode *IMMOffset;
157
158 if (Addr.getOpcode() == ISD::ADD &&
159 (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) &&
160 isInt<16>(IMMOffset->getZExtValue())) {
161
162 Base = Addr.getOperand(0);
163 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr),
164 MVT::i32);
165 return true;
166 // If the pointer address is constant, we can move it to the offset field.
167 } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) &&
168 isInt<16>(IMMOffset->getZExtValue())) {
169 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
170 SDLoc(CurDAG->getEntryNode()), R600::ZERO,
171 MVT::i32);
172 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr),
173 MVT::i32);
174 return true;
175 }
176
177 // Default case, no offset
178 Base = Addr;
179 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
180 return true;
181}
182
183/// This pass converts a legalized DAG into a R600-specific
184// DAG, ready for instruction scheduling.
186 CodeGenOptLevel OptLevel) {
187 return new R600DAGToDAGISel(TM, OptLevel);
188}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Defines an instruction selector for the AMDGPU target.
amdgpu AMDGPU Register Bank Select
uint64_t Addr
const char LLVMTargetMachineRef TM
Provides R600 specific target descriptions.
AMDGPU R600 specific subclass of TargetSubtarget.
AMDGPU specific code to select AMDGPU machine instructions for SelectionDAG operations.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void PreprocessISelDAG() override
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
uint64_t getZExtValue() const
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This is an abstract virtual class for memory operations.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
@ BUILD_VERTICAL_VECTOR
This node is for VLIW targets and it is used to represent a vector that is stored in consecutive regi...
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition: ISDOpcodes.h:620
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:515
@ Offset
Definition: DWP.cpp:456
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
FunctionPass * createR600ISelDag(TargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a R600-specific.
#define N
Extended Value Type.
Definition: ValueTypes.h:34
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:326