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