]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86InstructionSelector.cpp
Merge lldb trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86InstructionSelector.cpp
1 //===- 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 "X86InstrBuilder.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/GlobalISel/InstructionSelector.h"
22 #include "llvm/CodeGen/MachineBasicBlock.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstr.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineOperand.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/raw_ostream.h"
31
32 #define DEBUG_TYPE "X86-isel"
33
34 using namespace llvm;
35
36 #ifndef LLVM_BUILD_GLOBAL_ISEL
37 #error "You shouldn't build this"
38 #endif
39
40 namespace {
41
42 class X86InstructionSelector : public InstructionSelector {
43 public:
44   X86InstructionSelector(const X86Subtarget &STI,
45                          const X86RegisterBankInfo &RBI);
46
47   bool select(MachineInstr &I) const override;
48
49 private:
50   /// tblgen-erated 'select' implementation, used as the initial selector for
51   /// the patterns that don't require complex C++.
52   bool selectImpl(MachineInstr &I) const;
53
54   // TODO: remove after selectImpl support pattern with a predicate.
55   unsigned getFAddOp(LLT &Ty, const RegisterBank &RB) const;
56   unsigned getFSubOp(LLT &Ty, const RegisterBank &RB) const;
57   unsigned getAddOp(LLT &Ty, const RegisterBank &RB) const;
58   unsigned getSubOp(LLT &Ty, const RegisterBank &RB) const;
59   unsigned getLoadStoreOp(LLT &Ty, const RegisterBank &RB, unsigned Opc,
60                           uint64_t Alignment) const;
61
62   bool selectBinaryOp(MachineInstr &I, MachineRegisterInfo &MRI,
63                       MachineFunction &MF) const;
64   bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
65                          MachineFunction &MF) const;
66   bool selectFrameIndex(MachineInstr &I, MachineRegisterInfo &MRI,
67                         MachineFunction &MF) const;
68   bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
69                       MachineFunction &MF) const;
70
71   const X86Subtarget &STI;
72   const X86InstrInfo &TII;
73   const X86RegisterInfo &TRI;
74   const X86RegisterBankInfo &RBI;
75
76 #define GET_GLOBALISEL_TEMPORARIES_DECL
77 #include "X86GenGlobalISel.inc"
78 #undef GET_GLOBALISEL_TEMPORARIES_DECL
79 };
80
81 } // end anonymous namespace
82
83 #define GET_GLOBALISEL_IMPL
84 #include "X86GenGlobalISel.inc"
85 #undef GET_GLOBALISEL_IMPL
86
87 X86InstructionSelector::X86InstructionSelector(const X86Subtarget &STI,
88                                                const X86RegisterBankInfo &RBI)
89     : InstructionSelector(), STI(STI), TII(*STI.getInstrInfo()),
90       TRI(*STI.getRegisterInfo()), RBI(RBI)
91 #define GET_GLOBALISEL_TEMPORARIES_INIT
92 #include "X86GenGlobalISel.inc"
93 #undef GET_GLOBALISEL_TEMPORARIES_INIT
94 {
95 }
96
97 // FIXME: This should be target-independent, inferred from the types declared
98 // for each class in the bank.
99 static const TargetRegisterClass *
100 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) {
101   if (RB.getID() == X86::GPRRegBankID) {
102     if (Ty.getSizeInBits() == 32)
103       return &X86::GR32RegClass;
104     if (Ty.getSizeInBits() == 64)
105       return &X86::GR64RegClass;
106   }
107   if (RB.getID() == X86::VECRRegBankID) {
108     if (Ty.getSizeInBits() == 32)
109       return &X86::FR32XRegClass;
110     if (Ty.getSizeInBits() == 64)
111       return &X86::FR64XRegClass;
112     if (Ty.getSizeInBits() == 128)
113       return &X86::VR128XRegClass;
114     if (Ty.getSizeInBits() == 256)
115       return &X86::VR256XRegClass;
116     if (Ty.getSizeInBits() == 512)
117       return &X86::VR512RegClass;
118   }
119
120   llvm_unreachable("Unknown RegBank!");
121 }
122
123 // Set X86 Opcode and constrain DestReg.
124 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
125                        MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
126                        const RegisterBankInfo &RBI) {
127
128   unsigned DstReg = I.getOperand(0).getReg();
129   if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
130     assert(I.isCopy() && "Generic operators do not allow physical registers");
131     return true;
132   }
133
134   const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
135   const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
136   (void)DstSize;
137   unsigned SrcReg = I.getOperand(1).getReg();
138   const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
139   (void)SrcSize;
140   assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
141          "No phys reg on generic operators");
142   assert((DstSize == SrcSize ||
143           // Copies are a mean to setup initial types, the number of
144           // bits may not exactly match.
145           (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
146            DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
147          "Copy with different width?!");
148
149   const TargetRegisterClass *RC = nullptr;
150
151   switch (RegBank.getID()) {
152   case X86::GPRRegBankID:
153     assert((DstSize <= 64) && "GPRs cannot get more than 64-bit width values.");
154     RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank);
155     break;
156   case X86::VECRRegBankID:
157     RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank);
158     break;
159   default:
160     llvm_unreachable("Unknown RegBank!");
161   }
162
163   // No need to constrain SrcReg. It will get constrained when
164   // we hit another of its use or its defs.
165   // Copies do not have constraints.
166   const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
167   if (!OldRC || !RC->hasSubClassEq(OldRC)) {
168     if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
169       DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
170                    << " operand\n");
171       return false;
172     }
173   }
174   I.setDesc(TII.get(X86::COPY));
175   return true;
176 }
177
178 bool X86InstructionSelector::select(MachineInstr &I) const {
179   assert(I.getParent() && "Instruction should be in a basic block!");
180   assert(I.getParent()->getParent() && "Instruction should be in a function!");
181
182   MachineBasicBlock &MBB = *I.getParent();
183   MachineFunction &MF = *MBB.getParent();
184   MachineRegisterInfo &MRI = MF.getRegInfo();
185
186   unsigned Opcode = I.getOpcode();
187   if (!isPreISelGenericOpcode(Opcode)) {
188     // Certain non-generic instructions also need some special handling.
189
190     if (I.isCopy())
191       return selectCopy(I, TII, MRI, TRI, RBI);
192
193     // TODO: handle more cases - LOAD_STACK_GUARD, PHI
194     return true;
195   }
196
197   assert(I.getNumOperands() == I.getNumExplicitOperands() &&
198          "Generic instruction has unexpected implicit operands\n");
199
200   // TODO: This should be implemented by tblgen, pattern with predicate not
201   // supported yet.
202   if (selectBinaryOp(I, MRI, MF))
203     return true;
204   if (selectLoadStoreOp(I, MRI, MF))
205     return true;
206   if (selectFrameIndex(I, MRI, MF))
207     return true;
208   if (selectConstant(I, MRI, MF))
209     return true;
210
211   return selectImpl(I);
212 }
213
214 unsigned X86InstructionSelector::getFAddOp(LLT &Ty,
215                                            const RegisterBank &RB) const {
216
217   if (X86::VECRRegBankID != RB.getID())
218     return TargetOpcode::G_FADD;
219
220   if (Ty == LLT::scalar(32)) {
221     if (STI.hasAVX512()) {
222       return X86::VADDSSZrr;
223     } else if (STI.hasAVX()) {
224       return X86::VADDSSrr;
225     } else if (STI.hasSSE1()) {
226       return X86::ADDSSrr;
227     }
228   } else if (Ty == LLT::scalar(64)) {
229     if (STI.hasAVX512()) {
230       return X86::VADDSDZrr;
231     } else if (STI.hasAVX()) {
232       return X86::VADDSDrr;
233     } else if (STI.hasSSE2()) {
234       return X86::ADDSDrr;
235     }
236   } else if (Ty == LLT::vector(4, 32)) {
237     if ((STI.hasAVX512()) && (STI.hasVLX())) {
238       return X86::VADDPSZ128rr;
239     } else if (STI.hasAVX()) {
240       return X86::VADDPSrr;
241     } else if (STI.hasSSE1()) {
242       return X86::ADDPSrr;
243     }
244   }
245
246   return TargetOpcode::G_FADD;
247 }
248
249 unsigned X86InstructionSelector::getFSubOp(LLT &Ty,
250                                            const RegisterBank &RB) const {
251
252   if (X86::VECRRegBankID != RB.getID())
253     return TargetOpcode::G_FSUB;
254
255   if (Ty == LLT::scalar(32)) {
256     if (STI.hasAVX512()) {
257       return X86::VSUBSSZrr;
258     } else if (STI.hasAVX()) {
259       return X86::VSUBSSrr;
260     } else if (STI.hasSSE1()) {
261       return X86::SUBSSrr;
262     }
263   } else if (Ty == LLT::scalar(64)) {
264     if (STI.hasAVX512()) {
265       return X86::VSUBSDZrr;
266     } else if (STI.hasAVX()) {
267       return X86::VSUBSDrr;
268     } else if (STI.hasSSE2()) {
269       return X86::SUBSDrr;
270     }
271   } else if (Ty == LLT::vector(4, 32)) {
272     if ((STI.hasAVX512()) && (STI.hasVLX())) {
273       return X86::VSUBPSZ128rr;
274     } else if (STI.hasAVX()) {
275       return X86::VSUBPSrr;
276     } else if (STI.hasSSE1()) {
277       return X86::SUBPSrr;
278     }
279   }
280
281   return TargetOpcode::G_FSUB;
282 }
283
284 unsigned X86InstructionSelector::getAddOp(LLT &Ty,
285                                           const RegisterBank &RB) const {
286
287   if (X86::VECRRegBankID != RB.getID())
288     return TargetOpcode::G_ADD;
289
290   if (Ty == LLT::vector(4, 32)) {
291     if (STI.hasAVX512() && STI.hasVLX()) {
292       return X86::VPADDDZ128rr;
293     } else if (STI.hasAVX()) {
294       return X86::VPADDDrr;
295     } else if (STI.hasSSE2()) {
296       return X86::PADDDrr;
297     }
298   }
299
300   return TargetOpcode::G_ADD;
301 }
302
303 unsigned X86InstructionSelector::getSubOp(LLT &Ty,
304                                           const RegisterBank &RB) const {
305
306   if (X86::VECRRegBankID != RB.getID())
307     return TargetOpcode::G_SUB;
308
309   if (Ty == LLT::vector(4, 32)) {
310     if (STI.hasAVX512() && STI.hasVLX()) {
311       return X86::VPSUBDZ128rr;
312     } else if (STI.hasAVX()) {
313       return X86::VPSUBDrr;
314     } else if (STI.hasSSE2()) {
315       return X86::PSUBDrr;
316     }
317   }
318
319   return TargetOpcode::G_SUB;
320 }
321
322 bool X86InstructionSelector::selectBinaryOp(MachineInstr &I,
323                                             MachineRegisterInfo &MRI,
324                                             MachineFunction &MF) const {
325
326   const unsigned DefReg = I.getOperand(0).getReg();
327   LLT Ty = MRI.getType(DefReg);
328   const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
329
330   unsigned NewOpc = I.getOpcode();
331
332   switch (NewOpc) {
333   case TargetOpcode::G_FADD:
334     NewOpc = getFAddOp(Ty, RB);
335     break;
336   case TargetOpcode::G_FSUB:
337     NewOpc = getFSubOp(Ty, RB);
338     break;
339   case TargetOpcode::G_ADD:
340     NewOpc = getAddOp(Ty, RB);
341     break;
342   case TargetOpcode::G_SUB:
343     NewOpc = getSubOp(Ty, RB);
344     break;
345   default:
346     break;
347   }
348
349   if (NewOpc == I.getOpcode())
350     return false;
351
352   I.setDesc(TII.get(NewOpc));
353
354   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
355 }
356
357 unsigned X86InstructionSelector::getLoadStoreOp(LLT &Ty, const RegisterBank &RB,
358                                                 unsigned Opc,
359                                                 uint64_t Alignment) const {
360   bool Isload = (Opc == TargetOpcode::G_LOAD);
361   bool HasAVX = STI.hasAVX();
362   bool HasAVX512 = STI.hasAVX512();
363   bool HasVLX = STI.hasVLX();
364
365   if (Ty == LLT::scalar(8)) {
366     if (X86::GPRRegBankID == RB.getID())
367       return Isload ? X86::MOV8rm : X86::MOV8mr;
368   } else if (Ty == LLT::scalar(16)) {
369     if (X86::GPRRegBankID == RB.getID())
370       return Isload ? X86::MOV16rm : X86::MOV16mr;
371   } else if (Ty == LLT::scalar(32)) {
372     if (X86::GPRRegBankID == RB.getID())
373       return Isload ? X86::MOV32rm : X86::MOV32mr;
374     if (X86::VECRRegBankID == RB.getID())
375       return Isload ? (HasAVX512 ? X86::VMOVSSZrm
376                                  : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm)
377                     : (HasAVX512 ? X86::VMOVSSZmr
378                                  : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr);
379   } else if (Ty == LLT::scalar(64)) {
380     if (X86::GPRRegBankID == RB.getID())
381       return Isload ? X86::MOV64rm : X86::MOV64mr;
382     if (X86::VECRRegBankID == RB.getID())
383       return Isload ? (HasAVX512 ? X86::VMOVSDZrm
384                                  : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm)
385                     : (HasAVX512 ? X86::VMOVSDZmr
386                                  : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr);
387   } else if (Ty.isVector() && Ty.getSizeInBits() == 128) {
388     if (Alignment >= 16)
389       return Isload ? (HasVLX ? X86::VMOVAPSZ128rm
390                               : HasAVX512
391                                     ? X86::VMOVAPSZ128rm_NOVLX
392                                     : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm)
393                     : (HasVLX ? X86::VMOVAPSZ128mr
394                               : HasAVX512
395                                     ? X86::VMOVAPSZ128mr_NOVLX
396                                     : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr);
397     else
398       return Isload ? (HasVLX ? X86::VMOVUPSZ128rm
399                               : HasAVX512
400                                     ? X86::VMOVUPSZ128rm_NOVLX
401                                     : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm)
402                     : (HasVLX ? X86::VMOVUPSZ128mr
403                               : HasAVX512
404                                     ? X86::VMOVUPSZ128mr_NOVLX
405                                     : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr);
406   }
407   return Opc;
408 }
409
410 bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
411                                                MachineRegisterInfo &MRI,
412                                                MachineFunction &MF) const {
413
414   unsigned Opc = I.getOpcode();
415
416   if (Opc != TargetOpcode::G_STORE && Opc != TargetOpcode::G_LOAD)
417     return false;
418
419   const unsigned DefReg = I.getOperand(0).getReg();
420   LLT Ty = MRI.getType(DefReg);
421   const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
422
423   auto &MemOp = **I.memoperands_begin();
424   unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
425   if (NewOpc == Opc)
426     return false;
427
428   I.setDesc(TII.get(NewOpc));
429   MachineInstrBuilder MIB(MF, I);
430   if (Opc == TargetOpcode::G_LOAD)
431     addOffset(MIB, 0);
432   else {
433     // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
434     I.RemoveOperand(0);
435     addOffset(MIB, 0).addUse(DefReg);
436   }
437   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
438 }
439
440 bool X86InstructionSelector::selectFrameIndex(MachineInstr &I,
441                                               MachineRegisterInfo &MRI,
442                                               MachineFunction &MF) const {
443   if (I.getOpcode() != TargetOpcode::G_FRAME_INDEX)
444     return false;
445
446   const unsigned DefReg = I.getOperand(0).getReg();
447   LLT Ty = MRI.getType(DefReg);
448
449   // Use LEA to calculate frame index.
450   unsigned NewOpc;
451   if (Ty == LLT::pointer(0, 64))
452     NewOpc = X86::LEA64r;
453   else if (Ty == LLT::pointer(0, 32))
454     NewOpc = STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
455   else
456     llvm_unreachable("Can't select G_FRAME_INDEX, unsupported type.");
457
458   I.setDesc(TII.get(NewOpc));
459   MachineInstrBuilder MIB(MF, I);
460   addOffset(MIB, 0);
461
462   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
463 }
464
465 bool X86InstructionSelector::selectConstant(MachineInstr &I,
466                                             MachineRegisterInfo &MRI,
467                                             MachineFunction &MF) const {
468   if (I.getOpcode() != TargetOpcode::G_CONSTANT)
469     return false;
470
471   const unsigned DefReg = I.getOperand(0).getReg();
472   LLT Ty = MRI.getType(DefReg);
473
474   assert(Ty.isScalar() && "invalid element type.");
475
476   uint64_t Val = 0;
477   if (I.getOperand(1).isCImm()) {
478     Val = I.getOperand(1).getCImm()->getZExtValue();
479     I.getOperand(1).ChangeToImmediate(Val);
480   } else if (I.getOperand(1).isImm()) {
481     Val = I.getOperand(1).getImm();
482   } else
483     llvm_unreachable("Unsupported operand type.");
484
485   unsigned NewOpc;
486   switch (Ty.getSizeInBits()) {
487   case 8:
488     NewOpc = X86::MOV8ri;
489     break;
490   case 16:
491     NewOpc = X86::MOV16ri;
492     break;
493   case 32:
494     NewOpc = X86::MOV32ri;
495     break;
496   case 64: {
497     // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
498     if (isInt<32>(Val))
499       NewOpc = X86::MOV64ri32;
500     else
501       NewOpc = X86::MOV64ri;
502     break;
503   }
504   default:
505     llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
506   }
507
508   I.setDesc(TII.get(NewOpc));
509   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
510 }
511
512 InstructionSelector *
513 llvm::createX86InstructionSelector(X86Subtarget &Subtarget,
514                                    X86RegisterBankInfo &RBI) {
515   return new X86InstructionSelector(Subtarget, RBI);
516 }