LLVM  13.0.0git
MipsISelDAGToDAG.cpp
Go to the documentation of this file.
1 //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
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 // This file defines an instruction selector for the MIPS target.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsISelDAGToDAG.h"
15 #include "Mips.h"
16 #include "Mips16ISelDAGToDAG.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsRegisterInfo.h"
19 #include "MipsSEISelDAGToDAG.h"
27 #include "llvm/IR/CFG.h"
28 #include "llvm/IR/GlobalValue.h"
29 #include "llvm/IR/Instructions.h"
30 #include "llvm/IR/Intrinsics.h"
31 #include "llvm/IR/Type.h"
32 #include "llvm/Support/Debug.h"
36 using namespace llvm;
37 
38 #define DEBUG_TYPE "mips-isel"
39 
40 //===----------------------------------------------------------------------===//
41 // Instruction Selector Implementation
42 //===----------------------------------------------------------------------===//
43 
44 //===----------------------------------------------------------------------===//
45 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
46 // instructions for SelectionDAG operations.
47 //===----------------------------------------------------------------------===//
48 
50  // There are multiple MipsDAGToDAGISel instances added to the pass pipeline.
51  // We need to preserve StackProtector for the next one.
54 }
55 
57  Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
59 
60  processFunctionAfterISel(MF);
61 
62  return Ret;
63 }
64 
65 /// getGlobalBaseReg - Output the instructions required to put the
66 /// GOT address into a register.
69  return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy(
71  .getNode();
72 }
73 
74 /// ComplexPattern used on MipsInstrInfo
75 /// Used on Mips Load/Store instructions
76 bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
77  SDValue &Offset) const {
78  llvm_unreachable("Unimplemented function.");
79  return false;
80 }
81 
82 bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
83  SDValue &Offset) const {
84  llvm_unreachable("Unimplemented function.");
85  return false;
86 }
87 
88 bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
89  SDValue &Offset) const {
90  llvm_unreachable("Unimplemented function.");
91  return false;
92 }
93 
94 bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base,
95  SDValue &Offset) const {
96  llvm_unreachable("Unimplemented function.");
97  return false;
98 }
99 
100 bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base,
101  SDValue &Offset) const {
102  llvm_unreachable("Unimplemented function.");
103  return false;
104 }
105 
106 bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base,
107  SDValue &Offset) const {
108  llvm_unreachable("Unimplemented function.");
109  return false;
110 }
111 
112 bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
113  SDValue &Offset) const {
114  llvm_unreachable("Unimplemented function.");
115  return false;
116 }
117 
118 bool MipsDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base,
119  SDValue &Offset) const {
120  llvm_unreachable("Unimplemented function.");
121  return false;
122 }
123 
124 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,
125  SDValue &Offset) const {
126  llvm_unreachable("Unimplemented function.");
127  return false;
128 }
129 
130 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,
131  SDValue &Offset) const {
132  llvm_unreachable("Unimplemented function.");
133  return false;
134 }
135 
136 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,
137  SDValue &Offset) const {
138  llvm_unreachable("Unimplemented function.");
139  return false;
140 }
141 
142 bool MipsDAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base,
143  SDValue &Offset) {
144  llvm_unreachable("Unimplemented function.");
145  return false;
146 }
147 
148 bool MipsDAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base,
149  SDValue &Offset) {
150  llvm_unreachable("Unimplemented function.");
151  return false;
152 }
153 
154 bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
155  unsigned MinSizeInBits) const {
156  llvm_unreachable("Unimplemented function.");
157  return false;
158 }
159 
160 bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
161  llvm_unreachable("Unimplemented function.");
162  return false;
163 }
164 
165 bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
166  llvm_unreachable("Unimplemented function.");
167  return false;
168 }
169 
170 bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
171  llvm_unreachable("Unimplemented function.");
172  return false;
173 }
174 
175 bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
176  llvm_unreachable("Unimplemented function.");
177  return false;
178 }
179 
180 bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
181  llvm_unreachable("Unimplemented function.");
182  return false;
183 }
184 
185 bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
186  llvm_unreachable("Unimplemented function.");
187  return false;
188 }
189 
190 bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
191  llvm_unreachable("Unimplemented function.");
192  return false;
193 }
194 
195 bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
196  llvm_unreachable("Unimplemented function.");
197  return false;
198 }
199 
200 bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
201  llvm_unreachable("Unimplemented function.");
202  return false;
203 }
204 
205 bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
206  llvm_unreachable("Unimplemented function.");
207  return false;
208 }
209 
210 bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
211  llvm_unreachable("Unimplemented function.");
212  return false;
213 }
214 
215 bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
216  llvm_unreachable("Unimplemented function.");
217  return false;
218 }
219 
220 /// Convert vector addition with vector subtraction if that allows to encode
221 /// constant as an immediate and thus avoid extra 'ldi' instruction.
222 /// add X, <-1, -1...> --> sub X, <1, 1...>
223 bool MipsDAGToDAGISel::selectVecAddAsVecSubIfProfitable(SDNode *Node) {
224  assert(Node->getOpcode() == ISD::ADD && "Should only get 'add' here.");
225 
226  EVT VT = Node->getValueType(0);
227  assert(VT.isVector() && "Should only be called for vectors.");
228 
229  SDValue X = Node->getOperand(0);
230  SDValue C = Node->getOperand(1);
231 
232  auto *BVN = dyn_cast<BuildVectorSDNode>(C);
233  if (!BVN)
234  return false;
235 
236  APInt SplatValue, SplatUndef;
237  unsigned SplatBitSize;
238  bool HasAnyUndefs;
239 
240  if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
241  8, !Subtarget->isLittle()))
242  return false;
243 
244  auto IsInlineConstant = [](const APInt &Imm) { return Imm.isIntN(5); };
245 
246  if (IsInlineConstant(SplatValue))
247  return false; // Can already be encoded as an immediate.
248 
249  APInt NegSplatValue = 0 - SplatValue;
250  if (!IsInlineConstant(NegSplatValue))
251  return false; // Even if we negate it it won't help.
252 
253  SDLoc DL(Node);
254 
256  ISD::SUB, DL, VT, {CurDAG->getConstant(0, DL, VT), C});
257  assert(NegC && "Constant-folding failed!");
258  SDValue NewNode = CurDAG->getNode(ISD::SUB, DL, VT, X, NegC);
259 
260  ReplaceNode(Node, NewNode.getNode());
261  SelectCode(NewNode.getNode());
262  return true;
263 }
264 
265 /// Select instructions not customized! Used for
266 /// expanded, promoted and normal instructions
267 void MipsDAGToDAGISel::Select(SDNode *Node) {
268  unsigned Opcode = Node->getOpcode();
269 
270  // If we have a custom node, we already have selected!
271  if (Node->isMachineOpcode()) {
272  LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
273  Node->setNodeId(-1);
274  return;
275  }
276 
277  // See if subclasses can handle this node.
278  if (trySelect(Node))
279  return;
280 
281  switch(Opcode) {
282  default: break;
283 
284  case ISD::ADD:
285  if (Node->getSimpleValueType(0).isVector() &&
286  selectVecAddAsVecSubIfProfitable(Node))
287  return;
288  break;
289 
290  // Get target GOT address.
292  ReplaceNode(Node, getGlobalBaseReg());
293  return;
294 
295 #ifndef NDEBUG
296  case ISD::LOAD:
297  case ISD::STORE:
299  cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
300  cast<MemSDNode>(Node)->getAlignment()) &&
301  "Unexpected unaligned loads/stores.");
302  break;
303 #endif
304  }
305 
306  // Select the default instruction
307  SelectCode(Node);
308 }
309 
310 bool MipsDAGToDAGISel::
311 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
312  std::vector<SDValue> &OutOps) {
313  // All memory constraints can at least accept raw pointers.
314  switch(ConstraintID) {
315  default:
316  llvm_unreachable("Unexpected asm memory constraint");
320  OutOps.push_back(Op);
321  return false;
322  }
323  return true;
324 }
llvm::ISD::SUB
@ SUB
Definition: ISDOpcodes.h:233
Mips16ISelDAGToDAG.h
StackProtector.h
llvm::SelectionDAGISel::getTargetLowering
const TargetLowering * getTargetLowering() const
Definition: SelectionDAGISel.h:67
MipsBaseInfo.h
llvm
Definition: AllocatorList.h:23
llvm::SDLoc
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Definition: SelectionDAGNodes.h:1078
llvm::SDValue::getNode
SDNode * getNode() const
get the SDNode which holds the desired result
Definition: SelectionDAGNodes.h:152
llvm::MipsDAGToDAGISel::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MipsISelDAGToDAG.cpp:49
llvm::MipsSubtarget::systemSupportsUnalignedAccess
bool systemSupportsUnalignedAccess() const
Does the system support unaligned memory access.
Definition: MipsSubtarget.h:373
ErrorHandling.h
llvm::SDNode
Represents one node in the SelectionDAG.
Definition: SelectionDAGNodes.h:455
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
llvm::MipsFunctionInfo
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
Definition: MipsMachineFunction.h:25
MachineRegisterInfo.h
llvm::SelectionDAG::getRegister
SDValue getRegister(unsigned Reg, EVT VT)
Definition: SelectionDAG.cpp:1953
llvm::MipsDAGToDAGISel::Subtarget
const MipsSubtarget * Subtarget
Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...
Definition: MipsISelDAGToDAG.h:50
GlobalValue.h
TargetMachine.h
SelectionDAGNodes.h
llvm::PPCISD::GlobalBaseReg
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
Definition: PPCISelLowering.h:156
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:656
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:35
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::SelectionDAG::getConstant
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
Definition: SelectionDAG.cpp:1347
llvm::StackProtector
Definition: StackProtector.h:37
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
Mips.h
llvm::ISD::GLOBAL_OFFSET_TABLE
@ GLOBAL_OFFSET_TABLE
The address of the GOT.
Definition: ISDOpcodes.h:80
llvm::SelectionDAGISel::ReplaceNode
void ReplaceNode(SDNode *F, SDNode *T)
Replace all uses of F with T, then remove F from the DAG.
Definition: SelectionDAGISel.h:227
MipsRegisterInfo.h
llvm::APInt::isIntN
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
Definition: APInt.h:455
Type.h
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
CFG.h
llvm::InlineAsm::Constraint_R
@ Constraint_R
Definition: InlineAsm.h:250
llvm::MipsSubtarget::isLittle
bool isLittle() const
Definition: MipsSubtarget.h:281
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:558
llvm::SelectionDAGISel::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: SelectionDAGISel.cpp:330
llvm::ISD::LOAD
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:911
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::SelectionDAG::getNode
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
Definition: SelectionDAG.cpp:7818
MipsMachineFunction.h
MachineConstantPool.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::SelectionDAGISel::CurDAG
SelectionDAG * CurDAG
Definition: SelectionDAGISel.h:47
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:70
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:149
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::SelectionDAGISel::MF
MachineFunction * MF
Definition: SelectionDAGISel.h:45
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
MachineFrameInfo.h
llvm::SelectionDAG::getDataLayout
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:440
llvm::SDValue
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
Definition: SelectionDAGNodes.h:138
llvm::InlineAsm::Constraint_m
@ Constraint_m
Definition: InlineAsm.h:245
llvm::SelectionDAG::FoldConstantArithmetic
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops)
Definition: SelectionDAG.cpp:5128
llvm::ISD::STORE
@ STORE
Definition: ISDOpcodes.h:912
llvm::ISD::ADD
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:232
Instructions.h
MipsISelDAGToDAG.h
MachineInstrBuilder.h
N
#define N
llvm::MipsDAGToDAGISel::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: MipsISelDAGToDAG.cpp:56
raw_ostream.h
llvm::SelectionDAGISel::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition: SelectionDAGISel.cpp:411
MachineFunction.h
MipsSEISelDAGToDAG.h
Debug.h
llvm::MipsDAGToDAGISel::getGlobalBaseReg
SDNode * getGlobalBaseReg()
getGlobalBaseReg - Output the instructions required to put the GOT address into a register.
Definition: MipsISelDAGToDAG.cpp:67
llvm::InlineAsm::Constraint_ZC
@ Constraint_ZC
Definition: InlineAsm.h:262