LLVM 22.0.0git
Thumb2ITBlockPass.cpp
Go to the documentation of this file.
1//===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===//
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#include "ARM.h"
11#include "ARMSubtarget.h"
12#include "Thumb2InstrInfo.h"
13#include "llvm/ADT/SmallSet.h"
15#include "llvm/ADT/Statistic.h"
16#include "llvm/ADT/StringRef.h"
24#include "llvm/IR/DebugLoc.h"
25#include "llvm/MC/MCInstrDesc.h"
26#include <cassert>
27#include <new>
28
29using namespace llvm;
30
31#define DEBUG_TYPE "thumb2-it"
32#define PASS_NAME "Thumb IT blocks insertion pass"
33
34STATISTIC(NumITs, "Number of IT blocks inserted");
35STATISTIC(NumMovedInsts, "Number of predicated instructions moved");
36
38
39namespace {
40
41 class Thumb2ITBlock : public MachineFunctionPass {
42 public:
43 static char ID;
44
45 bool restrictIT;
46 const Thumb2InstrInfo *TII;
48 ARMFunctionInfo *AFI;
49
50 Thumb2ITBlock() : MachineFunctionPass(ID) {}
51
52 bool runOnMachineFunction(MachineFunction &Fn) override;
53
55 return MachineFunctionProperties().setNoVRegs();
56 }
57
58 StringRef getPassName() const override {
59 return PASS_NAME;
60 }
61
62 private:
63 bool MoveCopyOutOfITBlock(MachineInstr *MI,
66 bool InsertITInstructions(MachineBasicBlock &Block);
67 };
68
69 char Thumb2ITBlock::ID = 0;
70
71} // end anonymous namespace
72
73INITIALIZE_PASS(Thumb2ITBlock, DEBUG_TYPE, PASS_NAME, false, false)
74
75/// TrackDefUses - Tracking what registers are being defined and used by
76/// instructions in the IT block. This also tracks "dependencies", i.e. uses
77/// in the IT block that are defined before the IT instruction.
80 using RegList = SmallVector<unsigned, 4>;
81 RegList LocalDefs;
82 RegList LocalUses;
83
84 for (auto &MO : MI->operands()) {
85 if (!MO.isReg())
86 continue;
87 Register Reg = MO.getReg();
88 if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
89 continue;
90 if (MO.isUse())
91 LocalUses.push_back(Reg);
92 else
93 LocalDefs.push_back(Reg);
94 }
95
96 auto InsertUsesDefs = [&](RegList &Regs, RegisterSet &UsesDefs) {
97 for (unsigned Reg : Regs)
98 UsesDefs.insert_range(TRI->subregs_inclusive(Reg));
99 };
100
101 InsertUsesDefs(LocalDefs, Defs);
102 InsertUsesDefs(LocalUses, Uses);
103}
104
105/// Clear kill flags for any uses in the given set. This will likely
106/// conservatively remove more kill flags than are necessary, but removing them
107/// is safer than incorrect kill flags remaining on instructions.
109 for (MachineOperand &MO : MI->operands()) {
110 if (!MO.isReg() || MO.isDef() || !MO.isKill())
111 continue;
112 if (!Uses.count(MO.getReg()))
113 continue;
114 MO.setIsKill(false);
115 }
116}
117
118static bool isCopy(MachineInstr *MI) {
119 switch (MI->getOpcode()) {
120 default:
121 return false;
122 case ARM::MOVr:
123 case ARM::MOVr_TC:
124 case ARM::tMOVr:
125 case ARM::t2MOVr:
126 return true;
127 }
128}
129
130bool
131Thumb2ITBlock::MoveCopyOutOfITBlock(MachineInstr *MI,
133 RegisterSet &Defs, RegisterSet &Uses) {
134 if (!isCopy(MI))
135 return false;
136 // llvm models select's as two-address instructions. That means a copy
137 // is inserted before a t2MOVccr, etc. If the copy is scheduled in
138 // between selects we would end up creating multiple IT blocks.
139 assert(MI->getOperand(0).getSubReg() == 0 &&
140 MI->getOperand(1).getSubReg() == 0 &&
141 "Sub-register indices still around?");
142
143 Register DstReg = MI->getOperand(0).getReg();
144 Register SrcReg = MI->getOperand(1).getReg();
145
146 // First check if it's safe to move it.
147 if (Uses.count(DstReg) || Defs.count(SrcReg))
148 return false;
149
150 // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
151 // if we have:
152 //
153 // movs r1, r1
154 // rsb r1, 0
155 // movs r2, r2
156 // rsb r2, 0
157 //
158 // we don't want this to be converted to:
159 //
160 // movs r1, r1
161 // movs r2, r2
162 // itt mi
163 // rsb r1, 0
164 // rsb r2, 0
165 //
166 const MCInstrDesc &MCID = MI->getDesc();
167 if (MI->hasOptionalDef() &&
168 MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
169 return false;
170
171 // Then peek at the next instruction to see if it's predicated on CC or OCC.
172 // If not, then there is nothing to be gained by moving the copy.
174 ++I;
175 MachineBasicBlock::iterator E = MI->getParent()->end();
176
177 while (I != E && I->isDebugInstr())
178 ++I;
179
180 if (I != E) {
181 Register NPredReg;
182 ARMCC::CondCodes NCC = getITInstrPredicate(*I, NPredReg);
183 if (NCC == CC || NCC == OCC)
184 return true;
185 }
186 return false;
187}
188
189bool Thumb2ITBlock::InsertITInstructions(MachineBasicBlock &MBB) {
190 bool Modified = false;
191 RegisterSet Defs, Uses;
193
194 while (MBBI != E) {
195 MachineInstr *MI = &*MBBI;
196 DebugLoc dl = MI->getDebugLoc();
197 Register PredReg;
199 if (CC == ARMCC::AL) {
200 ++MBBI;
201 continue;
202 }
203
204 Defs.clear();
205 Uses.clear();
206 TrackDefUses(MI, Defs, Uses, TRI);
207
208 // Insert an IT instruction.
209 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
210 .addImm(CC);
211
212 // Add implicit use of ITSTATE to IT block instructions.
213 MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
214 true/*isImp*/, false/*isKill*/));
215
216 MachineInstr *LastITMI = MI;
217 MachineBasicBlock::iterator InsertPos = MIB.getInstr();
218 ++MBBI;
219
220 // Form IT block.
222 unsigned Mask = 0, Pos = 3;
223
224 // IT blocks are limited to one conditional op if -arm-restrict-it
225 // is set: skip the loop
226 if (!restrictIT) {
227 LLVM_DEBUG(dbgs() << "Allowing complex IT block\n");
228 // Branches, including tricky ones like LDM_RET, need to end an IT
229 // block so check the instruction we just put in the block.
230 for (; MBBI != E && Pos &&
231 (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
232 if (MBBI->isDebugInstr())
233 continue;
234
235 MachineInstr *NMI = &*MBBI;
236 MI = NMI;
237
238 Register NPredReg;
239 ARMCC::CondCodes NCC = getITInstrPredicate(*NMI, NPredReg);
240 if (NCC == CC || NCC == OCC) {
241 Mask |= ((NCC ^ CC) & 1) << Pos;
242 // Add implicit use of ITSTATE.
243 NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
244 true/*isImp*/, false/*isKill*/));
245 LastITMI = NMI;
246 } else {
247 if (NCC == ARMCC::AL &&
248 MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
249 --MBBI;
250 MBB.remove(NMI);
251 MBB.insert(InsertPos, NMI);
253 ++NumMovedInsts;
254 continue;
255 }
256 break;
257 }
258 TrackDefUses(NMI, Defs, Uses, TRI);
259 --Pos;
260 }
261 }
262
263 // Finalize IT mask.
264 Mask |= (1 << Pos);
265 MIB.addImm(Mask);
266
267 // Last instruction in IT block kills ITSTATE.
268 LastITMI->findRegisterUseOperand(ARM::ITSTATE, /*TRI=*/nullptr)
269 ->setIsKill();
270
271 // Finalize the bundle.
273 ++LastITMI->getIterator());
274
275 Modified = true;
276 ++NumITs;
277 }
278
279 return Modified;
280}
281
282bool Thumb2ITBlock::runOnMachineFunction(MachineFunction &Fn) {
283 const ARMSubtarget &STI = Fn.getSubtarget<ARMSubtarget>();
284 if (!STI.isThumb2())
285 return false;
286 AFI = Fn.getInfo<ARMFunctionInfo>();
287 TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo());
288 TRI = STI.getRegisterInfo();
289 restrictIT = STI.restrictIT();
290
291 if (!AFI->isThumbFunction())
292 return false;
293
294 bool Modified = false;
295 for (auto &MBB : Fn )
296 Modified |= InsertITInstructions(MBB);
297
298 if (Modified)
299 AFI->setHasITBlocks(true);
300
301 return Modified;
302}
303
304/// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
305/// insertion pass.
306FunctionPass *llvm::createThumb2ITBlockPass() { return new Thumb2ITBlock(); }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
Remove Loads Into Fake Uses
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
#define LLVM_DEBUG(...)
Definition: Debug.h:119
SmallSet< unsigned, 4 > RegisterSet
static bool isCopy(MachineInstr *MI)
static void ClearKillFlags(MachineInstr *MI, RegisterSet &Uses)
Clear kill flags for any uses in the given set.
#define PASS_NAME
#define DEBUG_TYPE
static void TrackDefUses(MachineInstr *MI, RegisterSet &Defs, RegisterSet &Uses, const TargetRegisterInfo *TRI)
TrackDefUses - Tracking what registers are being defined and used by instructions in the IT block.
#define PASS_NAME
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const ARMBaseInstrInfo * getInstrInfo() const override
Definition: ARMSubtarget.h:235
bool isThumb2() const
Definition: ARMSubtarget.h:376
const ARMBaseRegisterInfo * getRegisterInfo() const override
Definition: ARMSubtarget.h:247
bool restrictIT() const
Definition: ARMSubtarget.h:403
A debug info location.
Definition: DebugLoc.h:124
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:199
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:238
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
Definition: MachineInstr.h:72
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
MachineOperand * findRegisterUseOperand(Register Reg, const TargetRegisterInfo *TRI, bool isKill=false)
Wrapper for findRegisterUseOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
MachineOperand class - Representation of each machine instruction operand.
void setIsKill(bool Val=true)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:85
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
Definition: ilist_node.h:134
static CondCodes getOppositeCondition(CondCodes CC)
Definition: ARMBaseInfo.h:48
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:126
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
ARMCC::CondCodes getITInstrPredicate(const MachineInstr &MI, Register &PredReg)
getITInstrPredicate - Valid only in Thumb2 mode.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
FunctionPass * createThumb2ITBlockPass()
createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks insertion pass.