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
52class R600DAGToDAGISelLegacy : public SelectionDAGISelLegacy {
53public:
54 static char ID;
55 explicit R600DAGToDAGISelLegacy(TargetMachine &TM, CodeGenOptLevel OptLevel)
57 ID, std::make_unique<R600DAGToDAGISel>(TM, OptLevel)) {}
58};
59
60char R600DAGToDAGISelLegacy::ID = 0;
61
62} // namespace
63
64bool R600DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
65 Subtarget = &MF.getSubtarget<R600Subtarget>();
67}
68
69bool R600DAGToDAGISel::isConstantLoad(const MemSDNode *N, int CbId) const {
70 if (!N->readMem())
71 return false;
72 if (CbId == -1)
73 return N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
74 N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT;
75
76 return N->getAddressSpace() == AMDGPUAS::CONSTANT_BUFFER_0 + CbId;
77}
78
79bool R600DAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr,
80 SDValue &IntPtr) {
81 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) {
82 IntPtr =
83 CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, SDLoc(Addr), true);
84 return true;
85 }
86 return false;
87}
88
89bool R600DAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr,
90 SDValue &BaseReg,
91 SDValue &Offset) {
92 if (!isa<ConstantSDNode>(Addr)) {
93 BaseReg = Addr;
94 Offset = CurDAG->getIntPtrConstant(0, SDLoc(Addr), true);
95 return true;
96 }
97 return false;
98}
99
100void R600DAGToDAGISel::Select(SDNode *N) {
101 unsigned int Opc = N->getOpcode();
102 if (N->isMachineOpcode()) {
103 N->setNodeId(-1);
104 return; // Already selected.
105 }
106
107 switch (Opc) {
108 default:
109 break;
112 case ISD::BUILD_VECTOR: {
113 EVT VT = N->getValueType(0);
114 unsigned NumVectorElts = VT.getVectorNumElements();
115 unsigned RegClassID;
116 // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG
117 // that adds a 128 bits reg copy when going through TwoAddressInstructions
118 // pass. We want to avoid 128 bits copies as much as possible because they
119 // can't be bundled by our scheduler.
120 switch (NumVectorElts) {
121 case 2:
122 RegClassID = R600::R600_Reg64RegClassID;
123 break;
124 case 4:
126 RegClassID = R600::R600_Reg128VerticalRegClassID;
127 else
128 RegClassID = R600::R600_Reg128RegClassID;
129 break;
130 default:
131 llvm_unreachable("Do not know how to lower this BUILD_VECTOR");
132 }
133 SelectBuildVector(N, RegClassID);
134 return;
135 }
136 }
137
138 SelectCode(N);
139}
140
141bool R600DAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
142 SDValue &Offset) {
144 SDLoc DL(Addr);
145
146 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
147 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
148 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
149 } else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) &&
150 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(0)))) {
151 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
152 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
153 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) &&
154 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) {
155 Base = Addr.getOperand(0);
156 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
157 } else {
158 Base = Addr;
159 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32);
160 }
161
162 return true;
163}
164
165bool R600DAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
166 SDValue &Offset) {
167 ConstantSDNode *IMMOffset;
168
169 if (Addr.getOpcode() == ISD::ADD &&
170 (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) &&
171 isInt<16>(IMMOffset->getZExtValue())) {
172
173 Base = Addr.getOperand(0);
174 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr),
175 MVT::i32);
176 return true;
177 // If the pointer address is constant, we can move it to the offset field.
178 } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) &&
179 isInt<16>(IMMOffset->getZExtValue())) {
180 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
181 SDLoc(CurDAG->getEntryNode()), R600::ZERO,
182 MVT::i32);
183 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr),
184 MVT::i32);
185 return true;
186 }
187
188 // Default case, no offset
189 Base = Addr;
190 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
191 return true;
192}
193
194/// This pass converts a legalized DAG into a R600-specific
195// DAG, ready for instruction scheduling.
197 CodeGenOptLevel OptLevel) {
198 return new R600DAGToDAGISelLegacy(TM, OptLevel);
199}
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
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.
virtual bool runOnMachineFunction(MachineFunction &mf)
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
#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...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition: ISDOpcodes.h:628
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:523
@ Offset
Definition: DWP.cpp:480
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.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#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