1 //===-- Thumb2ITBlockPass.cpp - Insert Thumb IT blocks ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define DEBUG_TYPE "thumb2-it"
12 #include "ARMMachineFunctionInfo.h"
13 #include "Thumb2InstrInfo.h"
14 #include "llvm/CodeGen/MachineInstr.h"
15 #include "llvm/CodeGen/MachineInstrBuilder.h"
16 #include "llvm/CodeGen/MachineFunctionPass.h"
17 #include "llvm/ADT/SmallSet.h"
18 #include "llvm/ADT/Statistic.h"
21 STATISTIC(NumITs
, "Number of IT blocks inserted");
22 STATISTIC(NumMovedInsts
, "Number of predicated instructions moved");
25 class Thumb2ITBlockPass
: public MachineFunctionPass
{
30 Thumb2ITBlockPass() : MachineFunctionPass(ID
) {}
32 const Thumb2InstrInfo
*TII
;
33 const TargetRegisterInfo
*TRI
;
36 virtual bool runOnMachineFunction(MachineFunction
&Fn
);
38 virtual const char *getPassName() const {
39 return "Thumb IT blocks insertion pass";
43 bool MoveCopyOutOfITBlock(MachineInstr
*MI
,
44 ARMCC::CondCodes CC
, ARMCC::CondCodes OCC
,
45 SmallSet
<unsigned, 4> &Defs
,
46 SmallSet
<unsigned, 4> &Uses
);
47 bool InsertITInstructions(MachineBasicBlock
&MBB
);
49 char Thumb2ITBlockPass::ID
= 0;
52 /// TrackDefUses - Tracking what registers are being defined and used by
53 /// instructions in the IT block. This also tracks "dependencies", i.e. uses
54 /// in the IT block that are defined before the IT instruction.
55 static void TrackDefUses(MachineInstr
*MI
,
56 SmallSet
<unsigned, 4> &Defs
,
57 SmallSet
<unsigned, 4> &Uses
,
58 const TargetRegisterInfo
*TRI
) {
59 SmallVector
<unsigned, 4> LocalDefs
;
60 SmallVector
<unsigned, 4> LocalUses
;
62 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
63 MachineOperand
&MO
= MI
->getOperand(i
);
66 unsigned Reg
= MO
.getReg();
67 if (!Reg
|| Reg
== ARM::ITSTATE
|| Reg
== ARM::SP
)
70 LocalUses
.push_back(Reg
);
72 LocalDefs
.push_back(Reg
);
75 for (unsigned i
= 0, e
= LocalUses
.size(); i
!= e
; ++i
) {
76 unsigned Reg
= LocalUses
[i
];
78 for (const unsigned *Subreg
= TRI
->getSubRegisters(Reg
);
83 for (unsigned i
= 0, e
= LocalDefs
.size(); i
!= e
; ++i
) {
84 unsigned Reg
= LocalDefs
[i
];
86 for (const unsigned *Subreg
= TRI
->getSubRegisters(Reg
);
94 static bool isCopy(MachineInstr
*MI
) {
95 switch (MI
->getOpcode()) {
101 case ARM::tMOVgpr2tgpr
:
102 case ARM::tMOVtgpr2gpr
:
103 case ARM::tMOVgpr2gpr
:
110 Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr
*MI
,
111 ARMCC::CondCodes CC
, ARMCC::CondCodes OCC
,
112 SmallSet
<unsigned, 4> &Defs
,
113 SmallSet
<unsigned, 4> &Uses
) {
116 // llvm models select's as two-address instructions. That means a copy
117 // is inserted before a t2MOVccr, etc. If the copy is scheduled in
118 // between selects we would end up creating multiple IT blocks.
119 assert(MI
->getOperand(0).getSubReg() == 0 &&
120 MI
->getOperand(1).getSubReg() == 0 &&
121 "Sub-register indices still around?");
123 unsigned DstReg
= MI
->getOperand(0).getReg();
124 unsigned SrcReg
= MI
->getOperand(1).getReg();
126 // First check if it's safe to move it.
127 if (Uses
.count(DstReg
) || Defs
.count(SrcReg
))
130 // Then peek at the next instruction to see if it's predicated on CC or OCC.
131 // If not, then there is nothing to be gained by moving the copy.
132 MachineBasicBlock::iterator I
= MI
; ++I
;
133 MachineBasicBlock::iterator E
= MI
->getParent()->end();
134 while (I
!= E
&& I
->isDebugValue())
137 unsigned NPredReg
= 0;
138 ARMCC::CondCodes NCC
= llvm::getITInstrPredicate(I
, NPredReg
);
139 if (NCC
== CC
|| NCC
== OCC
)
145 bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock
&MBB
) {
146 bool Modified
= false;
148 SmallSet
<unsigned, 4> Defs
;
149 SmallSet
<unsigned, 4> Uses
;
150 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
152 MachineInstr
*MI
= &*MBBI
;
153 DebugLoc dl
= MI
->getDebugLoc();
154 unsigned PredReg
= 0;
155 ARMCC::CondCodes CC
= llvm::getITInstrPredicate(MI
, PredReg
);
156 if (CC
== ARMCC::AL
) {
163 TrackDefUses(MI
, Defs
, Uses
, TRI
);
165 // Insert an IT instruction.
166 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, dl
, TII
->get(ARM::t2IT
))
169 // Add implicit use of ITSTATE to IT block instructions.
170 MI
->addOperand(MachineOperand::CreateReg(ARM::ITSTATE
, false/*ifDef*/,
171 true/*isImp*/, false/*isKill*/));
173 MachineInstr
*LastITMI
= MI
;
174 MachineBasicBlock::iterator InsertPos
= MIB
;
178 ARMCC::CondCodes OCC
= ARMCC::getOppositeCondition(CC
);
179 unsigned Mask
= 0, Pos
= 3;
180 // Branches, including tricky ones like LDM_RET, need to end an IT
181 // block so check the instruction we just put in the block.
182 for (; MBBI
!= E
&& Pos
&&
183 (!MI
->getDesc().isBranch() && !MI
->getDesc().isReturn()) ; ++MBBI
) {
184 if (MBBI
->isDebugValue())
187 MachineInstr
*NMI
= &*MBBI
;
190 unsigned NPredReg
= 0;
191 ARMCC::CondCodes NCC
= llvm::getITInstrPredicate(NMI
, NPredReg
);
192 if (NCC
== CC
|| NCC
== OCC
) {
193 Mask
|= (NCC
& 1) << Pos
;
194 // Add implicit use of ITSTATE.
195 NMI
->addOperand(MachineOperand::CreateReg(ARM::ITSTATE
, false/*ifDef*/,
196 true/*isImp*/, false/*isKill*/));
199 if (NCC
== ARMCC::AL
&&
200 MoveCopyOutOfITBlock(NMI
, CC
, OCC
, Defs
, Uses
)) {
203 MBB
.insert(InsertPos
, NMI
);
209 TrackDefUses(NMI
, Defs
, Uses
, TRI
);
215 // Tag along (firstcond[0] << 4) with the mask.
216 Mask
|= (CC
& 1) << 4;
219 // Last instruction in IT block kills ITSTATE.
220 LastITMI
->findRegisterUseOperand(ARM::ITSTATE
)->setIsKill();
229 bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction
&Fn
) {
230 const TargetMachine
&TM
= Fn
.getTarget();
231 AFI
= Fn
.getInfo
<ARMFunctionInfo
>();
232 TII
= static_cast<const Thumb2InstrInfo
*>(TM
.getInstrInfo());
233 TRI
= TM
.getRegisterInfo();
235 if (!AFI
->isThumbFunction())
238 bool Modified
= false;
239 for (MachineFunction::iterator MFI
= Fn
.begin(), E
= Fn
.end(); MFI
!= E
; ) {
240 MachineBasicBlock
&MBB
= *MFI
;
242 Modified
|= InsertITInstructions(MBB
);
246 AFI
->setHasITBlocks(true);
251 /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
253 FunctionPass
*llvm::createThumb2ITBlockPass() {
254 return new Thumb2ITBlockPass();