LLVM  6.0.0svn
ARMInstructionSelector.cpp
Go to the documentation of this file.
1 //===- ARMInstructionSelector.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 ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARMRegisterBankInfo.h"
15 #include "ARMSubtarget.h"
16 #include "ARMTargetMachine.h"
21 #include "llvm/Support/Debug.h"
22 
23 #define DEBUG_TYPE "arm-isel"
24 
25 using namespace llvm;
26 
27 namespace {
28 
29 #define GET_GLOBALISEL_PREDICATE_BITSET
30 #include "ARMGenGlobalISel.inc"
31 #undef GET_GLOBALISEL_PREDICATE_BITSET
32 
33 class ARMInstructionSelector : public InstructionSelector {
34 public:
35  ARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI,
36  const ARMRegisterBankInfo &RBI);
37 
38  bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override;
39  static const char *getName() { return DEBUG_TYPE; }
40 
41 private:
42  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
43 
44  struct CmpConstants;
45  struct InsertInfo;
46 
47  bool selectCmp(CmpConstants Helper, MachineInstrBuilder &MIB,
48  MachineRegisterInfo &MRI) const;
49 
50  // Helper for inserting a comparison sequence that sets \p ResReg to either 1
51  // if \p LHSReg and \p RHSReg are in the relationship defined by \p Cond, or
52  // \p PrevRes otherwise. In essence, it computes PrevRes OR (LHS Cond RHS).
53  bool insertComparison(CmpConstants Helper, InsertInfo I, unsigned ResReg,
54  ARMCC::CondCodes Cond, unsigned LHSReg, unsigned RHSReg,
55  unsigned PrevRes) const;
56 
57  // Set \p DestReg to \p Constant.
58  void putConstant(InsertInfo I, unsigned DestReg, unsigned Constant) const;
59 
60  bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
61  bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const;
62  bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const;
63 
64  // Check if the types match and both operands have the expected size and
65  // register bank.
66  bool validOpRegPair(MachineRegisterInfo &MRI, unsigned LHS, unsigned RHS,
67  unsigned ExpectedSize, unsigned ExpectedRegBankID) const;
68 
69  // Check if the register has the expected size and register bank.
70  bool validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize,
71  unsigned ExpectedRegBankID) const;
72 
73  const ARMBaseInstrInfo &TII;
74  const ARMBaseRegisterInfo &TRI;
75  const ARMBaseTargetMachine &TM;
76  const ARMRegisterBankInfo &RBI;
77  const ARMSubtarget &STI;
78 
79 #define GET_GLOBALISEL_PREDICATES_DECL
80 #include "ARMGenGlobalISel.inc"
81 #undef GET_GLOBALISEL_PREDICATES_DECL
82 
83 // We declare the temporaries used by selectImpl() in the class to minimize the
84 // cost of constructing placeholder values.
85 #define GET_GLOBALISEL_TEMPORARIES_DECL
86 #include "ARMGenGlobalISel.inc"
87 #undef GET_GLOBALISEL_TEMPORARIES_DECL
88 };
89 } // end anonymous namespace
90 
91 namespace llvm {
94  const ARMSubtarget &STI,
95  const ARMRegisterBankInfo &RBI) {
96  return new ARMInstructionSelector(TM, STI, RBI);
97 }
98 }
99 
100 const unsigned zero_reg = 0;
101 
102 #define GET_GLOBALISEL_IMPL
103 #include "ARMGenGlobalISel.inc"
104 #undef GET_GLOBALISEL_IMPL
105 
106 ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM,
107  const ARMSubtarget &STI,
108  const ARMRegisterBankInfo &RBI)
109  : InstructionSelector(), TII(*STI.getInstrInfo()),
110  TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI), STI(STI),
112 #include "ARMGenGlobalISel.inc"
115 #include "ARMGenGlobalISel.inc"
117 {
118 }
119 
120 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
122  const RegisterBankInfo &RBI) {
123  unsigned DstReg = I.getOperand(0).getReg();
124  if (TargetRegisterInfo::isPhysicalRegister(DstReg))
125  return true;
126 
127  const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI);
128  (void)RegBank;
129  assert(RegBank && "Can't get reg bank for virtual register");
130 
131  const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
132  assert((RegBank->getID() == ARM::GPRRegBankID ||
133  RegBank->getID() == ARM::FPRRegBankID) &&
134  "Unsupported reg bank");
135 
136  const TargetRegisterClass *RC = &ARM::GPRRegClass;
137 
138  if (RegBank->getID() == ARM::FPRRegBankID) {
139  if (DstSize == 32)
140  RC = &ARM::SPRRegClass;
141  else if (DstSize == 64)
142  RC = &ARM::DPRRegClass;
143  else
144  llvm_unreachable("Unsupported destination size");
145  }
146 
147  // No need to constrain SrcReg. It will get constrained when
148  // we hit another of its uses or its defs.
149  // Copies do not have constraints.
150  if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
151  DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
152  << " operand\n");
153  return false;
154  }
155  return true;
156 }
157 
159  const ARMBaseInstrInfo &TII,
160  MachineRegisterInfo &MRI,
161  const TargetRegisterInfo &TRI,
162  const RegisterBankInfo &RBI) {
163  assert(TII.getSubtarget().hasVFP2() && "Can't select merge without VFP");
164 
165  // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
166  // into one DPR.
167  unsigned VReg0 = MIB->getOperand(0).getReg();
168  (void)VReg0;
169  assert(MRI.getType(VReg0).getSizeInBits() == 64 &&
170  RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID &&
171  "Unsupported operand for G_MERGE_VALUES");
172  unsigned VReg1 = MIB->getOperand(1).getReg();
173  (void)VReg1;
174  assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
175  RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
176  "Unsupported operand for G_MERGE_VALUES");
177  unsigned VReg2 = MIB->getOperand(2).getReg();
178  (void)VReg2;
179  assert(MRI.getType(VReg2).getSizeInBits() == 32 &&
180  RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID &&
181  "Unsupported operand for G_MERGE_VALUES");
182 
183  MIB->setDesc(TII.get(ARM::VMOVDRR));
184  MIB.add(predOps(ARMCC::AL));
185 
186  return true;
187 }
188 
190  const ARMBaseInstrInfo &TII,
191  MachineRegisterInfo &MRI,
192  const TargetRegisterInfo &TRI,
193  const RegisterBankInfo &RBI) {
194  assert(TII.getSubtarget().hasVFP2() && "Can't select unmerge without VFP");
195 
196  // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
197  // GPRs.
198  unsigned VReg0 = MIB->getOperand(0).getReg();
199  (void)VReg0;
200  assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
201  RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
202  "Unsupported operand for G_UNMERGE_VALUES");
203  unsigned VReg1 = MIB->getOperand(1).getReg();
204  (void)VReg1;
205  assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
206  RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
207  "Unsupported operand for G_UNMERGE_VALUES");
208  unsigned VReg2 = MIB->getOperand(2).getReg();
209  (void)VReg2;
210  assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
211  RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
212  "Unsupported operand for G_UNMERGE_VALUES");
213 
214  MIB->setDesc(TII.get(ARM::VMOVRRD));
215  MIB.add(predOps(ARMCC::AL));
216 
217  return true;
218 }
219 
220 /// Select the opcode for simple extensions (that translate to a single SXT/UXT
221 /// instruction). Extension operations more complicated than that should not
222 /// invoke this. Returns the original opcode if it doesn't know how to select a
223 /// better one.
224 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) {
225  using namespace TargetOpcode;
226 
227  if (Size != 8 && Size != 16)
228  return Opc;
229 
230  if (Opc == G_SEXT)
231  return Size == 8 ? ARM::SXTB : ARM::SXTH;
232 
233  if (Opc == G_ZEXT)
234  return Size == 8 ? ARM::UXTB : ARM::UXTH;
235 
236  return Opc;
237 }
238 
239 /// Select the opcode for simple loads and stores. For types smaller than 32
240 /// bits, the value will be zero extended. Returns the original opcode if it
241 /// doesn't know how to select a better one.
242 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
243  unsigned Size) {
244  bool isStore = Opc == TargetOpcode::G_STORE;
245 
246  if (RegBank == ARM::GPRRegBankID) {
247  switch (Size) {
248  case 1:
249  case 8:
250  return isStore ? ARM::STRBi12 : ARM::LDRBi12;
251  case 16:
252  return isStore ? ARM::STRH : ARM::LDRH;
253  case 32:
254  return isStore ? ARM::STRi12 : ARM::LDRi12;
255  default:
256  return Opc;
257  }
258  }
259 
260  if (RegBank == ARM::FPRRegBankID) {
261  switch (Size) {
262  case 32:
263  return isStore ? ARM::VSTRS : ARM::VLDRS;
264  case 64:
265  return isStore ? ARM::VSTRD : ARM::VLDRD;
266  default:
267  return Opc;
268  }
269  }
270 
271  return Opc;
272 }
273 
274 // When lowering comparisons, we sometimes need to perform two compares instead
275 // of just one. Get the condition codes for both comparisons. If only one is
276 // needed, the second member of the pair is ARMCC::AL.
277 static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
279  std::pair<ARMCC::CondCodes, ARMCC::CondCodes> Preds = {ARMCC::AL, ARMCC::AL};
280  switch (Pred) {
281  case CmpInst::FCMP_ONE:
282  Preds = {ARMCC::GT, ARMCC::MI};
283  break;
284  case CmpInst::FCMP_UEQ:
285  Preds = {ARMCC::EQ, ARMCC::VS};
286  break;
287  case CmpInst::ICMP_EQ:
288  case CmpInst::FCMP_OEQ:
289  Preds.first = ARMCC::EQ;
290  break;
291  case CmpInst::ICMP_SGT:
292  case CmpInst::FCMP_OGT:
293  Preds.first = ARMCC::GT;
294  break;
295  case CmpInst::ICMP_SGE:
296  case CmpInst::FCMP_OGE:
297  Preds.first = ARMCC::GE;
298  break;
299  case CmpInst::ICMP_UGT:
300  case CmpInst::FCMP_UGT:
301  Preds.first = ARMCC::HI;
302  break;
303  case CmpInst::FCMP_OLT:
304  Preds.first = ARMCC::MI;
305  break;
306  case CmpInst::ICMP_ULE:
307  case CmpInst::FCMP_OLE:
308  Preds.first = ARMCC::LS;
309  break;
310  case CmpInst::FCMP_ORD:
311  Preds.first = ARMCC::VC;
312  break;
313  case CmpInst::FCMP_UNO:
314  Preds.first = ARMCC::VS;
315  break;
316  case CmpInst::FCMP_UGE:
317  Preds.first = ARMCC::PL;
318  break;
319  case CmpInst::ICMP_SLT:
320  case CmpInst::FCMP_ULT:
321  Preds.first = ARMCC::LT;
322  break;
323  case CmpInst::ICMP_SLE:
324  case CmpInst::FCMP_ULE:
325  Preds.first = ARMCC::LE;
326  break;
327  case CmpInst::FCMP_UNE:
328  case CmpInst::ICMP_NE:
329  Preds.first = ARMCC::NE;
330  break;
331  case CmpInst::ICMP_UGE:
332  Preds.first = ARMCC::HS;
333  break;
334  case CmpInst::ICMP_ULT:
335  Preds.first = ARMCC::LO;
336  break;
337  default:
338  break;
339  }
340  assert(Preds.first != ARMCC::AL && "No comparisons needed?");
341  return Preds;
342 }
343 
345  CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned OpRegBank,
346  unsigned OpSize)
347  : ComparisonOpcode(CmpOpcode), ReadFlagsOpcode(FlagsOpcode),
348  OperandRegBankID(OpRegBank), OperandSize(OpSize) {}
349 
350  // The opcode used for performing the comparison.
351  const unsigned ComparisonOpcode;
352 
353  // The opcode used for reading the flags set by the comparison. May be
354  // ARM::INSTRUCTION_LIST_END if we don't need to read the flags.
355  const unsigned ReadFlagsOpcode;
356 
357  // The assumed register bank ID for the operands.
358  const unsigned OperandRegBankID;
359 
360  // The assumed size in bits for the operands.
361  const unsigned OperandSize;
362 };
363 
366  : MBB(*MIB->getParent()), InsertBefore(std::next(MIB->getIterator())),
367  DbgLoc(MIB->getDebugLoc()) {}
368 
371  const DebugLoc &DbgLoc;
372 };
373 
374 void ARMInstructionSelector::putConstant(InsertInfo I, unsigned DestReg,
375  unsigned Constant) const {
376  (void)BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(ARM::MOVi))
377  .addDef(DestReg)
378  .addImm(Constant)
380  .add(condCodeOp());
381 }
382 
383 bool ARMInstructionSelector::validOpRegPair(MachineRegisterInfo &MRI,
384  unsigned LHSReg, unsigned RHSReg,
385  unsigned ExpectedSize,
386  unsigned ExpectedRegBankID) const {
387  return MRI.getType(LHSReg) == MRI.getType(RHSReg) &&
388  validReg(MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
389  validReg(MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
390 }
391 
392 bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg,
393  unsigned ExpectedSize,
394  unsigned ExpectedRegBankID) const {
395  if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) {
396  DEBUG(dbgs() << "Unexpected size for register");
397  return false;
398  }
399 
400  if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) {
401  DEBUG(dbgs() << "Unexpected register bank for register");
402  return false;
403  }
404 
405  return true;
406 }
407 
408 bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
409  MachineInstrBuilder &MIB,
410  MachineRegisterInfo &MRI) const {
411  const InsertInfo I(MIB);
412 
413  auto ResReg = MIB->getOperand(0).getReg();
414  if (!validReg(MRI, ResReg, 1, ARM::GPRRegBankID))
415  return false;
416 
417  auto Cond =
418  static_cast<CmpInst::Predicate>(MIB->getOperand(1).getPredicate());
419  if (Cond == CmpInst::FCMP_TRUE || Cond == CmpInst::FCMP_FALSE) {
420  putConstant(I, ResReg, Cond == CmpInst::FCMP_TRUE ? 1 : 0);
421  MIB->eraseFromParent();
422  return true;
423  }
424 
425  auto LHSReg = MIB->getOperand(2).getReg();
426  auto RHSReg = MIB->getOperand(3).getReg();
427  if (!validOpRegPair(MRI, LHSReg, RHSReg, Helper.OperandSize,
428  Helper.OperandRegBankID))
429  return false;
430 
431  auto ARMConds = getComparePreds(Cond);
432  auto ZeroReg = MRI.createVirtualRegister(&ARM::GPRRegClass);
433  putConstant(I, ZeroReg, 0);
434 
435  if (ARMConds.second == ARMCC::AL) {
436  // Simple case, we only need one comparison and we're done.
437  if (!insertComparison(Helper, I, ResReg, ARMConds.first, LHSReg, RHSReg,
438  ZeroReg))
439  return false;
440  } else {
441  // Not so simple, we need two successive comparisons.
442  auto IntermediateRes = MRI.createVirtualRegister(&ARM::GPRRegClass);
443  if (!insertComparison(Helper, I, IntermediateRes, ARMConds.first, LHSReg,
444  RHSReg, ZeroReg))
445  return false;
446  if (!insertComparison(Helper, I, ResReg, ARMConds.second, LHSReg, RHSReg,
447  IntermediateRes))
448  return false;
449  }
450 
451  MIB->eraseFromParent();
452  return true;
453 }
454 
455 bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I,
456  unsigned ResReg,
457  ARMCC::CondCodes Cond,
458  unsigned LHSReg, unsigned RHSReg,
459  unsigned PrevRes) const {
460  // Perform the comparison.
461  auto CmpI =
462  BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(Helper.ComparisonOpcode))
463  .addUse(LHSReg)
464  .addUse(RHSReg)
465  .add(predOps(ARMCC::AL));
466  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
467  return false;
468 
469  // Read the comparison flags (if necessary).
470  if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
471  auto ReadI = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc,
472  TII.get(Helper.ReadFlagsOpcode))
473  .add(predOps(ARMCC::AL));
474  if (!constrainSelectedInstRegOperands(*ReadI, TII, TRI, RBI))
475  return false;
476  }
477 
478  // Select either 1 or the previous result based on the value of the flags.
479  auto Mov1I = BuildMI(I.MBB, I.InsertBefore, I.DbgLoc, TII.get(ARM::MOVCCi))
480  .addDef(ResReg)
481  .addUse(PrevRes)
482  .addImm(1)
483  .add(predOps(Cond, ARM::CPSR));
484  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
485  return false;
486 
487  return true;
488 }
489 
490 bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
491  MachineRegisterInfo &MRI) const {
492  if ((STI.isROPI() || STI.isRWPI()) && !STI.isTargetELF()) {
493  DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n");
494  return false;
495  }
496 
497  auto GV = MIB->getOperand(1).getGlobal();
498  if (GV->isThreadLocal()) {
499  DEBUG(dbgs() << "TLS variables not supported yet\n");
500  return false;
501  }
502 
503  auto &MBB = *MIB->getParent();
504  auto &MF = *MBB.getParent();
505 
506  bool UseMovt = STI.useMovt(MF);
507 
508  unsigned Size = TM.getPointerSize();
509  unsigned Alignment = 4;
510 
511  auto addOpsForConstantPoolLoad = [&MF, Alignment,
513  const GlobalValue *GV, bool IsSBREL) {
514  assert(MIB->getOpcode() == ARM::LDRi12 && "Unsupported instruction");
515  auto ConstPool = MF.getConstantPool();
516  auto CPIndex =
517  // For SB relative entries we need a target-specific constant pool.
518  // Otherwise, just use a regular constant pool entry.
519  IsSBREL
520  ? ConstPool->getConstantPoolIndex(
521  ARMConstantPoolConstant::Create(GV, ARMCP::SBREL), Alignment)
522  : ConstPool->getConstantPoolIndex(GV, Alignment);
523  MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
524  .addMemOperand(
525  MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
526  MachineMemOperand::MOLoad, Size, Alignment))
527  .addImm(0)
528  .add(predOps(ARMCC::AL));
529  };
530 
531  if (TM.isPositionIndependent()) {
532  bool Indirect = STI.isGVIndirectSymbol(GV);
533  // FIXME: Taking advantage of MOVT for ELF is pretty involved, so we don't
534  // support it yet. See PR28229.
535  unsigned Opc =
536  UseMovt && !STI.isTargetELF()
537  ? (Indirect ? ARM::MOV_ga_pcrel_ldr : ARM::MOV_ga_pcrel)
538  : (Indirect ? ARM::LDRLIT_ga_pcrel_ldr : ARM::LDRLIT_ga_pcrel);
539  MIB->setDesc(TII.get(Opc));
540 
542  if (STI.isTargetDarwin())
543  TargetFlags |= ARMII::MO_NONLAZY;
544  if (STI.isGVInGOT(GV))
545  TargetFlags |= ARMII::MO_GOT;
546  MIB->getOperand(1).setTargetFlags(TargetFlags);
547 
548  if (Indirect)
549  MIB.addMemOperand(MF.getMachineMemOperand(
550  MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad,
551  TM.getPointerSize(), Alignment));
552 
553  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
554  }
555 
556  bool isReadOnly = STI.getTargetLowering()->isReadOnly(GV);
557  if (STI.isROPI() && isReadOnly) {
558  unsigned Opc = UseMovt ? ARM::MOV_ga_pcrel : ARM::LDRLIT_ga_pcrel;
559  MIB->setDesc(TII.get(Opc));
560  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
561  }
562  if (STI.isRWPI() && !isReadOnly) {
563  auto Offset = MRI.createVirtualRegister(&ARM::GPRRegClass);
564  MachineInstrBuilder OffsetMIB;
565  if (UseMovt) {
566  OffsetMIB = BuildMI(MBB, *MIB, MIB->getDebugLoc(),
567  TII.get(ARM::MOVi32imm), Offset);
568  OffsetMIB.addGlobalAddress(GV, /*Offset*/ 0, ARMII::MO_SBREL);
569  } else {
570  // Load the offset from the constant pool.
571  OffsetMIB =
572  BuildMI(MBB, *MIB, MIB->getDebugLoc(), TII.get(ARM::LDRi12), Offset);
573  addOpsForConstantPoolLoad(OffsetMIB, GV, /*IsSBREL*/ true);
574  }
575  if (!constrainSelectedInstRegOperands(*OffsetMIB, TII, TRI, RBI))
576  return false;
577 
578  // Add the offset to the SB register.
579  MIB->setDesc(TII.get(ARM::ADDrr));
580  MIB->RemoveOperand(1);
581  MIB.addReg(ARM::R9) // FIXME: don't hardcode R9
582  .addReg(Offset)
583  .add(predOps(ARMCC::AL))
584  .add(condCodeOp());
585 
586  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
587  }
588 
589  if (STI.isTargetELF()) {
590  if (UseMovt) {
591  MIB->setDesc(TII.get(ARM::MOVi32imm));
592  } else {
593  // Load the global's address from the constant pool.
594  MIB->setDesc(TII.get(ARM::LDRi12));
595  MIB->RemoveOperand(1);
596  addOpsForConstantPoolLoad(MIB, GV, /*IsSBREL*/ false);
597  }
598  } else if (STI.isTargetMachO()) {
599  if (UseMovt)
600  MIB->setDesc(TII.get(ARM::MOVi32imm));
601  else
602  MIB->setDesc(TII.get(ARM::LDRLIT_ga_abs));
603  } else {
604  DEBUG(dbgs() << "Object format not supported yet\n");
605  return false;
606  }
607 
608  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
609 }
610 
611 bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
612  MachineRegisterInfo &MRI) const {
613  auto &MBB = *MIB->getParent();
614  auto InsertBefore = std::next(MIB->getIterator());
615  auto &DbgLoc = MIB->getDebugLoc();
616 
617  // Compare the condition to 0.
618  auto CondReg = MIB->getOperand(1).getReg();
619  assert(validReg(MRI, CondReg, 1, ARM::GPRRegBankID) &&
620  "Unsupported types for select operation");
621  auto CmpI = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::CMPri))
622  .addUse(CondReg)
623  .addImm(0)
624  .add(predOps(ARMCC::AL));
625  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI))
626  return false;
627 
628  // Move a value into the result register based on the result of the
629  // comparison.
630  auto ResReg = MIB->getOperand(0).getReg();
631  auto TrueReg = MIB->getOperand(2).getReg();
632  auto FalseReg = MIB->getOperand(3).getReg();
633  assert(validOpRegPair(MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
634  validOpRegPair(MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
635  "Unsupported types for select operation");
636  auto Mov1I = BuildMI(MBB, InsertBefore, DbgLoc, TII.get(ARM::MOVCCr))
637  .addDef(ResReg)
638  .addUse(TrueReg)
639  .addUse(FalseReg)
640  .add(predOps(ARMCC::EQ, ARM::CPSR));
641  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI))
642  return false;
643 
644  MIB->eraseFromParent();
645  return true;
646 }
647 
648 bool ARMInstructionSelector::selectShift(unsigned ShiftOpc,
649  MachineInstrBuilder &MIB) const {
650  MIB->setDesc(TII.get(ARM::MOVsr));
651  MIB.addImm(ShiftOpc);
653  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
654 }
655 
656 bool ARMInstructionSelector::select(MachineInstr &I,
657  CodeGenCoverage &CoverageInfo) const {
658  assert(I.getParent() && "Instruction should be in a basic block!");
659  assert(I.getParent()->getParent() && "Instruction should be in a function!");
660 
661  auto &MBB = *I.getParent();
662  auto &MF = *MBB.getParent();
663  auto &MRI = MF.getRegInfo();
664 
665  if (!isPreISelGenericOpcode(I.getOpcode())) {
666  if (I.isCopy())
667  return selectCopy(I, TII, MRI, TRI, RBI);
668 
669  return true;
670  }
671 
672  if (selectImpl(I, CoverageInfo))
673  return true;
674 
675  MachineInstrBuilder MIB{MF, I};
676  bool isSExt = false;
677 
678  using namespace TargetOpcode;
679  switch (I.getOpcode()) {
680  case G_SEXT:
681  isSExt = true;
683  case G_ZEXT: {
684  LLT DstTy = MRI.getType(I.getOperand(0).getReg());
685  // FIXME: Smaller destination sizes coming soon!
686  if (DstTy.getSizeInBits() != 32) {
687  DEBUG(dbgs() << "Unsupported destination size for extension");
688  return false;
689  }
690 
691  LLT SrcTy = MRI.getType(I.getOperand(1).getReg());
692  unsigned SrcSize = SrcTy.getSizeInBits();
693  switch (SrcSize) {
694  case 1: {
695  // ZExt boils down to & 0x1; for SExt we also subtract that from 0
696  I.setDesc(TII.get(ARM::ANDri));
698 
699  if (isSExt) {
700  unsigned SExtResult = I.getOperand(0).getReg();
701 
702  // Use a new virtual register for the result of the AND
703  unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass);
704  I.getOperand(0).setReg(AndResult);
705 
706  auto InsertBefore = std::next(I.getIterator());
707  auto SubI =
708  BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri))
709  .addDef(SExtResult)
710  .addUse(AndResult)
711  .addImm(0)
713  .add(condCodeOp());
714  if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI))
715  return false;
716  }
717  break;
718  }
719  case 8:
720  case 16: {
721  unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize);
722  if (NewOpc == I.getOpcode())
723  return false;
724  I.setDesc(TII.get(NewOpc));
725  MIB.addImm(0).add(predOps(ARMCC::AL));
726  break;
727  }
728  default:
729  DEBUG(dbgs() << "Unsupported source size for extension");
730  return false;
731  }
732  break;
733  }
734  case G_ANYEXT:
735  case G_TRUNC: {
736  // The high bits are undefined, so there's nothing special to do, just
737  // treat it as a copy.
738  auto SrcReg = I.getOperand(1).getReg();
739  auto DstReg = I.getOperand(0).getReg();
740 
741  const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
742  const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
743 
744  if (SrcRegBank.getID() != DstRegBank.getID()) {
745  DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n");
746  return false;
747  }
748 
749  if (SrcRegBank.getID() != ARM::GPRRegBankID) {
750  DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
751  return false;
752  }
753 
754  I.setDesc(TII.get(COPY));
755  return selectCopy(I, TII, MRI, TRI, RBI);
756  }
757  case G_SELECT:
758  return selectSelect(MIB, MRI);
759  case G_ICMP: {
760  CmpConstants Helper(ARM::CMPrr, ARM::INSTRUCTION_LIST_END,
761  ARM::GPRRegBankID, 32);
762  return selectCmp(Helper, MIB, MRI);
763  }
764  case G_FCMP: {
765  assert(STI.hasVFP2() && "Can't select fcmp without VFP");
766 
767  unsigned OpReg = I.getOperand(2).getReg();
768  unsigned Size = MRI.getType(OpReg).getSizeInBits();
769 
770  if (Size == 64 && STI.isFPOnlySP()) {
771  DEBUG(dbgs() << "Subtarget only supports single precision");
772  return false;
773  }
774  if (Size != 32 && Size != 64) {
775  DEBUG(dbgs() << "Unsupported size for G_FCMP operand");
776  return false;
777  }
778 
779  CmpConstants Helper(Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
780  ARM::FPRRegBankID, Size);
781  return selectCmp(Helper, MIB, MRI);
782  }
783  case G_LSHR:
784  return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
785  case G_ASHR:
786  return selectShift(ARM_AM::ShiftOpc::asr, MIB);
787  case G_SHL: {
788  return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
789  }
790  case G_GEP:
791  I.setDesc(TII.get(ARM::ADDrr));
793  break;
794  case G_FRAME_INDEX:
795  // Add 0 to the given frame index and hope it will eventually be folded into
796  // the user(s).
797  I.setDesc(TII.get(ARM::ADDri));
799  break;
800  case G_GLOBAL_VALUE:
801  return selectGlobal(MIB, MRI);
802  case G_STORE:
803  case G_LOAD: {
804  const auto &MemOp = **I.memoperands_begin();
805  if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) {
806  DEBUG(dbgs() << "Atomic load/store not supported yet\n");
807  return false;
808  }
809 
810  unsigned Reg = I.getOperand(0).getReg();
811  unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID();
812 
813  LLT ValTy = MRI.getType(Reg);
814  const auto ValSize = ValTy.getSizeInBits();
815 
816  assert((ValSize != 64 || STI.hasVFP2()) &&
817  "Don't know how to load/store 64-bit value without VFP");
818 
819  const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
820  if (NewOpc == G_LOAD || NewOpc == G_STORE)
821  return false;
822 
823  I.setDesc(TII.get(NewOpc));
824 
825  if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
826  // LDRH has a funny addressing mode (there's already a FIXME for it).
827  MIB.addReg(0);
828  MIB.addImm(0).add(predOps(ARMCC::AL));
829  break;
830  }
831  case G_MERGE_VALUES: {
832  if (!selectMergeValues(MIB, TII, MRI, TRI, RBI))
833  return false;
834  break;
835  }
836  case G_UNMERGE_VALUES: {
837  if (!selectUnmergeValues(MIB, TII, MRI, TRI, RBI))
838  return false;
839  break;
840  }
841  case G_BRCOND: {
842  if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
843  DEBUG(dbgs() << "Unsupported condition register for G_BRCOND");
844  return false;
845  }
846 
847  // Set the flags.
848  auto Test = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::TSTri))
849  .addReg(I.getOperand(0).getReg())
850  .addImm(1)
851  .add(predOps(ARMCC::AL));
852  if (!constrainSelectedInstRegOperands(*Test, TII, TRI, RBI))
853  return false;
854 
855  // Branch conditionally.
856  auto Branch = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(ARM::Bcc))
857  .add(I.getOperand(1))
858  .add(predOps(ARMCC::EQ, ARM::CPSR));
859  if (!constrainSelectedInstRegOperands(*Branch, TII, TRI, RBI))
860  return false;
861  I.eraseFromParent();
862  return true;
863  }
864  default:
865  return false;
866  }
867 
868  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
869 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
const unsigned zero_reg
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:268
unsigned getReg() const
getReg - Returns the register number.
#define DEBUG_TYPE
#define GET_GLOBALISEL_PREDICATES_INIT
A debug info location.
Definition: DebugLoc.h:34
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
InstructionSelector * createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI, const ARMRegisterBankInfo &RBI)
Holds all the information related to register banks.
Definition: BitVector.h:920
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
Definition: ARMBaseInfo.h:238
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
const HexagonInstrInfo * TII
CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned OpRegBank, unsigned OpSize)
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
Reg
All possible values of the reg field in the ModR/M byte.
static StringRef getName(Value *V)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:290
bool hasVFP2() const
Definition: ARMSubtarget.h:529
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
static bool isStore(int Opcode)
This class provides the information for the target register banks.
const ARMSubtarget & getSubtarget() const
#define EQ(a, b)
Definition: regexec.c:112
static std::pair< ARMCC::CondCodes, ARMCC::CondCodes > getComparePreds(CmpInst::Predicate Pred)
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
This file declares the targeting of the RegisterBankInfo class for ARM.
This is an important base class in LLVM.
Definition: Constant.h:42
const GlobalValue * getGlobal() const
static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank, unsigned Size)
Select the opcode for simple loads and stores.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:853
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
self_iterator getIterator()
Definition: ilist_node.h:82
bool isCopy() const
Definition: MachineInstr.h:857
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:51
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Iterator for intrusive lists based on ilist_node.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
This class implements the register bank concept.
Definition: RegisterBank.h:29
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:139
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Section Relative (Windows TLS)
Provides the logic to select generic machine instructions.
Representation of each machine instruction.
Definition: MachineInstr.h:59
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
#define I(x, y, z)
Definition: MD5.cpp:58
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
static const TargetRegisterClass * constrainGenericRegister(unsigned Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
#define GET_GLOBALISEL_TEMPORARIES_INIT
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel...
Definition: TargetOpcodes.h:31
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:235
static const Function * getParent(const Value *V)
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
Definition: ARMBaseInfo.h:256
const MachineBasicBlock::instr_iterator InsertBefore
#define DEBUG(X)
Definition: Debug.h:118
IRTranslator LLVM IR MI
static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size)
Select the opcode for simple extensions (that translate to a single SXT/UXT instruction).
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:295
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:48
unsigned getPredicate() const