LLVM  15.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:1564
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:42
AMDGPUISelDAGToDAG.h
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1090
llvm::ISD::OR
@ OR
Definition: ISDOpcodes.h:667
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:79
llvm::MemSDNode
This is an abstract virtual class for memory operations.
Definition: SelectionDAGNodes.h:1259
AMDGPUDAGToDAGISel::SelectBuildVector
void SelectBuildVector(SDNode *N, unsigned RegClassID)
Definition: AMDGPUISelDAGToDAG.cpp:451
llvm::AMDGPUAS::CONSTANT_ADDRESS_32BIT
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
Definition: AMDGPU.h:366
llvm::SelectionDAG::getRegister
SDValue getRegister(unsigned Reg, EVT VT)
Definition: SelectionDAG.cpp:2061
R600.h
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::SelectionDAGISel::OptLevel
CodeGenOpt::Level OptLevel
Definition: SelectionDAGISel.h:52
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:308
llvm::AMDGPUAS::CONSTANT_BUFFER_0
@ CONSTANT_BUFFER_0
Definition: AMDGPU.h:381
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:479
R600MCTargetDesc.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:640
llvm::R600Subtarget
Definition: R600Subtarget.h:29
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
llvm::SelectionDAG::getIntPtrConstant
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
Definition: SelectionDAG.cpp:1572
llvm::SelectionDAG::getCopyFromReg
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:776
llvm::AMDGPUAS::CONSTANT_ADDRESS
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
Definition: AMDGPU.h:362
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
llvm::ConstantSDNode::getZExtValue
uint64_t getZExtValue() const
Definition: SelectionDAGNodes.h:1579
llvm::SelectionDAGISel::CurDAG
SelectionDAG * CurDAG
Definition: SelectionDAGISel.h:48
llvm::MachineFunction
Definition: MachineFunction.h:241
AMDGPU.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
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
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:46
llvm::SelectionDAG::getEntryNode
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:531
llvm::ISD::BUILD_VECTOR
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:514
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:652
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:308
llvm::AMDGPUISD::DWORDADDR
@ DWORDADDR
Definition: AMDGPUISelLowering.h:371
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:606
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58