Thumb2ITBlockPass.cpp revision 205407
1//===-- Thumb2ITBlockPass.cpp - Insert Thumb IT blocks ----------*- C++ -*-===// 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/CodeGen/MachineInstr.h" 15#include "llvm/CodeGen/MachineInstrBuilder.h" 16#include "llvm/CodeGen/MachineFunctionPass.h" 17#include "llvm/ADT/Statistic.h" 18using namespace llvm; 19 20STATISTIC(NumITs, "Number of IT blocks inserted"); 21 22namespace { 23 struct Thumb2ITBlockPass : public MachineFunctionPass { 24 static char ID; 25 Thumb2ITBlockPass() : MachineFunctionPass(&ID) {} 26 27 const Thumb2InstrInfo *TII; 28 ARMFunctionInfo *AFI; 29 30 virtual bool runOnMachineFunction(MachineFunction &Fn); 31 32 virtual const char *getPassName() const { 33 return "Thumb IT blocks insertion pass"; 34 } 35 36 private: 37 bool InsertITBlocks(MachineBasicBlock &MBB); 38 }; 39 char Thumb2ITBlockPass::ID = 0; 40} 41 42static ARMCC::CondCodes getPredicate(const MachineInstr *MI, unsigned &PredReg){ 43 unsigned Opc = MI->getOpcode(); 44 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) 45 return ARMCC::AL; 46 return llvm::getInstrPredicate(MI, PredReg); 47} 48 49bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { 50 bool Modified = false; 51 52 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 53 while (MBBI != E) { 54 MachineInstr *MI = &*MBBI; 55 DebugLoc dl = MI->getDebugLoc(); 56 unsigned PredReg = 0; 57 ARMCC::CondCodes CC = getPredicate(MI, PredReg); 58 59 if (CC == ARMCC::AL) { 60 ++MBBI; 61 continue; 62 } 63 64 // Insert an IT instruction. 65 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) 66 .addImm(CC); 67 ++MBBI; 68 69 // Finalize IT mask. 70 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); 71 unsigned Mask = 0, Pos = 3; 72 // Branches, including tricky ones like LDM_RET, need to end an IT 73 // block so check the instruction we just put in the block. 74 while (MBBI != E && Pos && 75 (!MI->getDesc().isBranch() && !MI->getDesc().isReturn())) { 76 MachineInstr *NMI = &*MBBI; 77 MI = NMI; 78 DebugLoc ndl = NMI->getDebugLoc(); 79 unsigned NPredReg = 0; 80 ARMCC::CondCodes NCC = getPredicate(NMI, NPredReg); 81 if (NCC == CC || NCC == OCC) 82 Mask |= (NCC & 1) << Pos; 83 else 84 break; 85 --Pos; 86 ++MBBI; 87 } 88 Mask |= (1 << Pos); 89 // Tag along (firstcond[0] << 4) with the mask. 90 Mask |= (CC & 1) << 4; 91 MIB.addImm(Mask); 92 Modified = true; 93 ++NumITs; 94 } 95 96 return Modified; 97} 98 99bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { 100 const TargetMachine &TM = Fn.getTarget(); 101 AFI = Fn.getInfo<ARMFunctionInfo>(); 102 TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo()); 103 104 if (!AFI->isThumbFunction()) 105 return false; 106 107 bool Modified = false; 108 for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; 109 ++MFI) { 110 MachineBasicBlock &MBB = *MFI; 111 Modified |= InsertITBlocks(MBB); 112 } 113 114 return Modified; 115} 116 117/// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks 118/// insertion pass. 119FunctionPass *llvm::createThumb2ITBlockPass() { 120 return new Thumb2ITBlockPass(); 121} 122