Thumb2ITBlockPass.cpp revision 249423
123925Sgibbs//===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===//
223925Sgibbs//
323925Sgibbs//                     The LLVM Compiler Infrastructure
423925Sgibbs//
523925Sgibbs// This file is distributed under the University of Illinois Open Source
623925Sgibbs// License. See LICENSE.TXT for details.
723925Sgibbs//
823925Sgibbs//===----------------------------------------------------------------------===//
923925Sgibbs
1023925Sgibbs#define DEBUG_TYPE "thumb2-it"
1126997Sgibbs#include "ARM.h"
1226997Sgibbs#include "ARMMachineFunctionInfo.h"
1323925Sgibbs#include "Thumb2InstrInfo.h"
1423925Sgibbs#include "llvm/ADT/SmallSet.h"
1523925Sgibbs#include "llvm/ADT/Statistic.h"
1623925Sgibbs#include "llvm/CodeGen/MachineFunctionPass.h"
1723925Sgibbs#include "llvm/CodeGen/MachineInstr.h"
1823925Sgibbs#include "llvm/CodeGen/MachineInstrBuilder.h"
1923925Sgibbs#include "llvm/CodeGen/MachineInstrBundle.h"
2023925Sgibbsusing namespace llvm;
2123925Sgibbs
2223925SgibbsSTATISTIC(NumITs,        "Number of IT blocks inserted");
2323925SgibbsSTATISTIC(NumMovedInsts, "Number of predicated instructions moved");
2423925Sgibbs
2523925Sgibbsnamespace {
2623925Sgibbs  class Thumb2ITBlockPass : public MachineFunctionPass {
2723925Sgibbs  public:
2823925Sgibbs    static char ID;
2923925Sgibbs    Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
3023925Sgibbs
3126997Sgibbs    const Thumb2InstrInfo *TII;
3223925Sgibbs    const TargetRegisterInfo *TRI;
3323925Sgibbs    ARMFunctionInfo *AFI;
3423925Sgibbs
3523925Sgibbs    virtual bool runOnMachineFunction(MachineFunction &Fn);
3623925Sgibbs
3723925Sgibbs    virtual const char *getPassName() const {
3823925Sgibbs      return "Thumb IT blocks insertion pass";
3923925Sgibbs    }
4023925Sgibbs
4123925Sgibbs  private:
4223925Sgibbs    bool MoveCopyOutOfITBlock(MachineInstr *MI,
4323925Sgibbs                              ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
4423925Sgibbs                              SmallSet<unsigned, 4> &Defs,
4523925Sgibbs                              SmallSet<unsigned, 4> &Uses);
4623925Sgibbs    bool InsertITInstructions(MachineBasicBlock &MBB);
4723925Sgibbs  };
4823925Sgibbs  char Thumb2ITBlockPass::ID = 0;
4923925Sgibbs}
5023925Sgibbs
5123925Sgibbs/// TrackDefUses - Tracking what registers are being defined and used by
5223925Sgibbs/// instructions in the IT block. This also tracks "dependencies", i.e. uses
5323925Sgibbs/// in the IT block that are defined before the IT instruction.
5423925Sgibbsstatic void TrackDefUses(MachineInstr *MI,
5523925Sgibbs                         SmallSet<unsigned, 4> &Defs,
5623925Sgibbs                         SmallSet<unsigned, 4> &Uses,
5723925Sgibbs                         const TargetRegisterInfo *TRI) {
5823925Sgibbs  SmallVector<unsigned, 4> LocalDefs;
5923925Sgibbs  SmallVector<unsigned, 4> LocalUses;
6023925Sgibbs
6123925Sgibbs  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
6223925Sgibbs    MachineOperand &MO = MI->getOperand(i);
6323925Sgibbs    if (!MO.isReg())
6423925Sgibbs      continue;
6523925Sgibbs    unsigned Reg = MO.getReg();
6623925Sgibbs    if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
6723925Sgibbs      continue;
6823925Sgibbs    if (MO.isUse())
6923925Sgibbs      LocalUses.push_back(Reg);
7023925Sgibbs    else
7123925Sgibbs      LocalDefs.push_back(Reg);
7223925Sgibbs  }
7323925Sgibbs
7423925Sgibbs  for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
7523925Sgibbs    unsigned Reg = LocalUses[i];
7623925Sgibbs    Uses.insert(Reg);
7723925Sgibbs    for (MCSubRegIterator Subreg(Reg, TRI); Subreg.isValid(); ++Subreg)
7823925Sgibbs      Uses.insert(*Subreg);
7923925Sgibbs  }
8023925Sgibbs
8123925Sgibbs  for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
8223925Sgibbs    unsigned Reg = LocalDefs[i];
8323925Sgibbs    Defs.insert(Reg);
8423925Sgibbs    for (MCSubRegIterator Subreg(Reg, TRI); Subreg.isValid(); ++Subreg)
8523925Sgibbs      Defs.insert(*Subreg);
8623925Sgibbs    if (Reg == ARM::CPSR)
8723925Sgibbs      continue;
8823925Sgibbs  }
8923925Sgibbs}
9023925Sgibbs
9123925Sgibbsstatic bool isCopy(MachineInstr *MI) {
9223925Sgibbs  switch (MI->getOpcode()) {
9323925Sgibbs  default:
9423925Sgibbs    return false;
9523925Sgibbs  case ARM::MOVr:
9623925Sgibbs  case ARM::MOVr_TC:
9723925Sgibbs  case ARM::tMOVr:
9823925Sgibbs  case ARM::t2MOVr:
9923925Sgibbs    return true;
10023925Sgibbs  }
10123925Sgibbs}
10223925Sgibbs
10323925Sgibbsbool
10423925SgibbsThumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
10523925Sgibbs                                      ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
10623925Sgibbs                                        SmallSet<unsigned, 4> &Defs,
10723925Sgibbs                                        SmallSet<unsigned, 4> &Uses) {
10823925Sgibbs  if (!isCopy(MI))
10923925Sgibbs    return false;
11023925Sgibbs  // llvm models select's as two-address instructions. That means a copy
11123925Sgibbs  // is inserted before a t2MOVccr, etc. If the copy is scheduled in
11223925Sgibbs  // between selects we would end up creating multiple IT blocks.
11323925Sgibbs  assert(MI->getOperand(0).getSubReg() == 0 &&
11423925Sgibbs         MI->getOperand(1).getSubReg() == 0 &&
11523925Sgibbs         "Sub-register indices still around?");
11623925Sgibbs
11723925Sgibbs  unsigned DstReg = MI->getOperand(0).getReg();
11823925Sgibbs  unsigned SrcReg = MI->getOperand(1).getReg();
11923925Sgibbs
12023925Sgibbs  // First check if it's safe to move it.
12123925Sgibbs  if (Uses.count(DstReg) || Defs.count(SrcReg))
12223925Sgibbs    return false;
12323925Sgibbs
12423925Sgibbs  // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
12523925Sgibbs  // if we have:
12623925Sgibbs  //
12723925Sgibbs  //   movs  r1, r1
12823925Sgibbs  //   rsb   r1, 0
12923925Sgibbs  //   movs  r2, r2
13023925Sgibbs  //   rsb   r2, 0
13123925Sgibbs  //
13223925Sgibbs  // we don't want this to be converted to:
13323925Sgibbs  //
13423925Sgibbs  //   movs  r1, r1
13523925Sgibbs  //   movs  r2, r2
13623925Sgibbs  //   itt   mi
13723925Sgibbs  //   rsb   r1, 0
13823925Sgibbs  //   rsb   r2, 0
13923925Sgibbs  //
14023925Sgibbs  const MCInstrDesc &MCID = MI->getDesc();
14123925Sgibbs  if (MI->hasOptionalDef() &&
14223925Sgibbs      MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
14323925Sgibbs    return false;
14423925Sgibbs
145  // Then peek at the next instruction to see if it's predicated on CC or OCC.
146  // If not, then there is nothing to be gained by moving the copy.
147  MachineBasicBlock::iterator I = MI; ++I;
148  MachineBasicBlock::iterator E = MI->getParent()->end();
149  while (I != E && I->isDebugValue())
150    ++I;
151  if (I != E) {
152    unsigned NPredReg = 0;
153    ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg);
154    if (NCC == CC || NCC == OCC)
155      return true;
156  }
157  return false;
158}
159
160bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
161  bool Modified = false;
162
163  SmallSet<unsigned, 4> Defs;
164  SmallSet<unsigned, 4> Uses;
165  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
166  while (MBBI != E) {
167    MachineInstr *MI = &*MBBI;
168    DebugLoc dl = MI->getDebugLoc();
169    unsigned PredReg = 0;
170    ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
171    if (CC == ARMCC::AL) {
172      ++MBBI;
173      continue;
174    }
175
176    Defs.clear();
177    Uses.clear();
178    TrackDefUses(MI, Defs, Uses, TRI);
179
180    // Insert an IT instruction.
181    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
182      .addImm(CC);
183
184    // Add implicit use of ITSTATE to IT block instructions.
185    MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
186                                             true/*isImp*/, false/*isKill*/));
187
188    MachineInstr *LastITMI = MI;
189    MachineBasicBlock::iterator InsertPos = MIB;
190    ++MBBI;
191
192    // Form IT block.
193    ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
194    unsigned Mask = 0, Pos = 3;
195    // Branches, including tricky ones like LDM_RET, need to end an IT
196    // block so check the instruction we just put in the block.
197    for (; MBBI != E && Pos &&
198           (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
199      if (MBBI->isDebugValue())
200        continue;
201
202      MachineInstr *NMI = &*MBBI;
203      MI = NMI;
204
205      unsigned NPredReg = 0;
206      ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg);
207      if (NCC == CC || NCC == OCC) {
208        Mask |= (NCC & 1) << Pos;
209        // Add implicit use of ITSTATE.
210        NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
211                                               true/*isImp*/, false/*isKill*/));
212        LastITMI = NMI;
213      } else {
214        if (NCC == ARMCC::AL &&
215            MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
216          --MBBI;
217          MBB.remove(NMI);
218          MBB.insert(InsertPos, NMI);
219          ++NumMovedInsts;
220          continue;
221        }
222        break;
223      }
224      TrackDefUses(NMI, Defs, Uses, TRI);
225      --Pos;
226    }
227
228    // Finalize IT mask.
229    Mask |= (1 << Pos);
230    // Tag along (firstcond[0] << 4) with the mask.
231    Mask |= (CC & 1) << 4;
232    MIB.addImm(Mask);
233
234    // Last instruction in IT block kills ITSTATE.
235    LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
236
237    // Finalize the bundle.
238    MachineBasicBlock::instr_iterator LI = LastITMI;
239    finalizeBundle(MBB, InsertPos.getInstrIterator(), llvm::next(LI));
240
241    Modified = true;
242    ++NumITs;
243  }
244
245  return Modified;
246}
247
248bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) {
249  const TargetMachine &TM = Fn.getTarget();
250  AFI = Fn.getInfo<ARMFunctionInfo>();
251  TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo());
252  TRI = TM.getRegisterInfo();
253
254  if (!AFI->isThumbFunction())
255    return false;
256
257  bool Modified = false;
258  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) {
259    MachineBasicBlock &MBB = *MFI;
260    ++MFI;
261    Modified |= InsertITInstructions(MBB);
262  }
263
264  if (Modified)
265    AFI->setHasITBlocks(true);
266
267  return Modified;
268}
269
270/// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
271/// insertion pass.
272FunctionPass *llvm::createThumb2ITBlockPass() {
273  return new Thumb2ITBlockPass();
274}
275