LLVM  16.0.0git
AArch64MIPeepholeOpt.cpp
Go to the documentation of this file.
1 //===- AArch64MIPeepholeOpt.cpp - AArch64 MI peephole optimization pass ---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass performs below peephole optimizations on MIR level.
10 //
11 // 1. MOVi32imm + ANDWrr ==> ANDWri + ANDWri
12 // MOVi64imm + ANDXrr ==> ANDXri + ANDXri
13 //
14 // 2. MOVi32imm + ADDWrr ==> ADDWRi + ADDWRi
15 // MOVi64imm + ADDXrr ==> ANDXri + ANDXri
16 //
17 // 3. MOVi32imm + SUBWrr ==> SUBWRi + SUBWRi
18 // MOVi64imm + SUBXrr ==> SUBXri + SUBXri
19 //
20 // The mov pseudo instruction could be expanded to multiple mov instructions
21 // later. In this case, we could try to split the constant operand of mov
22 // instruction into two immediates which can be directly encoded into
23 // *Wri/*Xri instructions. It makes two AND/ADD/SUB instructions instead of
24 // multiple `mov` + `and/add/sub` instructions.
25 //
26 // 4. Remove redundant ORRWrs which is generated by zero-extend.
27 //
28 // %3:gpr32 = ORRWrs $wzr, %2, 0
29 // %4:gpr64 = SUBREG_TO_REG 0, %3, %subreg.sub_32
30 //
31 // If AArch64's 32-bit form of instruction defines the source operand of
32 // ORRWrs, we can remove the ORRWrs because the upper 32 bits of the source
33 // operand are set to zero.
34 //
35 // 5. %reg = INSERT_SUBREG %reg(tied-def 0), %subreg, subidx
36 // ==> %reg:subidx = SUBREG_TO_REG 0, %subreg, subidx
37 //
38 //===----------------------------------------------------------------------===//
39 
40 #include "AArch64ExpandImm.h"
41 #include "AArch64InstrInfo.h"
43 #include "llvm/ADT/Optional.h"
46 
47 using namespace llvm;
48 
49 #define DEBUG_TYPE "aarch64-mi-peephole-opt"
50 
51 namespace {
52 
53 struct AArch64MIPeepholeOpt : public MachineFunctionPass {
54  static char ID;
55 
56  AArch64MIPeepholeOpt() : MachineFunctionPass(ID) {
58  }
59 
60  const AArch64InstrInfo *TII;
61  const AArch64RegisterInfo *TRI;
62  MachineLoopInfo *MLI;
64 
65  using OpcodePair = std::pair<unsigned, unsigned>;
66  template <typename T>
67  using SplitAndOpcFunc =
68  std::function<Optional<OpcodePair>(T, unsigned, T &, T &)>;
69  using BuildMIFunc =
70  std::function<void(MachineInstr &, OpcodePair, unsigned, unsigned,
72 
73  /// For instructions where an immediate operand could be split into two
74  /// separate immediate instructions, use the splitTwoPartImm two handle the
75  /// optimization.
76  ///
77  /// To implement, the following function types must be passed to
78  /// splitTwoPartImm. A SplitAndOpcFunc must be implemented that determines if
79  /// splitting the immediate is valid and returns the associated new opcode. A
80  /// BuildMIFunc must be implemented to build the two immediate instructions.
81  ///
82  /// Example Pattern (where IMM would require 2+ MOV instructions):
83  /// %dst = <Instr>rr %src IMM [...]
84  /// becomes:
85  /// %tmp = <Instr>ri %src (encode half IMM) [...]
86  /// %dst = <Instr>ri %tmp (encode half IMM) [...]
87  template <typename T>
88  bool splitTwoPartImm(MachineInstr &MI,
89  SplitAndOpcFunc<T> SplitAndOpc, BuildMIFunc BuildInstr);
90 
91  bool checkMovImmInstr(MachineInstr &MI, MachineInstr *&MovMI,
92  MachineInstr *&SubregToRegMI);
93 
94  template <typename T>
95  bool visitADDSUB(unsigned PosOpc, unsigned NegOpc, MachineInstr &MI);
96  template <typename T>
97  bool visitADDSSUBS(OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI);
98 
99  template <typename T>
100  bool visitAND(unsigned Opc, MachineInstr &MI);
101  bool visitORR(MachineInstr &MI);
102  bool visitINSERT(MachineInstr &MI);
103  bool runOnMachineFunction(MachineFunction &MF) override;
104 
105  StringRef getPassName() const override {
106  return "AArch64 MI Peephole Optimization pass";
107  }
108 
109  void getAnalysisUsage(AnalysisUsage &AU) const override {
110  AU.setPreservesCFG();
113  }
114 };
115 
116 char AArch64MIPeepholeOpt::ID = 0;
117 
118 } // end anonymous namespace
119 
120 INITIALIZE_PASS(AArch64MIPeepholeOpt, "aarch64-mi-peephole-opt",
121  "AArch64 MI Peephole Optimization", false, false)
122 
123 template <typename T>
124 static bool splitBitmaskImm(T Imm, unsigned RegSize, T &Imm1Enc, T &Imm2Enc) {
125  T UImm = static_cast<T>(Imm);
127  return false;
128 
129  // If this immediate can be handled by one instruction, do not split it.
132  if (Insn.size() == 1)
133  return false;
134 
135  // The bitmask immediate consists of consecutive ones. Let's say there is
136  // constant 0b00000000001000000000010000000000 which does not consist of
137  // consecutive ones. We can split it in to two bitmask immediate like
138  // 0b00000000001111111111110000000000 and 0b11111111111000000000011111111111.
139  // If we do AND with these two bitmask immediate, we can see original one.
141  unsigned HighestBitSet = Log2_64(UImm);
142 
143  // Create a mask which is filled with one from the position of lowest bit set
144  // to the position of highest bit set.
145  T NewImm1 = (static_cast<T>(2) << HighestBitSet) -
146  (static_cast<T>(1) << LowestBitSet);
147  // Create a mask which is filled with one outside the position of lowest bit
148  // set and the position of highest bit set.
149  T NewImm2 = UImm | ~NewImm1;
150 
151  // If the split value is not valid bitmask immediate, do not split this
152  // constant.
154  return false;
155 
158  return true;
159 }
160 
161 template <typename T>
162 bool AArch64MIPeepholeOpt::visitAND(
163  unsigned Opc, MachineInstr &MI) {
164  // Try below transformation.
165  //
166  // MOVi32imm + ANDWrr ==> ANDWri + ANDWri
167  // MOVi64imm + ANDXrr ==> ANDXri + ANDXri
168  //
169  // The mov pseudo instruction could be expanded to multiple mov instructions
170  // later. Let's try to split the constant operand of mov instruction into two
171  // bitmask immediates. It makes only two AND instructions intead of multiple
172  // mov + and instructions.
173 
174  return splitTwoPartImm<T>(
175  MI,
176  [Opc](T Imm, unsigned RegSize, T &Imm0, T &Imm1) -> Optional<OpcodePair> {
177  if (splitBitmaskImm(Imm, RegSize, Imm0, Imm1))
178  return std::make_pair(Opc, Opc);
179  return None;
180  },
181  [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
182  unsigned Imm1, Register SrcReg, Register NewTmpReg,
183  Register NewDstReg) {
184  DebugLoc DL = MI.getDebugLoc();
185  MachineBasicBlock *MBB = MI.getParent();
186  BuildMI(*MBB, MI, DL, TII->get(Opcode.first), NewTmpReg)
187  .addReg(SrcReg)
188  .addImm(Imm0);
189  BuildMI(*MBB, MI, DL, TII->get(Opcode.second), NewDstReg)
190  .addReg(NewTmpReg)
191  .addImm(Imm1);
192  });
193 }
194 
195 bool AArch64MIPeepholeOpt::visitORR(MachineInstr &MI) {
196  // Check this ORR comes from below zero-extend pattern.
197  //
198  // def : Pat<(i64 (zext GPR32:$src)),
199  // (SUBREG_TO_REG (i32 0), (ORRWrs WZR, GPR32:$src, 0), sub_32)>;
200  if (MI.getOperand(3).getImm() != 0)
201  return false;
202 
203  if (MI.getOperand(1).getReg() != AArch64::WZR)
204  return false;
205 
206  MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());
207  if (!SrcMI)
208  return false;
209 
210  // From https://developer.arm.com/documentation/dui0801/b/BABBGCAC
211  //
212  // When you use the 32-bit form of an instruction, the upper 32 bits of the
213  // source registers are ignored and the upper 32 bits of the destination
214  // register are set to zero.
215  //
216  // If AArch64's 32-bit form of instruction defines the source operand of
217  // zero-extend, we do not need the zero-extend. Let's check the MI's opcode is
218  // real AArch64 instruction and if it is not, do not process the opcode
219  // conservatively.
220  if (SrcMI->getOpcode() == TargetOpcode::COPY &&
221  SrcMI->getOperand(1).getReg().isVirtual()) {
222  const TargetRegisterClass *RC =
223  MRI->getRegClass(SrcMI->getOperand(1).getReg());
224 
225  // A COPY from an FPR will become a FMOVSWr, so do so now so that we know
226  // that the upper bits are zero.
227  if (RC != &AArch64::FPR32RegClass &&
228  ((RC != &AArch64::FPR64RegClass && RC != &AArch64::FPR128RegClass) ||
229  SrcMI->getOperand(1).getSubReg() != AArch64::ssub))
230  return false;
231  Register CpySrc = SrcMI->getOperand(1).getReg();
232  if (SrcMI->getOperand(1).getSubReg() == AArch64::ssub) {
233  CpySrc = MRI->createVirtualRegister(&AArch64::FPR32RegClass);
234  BuildMI(*SrcMI->getParent(), SrcMI, SrcMI->getDebugLoc(),
235  TII->get(TargetOpcode::COPY), CpySrc)
236  .add(SrcMI->getOperand(1));
237  }
238  BuildMI(*SrcMI->getParent(), SrcMI, SrcMI->getDebugLoc(),
239  TII->get(AArch64::FMOVSWr), SrcMI->getOperand(0).getReg())
240  .addReg(CpySrc);
241  SrcMI->eraseFromParent();
242  }
243  else if (SrcMI->getOpcode() <= TargetOpcode::GENERIC_OP_END)
244  return false;
245 
246  Register DefReg = MI.getOperand(0).getReg();
247  Register SrcReg = MI.getOperand(2).getReg();
248  MRI->replaceRegWith(DefReg, SrcReg);
249  MRI->clearKillFlags(SrcReg);
250  LLVM_DEBUG(dbgs() << "Removed: " << MI << "\n");
251  MI.eraseFromParent();
252 
253  return true;
254 }
255 
256 bool AArch64MIPeepholeOpt::visitINSERT(MachineInstr &MI) {
257  // Check this INSERT_SUBREG comes from below zero-extend pattern.
258  //
259  // From %reg = INSERT_SUBREG %reg(tied-def 0), %subreg, subidx
260  // To %reg:subidx = SUBREG_TO_REG 0, %subreg, subidx
261  //
262  // We're assuming the first operand to INSERT_SUBREG is irrelevant because a
263  // COPY would destroy the upper part of the register anyway
264  if (!MI.isRegTiedToDefOperand(1))
265  return false;
266 
267  Register DstReg = MI.getOperand(0).getReg();
268  const TargetRegisterClass *RC = MRI->getRegClass(DstReg);
269  MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());
270  if (!SrcMI)
271  return false;
272 
273  // From https://developer.arm.com/documentation/dui0801/b/BABBGCAC
274  //
275  // When you use the 32-bit form of an instruction, the upper 32 bits of the
276  // source registers are ignored and the upper 32 bits of the destination
277  // register are set to zero.
278  //
279  // If AArch64's 32-bit form of instruction defines the source operand of
280  // zero-extend, we do not need the zero-extend. Let's check the MI's opcode is
281  // real AArch64 instruction and if it is not, do not process the opcode
282  // conservatively.
283  if ((SrcMI->getOpcode() <= TargetOpcode::GENERIC_OP_END) ||
284  !AArch64::GPR64allRegClass.hasSubClassEq(RC))
285  return false;
286 
287  // Build a SUBREG_TO_REG instruction
288  MachineInstr *SubregMI =
289  BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
290  TII->get(TargetOpcode::SUBREG_TO_REG), DstReg)
291  .addImm(0)
292  .add(MI.getOperand(2))
293  .add(MI.getOperand(3));
294  LLVM_DEBUG(dbgs() << MI << " replace by:\n: " << *SubregMI << "\n");
295  (void)SubregMI;
296  MI.eraseFromParent();
297 
298  return true;
299 }
300 
301 template <typename T>
302 static bool splitAddSubImm(T Imm, unsigned RegSize, T &Imm0, T &Imm1) {
303  // The immediate must be in the form of ((imm0 << 12) + imm1), in which both
304  // imm0 and imm1 are non-zero 12-bit unsigned int.
305  if ((Imm & 0xfff000) == 0 || (Imm & 0xfff) == 0 ||
306  (Imm & ~static_cast<T>(0xffffff)) != 0)
307  return false;
308 
309  // The immediate can not be composed via a single instruction.
312  if (Insn.size() == 1)
313  return false;
314 
315  // Split Imm into (Imm0 << 12) + Imm1;
316  Imm0 = (Imm >> 12) & 0xfff;
317  Imm1 = Imm & 0xfff;
318  return true;
319 }
320 
321 template <typename T>
322 bool AArch64MIPeepholeOpt::visitADDSUB(
323  unsigned PosOpc, unsigned NegOpc, MachineInstr &MI) {
324  // Try below transformation.
325  //
326  // MOVi32imm + ADDWrr ==> ADDWri + ADDWri
327  // MOVi64imm + ADDXrr ==> ADDXri + ADDXri
328  //
329  // MOVi32imm + SUBWrr ==> SUBWri + SUBWri
330  // MOVi64imm + SUBXrr ==> SUBXri + SUBXri
331  //
332  // The mov pseudo instruction could be expanded to multiple mov instructions
333  // later. Let's try to split the constant operand of mov instruction into two
334  // legal add/sub immediates. It makes only two ADD/SUB instructions intead of
335  // multiple `mov` + `and/sub` instructions.
336 
337  return splitTwoPartImm<T>(
338  MI,
339  [PosOpc, NegOpc](T Imm, unsigned RegSize, T &Imm0,
340  T &Imm1) -> Optional<OpcodePair> {
341  if (splitAddSubImm(Imm, RegSize, Imm0, Imm1))
342  return std::make_pair(PosOpc, PosOpc);
343  if (splitAddSubImm(-Imm, RegSize, Imm0, Imm1))
344  return std::make_pair(NegOpc, NegOpc);
345  return None;
346  },
347  [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
348  unsigned Imm1, Register SrcReg, Register NewTmpReg,
349  Register NewDstReg) {
350  DebugLoc DL = MI.getDebugLoc();
351  MachineBasicBlock *MBB = MI.getParent();
352  BuildMI(*MBB, MI, DL, TII->get(Opcode.first), NewTmpReg)
353  .addReg(SrcReg)
354  .addImm(Imm0)
355  .addImm(12);
356  BuildMI(*MBB, MI, DL, TII->get(Opcode.second), NewDstReg)
357  .addReg(NewTmpReg)
358  .addImm(Imm1)
359  .addImm(0);
360  });
361 }
362 
363 template <typename T>
364 bool AArch64MIPeepholeOpt::visitADDSSUBS(
365  OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI) {
366  // Try the same transformation as ADDSUB but with additional requirement
367  // that the condition code usages are only for Equal and Not Equal
368  return splitTwoPartImm<T>(
369  MI,
370  [PosOpcs, NegOpcs, &MI, &TRI = TRI, &MRI = MRI](
371  T Imm, unsigned RegSize, T &Imm0, T &Imm1) -> Optional<OpcodePair> {
372  OpcodePair OP;
373  if (splitAddSubImm(Imm, RegSize, Imm0, Imm1))
374  OP = PosOpcs;
375  else if (splitAddSubImm(-Imm, RegSize, Imm0, Imm1))
376  OP = NegOpcs;
377  else
378  return None;
379  // Check conditional uses last since it is expensive for scanning
380  // proceeding instructions
381  MachineInstr &SrcMI = *MRI->getUniqueVRegDef(MI.getOperand(1).getReg());
382  Optional<UsedNZCV> NZCVUsed = examineCFlagsUse(SrcMI, MI, *TRI);
383  if (!NZCVUsed || NZCVUsed->C || NZCVUsed->V)
384  return None;
385  return OP;
386  },
387  [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
388  unsigned Imm1, Register SrcReg, Register NewTmpReg,
389  Register NewDstReg) {
390  DebugLoc DL = MI.getDebugLoc();
391  MachineBasicBlock *MBB = MI.getParent();
392  BuildMI(*MBB, MI, DL, TII->get(Opcode.first), NewTmpReg)
393  .addReg(SrcReg)
394  .addImm(Imm0)
395  .addImm(12);
396  BuildMI(*MBB, MI, DL, TII->get(Opcode.second), NewDstReg)
397  .addReg(NewTmpReg)
398  .addImm(Imm1)
399  .addImm(0);
400  });
401 }
402 
403 // Checks if the corresponding MOV immediate instruction is applicable for
404 // this peephole optimization.
405 bool AArch64MIPeepholeOpt::checkMovImmInstr(MachineInstr &MI,
406  MachineInstr *&MovMI,
407  MachineInstr *&SubregToRegMI) {
408  // Check whether current MBB is in loop and the AND is loop invariant.
409  MachineBasicBlock *MBB = MI.getParent();
410  MachineLoop *L = MLI->getLoopFor(MBB);
411  if (L && !L->isLoopInvariant(MI))
412  return false;
413 
414  // Check whether current MI's operand is MOV with immediate.
415  MovMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());
416  if (!MovMI)
417  return false;
418 
419  // If it is SUBREG_TO_REG, check its operand.
420  SubregToRegMI = nullptr;
421  if (MovMI->getOpcode() == TargetOpcode::SUBREG_TO_REG) {
422  SubregToRegMI = MovMI;
423  MovMI = MRI->getUniqueVRegDef(MovMI->getOperand(2).getReg());
424  if (!MovMI)
425  return false;
426  }
427 
428  if (MovMI->getOpcode() != AArch64::MOVi32imm &&
429  MovMI->getOpcode() != AArch64::MOVi64imm)
430  return false;
431 
432  // If the MOV has multiple uses, do not split the immediate because it causes
433  // more instructions.
434  if (!MRI->hasOneUse(MovMI->getOperand(0).getReg()))
435  return false;
436  if (SubregToRegMI && !MRI->hasOneUse(SubregToRegMI->getOperand(0).getReg()))
437  return false;
438 
439  // It is OK to perform this peephole optimization.
440  return true;
441 }
442 
443 template <typename T>
444 bool AArch64MIPeepholeOpt::splitTwoPartImm(
445  MachineInstr &MI,
446  SplitAndOpcFunc<T> SplitAndOpc, BuildMIFunc BuildInstr) {
447  unsigned RegSize = sizeof(T) * 8;
448  assert((RegSize == 32 || RegSize == 64) &&
449  "Invalid RegSize for legal immediate peephole optimization");
450 
451  // Perform several essential checks against current MI.
452  MachineInstr *MovMI, *SubregToRegMI;
453  if (!checkMovImmInstr(MI, MovMI, SubregToRegMI))
454  return false;
455 
456  // Split the immediate to Imm0 and Imm1, and calculate the Opcode.
457  T Imm = static_cast<T>(MovMI->getOperand(1).getImm()), Imm0, Imm1;
458  // For the 32 bit form of instruction, the upper 32 bits of the destination
459  // register are set to zero. If there is SUBREG_TO_REG, set the upper 32 bits
460  // of Imm to zero. This is essential if the Immediate value was a negative
461  // number since it was sign extended when we assign to the 64-bit Imm.
462  if (SubregToRegMI)
463  Imm &= 0xFFFFFFFF;
464  OpcodePair Opcode;
465  if (auto R = SplitAndOpc(Imm, RegSize, Imm0, Imm1))
466  Opcode = *R;
467  else
468  return false;
469 
470  // Create new MIs using the first and second opcodes. Opcodes might differ for
471  // flag setting operations that should only set flags on second instruction.
472  // NewTmpReg = Opcode.first SrcReg Imm0
473  // NewDstReg = Opcode.second NewTmpReg Imm1
474 
475  // Determine register classes for destinations and register operands
476  MachineFunction *MF = MI.getMF();
477  const TargetRegisterClass *FirstInstrDstRC =
478  TII->getRegClass(TII->get(Opcode.first), 0, TRI, *MF);
479  const TargetRegisterClass *FirstInstrOperandRC =
480  TII->getRegClass(TII->get(Opcode.first), 1, TRI, *MF);
481  const TargetRegisterClass *SecondInstrDstRC =
482  (Opcode.first == Opcode.second)
483  ? FirstInstrDstRC
484  : TII->getRegClass(TII->get(Opcode.second), 0, TRI, *MF);
485  const TargetRegisterClass *SecondInstrOperandRC =
486  (Opcode.first == Opcode.second)
487  ? FirstInstrOperandRC
488  : TII->getRegClass(TII->get(Opcode.second), 1, TRI, *MF);
489 
490  // Get old registers destinations and new register destinations
491  Register DstReg = MI.getOperand(0).getReg();
492  Register SrcReg = MI.getOperand(1).getReg();
493  Register NewTmpReg = MRI->createVirtualRegister(FirstInstrDstRC);
494  // In the situation that DstReg is not Virtual (likely WZR or XZR), we want to
495  // reuse that same destination register.
496  Register NewDstReg = DstReg.isVirtual()
497  ? MRI->createVirtualRegister(SecondInstrDstRC)
498  : DstReg;
499 
500  // Constrain registers based on their new uses
501  MRI->constrainRegClass(SrcReg, FirstInstrOperandRC);
502  MRI->constrainRegClass(NewTmpReg, SecondInstrOperandRC);
503  if (DstReg != NewDstReg)
504  MRI->constrainRegClass(NewDstReg, MRI->getRegClass(DstReg));
505 
506  // Call the delegating operation to build the instruction
507  BuildInstr(MI, Opcode, Imm0, Imm1, SrcReg, NewTmpReg, NewDstReg);
508 
509  // replaceRegWith changes MI's definition register. Keep it for SSA form until
510  // deleting MI. Only if we made a new destination register.
511  if (DstReg != NewDstReg) {
512  MRI->replaceRegWith(DstReg, NewDstReg);
513  MI.getOperand(0).setReg(DstReg);
514  }
515 
516  // Record the MIs need to be removed.
517  MI.eraseFromParent();
518  if (SubregToRegMI)
519  SubregToRegMI->eraseFromParent();
520  MovMI->eraseFromParent();
521 
522  return true;
523 }
524 
525 bool AArch64MIPeepholeOpt::runOnMachineFunction(MachineFunction &MF) {
526  if (skipFunction(MF.getFunction()))
527  return false;
528 
529  TII = static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
530  TRI = static_cast<const AArch64RegisterInfo *>(
532  MLI = &getAnalysis<MachineLoopInfo>();
533  MRI = &MF.getRegInfo();
534 
535  assert(MRI->isSSA() && "Expected to be run on SSA form!");
536 
537  bool Changed = false;
538 
539  for (MachineBasicBlock &MBB : MF) {
541  switch (MI.getOpcode()) {
542  default:
543  break;
544  case AArch64::INSERT_SUBREG:
545  Changed = visitINSERT(MI);
546  break;
547  case AArch64::ANDWrr:
548  Changed = visitAND<uint32_t>(AArch64::ANDWri, MI);
549  break;
550  case AArch64::ANDXrr:
551  Changed = visitAND<uint64_t>(AArch64::ANDXri, MI);
552  break;
553  case AArch64::ORRWrs:
554  Changed = visitORR(MI);
555  break;
556  case AArch64::ADDWrr:
557  Changed = visitADDSUB<uint32_t>(AArch64::ADDWri, AArch64::SUBWri, MI);
558  break;
559  case AArch64::SUBWrr:
560  Changed = visitADDSUB<uint32_t>(AArch64::SUBWri, AArch64::ADDWri, MI);
561  break;
562  case AArch64::ADDXrr:
563  Changed = visitADDSUB<uint64_t>(AArch64::ADDXri, AArch64::SUBXri, MI);
564  break;
565  case AArch64::SUBXrr:
566  Changed = visitADDSUB<uint64_t>(AArch64::SUBXri, AArch64::ADDXri, MI);
567  break;
568  case AArch64::ADDSWrr:
569  Changed = visitADDSSUBS<uint32_t>({AArch64::ADDWri, AArch64::ADDSWri},
570  {AArch64::SUBWri, AArch64::SUBSWri},
571  MI);
572  break;
573  case AArch64::SUBSWrr:
574  Changed = visitADDSSUBS<uint32_t>({AArch64::SUBWri, AArch64::SUBSWri},
575  {AArch64::ADDWri, AArch64::ADDSWri},
576  MI);
577  break;
578  case AArch64::ADDSXrr:
579  Changed = visitADDSSUBS<uint64_t>({AArch64::ADDXri, AArch64::ADDSXri},
580  {AArch64::SUBXri, AArch64::SUBSXri},
581  MI);
582  break;
583  case AArch64::SUBSXrr:
584  Changed = visitADDSSUBS<uint64_t>({AArch64::SUBXri, AArch64::SUBSXri},
585  {AArch64::ADDXri, AArch64::ADDSXri},
586  MI);
587  break;
588  }
589  }
590  }
591 
592  return Changed;
593 }
594 
596  return new AArch64MIPeepholeOpt();
597 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Optional.h
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
T
RegSize
unsigned RegSize
Definition: AArch64MIPeepholeOpt.cpp:124
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:93
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1182
llvm::MachineRegisterInfo::getUniqueVRegDef
MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Definition: MachineRegisterInfo.cpp:407
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::examineCFlagsUse
Optional< UsedNZCV > examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, const TargetRegisterInfo &TRI, SmallVectorImpl< MachineInstr * > *CCUseInstrs=nullptr)
Definition: AArch64InstrInfo.cpp:1617
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:125
llvm::Optional
Definition: APInt.h:33
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:167
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MachineLoopInfo
Definition: MachineLoopInfo.h:89
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:666
llvm::Log2_64
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:554
MachineLoopInfo.h
Imm1Enc
unsigned T & Imm1Enc
Definition: AArch64MIPeepholeOpt.cpp:124
AArch64InstrInfo.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
llvm::AArch64InstrInfo
Definition: AArch64InstrInfo.h:37
llvm::AArch64_AM::isLogicalImmediate
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
Definition: AArch64AddressingModes.h:276
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:546
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
splitAddSubImm
static bool splitAddSubImm(T Imm, unsigned RegSize, T &Imm0, T &Imm1)
Definition: AArch64MIPeepholeOpt.cpp:302
INITIALIZE_PASS
INITIALIZE_PASS(AArch64MIPeepholeOpt, "aarch64-mi-peephole-opt", "AArch64 MI Peephole Optimization", false, false) template< typename T > static bool splitBitmaskImm(T Imm
llvm::None
const NoneType None
Definition: None.h:24
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:647
llvm::MachineRegisterInfo::isSSA
bool isSSA() const
Definition: MachineRegisterInfo.h:183
AArch64AddressingModes.h
llvm::Register::isVirtual
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
llvm::MachineRegisterInfo::clearKillFlags
void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
Definition: MachineRegisterInfo.cpp:433
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
llvm::MachineInstr::getDebugLoc
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:445
llvm::MachineLoop
Definition: MachineLoopInfo.h:44
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
Imm2Enc
unsigned T T & Imm2Enc
Definition: AArch64MIPeepholeOpt.cpp:124
AArch64ExpandImm.h
NewImm2
T NewImm2
Definition: AArch64MIPeepholeOpt.cpp:149
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:596
llvm::createAArch64MIPeepholeOptPass
FunctionPass * createAArch64MIPeepholeOptPass()
Definition: AArch64MIPeepholeOpt.cpp:595
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
OP
#define OP(n)
Definition: regex2.h:73
HighestBitSet
unsigned HighestBitSet
Definition: AArch64MIPeepholeOpt.cpp:141
llvm::MachineFunction
Definition: MachineFunction.h:257
llvm::AArch64_AM::encodeLogicalImmediate
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
Definition: AArch64AddressingModes.h:283
llvm::countTrailingZeros
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:153
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:263
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::AArch64RegisterInfo
Definition: AArch64RegisterInfo.h:26
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:313
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:364
llvm::MachineRegisterInfo::replaceRegWith
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Definition: MachineRegisterInfo.cpp:378
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::initializeAArch64MIPeepholeOptPass
void initializeAArch64MIPeepholeOptPass(PassRegistry &)
Insn
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
Definition: AArch64MIPeepholeOpt.cpp:130
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:622
llvm::AArch64_IMM::expandMOVImm
void expandMOVImm(uint64_t Imm, unsigned BitSize, SmallVectorImpl< ImmInsnModel > &Insn)
Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more real move-immediate instructions to...
Definition: AArch64ExpandImm.cpp:303
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
NewImm1
T NewImm1
Definition: AArch64MIPeepholeOpt.cpp:145
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
llvm::MachineRegisterInfo::hasOneUse
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
Definition: MachineRegisterInfo.h:518
llvm::MachineRegisterInfo::constrainRegClass
const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
Definition: MachineRegisterInfo.cpp:82
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineLoop::isLoopInvariant
bool isLoopInvariant(MachineInstr &I) const
Returns true if the instruction is loop invariant.
Definition: MachineLoopInfo.cpp:154
llvm::MachineInstr::eraseFromParent
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Definition: MachineInstr.cpp:684
LowestBitSet
unsigned LowestBitSet
Definition: AArch64MIPeepholeOpt.cpp:140
MachineDominators.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38