blob: 0927c96abaa8d888f49f793b76099d37b7b7e793 [file] [log] [blame]
Igor Bregerf7359d82017-02-22 12:25:09 +00001//===- X86InstructionSelector.cpp ----------------------------*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the targeting of the InstructionSelector class for
11/// X86.
12/// \todo This should be generated by TableGen.
13//===----------------------------------------------------------------------===//
14
15#include "X86InstructionSelector.h"
16#include "X86InstrInfo.h"
17#include "X86RegisterBankInfo.h"
18#include "X86RegisterInfo.h"
19#include "X86Subtarget.h"
20#include "X86TargetMachine.h"
21#include "llvm/CodeGen/MachineBasicBlock.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineInstr.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/CodeGen/MachineRegisterInfo.h"
26#include "llvm/IR/Type.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Support/raw_ostream.h"
29
30#define DEBUG_TYPE "X86-isel"
31
32using namespace llvm;
33
34#ifndef LLVM_BUILD_GLOBAL_ISEL
35#error "You shouldn't build this"
36#endif
37
38#include "X86GenGlobalISel.inc"
39
Benjamin Kramer5a7e0f82017-02-22 12:59:47 +000040X86InstructionSelector::X86InstructionSelector(const X86Subtarget &STI,
Igor Bregerf7359d82017-02-22 12:25:09 +000041 const X86RegisterBankInfo &RBI)
Igor Breger321cf3c2017-03-03 08:06:46 +000042 : InstructionSelector(), STI(STI), TII(*STI.getInstrInfo()),
Igor Bregerf7359d82017-02-22 12:25:09 +000043 TRI(*STI.getRegisterInfo()), RBI(RBI) {}
44
45// FIXME: This should be target-independent, inferred from the types declared
46// for each class in the bank.
47static const TargetRegisterClass *
48getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) {
49 if (RB.getID() == X86::GPRRegBankID) {
Igor Breger321cf3c2017-03-03 08:06:46 +000050 if (Ty.getSizeInBits() == 32)
Igor Bregerf7359d82017-02-22 12:25:09 +000051 return &X86::GR32RegClass;
52 if (Ty.getSizeInBits() == 64)
53 return &X86::GR64RegClass;
54 }
Igor Breger321cf3c2017-03-03 08:06:46 +000055 if (RB.getID() == X86::VECRRegBankID) {
56 if (Ty.getSizeInBits() == 32)
57 return &X86::FR32XRegClass;
58 if (Ty.getSizeInBits() == 64)
59 return &X86::FR64XRegClass;
60 if (Ty.getSizeInBits() == 128)
61 return &X86::VR128XRegClass;
62 if (Ty.getSizeInBits() == 256)
63 return &X86::VR256XRegClass;
64 if (Ty.getSizeInBits() == 512)
65 return &X86::VR512RegClass;
66 }
Igor Bregerf7359d82017-02-22 12:25:09 +000067
68 llvm_unreachable("Unknown RegBank!");
69}
70
71// Set X86 Opcode and constrain DestReg.
72static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
73 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
74 const RegisterBankInfo &RBI) {
75
76 unsigned DstReg = I.getOperand(0).getReg();
77 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
78 assert(I.isCopy() && "Generic operators do not allow physical registers");
79 return true;
80 }
81
82 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
83 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
Benjamin Kramer5a7e0f82017-02-22 12:59:47 +000084 (void)DstSize;
Igor Bregerf7359d82017-02-22 12:25:09 +000085 unsigned SrcReg = I.getOperand(1).getReg();
86 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
87 (void)SrcSize;
88 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
89 "No phys reg on generic operators");
90 assert((DstSize == SrcSize ||
91 // Copies are a mean to setup initial types, the number of
92 // bits may not exactly match.
93 (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
94 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
95 "Copy with different width?!");
96
97 const TargetRegisterClass *RC = nullptr;
98
99 switch (RegBank.getID()) {
100 case X86::GPRRegBankID:
101 assert((DstSize <= 64) && "GPRs cannot get more than 64-bit width values.");
102 RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank);
103 break;
Igor Breger321cf3c2017-03-03 08:06:46 +0000104 case X86::VECRRegBankID:
105 RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank);
106 break;
Igor Bregerf7359d82017-02-22 12:25:09 +0000107 default:
108 llvm_unreachable("Unknown RegBank!");
109 }
110
111 // No need to constrain SrcReg. It will get constrained when
112 // we hit another of its use or its defs.
113 // Copies do not have constraints.
Igor Breger321cf3c2017-03-03 08:06:46 +0000114 const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
115 if (!OldRC || !RC->hasSubClassEq(OldRC)) {
116 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
117 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
118 << " operand\n");
119 return false;
120 }
Igor Bregerf7359d82017-02-22 12:25:09 +0000121 }
122 I.setDesc(TII.get(X86::COPY));
123 return true;
124}
125
126bool X86InstructionSelector::select(MachineInstr &I) const {
127 assert(I.getParent() && "Instruction should be in a basic block!");
128 assert(I.getParent()->getParent() && "Instruction should be in a function!");
129
130 MachineBasicBlock &MBB = *I.getParent();
131 MachineFunction &MF = *MBB.getParent();
132 MachineRegisterInfo &MRI = MF.getRegInfo();
133
134 unsigned Opcode = I.getOpcode();
135 if (!isPreISelGenericOpcode(Opcode)) {
136 // Certain non-generic instructions also need some special handling.
137
138 if (I.isCopy())
139 return selectCopy(I, TII, MRI, TRI, RBI);
140
141 // TODO: handle more cases - LOAD_STACK_GUARD, PHI
142 return true;
143 }
144
Benjamin Kramer5a7e0f82017-02-22 12:59:47 +0000145 assert(I.getNumOperands() == I.getNumExplicitOperands() &&
146 "Generic instruction has unexpected implicit operands\n");
Igor Bregerf7359d82017-02-22 12:25:09 +0000147
Igor Breger321cf3c2017-03-03 08:06:46 +0000148 // TODO: This should be implemented by tblgen, pattern with predicate not supported yet.
149 if (selectBinaryOp(I, MRI))
150 return true;
151
Igor Bregerf7359d82017-02-22 12:25:09 +0000152 return selectImpl(I);
153}
Igor Breger321cf3c2017-03-03 08:06:46 +0000154
155unsigned X86InstructionSelector::getFAddOp(LLT &Ty,
156 const RegisterBank &RB) const {
157
158 if (X86::VECRRegBankID != RB.getID())
159 return TargetOpcode::G_FADD;
160
161 if (Ty == LLT::scalar(32)) {
162 if (STI.hasAVX512()) {
163 return X86::VADDSSZrr;
164 } else if (STI.hasAVX()) {
165 return X86::VADDSSrr;
166 } else if (STI.hasSSE1()) {
167 return X86::ADDSSrr;
168 }
169 } else if (Ty == LLT::scalar(64)) {
170 if (STI.hasAVX512()) {
171 return X86::VADDSDZrr;
172 } else if (STI.hasAVX()) {
173 return X86::VADDSDrr;
174 } else if (STI.hasSSE2()) {
175 return X86::ADDSDrr;
176 }
177 } else if (Ty == LLT::vector(4, 32)) {
178 if ((STI.hasAVX512()) && (STI.hasVLX())) {
179 return X86::VADDPSZ128rr;
180 } else if (STI.hasAVX()) {
181 return X86::VADDPSrr;
182 } else if (STI.hasSSE1()) {
183 return X86::ADDPSrr;
184 }
185 }
186
187 return TargetOpcode::G_FADD;
188}
189
190unsigned X86InstructionSelector::getFSubOp(LLT &Ty,
191 const RegisterBank &RB) const {
192
193 if (X86::VECRRegBankID != RB.getID())
194 return TargetOpcode::G_FSUB;
195
196 if (Ty == LLT::scalar(32)) {
197 if (STI.hasAVX512()) {
198 return X86::VSUBSSZrr;
199 } else if (STI.hasAVX()) {
200 return X86::VSUBSSrr;
201 } else if (STI.hasSSE1()) {
202 return X86::SUBSSrr;
203 }
204 } else if (Ty == LLT::scalar(64)) {
205 if (STI.hasAVX512()) {
206 return X86::VSUBSDZrr;
207 } else if (STI.hasAVX()) {
208 return X86::VSUBSDrr;
209 } else if (STI.hasSSE2()) {
210 return X86::SUBSDrr;
211 }
212 } else if (Ty == LLT::vector(4, 32)) {
213 if ((STI.hasAVX512()) && (STI.hasVLX())) {
214 return X86::VSUBPSZ128rr;
215 } else if (STI.hasAVX()) {
216 return X86::VSUBPSrr;
217 } else if (STI.hasSSE1()) {
218 return X86::SUBPSrr;
219 }
220 }
221
222 return TargetOpcode::G_FSUB;
223}
224
225unsigned X86InstructionSelector::getAddOp(LLT &Ty,
226 const RegisterBank &RB) const {
227
228 if (X86::VECRRegBankID != RB.getID())
229 return TargetOpcode::G_ADD;
230
231 if (Ty == LLT::vector(4, 32)) {
232 if (STI.hasAVX512() && STI.hasVLX()) {
233 return X86::VPADDDZ128rr;
234 } else if (STI.hasAVX()) {
235 return X86::VPADDDrr;
236 } else if (STI.hasSSE2()) {
237 return X86::PADDDrr;
238 }
239 }
240
241 return TargetOpcode::G_ADD;
242}
243
244unsigned X86InstructionSelector::getSubOp(LLT &Ty,
245 const RegisterBank &RB) const {
246
247 if (X86::VECRRegBankID != RB.getID())
248 return TargetOpcode::G_SUB;
249
250 if (Ty == LLT::vector(4, 32)) {
251 if (STI.hasAVX512() && STI.hasVLX()) {
252 return X86::VPSUBDZ128rr;
253 } else if (STI.hasAVX()) {
254 return X86::VPSUBDrr;
255 } else if (STI.hasSSE2()) {
256 return X86::PSUBDrr;
257 }
258 }
259
260 return TargetOpcode::G_SUB;
261}
262
263bool X86InstructionSelector::selectBinaryOp(MachineInstr &I,
264 MachineRegisterInfo &MRI) const {
265
266 LLT Ty = MRI.getType(I.getOperand(0).getReg());
267 const unsigned DefReg = I.getOperand(0).getReg();
268 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
269
270 unsigned NewOpc = I.getOpcode();
271
272 switch (I.getOpcode()) {
273 case TargetOpcode::G_FADD:
274 NewOpc = getFAddOp(Ty, RB);
275 break;
276 case TargetOpcode::G_FSUB:
277 NewOpc = getFSubOp(Ty, RB);
278 break;
279 case TargetOpcode::G_ADD:
280 NewOpc = getAddOp(Ty, RB);
281 break;
282 case TargetOpcode::G_SUB:
283 NewOpc = getSubOp(Ty, RB);
284 break;
285 default:
286 break;
287 }
288
289 if (NewOpc == I.getOpcode())
290 return false;
291
292 I.setDesc(TII.get(NewOpc));
293
294 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
295}
296