LLVM  13.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 isLoopStart(MachineInstr &MI) {
72  return MI.getOpcode() == ARM::t2DoLoopStart ||
73  MI.getOpcode() == ARM::t2DoLoopStartTP ||
74  MI.getOpcode() == ARM::t2WhileLoopStart ||
75  MI.getOpcode() == ARM::t2WhileLoopStartLR;
76 }
77 
78 // WhileLoopStart holds the exit block, so produce a subs Op0, Op1, 0 and then a
79 // beq that branches to the exit branch.
80 // If UseCmp is true, this will create a t2CMP instead of a t2SUBri, meaning the
81 // value of LR into the loop will not be setup. This is used if the LR setup is
82 // done via another means (via a t2DoLoopStart, for example).
84  unsigned BrOpc = ARM::t2Bcc,
85  bool UseCmp = false) {
86  MachineBasicBlock *MBB = MI->getParent();
87  assert(MI->getOpcode() == ARM::t2WhileLoopStartLR &&
88  "Only expected a t2WhileLoopStartLR in RevertWhileLoopStartLR!");
89 
90  // Subs/Cmp
91  if (UseCmp) {
93  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
94  MIB.add(MI->getOperand(1));
95  MIB.addImm(0);
96  MIB.addImm(ARMCC::AL);
97  MIB.addReg(ARM::NoRegister);
98  } else {
100  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
101  MIB.add(MI->getOperand(0));
102  MIB.add(MI->getOperand(1));
103  MIB.addImm(0);
104  MIB.addImm(ARMCC::AL);
105  MIB.addReg(ARM::NoRegister);
106  MIB.addReg(ARM::CPSR, RegState::Define);
107  }
108 
109  // Branch
110  MachineInstrBuilder MIB =
111  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
112  MIB.add(MI->getOperand(2)); // branch target
113  MIB.addImm(ARMCC::EQ); // condition code
114  MIB.addReg(ARM::CPSR);
115 
116  MI->eraseFromParent();
117 }
118 
120  MachineBasicBlock *MBB = MI->getParent();
121  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::tMOVr))
122  .add(MI->getOperand(0))
123  .add(MI->getOperand(1))
124  .add(predOps(ARMCC::AL));
125 
126  MI->eraseFromParent();
127 }
128 
130  bool SetFlags = false) {
131  MachineBasicBlock *MBB = MI->getParent();
132 
133  MachineInstrBuilder MIB =
134  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2SUBri));
135  MIB.add(MI->getOperand(0));
136  MIB.add(MI->getOperand(1));
137  MIB.add(MI->getOperand(2));
138  MIB.addImm(ARMCC::AL);
139  MIB.addReg(0);
140 
141  if (SetFlags) {
142  MIB.addReg(ARM::CPSR);
143  MIB->getOperand(5).setIsDef(true);
144  } else
145  MIB.addReg(0);
146 
147  MI->eraseFromParent();
148 }
149 
150 // Generate a subs, or sub and cmp, and a branch instead of an LE.
152  unsigned BrOpc = ARM::t2Bcc, bool SkipCmp = false) {
153  MachineBasicBlock *MBB = MI->getParent();
154 
155  // Create cmp
156  if (!SkipCmp) {
157  MachineInstrBuilder MIB =
158  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(ARM::t2CMPri));
159  MIB.add(MI->getOperand(0));
160  MIB.addImm(0);
161  MIB.addImm(ARMCC::AL);
162  MIB.addReg(ARM::NoRegister);
163  }
164 
165  // Create bne
166  MachineInstrBuilder MIB =
167  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(BrOpc));
168  MIB.add(MI->getOperand(1)); // branch target
169  MIB.addImm(ARMCC::NE); // condition code
170  MIB.addReg(ARM::CPSR);
171  MI->eraseFromParent();
172 }
173 
174 } // end namespace llvm
175 
176 #endif // LLVM_LIB_TARGET_ARM_MVETAILPREDUTILS_H
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:132
llvm
Definition: AllocatorList.h:23
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:225
TargetInstrInfo.h
llvm::VCTPOpcodeToLSTP
static unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop)
Definition: MVETailPredUtils.h:25
llvm::isLoopStart
static bool isLoopStart(MachineInstr &MI)
Definition: MVETailPredUtils.h:71
llvm::ARMCC::EQ
@ EQ
Definition: ARMBaseInfo.h:31
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:488
llvm::RevertLoopDec
void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII, bool SetFlags=false)
Definition: MVETailPredUtils.h:129
llvm::RevertLoopEnd
void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool SkipCmp=false)
Definition: MVETailPredUtils.h:151
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:45
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:70
llvm::RevertDoLoopStart
void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII)
Definition: MVETailPredUtils.h:119
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:98
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:83
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
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:329
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:540
llvm::getTailPredVectorWidth
static unsigned getTailPredVectorWidth(unsigned Opcode)
Definition: MVETailPredUtils.h:42