LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AArch64InstrInfo.cpp
Go to the documentation of this file.
1 //===- AArch64InstrInfo.cpp - AArch64 Instruction Information -------------===//
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 //
10 // This file contains the AArch64 implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AArch64.h"
15 #include "AArch64InstrInfo.h"
17 #include "AArch64TargetMachine.h"
19 #include "Utils/AArch64BaseInfo.h"
26 #include "llvm/IR/Function.h"
29 
30 #include <algorithm>
31 
32 #define GET_INSTRINFO_CTOR_DTOR
33 #include "AArch64GenInstrInfo.inc"
34 
35 using namespace llvm;
36 
38  : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP),
39  Subtarget(STI) {}
40 
43  unsigned DestReg, unsigned SrcReg,
44  bool KillSrc) const {
45  unsigned Opc = 0;
46  unsigned ZeroReg = 0;
47  if (DestReg == AArch64::XSP || SrcReg == AArch64::XSP) {
48  // E.g. ADD xDst, xsp, #0 (, lsl #0)
49  BuildMI(MBB, I, DL, get(AArch64::ADDxxi_lsl0_s), DestReg)
50  .addReg(SrcReg)
51  .addImm(0);
52  return;
53  } else if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
54  // E.g. ADD wDST, wsp, #0 (, lsl #0)
55  BuildMI(MBB, I, DL, get(AArch64::ADDwwi_lsl0_s), DestReg)
56  .addReg(SrcReg)
57  .addImm(0);
58  return;
59  } else if (DestReg == AArch64::NZCV) {
60  assert(AArch64::GPR64RegClass.contains(SrcReg));
61  // E.g. MSR NZCV, xDST
62  BuildMI(MBB, I, DL, get(AArch64::MSRix))
64  .addReg(SrcReg);
65  } else if (SrcReg == AArch64::NZCV) {
66  assert(AArch64::GPR64RegClass.contains(DestReg));
67  // E.g. MRS xDST, NZCV
68  BuildMI(MBB, I, DL, get(AArch64::MRSxi), DestReg)
70  } else if (AArch64::GPR64RegClass.contains(DestReg)) {
71  if(AArch64::GPR64RegClass.contains(SrcReg)){
72  Opc = AArch64::ORRxxx_lsl;
73  ZeroReg = AArch64::XZR;
74  } else{
75  assert(AArch64::FPR64RegClass.contains(SrcReg));
76  BuildMI(MBB, I, DL, get(AArch64::FMOVxd), DestReg)
77  .addReg(SrcReg);
78  return;
79  }
80  } else if (AArch64::GPR32RegClass.contains(DestReg)) {
81  if(AArch64::GPR32RegClass.contains(SrcReg)){
82  Opc = AArch64::ORRwww_lsl;
83  ZeroReg = AArch64::WZR;
84  } else{
85  assert(AArch64::FPR32RegClass.contains(SrcReg));
86  BuildMI(MBB, I, DL, get(AArch64::FMOVws), DestReg)
87  .addReg(SrcReg);
88  return;
89  }
90  } else if (AArch64::FPR32RegClass.contains(DestReg)) {
91  if(AArch64::FPR32RegClass.contains(SrcReg)){
92  BuildMI(MBB, I, DL, get(AArch64::FMOVss), DestReg)
93  .addReg(SrcReg);
94  return;
95  }
96  else {
97  assert(AArch64::GPR32RegClass.contains(SrcReg));
98  BuildMI(MBB, I, DL, get(AArch64::FMOVsw), DestReg)
99  .addReg(SrcReg);
100  return;
101  }
102  } else if (AArch64::FPR64RegClass.contains(DestReg)) {
103  if(AArch64::FPR64RegClass.contains(SrcReg)){
104  BuildMI(MBB, I, DL, get(AArch64::FMOVdd), DestReg)
105  .addReg(SrcReg);
106  return;
107  }
108  else {
109  assert(AArch64::GPR64RegClass.contains(SrcReg));
110  BuildMI(MBB, I, DL, get(AArch64::FMOVdx), DestReg)
111  .addReg(SrcReg);
112  return;
113  }
114  } else if (AArch64::FPR128RegClass.contains(DestReg)) {
115  assert(AArch64::FPR128RegClass.contains(SrcReg));
116 
117  // If NEON is enable, we use ORR to implement this copy.
118  // If NEON isn't available, emit STR and LDR to handle this.
119  if(getSubTarget().hasNEON()) {
120  BuildMI(MBB, I, DL, get(AArch64::ORRvvv_16B), DestReg)
121  .addReg(SrcReg)
122  .addReg(SrcReg);
123  return;
124  } else {
125  BuildMI(MBB, I, DL, get(AArch64::LSFP128_PreInd_STR), AArch64::XSP)
126  .addReg(SrcReg)
127  .addReg(AArch64::XSP)
128  .addImm(0x1ff & -16);
129 
130  BuildMI(MBB, I, DL, get(AArch64::LSFP128_PostInd_LDR), DestReg)
131  .addReg(AArch64::XSP, RegState::Define)
132  .addReg(AArch64::XSP)
133  .addImm(16);
134  return;
135  }
136  } else {
137  llvm_unreachable("Unknown register class in copyPhysReg");
138  }
139 
140  // E.g. ORR xDst, xzr, xSrc, lsl #0
141  BuildMI(MBB, I, DL, get(Opc), DestReg)
142  .addReg(ZeroReg)
143  .addReg(SrcReg)
144  .addImm(0);
145 }
146 
147 /// Does the Opcode represent a conditional branch that we can remove and re-add
148 /// at the end of a basic block?
149 static bool isCondBranch(unsigned Opc) {
150  return Opc == AArch64::Bcc || Opc == AArch64::CBZw || Opc == AArch64::CBZx ||
151  Opc == AArch64::CBNZw || Opc == AArch64::CBNZx ||
152  Opc == AArch64::TBZwii || Opc == AArch64::TBZxii ||
153  Opc == AArch64::TBNZwii || Opc == AArch64::TBNZxii;
154 }
155 
156 /// Takes apart a given conditional branch MachineInstr (see isCondBranch),
157 /// setting TBB to the destination basic block and populating the Cond vector
158 /// with data necessary to recreate the conditional branch at a later
159 /// date. First element will be the opcode, and subsequent ones define the
160 /// conditions being branched on in an instruction-specific manner.
163  switch(I->getOpcode()) {
164  case AArch64::Bcc:
165  case AArch64::CBZw:
166  case AArch64::CBZx:
167  case AArch64::CBNZw:
168  case AArch64::CBNZx:
169  // These instructions just have one predicate operand in position 0 (either
170  // a condition code or a register being compared).
172  Cond.push_back(I->getOperand(0));
173  TBB = I->getOperand(1).getMBB();
174  return;
175  case AArch64::TBZwii:
176  case AArch64::TBZxii:
177  case AArch64::TBNZwii:
178  case AArch64::TBNZxii:
179  // These have two predicate operands: a register and a bit position.
181  Cond.push_back(I->getOperand(0));
182  Cond.push_back(I->getOperand(1));
183  TBB = I->getOperand(2).getMBB();
184  return;
185  default:
186  llvm_unreachable("Unknown conditional branch to classify");
187  }
188 }
189 
190 
191 bool
193  MachineBasicBlock *&FBB,
195  bool AllowModify) const {
196  // If the block has no terminators, it just falls into the block after it.
198  if (I == MBB.begin())
199  return false;
200  --I;
201  while (I->isDebugValue()) {
202  if (I == MBB.begin())
203  return false;
204  --I;
205  }
206  if (!isUnpredicatedTerminator(I))
207  return false;
208 
209  // Get the last instruction in the block.
210  MachineInstr *LastInst = I;
211 
212  // If there is only one terminator instruction, process it.
213  unsigned LastOpc = LastInst->getOpcode();
214  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
215  if (LastOpc == AArch64::Bimm) {
216  TBB = LastInst->getOperand(0).getMBB();
217  return false;
218  }
219  if (isCondBranch(LastOpc)) {
220  classifyCondBranch(LastInst, TBB, Cond);
221  return false;
222  }
223  return true; // Can't handle indirect branch.
224  }
225 
226  // Get the instruction before it if it is a terminator.
227  MachineInstr *SecondLastInst = I;
228  unsigned SecondLastOpc = SecondLastInst->getOpcode();
229 
230  // If AllowModify is true and the block ends with two or more unconditional
231  // branches, delete all but the first unconditional branch.
232  if (AllowModify && LastOpc == AArch64::Bimm) {
233  while (SecondLastOpc == AArch64::Bimm) {
234  LastInst->eraseFromParent();
235  LastInst = SecondLastInst;
236  LastOpc = LastInst->getOpcode();
237  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
238  // Return now the only terminator is an unconditional branch.
239  TBB = LastInst->getOperand(0).getMBB();
240  return false;
241  } else {
242  SecondLastInst = I;
243  SecondLastOpc = SecondLastInst->getOpcode();
244  }
245  }
246  }
247 
248  // If there are three terminators, we don't know what sort of block this is.
249  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
250  return true;
251 
252  // If the block ends with a B and a Bcc, handle it.
253  if (LastOpc == AArch64::Bimm) {
254  if (SecondLastOpc == AArch64::Bcc) {
255  TBB = SecondLastInst->getOperand(1).getMBB();
256  Cond.push_back(MachineOperand::CreateImm(AArch64::Bcc));
257  Cond.push_back(SecondLastInst->getOperand(0));
258  FBB = LastInst->getOperand(0).getMBB();
259  return false;
260  } else if (isCondBranch(SecondLastOpc)) {
261  classifyCondBranch(SecondLastInst, TBB, Cond);
262  FBB = LastInst->getOperand(0).getMBB();
263  return false;
264  }
265  }
266 
267  // If the block ends with two unconditional branches, handle it. The second
268  // one is not executed, so remove it.
269  if (SecondLastOpc == AArch64::Bimm && LastOpc == AArch64::Bimm) {
270  TBB = SecondLastInst->getOperand(0).getMBB();
271  I = LastInst;
272  if (AllowModify)
273  I->eraseFromParent();
274  return false;
275  }
276 
277  // Otherwise, can't handle this.
278  return true;
279 }
280 
282  SmallVectorImpl<MachineOperand> &Cond) const {
283  switch (Cond[0].getImm()) {
284  case AArch64::Bcc: {
285  A64CC::CondCodes CC = static_cast<A64CC::CondCodes>(Cond[1].getImm());
286  CC = A64InvertCondCode(CC);
287  Cond[1].setImm(CC);
288  return false;
289  }
290  case AArch64::CBZw:
291  Cond[0].setImm(AArch64::CBNZw);
292  return false;
293  case AArch64::CBZx:
294  Cond[0].setImm(AArch64::CBNZx);
295  return false;
296  case AArch64::CBNZw:
297  Cond[0].setImm(AArch64::CBZw);
298  return false;
299  case AArch64::CBNZx:
300  Cond[0].setImm(AArch64::CBZx);
301  return false;
302  case AArch64::TBZwii:
303  Cond[0].setImm(AArch64::TBNZwii);
304  return false;
305  case AArch64::TBZxii:
306  Cond[0].setImm(AArch64::TBNZxii);
307  return false;
308  case AArch64::TBNZwii:
309  Cond[0].setImm(AArch64::TBZwii);
310  return false;
311  case AArch64::TBNZxii:
312  Cond[0].setImm(AArch64::TBZxii);
313  return false;
314  default:
315  llvm_unreachable("Unknown branch type");
316  }
317 }
318 
319 
320 unsigned
322  MachineBasicBlock *FBB,
324  DebugLoc DL) const {
325  if (FBB == 0 && Cond.empty()) {
326  BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(TBB);
327  return 1;
328  } else if (FBB == 0) {
329  MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
330  for (int i = 1, e = Cond.size(); i != e; ++i)
331  MIB.addOperand(Cond[i]);
332  MIB.addMBB(TBB);
333  return 1;
334  }
335 
336  MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
337  for (int i = 1, e = Cond.size(); i != e; ++i)
338  MIB.addOperand(Cond[i]);
339  MIB.addMBB(TBB);
340 
341  BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(FBB);
342  return 2;
343 }
344 
347  if (I == MBB.begin()) return 0;
348  --I;
349  while (I->isDebugValue()) {
350  if (I == MBB.begin())
351  return 0;
352  --I;
353  }
354  if (I->getOpcode() != AArch64::Bimm && !isCondBranch(I->getOpcode()))
355  return 0;
356 
357  // Remove the branch.
358  I->eraseFromParent();
359 
360  I = MBB.end();
361 
362  if (I == MBB.begin()) return 1;
363  --I;
364  if (!isCondBranch(I->getOpcode()))
365  return 1;
366 
367  // Remove the branch.
368  I->eraseFromParent();
369  return 2;
370 }
371 
372 bool
374  MachineInstr &MI = *MBBI;
375  MachineBasicBlock &MBB = *MI.getParent();
376 
377  unsigned Opcode = MI.getOpcode();
378  switch (Opcode) {
379  case AArch64::TLSDESC_BLRx: {
380  MachineInstr *NewMI =
381  BuildMI(MBB, MBBI, MI.getDebugLoc(), get(AArch64::TLSDESCCALL))
382  .addOperand(MI.getOperand(1));
383  MI.setDesc(get(AArch64::BLRx));
384 
385  llvm::finalizeBundle(MBB, NewMI, *++MBBI);
386  return true;
387  }
388  default:
389  return false;
390  }
391 
392  return false;
393 }
394 
395 void
398  unsigned SrcReg, bool isKill,
399  int FrameIdx,
400  const TargetRegisterClass *RC,
401  const TargetRegisterInfo *TRI) const {
402  DebugLoc DL = MBB.findDebugLoc(MBBI);
403  MachineFunction &MF = *MBB.getParent();
404  MachineFrameInfo &MFI = *MF.getFrameInfo();
405  unsigned Align = MFI.getObjectAlignment(FrameIdx);
406 
407  MachineMemOperand *MMO
410  MFI.getObjectSize(FrameIdx),
411  Align);
412 
413  unsigned StoreOp = 0;
414  if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) {
415  switch(RC->getSize()) {
416  case 4: StoreOp = AArch64::LS32_STR; break;
417  case 8: StoreOp = AArch64::LS64_STR; break;
418  default:
419  llvm_unreachable("Unknown size for regclass");
420  }
421  } else {
422  assert((RC->hasType(MVT::f32) || RC->hasType(MVT::f64) ||
423  RC->hasType(MVT::f128))
424  && "Expected integer or floating type for store");
425  switch (RC->getSize()) {
426  case 4: StoreOp = AArch64::LSFP32_STR; break;
427  case 8: StoreOp = AArch64::LSFP64_STR; break;
428  case 16: StoreOp = AArch64::LSFP128_STR; break;
429  default:
430  llvm_unreachable("Unknown size for regclass");
431  }
432  }
433 
434  MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(StoreOp));
435  NewMI.addReg(SrcReg, getKillRegState(isKill))
436  .addFrameIndex(FrameIdx)
437  .addImm(0)
438  .addMemOperand(MMO);
439 
440 }
441 
442 void
445  unsigned DestReg, int FrameIdx,
446  const TargetRegisterClass *RC,
447  const TargetRegisterInfo *TRI) const {
448  DebugLoc DL = MBB.findDebugLoc(MBBI);
449  MachineFunction &MF = *MBB.getParent();
450  MachineFrameInfo &MFI = *MF.getFrameInfo();
451  unsigned Align = MFI.getObjectAlignment(FrameIdx);
452 
453  MachineMemOperand *MMO
456  MFI.getObjectSize(FrameIdx),
457  Align);
458 
459  unsigned LoadOp = 0;
460  if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) {
461  switch(RC->getSize()) {
462  case 4: LoadOp = AArch64::LS32_LDR; break;
463  case 8: LoadOp = AArch64::LS64_LDR; break;
464  default:
465  llvm_unreachable("Unknown size for regclass");
466  }
467  } else {
468  assert((RC->hasType(MVT::f32) || RC->hasType(MVT::f64)
469  || RC->hasType(MVT::f128))
470  && "Expected integer or floating type for store");
471  switch (RC->getSize()) {
472  case 4: LoadOp = AArch64::LSFP32_LDR; break;
473  case 8: LoadOp = AArch64::LSFP64_LDR; break;
474  case 16: LoadOp = AArch64::LSFP128_LDR; break;
475  default:
476  llvm_unreachable("Unknown size for regclass");
477  }
478  }
479 
480  MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(LoadOp), DestReg);
481  NewMI.addFrameIndex(FrameIdx)
482  .addImm(0)
483  .addMemOperand(MMO);
484 }
485 
487  unsigned Limit = (1 << 16) - 1;
488  for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
489  for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
490  I != E; ++I) {
491  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
492  if (!I->getOperand(i).isFI()) continue;
493 
494  // When using ADDxxi_lsl0_s to get the address of a stack object, 0xfff
495  // is the largest offset guaranteed to fit in the immediate offset.
496  if (I->getOpcode() == AArch64::ADDxxi_lsl0_s) {
497  Limit = std::min(Limit, 0xfffu);
498  break;
499  }
500 
501  int AccessScale, MinOffset, MaxOffset;
502  getAddressConstraints(*I, AccessScale, MinOffset, MaxOffset);
503  Limit = std::min(Limit, static_cast<unsigned>(MaxOffset));
504 
505  break; // At most one FI per instruction
506  }
507  }
508  }
509 
510  return Limit;
511 }
513  int &AccessScale, int &MinOffset,
514  int &MaxOffset) const {
515  switch (MI.getOpcode()) {
516  default: llvm_unreachable("Unkown load/store kind");
518  AccessScale = 1;
519  MinOffset = INT_MIN;
520  MaxOffset = INT_MAX;
521  return;
522  case AArch64::LS8_LDR: case AArch64::LS8_STR:
523  case AArch64::LSFP8_LDR: case AArch64::LSFP8_STR:
524  case AArch64::LDRSBw:
525  case AArch64::LDRSBx:
526  AccessScale = 1;
527  MinOffset = 0;
528  MaxOffset = 0xfff;
529  return;
530  case AArch64::LS16_LDR: case AArch64::LS16_STR:
531  case AArch64::LSFP16_LDR: case AArch64::LSFP16_STR:
532  case AArch64::LDRSHw:
533  case AArch64::LDRSHx:
534  AccessScale = 2;
535  MinOffset = 0;
536  MaxOffset = 0xfff * AccessScale;
537  return;
538  case AArch64::LS32_LDR: case AArch64::LS32_STR:
539  case AArch64::LSFP32_LDR: case AArch64::LSFP32_STR:
540  case AArch64::LDRSWx:
541  case AArch64::LDPSWx:
542  AccessScale = 4;
543  MinOffset = 0;
544  MaxOffset = 0xfff * AccessScale;
545  return;
546  case AArch64::LS64_LDR: case AArch64::LS64_STR:
547  case AArch64::LSFP64_LDR: case AArch64::LSFP64_STR:
548  case AArch64::PRFM:
549  AccessScale = 8;
550  MinOffset = 0;
551  MaxOffset = 0xfff * AccessScale;
552  return;
553  case AArch64::LSFP128_LDR: case AArch64::LSFP128_STR:
554  AccessScale = 16;
555  MinOffset = 0;
556  MaxOffset = 0xfff * AccessScale;
557  return;
558  case AArch64::LSPair32_LDR: case AArch64::LSPair32_STR:
559  case AArch64::LSFPPair32_LDR: case AArch64::LSFPPair32_STR:
560  AccessScale = 4;
561  MinOffset = -0x40 * AccessScale;
562  MaxOffset = 0x3f * AccessScale;
563  return;
564  case AArch64::LSPair64_LDR: case AArch64::LSPair64_STR:
565  case AArch64::LSFPPair64_LDR: case AArch64::LSFPPair64_STR:
566  AccessScale = 8;
567  MinOffset = -0x40 * AccessScale;
568  MaxOffset = 0x3f * AccessScale;
569  return;
570  case AArch64::LSFPPair128_LDR: case AArch64::LSFPPair128_STR:
571  AccessScale = 16;
572  MinOffset = -0x40 * AccessScale;
573  MaxOffset = 0x3f * AccessScale;
574  return;
575  }
576 }
577 
579  const MCInstrDesc &MCID = MI.getDesc();
580  const MachineBasicBlock &MBB = *MI.getParent();
581  const MachineFunction &MF = *MBB.getParent();
582  const MCAsmInfo &MAI = *MF.getTarget().getMCAsmInfo();
583 
584  if (MCID.getSize())
585  return MCID.getSize();
586 
587  if (MI.getOpcode() == AArch64::INLINEASM)
588  return getInlineAsmLength(MI.getOperand(0).getSymbolName(), MAI);
589 
590  if (MI.isLabel())
591  return 0;
592 
593  switch (MI.getOpcode()) {
595  return getInstBundleLength(MI);
597  case TargetOpcode::KILL:
601  return 0;
603  return 0;
604  default:
605  llvm_unreachable("Unknown instruction class");
606  }
607 }
608 
610  unsigned Size = 0;
613  while (++I != E && I->isInsideBundle()) {
614  assert(!I->isBundle() && "No nested bundle!");
615  Size += getInstSizeInBytes(*I);
616  }
617  return Size;
618 }
619 
620 bool llvm::rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
621  unsigned FrameReg, int &Offset,
622  const AArch64InstrInfo &TII) {
623  MachineBasicBlock &MBB = *MI.getParent();
624  MachineFunction &MF = *MBB.getParent();
625  MachineFrameInfo &MFI = *MF.getFrameInfo();
626 
627  MFI.getObjectOffset(FrameRegIdx);
628  llvm_unreachable("Unimplemented rewriteFrameIndex");
629 }
630 
633  DebugLoc dl, const TargetInstrInfo &TII,
634  unsigned DstReg, unsigned SrcReg, unsigned ScratchReg,
635  int64_t NumBytes, MachineInstr::MIFlag MIFlags) {
636  if (NumBytes == 0 && DstReg == SrcReg)
637  return;
638  else if (abs64(NumBytes) & ~0xffffff) {
639  // Generically, we have to materialize the offset into a temporary register
640  // and subtract it. There are a couple of ways this could be done, for now
641  // we'll use a movz/movk or movn/movk sequence.
642  uint64_t Bits = static_cast<uint64_t>(abs64(NumBytes));
643  BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg)
644  .addImm(0xffff & Bits).addImm(0)
645  .setMIFlags(MIFlags);
646 
647  Bits >>= 16;
648  if (Bits & 0xffff) {
649  BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
650  .addReg(ScratchReg)
651  .addImm(0xffff & Bits).addImm(1)
652  .setMIFlags(MIFlags);
653  }
654 
655  Bits >>= 16;
656  if (Bits & 0xffff) {
657  BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
658  .addReg(ScratchReg)
659  .addImm(0xffff & Bits).addImm(2)
660  .setMIFlags(MIFlags);
661  }
662 
663  Bits >>= 16;
664  if (Bits & 0xffff) {
665  BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
666  .addReg(ScratchReg)
667  .addImm(0xffff & Bits).addImm(3)
668  .setMIFlags(MIFlags);
669  }
670 
671  // ADD DST, SRC, xTMP (, lsl #0)
672  unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
673  BuildMI(MBB, MBBI, dl, TII.get(AddOp), DstReg)
674  .addReg(SrcReg, RegState::Kill)
675  .addReg(ScratchReg, RegState::Kill)
676  .addImm(0)
677  .setMIFlag(MIFlags);
678  return;
679  }
680 
681  // Now we know that the adjustment can be done in at most two add/sub
682  // (immediate) instructions, which is always more efficient than a
683  // literal-pool load, or even a hypothetical movz/movk/add sequence
684 
685  // Decide whether we're doing addition or subtraction
686  unsigned LowOp, HighOp;
687  if (NumBytes >= 0) {
688  LowOp = AArch64::ADDxxi_lsl0_s;
689  HighOp = AArch64::ADDxxi_lsl12_s;
690  } else {
691  LowOp = AArch64::SUBxxi_lsl0_s;
692  HighOp = AArch64::SUBxxi_lsl12_s;
693  NumBytes = abs64(NumBytes);
694  }
695 
696  // If we're here, at the very least a move needs to be produced, which just
697  // happens to be materializable by an ADD.
698  if ((NumBytes & 0xfff) || NumBytes == 0) {
699  BuildMI(MBB, MBBI, dl, TII.get(LowOp), DstReg)
700  .addReg(SrcReg, RegState::Kill)
701  .addImm(NumBytes & 0xfff)
702  .setMIFlag(MIFlags);
703 
704  // Next update should use the register we've just defined.
705  SrcReg = DstReg;
706  }
707 
708  if (NumBytes & 0xfff000) {
709  BuildMI(MBB, MBBI, dl, TII.get(HighOp), DstReg)
710  .addReg(SrcReg, RegState::Kill)
711  .addImm(NumBytes >> 12)
712  .setMIFlag(MIFlags);
713  }
714 }
715 
717  DebugLoc dl, const TargetInstrInfo &TII,
718  unsigned ScratchReg, int64_t NumBytes,
719  MachineInstr::MIFlag MIFlags) {
720  emitRegUpdate(MBB, MI, dl, TII, AArch64::XSP, AArch64::XSP, AArch64::X16,
721  NumBytes, MIFlags);
722 }
723 
724 
725 namespace {
726  struct LDTLSCleanup : public MachineFunctionPass {
727  static char ID;
728  LDTLSCleanup() : MachineFunctionPass(ID) {}
729 
730  virtual bool runOnMachineFunction(MachineFunction &MF) {
733  if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
734  // No point folding accesses if there isn't at least two.
735  return false;
736  }
737 
738  MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
739  return VisitNode(DT->getRootNode(), 0);
740  }
741 
742  // Visit the dominator subtree rooted at Node in pre-order.
743  // If TLSBaseAddrReg is non-null, then use that to replace any
744  // TLS_base_addr instructions. Otherwise, create the register
745  // when the first such instruction is seen, and then use it
746  // as we encounter more instructions.
747  bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
748  MachineBasicBlock *BB = Node->getBlock();
749  bool Changed = false;
750 
751  // Traverse the current block.
752  for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
753  ++I) {
754  switch (I->getOpcode()) {
755  case AArch64::TLSDESC_BLRx:
756  // Make sure it's a local dynamic access.
757  if (!I->getOperand(1).isSymbol() ||
758  strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_"))
759  break;
760 
761  if (TLSBaseAddrReg)
762  I = ReplaceTLSBaseAddrCall(I, TLSBaseAddrReg);
763  else
764  I = SetRegister(I, &TLSBaseAddrReg);
765  Changed = true;
766  break;
767  default:
768  break;
769  }
770  }
771 
772  // Visit the children of this block in the dominator tree.
773  for (MachineDomTreeNode::iterator I = Node->begin(), E = Node->end();
774  I != E; ++I) {
775  Changed |= VisitNode(*I, TLSBaseAddrReg);
776  }
777 
778  return Changed;
779  }
780 
781  // Replace the TLS_base_addr instruction I with a copy from
782  // TLSBaseAddrReg, returning the new instruction.
783  MachineInstr *ReplaceTLSBaseAddrCall(MachineInstr *I,
784  unsigned TLSBaseAddrReg) {
785  MachineFunction *MF = I->getParent()->getParent();
786  const AArch64TargetMachine *TM =
787  static_cast<const AArch64TargetMachine *>(&MF->getTarget());
788  const AArch64InstrInfo *TII = TM->getInstrInfo();
789 
790  // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
791  // code sequence assumes the address will be.
792  MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
793  TII->get(TargetOpcode::COPY),
794  AArch64::X0)
795  .addReg(TLSBaseAddrReg);
796 
797  // Erase the TLS_base_addr instruction.
798  I->eraseFromParent();
799 
800  return Copy;
801  }
802 
803  // Create a virtal register in *TLSBaseAddrReg, and populate it by
804  // inserting a copy instruction after I. Returns the new instruction.
805  MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg) {
806  MachineFunction *MF = I->getParent()->getParent();
807  const AArch64TargetMachine *TM =
808  static_cast<const AArch64TargetMachine *>(&MF->getTarget());
809  const AArch64InstrInfo *TII = TM->getInstrInfo();
810 
811  // Create a virtual register for the TLS base address.
812  MachineRegisterInfo &RegInfo = MF->getRegInfo();
813  *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass);
814 
815  // Insert a copy from X0 to TLSBaseAddrReg for later.
816  MachineInstr *Next = I->getNextNode();
817  MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
818  TII->get(TargetOpcode::COPY),
819  *TLSBaseAddrReg)
820  .addReg(AArch64::X0);
821 
822  return Copy;
823  }
824 
825  virtual const char *getPassName() const {
826  return "Local Dynamic TLS Access Clean-up";
827  }
828 
829  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
830  AU.setPreservesCFG();
833  }
834  };
835 }
836 
837 char LDTLSCleanup::ID = 0;
839 llvm::createAArch64CleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); }
int strcmp(const char *s1, const char *s2);
The memory access reads data.
const MachineFunction * getParent() const
const AArch64InstrInfo * getInstrInfo() const
The memory access writes data.
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
MachineDomTreeNode * getRootNode() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
unsigned MaxOffset
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
const char * getSymbolName() const
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
AnalysisUsage & addRequired()
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const
const HexagonInstrInfo * TII
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
Definition: ilist_node.h:80
const MCAsmInfo * getMCAsmInfo() const
#define llvm_unreachable(msg)
int64_t abs64(int64_t x)
Definition: MathExtras.h:579
Abstract Stack Frame Information.
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
unsigned estimateRSStackLimit(MachineFunction &MF) const
const MachineInstrBuilder & addImm(int64_t Val) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:56
bool rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const AArch64InstrInfo &TII)
int getOpcode() const
Definition: MachineInstr.h:261
NodeT * getBlock() const
Definition: Dominators.h:82
unsigned getKillRegState(bool B)
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bundle_iterator< MachineInstr, instr_iterator > iterator
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:576
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
bool isLabel() const
Definition: MachineInstr.h:628
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getInstSizeInBytes(const MachineInstr &MI) const
const MCInstrDesc & get(unsigned Opcode) const
Definition: MCInstrInfo.h:48
int64_t getObjectOffset(int ObjectIdx) const
DebugLoc findDebugLoc(instr_iterator MBBI)
unsigned RemoveBranch(MachineBasicBlock &MBB) const
void setDesc(const MCInstrDesc &tid)
Definition: MachineInstr.h:984
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
MachineFrameInfo * getFrameInfo()
void setPreservesCFG()
Definition: Pass.cpp:249
const MachineInstrBuilder & addFrameIndex(int Idx) const
AArch64InstrInfo(const AArch64Subtarget &TM)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
const AArch64Subtarget & getSubTarget() const
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
Definition: TargetOpcodes.h:52
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
Definition: TargetOpcodes.h:69
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static MachineOperand CreateImm(int64_t Val)
static A64CC::CondCodes A64InvertCondCode(A64CC::CondCodes CC)
#define I(x, y, z)
Definition: MD5.cpp:54
void getAddressConstraints(const MachineInstr &MI, int &AccessScale, int &MinOffset, int &MaxOffset) const
const TargetMachine & getTarget() const
bool hasType(EVT vt) const
static void classifyCondBranch(MachineInstr *I, MachineBasicBlock *&TBB, SmallVectorImpl< MachineOperand > &Cond)
void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned DstReg, unsigned SrcReg, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
Definition: Dominators.h:73
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
static bool isCondBranch(unsigned Opc)
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
int64_t getObjectSize(int ObjectIdx) const
unsigned getInstBundleLength(const MachineInstr &MI) const
FunctionPass * createAArch64CleanupLocalDynamicTLSPass()
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244