LLVM  14.0.0git
MVETailPredUtils.h
Go to the documentation of this file.
1 //===-- MVETailPredUtils.h - Tail predication utility functions -*- C++-*-===//
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 file contains utility functions for low overhead and tail predicated
10 // loops, shared between the ARMLowOverheadLoops pass and anywhere else that
11 // needs them.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
16 #define LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
17 
22 
23 namespace llvm {
24 
25 static inline unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop) {
26  switch (Opcode) {
27  default:
28  llvm_unreachable("unhandled vctp opcode");
29  break;
30  case ARM::MVE_VCTP8:
31  return IsDoLoop ? ARM::MVE_DLSTP_8 : ARM::MVE_WLSTP_8;
32  case ARM::MVE_VCTP16:
33  return IsDoLoop ? ARM::MVE_DLSTP_16 : ARM::MVE_WLSTP_16;
34  case ARM::MVE_VCTP32:
35  return IsDoLoop ? ARM::MVE_DLSTP_32 : ARM::MVE_WLSTP_32;
36  case ARM::MVE_VCTP64:
37  return IsDoLoop ? ARM::MVE_DLSTP_64 : ARM::MVE_WLSTP_64;
38  }
39  return 0;
40 }
41 
42 static inline unsigned getTailPredVectorWidth(unsigned Opcode) {
43  switch (Opcode) {
44  default:
45  llvm_unreachable("unhandled vctp opcode");
46  case ARM::MVE_VCTP8:
47  return 16;
48  case ARM::MVE_VCTP16:
49  return 8;
50  case ARM::MVE_VCTP32:
51  return 4;
52  case ARM::MVE_VCTP64:
53  return 2;
54  }
55  return 0;
56 }
57 
58 static inline bool isVCTP(const MachineInstr *MI) {
59  switch (MI->getOpcode()) {
60  default:
61  break;
62  case ARM::MVE_VCTP8:
63  case ARM::MVE_VCTP16:
64  case ARM::MVE_VCTP32:
65  case ARM::MVE_VCTP64:
66  return true;
67  }
68  return false;
69 }
70 
71 static inline bool isDoLoopStart(const MachineInstr &MI) {
72  return MI.getOpcode() == ARM::t2DoLoopStart ||
73  MI.getOpcode() == ARM::t2DoLoopStartTP;
74 }
75 
76 static inline bool isWhileLoopStart(const MachineInstr &MI) {
77  return MI.getOpcode() == ARM::t2WhileLoopStart ||
78  MI.getOpcode() == ARM::t2WhileLoopStartLR ||
79  MI.getOpcode() == ARM::t2WhileLoopStartTP;
80 }
81 
82 static inline bool isLoopStart(const MachineInstr &MI) {
83  return isDoLoopStart(MI) || isWhileLoopStart(MI);
84 }
85 
86 // Return the TargetBB stored in a t2WhileLoopStartLR/t2WhileLoopStartTP.
88  assert(isWhileLoopStart(MI) && "Expected WhileLoopStart!");
89  unsigned Op = MI.getOpcode() == ARM::t2WhileLoopStartTP ? 3 : 2;
90  return MI.getOperand(Op).getMBB();
91 }
92 
93 // WhileLoopStart holds the exit block, so produce a subs Op0, Op1, 0 and then a
94 // beq that branches to the exit branch.
95 // If UseCmp is true, this will create a t2CMP instead of a t2SUBri, meaning the
96 // value of LR into the loop will not be setup. This is used if the LR setup is
97 // done via another means (via a t2DoLoopStart, for example).
99  unsigned BrOpc = ARM::t2Bcc,
100  bool UseCmp = false) {
101  MachineBasicBlock *MBB = MI->getParent();
102  assert((MI->getOpcode() == ARM::t2WhileLoopStartLR ||
103  MI->getOpcode() == ARM::t2WhileLoopStartTP) &&
104  "Only expected a t2WhileLoopStartLR/TP in RevertWhileLoopStartLR!");
105 
106  // Subs/Cmp
107  if (UseCmp) {
108  MachineInstrBuilder MIB =
109  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
110  MIB.add(MI->getOperand(1));
111  MIB.addImm(0);
112  MIB.addImm(ARMCC::AL);
113  MIB.addReg(ARM::NoRegister);
114  } else {
115  MachineInstrBuilder MIB =
116  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
117  MIB.add(MI->getOperand(0));
118  MIB.add(MI->getOperand(1));
119  MIB.addImm(0);
120  MIB.addImm(ARMCC::AL);
121  MIB.addReg(ARM::NoRegister);
122  MIB.addReg(ARM::CPSR, RegState::Define);
123  }
124 
125  // Branch
126  MachineInstrBuilder MIB =
127  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
128  MIB.addMBB(getWhileLoopStartTargetBB(*MI)); // branch target
129  MIB.addImm(ARMCC::EQ); // condition code
130  MIB.addReg(ARM::CPSR);
131 
132  MI->eraseFromParent();
133 }
134 
136  MachineBasicBlock *MBB = MI->getParent();
137  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::tMOVr))
138  .add(MI->getOperand(0))
139  .add(MI->getOperand(1))
140  .add(predOps(ARMCC::AL));
141 
142  MI->eraseFromParent();
143 }
144 
146  bool SetFlags = false) {
147  MachineBasicBlock *MBB = MI->getParent();
148 
149  MachineInstrBuilder MIB =
150  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
151  MIB.add(MI->getOperand(0));
152  MIB.add(MI->getOperand(1));
153  MIB.add(MI->getOperand(2));
154  MIB.addImm(ARMCC::AL);
155  MIB.addReg(0);
156 
157  if (SetFlags) {
158  MIB.addReg(ARM::CPSR);
159  MIB->getOperand(5).setIsDef(true);
160  } else
161  MIB.addReg(0);
162 
163  MI->eraseFromParent();
164 }
165 
166 // Generate a subs, or sub and cmp, and a branch instead of an LE.
168  unsigned BrOpc = ARM::t2Bcc, bool SkipCmp = false) {
169  MachineBasicBlock *MBB = MI->getParent();
170 
171  // Create cmp
172  if (!SkipCmp) {
173  MachineInstrBuilder MIB =
174  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
175  MIB.add(MI->getOperand(0));
176  MIB.addImm(0);
177  MIB.addImm(ARMCC::AL);
178  MIB.addReg(ARM::NoRegister);
179  }
180 
181  // Create bne
182  MachineInstrBuilder MIB =
183  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
184  MIB.add(MI->getOperand(1)); // branch target
185  MIB.addImm(ARMCC::NE); // condition code
186  MIB.addReg(ARM::CPSR);
187  MI->eraseFromParent();
188 }
189 
190 } // end namespace llvm
191 
192 #endif // LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::isDoLoopStart
static bool isDoLoopStart(const MachineInstr &MI)
Definition: MVETailPredUtils.h:71
TargetInstrInfo.h
llvm::VCTPOpcodeToLSTP
static unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop)
Definition: MVETailPredUtils.h:25
llvm::ARMCC::EQ
@ EQ
Definition: ARMBaseInfo.h:31
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:499
llvm::RevertLoopDec
void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII, bool SetFlags=false)
Definition: MVETailPredUtils.h:145
llvm::RevertLoopEnd
void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool SkipCmp=false)
Definition: MVETailPredUtils.h:167
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::ARMCC::NE
@ NE
Definition: ARMBaseInfo.h:32
llvm::ARMCC::AL
@ AL
Definition: ARMBaseInfo.h:45
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::RevertDoLoopStart
void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII)
Definition: MVETailPredUtils.h:135
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::isVCTP
static bool isVCTP(const MachineInstr *MI)
Definition: MVETailPredUtils.h:58
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::setIsDef
void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
Definition: MachineOperand.cpp:101
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::RevertWhileLoopStartLR
void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool UseCmp=false)
Definition: MVETailPredUtils.h:98
llvm::isWhileLoopStart
static bool isWhileLoopStart(const MachineInstr &MI)
Definition: MVETailPredUtils.h:76
llvm::getWhileLoopStartTargetBB
MachineBasicBlock * getWhileLoopStartTargetBB(const MachineInstr &MI)
Definition: MVETailPredUtils.h:87
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
MachineOperand.h
llvm::predOps
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
Definition: ARMBaseInstrInfo.h:541
llvm::getTailPredVectorWidth
static unsigned getTailPredVectorWidth(unsigned Opcode)
Definition: MVETailPredUtils.h:42
llvm::isLoopStart
static bool isLoopStart(const MachineInstr &MI)
Definition: MVETailPredUtils.h:82