LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thumb2ITBlockPass.cpp
Go to the documentation of this file.
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 #define DEBUG_TYPE "thumb2-it"
11 #include "ARM.h"
12 #include "ARMMachineFunctionInfo.h"
13 #include "Thumb2InstrInfo.h"
14 #include "llvm/ADT/SmallSet.h"
15 #include "llvm/ADT/Statistic.h"
20 using namespace llvm;
21 
22 STATISTIC(NumITs, "Number of IT blocks inserted");
23 STATISTIC(NumMovedInsts, "Number of predicated instructions moved");
24 
25 namespace {
26  class Thumb2ITBlockPass : public MachineFunctionPass {
27  public:
28  static char ID;
29  Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
30 
31  bool restrictIT;
32  const Thumb2InstrInfo *TII;
33  const TargetRegisterInfo *TRI;
34  ARMFunctionInfo *AFI;
35 
36  virtual bool runOnMachineFunction(MachineFunction &Fn);
37 
38  virtual const char *getPassName() const {
39  return "Thumb IT blocks insertion pass";
40  }
41 
42  private:
43  bool MoveCopyOutOfITBlock(MachineInstr *MI,
46  SmallSet<unsigned, 4> &Uses);
47  bool InsertITInstructions(MachineBasicBlock &MBB);
48  };
49  char Thumb2ITBlockPass::ID = 0;
50 }
51 
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.
58  const TargetRegisterInfo *TRI) {
59  SmallVector<unsigned, 4> LocalDefs;
60  SmallVector<unsigned, 4> LocalUses;
61 
62  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
63  MachineOperand &MO = MI->getOperand(i);
64  if (!MO.isReg())
65  continue;
66  unsigned Reg = MO.getReg();
67  if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
68  continue;
69  if (MO.isUse())
70  LocalUses.push_back(Reg);
71  else
72  LocalDefs.push_back(Reg);
73  }
74 
75  for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
76  unsigned Reg = LocalUses[i];
77  for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
78  Subreg.isValid(); ++Subreg)
79  Uses.insert(*Subreg);
80  }
81 
82  for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
83  unsigned Reg = LocalDefs[i];
84  for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
85  Subreg.isValid(); ++Subreg)
86  Defs.insert(*Subreg);
87  if (Reg == ARM::CPSR)
88  continue;
89  }
90 }
91 
92 static bool isCopy(MachineInstr *MI) {
93  switch (MI->getOpcode()) {
94  default:
95  return false;
96  case ARM::MOVr:
97  case ARM::MOVr_TC:
98  case ARM::tMOVr:
99  case ARM::t2MOVr:
100  return true;
101  }
102 }
103 
104 bool
105 Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
107  SmallSet<unsigned, 4> &Defs,
108  SmallSet<unsigned, 4> &Uses) {
109  if (!isCopy(MI))
110  return false;
111  // llvm models select's as two-address instructions. That means a copy
112  // is inserted before a t2MOVccr, etc. If the copy is scheduled in
113  // between selects we would end up creating multiple IT blocks.
114  assert(MI->getOperand(0).getSubReg() == 0 &&
115  MI->getOperand(1).getSubReg() == 0 &&
116  "Sub-register indices still around?");
117 
118  unsigned DstReg = MI->getOperand(0).getReg();
119  unsigned SrcReg = MI->getOperand(1).getReg();
120 
121  // First check if it's safe to move it.
122  if (Uses.count(DstReg) || Defs.count(SrcReg))
123  return false;
124 
125  // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
126  // if we have:
127  //
128  // movs r1, r1
129  // rsb r1, 0
130  // movs r2, r2
131  // rsb r2, 0
132  //
133  // we don't want this to be converted to:
134  //
135  // movs r1, r1
136  // movs r2, r2
137  // itt mi
138  // rsb r1, 0
139  // rsb r2, 0
140  //
141  const MCInstrDesc &MCID = MI->getDesc();
142  if (MI->hasOptionalDef() &&
143  MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
144  return false;
145 
146  // Then peek at the next instruction to see if it's predicated on CC or OCC.
147  // If not, then there is nothing to be gained by moving the copy.
150  while (I != E && I->isDebugValue())
151  ++I;
152  if (I != E) {
153  unsigned NPredReg = 0;
154  ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg);
155  if (NCC == CC || NCC == OCC)
156  return true;
157  }
158  return false;
159 }
160 
161 bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
162  bool Modified = false;
163 
166  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
167  while (MBBI != E) {
168  MachineInstr *MI = &*MBBI;
169  DebugLoc dl = MI->getDebugLoc();
170  unsigned PredReg = 0;
171  ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
172  if (CC == ARMCC::AL) {
173  ++MBBI;
174  continue;
175  }
176 
177  Defs.clear();
178  Uses.clear();
179  TrackDefUses(MI, Defs, Uses, TRI);
180 
181  // Insert an IT instruction.
182  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
183  .addImm(CC);
184 
185  // Add implicit use of ITSTATE to IT block instructions.
186  MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
187  true/*isImp*/, false/*isKill*/));
188 
189  MachineInstr *LastITMI = MI;
190  MachineBasicBlock::iterator InsertPos = MIB;
191  ++MBBI;
192 
193  // Form IT block.
195  unsigned Mask = 0, Pos = 3;
196 
197  // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it
198  // is set: skip the loop
199  if (!restrictIT) {
200  // Branches, including tricky ones like LDM_RET, need to end an IT
201  // block so check the instruction we just put in the block.
202  for (; MBBI != E && Pos &&
203  (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
204  if (MBBI->isDebugValue())
205  continue;
206 
207  MachineInstr *NMI = &*MBBI;
208  MI = NMI;
209 
210  unsigned NPredReg = 0;
211  ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg);
212  if (NCC == CC || NCC == OCC) {
213  Mask |= (NCC & 1) << Pos;
214  // Add implicit use of ITSTATE.
215  NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
216  true/*isImp*/, false/*isKill*/));
217  LastITMI = NMI;
218  } else {
219  if (NCC == ARMCC::AL &&
220  MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
221  --MBBI;
222  MBB.remove(NMI);
223  MBB.insert(InsertPos, NMI);
224  ++NumMovedInsts;
225  continue;
226  }
227  break;
228  }
229  TrackDefUses(NMI, Defs, Uses, TRI);
230  --Pos;
231  }
232  }
233 
234  // Finalize IT mask.
235  Mask |= (1 << Pos);
236  // Tag along (firstcond[0] << 4) with the mask.
237  Mask |= (CC & 1) << 4;
238  MIB.addImm(Mask);
239 
240  // Last instruction in IT block kills ITSTATE.
241  LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
242 
243  // Finalize the bundle.
245  finalizeBundle(MBB, InsertPos.getInstrIterator(), llvm::next(LI));
246 
247  Modified = true;
248  ++NumITs;
249  }
250 
251  return Modified;
252 }
253 
254 bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) {
255  const TargetMachine &TM = Fn.getTarget();
256  AFI = Fn.getInfo<ARMFunctionInfo>();
257  TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo());
258  TRI = TM.getRegisterInfo();
259  restrictIT = TM.getSubtarget<ARMSubtarget>().restrictIT();
260 
261  if (!AFI->isThumbFunction())
262  return false;
263 
264  bool Modified = false;
265  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) {
266  MachineBasicBlock &MBB = *MFI;
267  ++MFI;
268  Modified |= InsertITInstructions(MBB);
269  }
270 
271  if (Modified)
272  AFI->setHasITBlocks(true);
273 
274  return Modified;
275 }
276 
277 /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
278 /// insertion pass.
280  return new Thumb2ITBlockPass();
281 }
void push_back(const T &Elt)
Definition: SmallVector.h:236
static bool isCopy(MachineInstr *MI)
bool isBranch(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:374
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
Instructions::iterator instr_iterator
ARMCC::CondCodes getITInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
LoopInfoBase< BlockT, LoopT > * LI
Definition: LoopInfoImpl.h:411
const HexagonInstrInfo * TII
static MachineOperand CreateReg(unsigned 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 isReg() const
isReg - Tests if this is a MO_Register operand.
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
Definition: MachineInstr.h:265
void clear()
Definition: SmallSet.h:97
int getOpcode() const
Definition: MachineInstr.h:261
bool insert(const T &V)
Definition: SmallSet.h:59
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bundle_iterator< MachineInstr, instr_iterator > iterator
bool isReturn(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:345
STATISTIC(NumITs,"Number of IT blocks inserted")
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
static void TrackDefUses(MachineInstr *MI, SmallSet< unsigned, 4 > &Defs, SmallSet< unsigned, 4 > &Uses, const TargetRegisterInfo *TRI)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getSubReg() const
void setIsKill(bool Val=true)
virtual const TargetInstrInfo * getInstrInfo() const
MachineOperand * findRegisterUseOperand(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=NULL)
Definition: MachineInstr.h:780
const STC & getSubtarget() const
void addOperand(MachineFunction &MF, const MachineOperand &Op)
MachineInstr * remove(MachineInstr *I)
bool count(const T &V) const
count - Return true if the element is in the set.
Definition: SmallSet.h:48
static CondCodes getOppositeCondition(CondCodes CC)
Definition: ARMBaseInfo.h:47
#define I(x, y, z)
Definition: MD5.cpp:54
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const TargetMachine & getTarget() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
virtual const TargetRegisterInfo * getRegisterInfo() const
unsigned getReg() const
getReg - Returns the register number.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
Definition: MCInstrDesc.h:190
BasicBlockListType::iterator iterator
FunctionPass * createThumb2ITBlockPass()
bool hasOptionalDef(QueryType Type=IgnoreBundle) const
Definition: MachineInstr.h:334
void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244