Line data Source code
1 : //===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===//
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 : #include "ARM.h"
11 : #include "ARMMachineFunctionInfo.h"
12 : #include "ARMSubtarget.h"
13 : #include "MCTargetDesc/ARMBaseInfo.h"
14 : #include "Thumb2InstrInfo.h"
15 : #include "llvm/ADT/SmallSet.h"
16 : #include "llvm/ADT/SmallVector.h"
17 : #include "llvm/ADT/Statistic.h"
18 : #include "llvm/ADT/StringRef.h"
19 : #include "llvm/CodeGen/MachineBasicBlock.h"
20 : #include "llvm/CodeGen/MachineFunction.h"
21 : #include "llvm/CodeGen/MachineFunctionPass.h"
22 : #include "llvm/CodeGen/MachineInstr.h"
23 : #include "llvm/CodeGen/MachineInstrBuilder.h"
24 : #include "llvm/CodeGen/MachineInstrBundle.h"
25 : #include "llvm/CodeGen/MachineOperand.h"
26 : #include "llvm/IR/DebugLoc.h"
27 : #include "llvm/MC/MCInstrDesc.h"
28 : #include "llvm/MC/MCRegisterInfo.h"
29 : #include <cassert>
30 : #include <new>
31 :
32 : using namespace llvm;
33 :
34 : #define DEBUG_TYPE "thumb2-it"
35 :
36 : STATISTIC(NumITs, "Number of IT blocks inserted");
37 : STATISTIC(NumMovedInsts, "Number of predicated instructions moved");
38 :
39 : namespace {
40 :
41 : class Thumb2ITBlockPass : public MachineFunctionPass {
42 : public:
43 : static char ID;
44 :
45 : bool restrictIT;
46 : const Thumb2InstrInfo *TII;
47 : const TargetRegisterInfo *TRI;
48 : ARMFunctionInfo *AFI;
49 :
50 2829 : Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
51 :
52 : bool runOnMachineFunction(MachineFunction &Fn) override;
53 :
54 2817 : MachineFunctionProperties getRequiredProperties() const override {
55 2817 : return MachineFunctionProperties().set(
56 2817 : MachineFunctionProperties::Property::NoVRegs);
57 : }
58 :
59 2816 : StringRef getPassName() const override {
60 2816 : return "Thumb IT blocks insertion pass";
61 : }
62 :
63 : private:
64 : bool MoveCopyOutOfITBlock(MachineInstr *MI,
65 : ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
66 : SmallSet<unsigned, 4> &Defs,
67 : SmallSet<unsigned, 4> &Uses);
68 : bool InsertITInstructions(MachineBasicBlock &MBB);
69 : };
70 :
71 : char Thumb2ITBlockPass::ID = 0;
72 :
73 : } // end anonymous namespace
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.
78 1195 : static void TrackDefUses(MachineInstr *MI,
79 : SmallSet<unsigned, 4> &Defs,
80 : SmallSet<unsigned, 4> &Uses,
81 : const TargetRegisterInfo *TRI) {
82 : SmallVector<unsigned, 4> LocalDefs;
83 : SmallVector<unsigned, 4> LocalUses;
84 :
85 8081 : for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
86 6886 : MachineOperand &MO = MI->getOperand(i);
87 6886 : if (!MO.isReg())
88 3175 : continue;
89 4887 : unsigned Reg = MO.getReg();
90 4887 : if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
91 : continue;
92 3711 : if (MO.isUse())
93 2597 : LocalUses.push_back(Reg);
94 : else
95 1114 : LocalDefs.push_back(Reg);
96 : }
97 :
98 3792 : for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
99 2597 : unsigned Reg = LocalUses[i];
100 2597 : for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
101 5206 : Subreg.isValid(); ++Subreg)
102 2609 : Uses.insert(*Subreg);
103 : }
104 :
105 2309 : for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
106 1114 : unsigned Reg = LocalDefs[i];
107 1114 : for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
108 2236 : Subreg.isValid(); ++Subreg)
109 1122 : Defs.insert(*Subreg);
110 : if (Reg == ARM::CPSR)
111 : continue;
112 : }
113 1195 : }
114 :
115 : /// Clear kill flags for any uses in the given set. This will likely
116 : /// conservatively remove more kill flags than are necessary, but removing them
117 : /// is safer than incorrect kill flags remaining on instructions.
118 8 : static void ClearKillFlags(MachineInstr *MI, SmallSet<unsigned, 4> &Uses) {
119 40 : for (MachineOperand &MO : MI->operands()) {
120 32 : if (!MO.isReg() || MO.isDef() || !MO.isKill())
121 : continue;
122 0 : if (!Uses.count(MO.getReg()))
123 : continue;
124 : MO.setIsKill(false);
125 : }
126 8 : }
127 :
128 : static bool isCopy(MachineInstr *MI) {
129 0 : switch (MI->getOpcode()) {
130 : default:
131 : return false;
132 : case ARM::MOVr:
133 : case ARM::MOVr_TC:
134 : case ARM::tMOVr:
135 : case ARM::t2MOVr:
136 : return true;
137 : }
138 : }
139 :
140 : bool
141 0 : Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
142 : ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
143 : SmallSet<unsigned, 4> &Defs,
144 : SmallSet<unsigned, 4> &Uses) {
145 : if (!isCopy(MI))
146 0 : return false;
147 : // llvm models select's as two-address instructions. That means a copy
148 : // is inserted before a t2MOVccr, etc. If the copy is scheduled in
149 : // between selects we would end up creating multiple IT blocks.
150 : assert(MI->getOperand(0).getSubReg() == 0 &&
151 : MI->getOperand(1).getSubReg() == 0 &&
152 : "Sub-register indices still around?");
153 :
154 0 : unsigned DstReg = MI->getOperand(0).getReg();
155 0 : unsigned SrcReg = MI->getOperand(1).getReg();
156 :
157 : // First check if it's safe to move it.
158 0 : if (Uses.count(DstReg) || Defs.count(SrcReg))
159 0 : return false;
160 :
161 : // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
162 : // if we have:
163 : //
164 : // movs r1, r1
165 : // rsb r1, 0
166 : // movs r2, r2
167 : // rsb r2, 0
168 : //
169 : // we don't want this to be converted to:
170 : //
171 : // movs r1, r1
172 : // movs r2, r2
173 : // itt mi
174 : // rsb r1, 0
175 : // rsb r2, 0
176 : //
177 : const MCInstrDesc &MCID = MI->getDesc();
178 0 : if (MI->hasOptionalDef() &&
179 0 : MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
180 0 : return false;
181 :
182 : // Then peek at the next instruction to see if it's predicated on CC or OCC.
183 : // If not, then there is nothing to be gained by moving the copy.
184 : MachineBasicBlock::iterator I = MI; ++I;
185 0 : MachineBasicBlock::iterator E = MI->getParent()->end();
186 0 : while (I != E && I->isDebugInstr())
187 : ++I;
188 0 : if (I != E) {
189 0 : unsigned NPredReg = 0;
190 0 : ARMCC::CondCodes NCC = getITInstrPredicate(*I, NPredReg);
191 0 : if (NCC == CC || NCC == OCC)
192 0 : return true;
193 : }
194 : return false;
195 : }
196 :
197 6845 : bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
198 : bool Modified = false;
199 :
200 6845 : SmallSet<unsigned, 4> Defs;
201 6845 : SmallSet<unsigned, 4> Uses;
202 6845 : MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
203 64580 : while (MBBI != E) {
204 : MachineInstr *MI = &*MBBI;
205 : DebugLoc dl = MI->getDebugLoc();
206 57735 : unsigned PredReg = 0;
207 57735 : ARMCC::CondCodes CC = getITInstrPredicate(*MI, PredReg);
208 57735 : if (CC == ARMCC::AL) {
209 : ++MBBI;
210 : continue;
211 : }
212 :
213 : Defs.clear();
214 : Uses.clear();
215 1006 : TrackDefUses(MI, Defs, Uses, TRI);
216 :
217 : // Insert an IT instruction.
218 2012 : MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
219 1006 : .addImm(CC);
220 :
221 : // Add implicit use of ITSTATE to IT block instructions.
222 1006 : MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
223 : true/*isImp*/, false/*isKill*/));
224 :
225 : MachineInstr *LastITMI = MI;
226 : MachineBasicBlock::iterator InsertPos = MIB.getInstr();
227 : ++MBBI;
228 :
229 : // Form IT block.
230 : ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
231 : unsigned Mask = 0, Pos = 3;
232 :
233 : // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it
234 : // is set: skip the loop
235 1006 : if (!restrictIT) {
236 : // Branches, including tricky ones like LDM_RET, need to end an IT
237 : // block so check the instruction we just put in the block.
238 2046 : for (; MBBI != E && Pos &&
239 996 : (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
240 : if (MBBI->isDebugInstr())
241 9 : continue;
242 :
243 : MachineInstr *NMI = &*MBBI;
244 : MI = NMI;
245 :
246 863 : unsigned NPredReg = 0;
247 863 : ARMCC::CondCodes NCC = getITInstrPredicate(*NMI, NPredReg);
248 863 : if (NCC == CC || NCC == OCC) {
249 189 : Mask |= (NCC & 1) << Pos;
250 : // Add implicit use of ITSTATE.
251 189 : NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
252 : true/*isImp*/, false/*isKill*/));
253 : LastITMI = NMI;
254 : } else {
255 1331 : if (NCC == ARMCC::AL &&
256 657 : MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
257 : --MBBI;
258 : MBB.remove(NMI);
259 : MBB.insert(InsertPos, NMI);
260 8 : ClearKillFlags(MI, Uses);
261 : ++NumMovedInsts;
262 8 : continue;
263 : }
264 666 : break;
265 : }
266 189 : TrackDefUses(NMI, Defs, Uses, TRI);
267 189 : --Pos;
268 : }
269 : }
270 :
271 : // Finalize IT mask.
272 1006 : Mask |= (1 << Pos);
273 : // Tag along (firstcond[0] << 4) with the mask.
274 1006 : Mask |= (CC & 1) << 4;
275 1006 : MIB.addImm(Mask);
276 :
277 : // Last instruction in IT block kills ITSTATE.
278 : LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
279 :
280 : // Finalize the bundle.
281 1006 : finalizeBundle(MBB, InsertPos.getInstrIterator(),
282 1006 : ++LastITMI->getIterator());
283 :
284 : Modified = true;
285 : ++NumITs;
286 : }
287 :
288 6845 : return Modified;
289 : }
290 :
291 14591 : bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) {
292 : const ARMSubtarget &STI =
293 14591 : static_cast<const ARMSubtarget &>(Fn.getSubtarget());
294 14591 : if (!STI.isThumb2())
295 : return false;
296 4963 : AFI = Fn.getInfo<ARMFunctionInfo>();
297 4963 : TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo());
298 4963 : TRI = STI.getRegisterInfo();
299 4963 : restrictIT = STI.restrictIT();
300 :
301 4963 : if (!AFI->isThumbFunction())
302 : return false;
303 :
304 : bool Modified = false;
305 11808 : for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) {
306 : MachineBasicBlock &MBB = *MFI;
307 : ++MFI;
308 6845 : Modified |= InsertITInstructions(MBB);
309 : }
310 :
311 4963 : if (Modified)
312 810 : AFI->setHasITBlocks(true);
313 :
314 : return Modified;
315 : }
316 :
317 : /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
318 : /// insertion pass.
319 2829 : FunctionPass *llvm::createThumb2ITBlockPass() {
320 2829 : return new Thumb2ITBlockPass();
321 : }
|