LLVM  14.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 
22  const R600Subtarget *Subtarget;
23 
24  bool isConstantLoad(const MemSDNode *N, int cbID) const;
25  bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue &IntPtr);
26  bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg,
27  SDValue &Offset);
28 
29 public:
32 
33  void Select(SDNode *N) override;
34 
36  SDValue &Offset) override;
38  SDValue &Offset) override;
39 
40  bool runOnMachineFunction(MachineFunction &MF) override;
41 
42  void PreprocessISelDAG() override {}
43 
44 protected:
45  // Include the pieces autogenerated from the target description.
46 #include "R600GenDAGISel.inc"
47 };
48 
50  Subtarget = &MF.getSubtarget<R600Subtarget>();
51  return SelectionDAGISel::runOnMachineFunction(MF);
52 }
53 
54 bool R600DAGToDAGISel::isConstantLoad(const MemSDNode *N, int CbId) const {
55  if (!N->readMem())
56  return false;
57  if (CbId == -1)
58  return N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
59  N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT;
60 
61  return N->getAddressSpace() == AMDGPUAS::CONSTANT_BUFFER_0 + CbId;
62 }
63 
64 bool R600DAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr,
65  SDValue &IntPtr) {
66  if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) {
67  IntPtr =
68  CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, SDLoc(Addr), true);
69  return true;
70  }
71  return false;
72 }
73 
74 bool R600DAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr,
75  SDValue &BaseReg,
76  SDValue &Offset) {
77  if (!isa<ConstantSDNode>(Addr)) {
78  BaseReg = Addr;
80  return true;
81  }
82  return false;
83 }
84 
86  unsigned int Opc = N->getOpcode();
87  if (N->isMachineOpcode()) {
88  N->setNodeId(-1);
89  return; // Already selected.
90  }
91 
92  switch (Opc) {
93  default:
94  break;
97  case ISD::BUILD_VECTOR: {
98  EVT VT = N->getValueType(0);
99  unsigned NumVectorElts = VT.getVectorNumElements();
100  unsigned RegClassID;
101  // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG
102  // that adds a 128 bits reg copy when going through TwoAddressInstructions
103  // pass. We want to avoid 128 bits copies as much as possible because they
104  // can't be bundled by our scheduler.
105  switch (NumVectorElts) {
106  case 2:
107  RegClassID = R600::R600_Reg64RegClassID;
108  break;
109  case 4:
111  RegClassID = R600::R600_Reg128VerticalRegClassID;
112  else
113  RegClassID = R600::R600_Reg128RegClassID;
114  break;
115  default:
116  llvm_unreachable("Do not know how to lower this BUILD_VECTOR");
117  }
118  SelectBuildVector(N, RegClassID);
119  return;
120  }
121  }
122 
123  SelectCode(N);
124 }
125 
127  SDValue &Offset) {
128  ConstantSDNode *C;
129  SDLoc DL(Addr);
130 
131  if ((C = dyn_cast<ConstantSDNode>(Addr))) {
132  Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
133  Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
134  } else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) &&
135  (C = dyn_cast<ConstantSDNode>(Addr.getOperand(0)))) {
136  Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR, MVT::i32);
137  Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
138  } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) &&
139  (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) {
140  Base = Addr.getOperand(0);
141  Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32);
142  } else {
143  Base = Addr;
145  }
146 
147  return true;
148 }
149 
151  SDValue &Offset) {
152  ConstantSDNode *IMMOffset;
153 
154  if (Addr.getOpcode() == ISD::ADD &&
155  (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) &&
156  isInt<16>(IMMOffset->getZExtValue())) {
157 
158  Base = Addr.getOperand(0);
160  MVT::i32);
161  return true;
162  // If the pointer address is constant, we can move it to the offset field.
163  } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) &&
164  isInt<16>(IMMOffset->getZExtValue())) {
166  SDLoc(CurDAG->getEntryNode()), R600::ZERO,
167  MVT::i32);
169  MVT::i32);
170  return true;
171  }
172 
173  // Default case, no offset
174  Base = Addr;
176  return true;
177 }
178 
179 /// This pass converts a legalized DAG into a R600-specific
180 // DAG, ready for instruction scheduling.
182  CodeGenOpt::Level OptLevel) {
183  return new R600DAGToDAGISel(TM, OptLevel);
184 }
llvm::ConstantSDNode
Definition: SelectionDAGNodes.h:1555
R600DAGToDAGISel::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: R600ISelDAGToDAG.cpp:49
llvm::SelectionDAGISel::TM
TargetMachine & TM
Definition: SelectionDAGISel.h:41
AMDGPUISelDAGToDAG.h
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1085
llvm::ISD::OR
@ OR
Definition: ISDOpcodes.h:633
ValueTracking.h
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:454
AMDGPUDAGToDAGISel
AMDGPU specific code to select AMDGPU machine instructions for SelectionDAG operations.
Definition: AMDGPUISelDAGToDAG.h:79
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MemSDNode
This is an abstract virtual class for memory operations.
Definition: SelectionDAGNodes.h:1253
AMDGPUDAGToDAGISel::SelectBuildVector
void SelectBuildVector(SDNode *N, unsigned RegClassID)
Definition: AMDGPUISelDAGToDAG.cpp:451
llvm::SelectionDAG::getRegister
SDValue getRegister(unsigned Reg, EVT VT)
Definition: SelectionDAG.cpp:2010
R600.h
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:35
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::SelectionDAGISel::OptLevel
CodeGenOpt::Level OptLevel
Definition: SelectionDAGISel.h:51
R600DAGToDAGISel::SelectADDRVTX_READ
bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset) override
Definition: R600ISelDAGToDAG.cpp:150
llvm::EVT::getVectorNumElements
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:309
R600DAGToDAGISel::Select
void Select(SDNode *N) override
Main hook for targets to transform nodes into machine nodes.
Definition: R600ISelDAGToDAG.cpp:85
i32
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32
Definition: README.txt:122
llvm::AMDGPUISD::BUILD_VERTICAL_VECTOR
@ BUILD_VERTICAL_VECTOR
This node is for VLIW targets and it is used to represent a vector that is stored in consecutive regi...
Definition: AMDGPUISelLowering.h:481
R600MCTargetDesc.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
llvm::R600Subtarget
Definition: R600Subtarget.h:35
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1521
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:761
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:80
llvm::AMDGPUAS::CONSTANT_ADDRESS
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
Definition: AMDGPU.h:362
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition: SelectionDAGNodes.h:1570
llvm::SelectionDAGISel::CurDAG
SelectionDAG * CurDAG
Definition: SelectionDAGISel.h:47
llvm::MachineFunction
Definition: MachineFunction.h:234
AMDGPU.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
R600DAGToDAGISel::R600DAGToDAGISel
R600DAGToDAGISel(TargetMachine *TM, CodeGenOpt::Level OptLevel)
Definition: R600ISelDAGToDAG.cpp:30
llvm::CodeGenOpt::Level
Level
Definition: CodeGen.h:52
R600DAGToDAGISel
Definition: R600ISelDAGToDAG.cpp:21
llvm::AMDGPUAS::CONSTANT_BUFFER_0
@ CONSTANT_BUFFER_0
Definition: AMDGPU.h:381
llvm::AMDGPUAS::CONSTANT_ADDRESS_32BIT
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
Definition: AMDGPU.h:366
R600DAGToDAGISel::SelectADDRIndirect
bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset) override
Definition: R600ISelDAGToDAG.cpp:126
llvm::isInt< 16 >
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:370
llvm::SelectionDAGISel::MF
MachineFunction * MF
Definition: SelectionDAGISel.h:45
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:516
llvm::ISD::BUILD_VECTOR
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:491
R600Subtarget.h
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:137
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
N
#define N
llvm::SelectionDAG::getTargetConstant
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:637
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::AMDGPUISD::DWORDADDR
@ DWORDADDR
Definition: AMDGPUISelLowering.h:373
llvm::createR600ISelDag
FunctionPass * createR600ISelDag(TargetMachine *TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a R600-specific.
Definition: R600ISelDAGToDAG.cpp:181
R600DAGToDAGISel::PreprocessISelDAG
void PreprocessISelDAG() override
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
Definition: R600ISelDAGToDAG.cpp:42
llvm::ISD::SCALAR_TO_VECTOR
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
Definition: ISDOpcodes.h:583
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58