LLVM 22.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"
19
20using namespace llvm;
21
22namespace {
23class R600DAGToDAGISel : public AMDGPUDAGToDAGISel {
24 const R600Subtarget *Subtarget = nullptr;
25
26 bool isConstantLoad(const MemSDNode *N, int cbID) const;
27 bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue &IntPtr);
28 bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg,
30
31public:
32 R600DAGToDAGISel() = delete;
33
34 explicit R600DAGToDAGISel(TargetMachine &TM, CodeGenOptLevel OptLevel)
35 : AMDGPUDAGToDAGISel(TM, OptLevel) {}
36
37 void Select(SDNode *N) override;
38
39 bool SelectADDRIndirect(SDValue Addr, SDValue &Base,
40 SDValue &Offset) override;
41 bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
42 SDValue &Offset) override;
43
44 bool runOnMachineFunction(MachineFunction &MF) override;
45
46 void PreprocessISelDAG() override {}
47
48protected:
49 // Include the pieces autogenerated from the target description.
50#include "R600GenDAGISel.inc"
51};
52
53class R600DAGToDAGISelLegacy : public SelectionDAGISelLegacy {
54public:
55 static char ID;
56 explicit R600DAGToDAGISelLegacy(TargetMachine &TM, CodeGenOptLevel OptLevel)
57 : SelectionDAGISelLegacy(
58 ID, std::make_unique<R600DAGToDAGISel>(TM, OptLevel)) {}
59};
60
61char R600DAGToDAGISelLegacy::ID = 0;
62
63} // namespace
64
65bool R600DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
66 Subtarget = &MF.getSubtarget<R600Subtarget>();
68}
69
70bool R600DAGToDAGISel::isConstantLoad(const MemSDNode *N, int CbId) const {
71 if (!N->readMem())
72 return false;
73 if (CbId == -1)
74 return N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
75 N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT;
76
77 return N->getAddressSpace() == AMDGPUAS::CONSTANT_BUFFER_0 + CbId;
78}
79
80bool R600DAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr,
81 SDValue &IntPtr) {
82 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) {
83 IntPtr =
84 CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, SDLoc(Addr), true);
85 return true;
86 }
87 return false;
88}
89
90bool R600DAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr,
91 SDValue &BaseReg,
92 SDValue &Offset) {
93 if (!isa<ConstantSDNode>(Addr)) {
94 BaseReg = Addr;
95 Offset = CurDAG->getIntPtrConstant(0, SDLoc(Addr), true);
96 return true;
97 }
98 return false;
99}
100
101void R600DAGToDAGISel::Select(SDNode *N) {
102 unsigned int Opc = N->getOpcode();
103 if (N->isMachineOpcode()) {
104 N->setNodeId(-1);
105 return; // Already selected.
106 }
107
108 switch (Opc) {
109 default:
110 break;
113 case ISD::BUILD_VECTOR: {
114 EVT VT = N->getValueType(0);
115 unsigned NumVectorElts = VT.getVectorNumElements();
116 unsigned RegClassID;
117 // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG
118 // that adds a 128 bits reg copy when going through TwoAddressInstructions
119 // pass. We want to avoid 128 bits copies as much as possible because they
120 // can't be bundled by our scheduler.
121 switch (NumVectorElts) {
122 case 2:
123 RegClassID = R600::R600_Reg64RegClassID;
124 break;
125 case 4:
127 RegClassID = R600::R600_Reg128VerticalRegClassID;
128 else
129 RegClassID = R600::R600_Reg128RegClassID;
130 break;
131 default:
132 llvm_unreachable("Do not know how to lower this BUILD_VECTOR");
133 }
134 SelectBuildVector(N, RegClassID);
135 return;
136 }
137 }
138
139 SelectCode(N);
140}
141
142bool R600DAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
143 SDValue &Offset) {
144 ConstantSDNode *C;
145 SDLoc DL(Addr);
146
147 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
148 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
149 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
150 } else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) &&
152 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
153 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
154 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) &&
156 Base = Addr.getOperand(0);
157 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
158 } else {
159 Base = Addr;
160 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32);
161 }
162
163 return true;
164}
165
166bool R600DAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
167 SDValue &Offset) {
168 ConstantSDNode *IMMOffset;
169
170 if (Addr.getOpcode() == ISD::ADD &&
171 (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) &&
172 isInt<16>(IMMOffset->getZExtValue())) {
173
174 Base = Addr.getOperand(0);
175 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr),
176 MVT::i32);
177 return true;
178 // If the pointer address is constant, we can move it to the offset field.
179 }
180 if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) &&
181 isInt<16>(IMMOffset->getZExtValue())) {
182 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
183 SDLoc(CurDAG->getEntryNode()), R600::ZERO,
184 MVT::i32);
185 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr),
186 MVT::i32);
187 return true;
188 }
189
190 // Default case, no offset
191 Base = Addr;
192 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
193 return true;
194}
195
196/// This pass converts a legalized DAG into a R600-specific
197// DAG, ready for instruction scheduling.
199 CodeGenOptLevel OptLevel) {
200 return new R600DAGToDAGISelLegacy(TM, OptLevel);
201}
return SDValue()
Defines an instruction selector for the AMDGPU target.
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Provides R600 specific target descriptions.
AMDGPU R600 specific subclass of TargetSubtarget.
AMDGPU specific code to select AMDGPU machine instructions for SelectionDAG operations.
uint64_t getZExtValue() const
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const SDValue & getOperand(unsigned i) const
unsigned getOpcode() const
virtual bool runOnMachineFunction(MachineFunction &mf)
Primary interface to the complete machine description for the target machine.
#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:259
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition ISDOpcodes.h:656
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:543
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:174
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
FunctionPass * createR600ISelDag(TargetMachine &TM, CodeGenOptLevel OptLevel)
This pass converts a legalized DAG into a R600-specific.
#define N
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:336