Thumb2ITBlockPass.cpp revision ed338e80f92d6efa961d9f8c29239dde1507e683
106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//===-- Thumb2ITBlockPass.cpp - Insert Thumb IT blocks -----------*- C++ -*-===// 206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// 306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// The LLVM Compiler Infrastructure 406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// 506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// This file is distributed under the University of Illinois Open Source 606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// License. See LICENSE.TXT for details. 706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// 806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//===----------------------------------------------------------------------===// 906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 1006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#define DEBUG_TYPE "thumb2-it" 1106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "ARM.h" 1206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "ARMMachineFunctionInfo.h" 13ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng#include "Thumb2InstrInfo.h" 1406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineInstr.h" 1506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h" 1606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineFunctionPass.h" 1706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/Support/Compiler.h" 1806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/ADT/Statistic.h" 1906e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengusing namespace llvm; 2006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 2106e16587ebc81e43b42157fa3afcfd806b59b296Evan ChengSTATISTIC(NumITs, "Number of IT blocks inserted"); 2206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 2306e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengnamespace { 2406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng struct VISIBILITY_HIDDEN Thumb2ITBlockPass : public MachineFunctionPass { 2506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng static char ID; 2606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng Thumb2ITBlockPass() : MachineFunctionPass(&ID) {} 2706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 28ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng const Thumb2InstrInfo *TII; 2906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ARMFunctionInfo *AFI; 3006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 3106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng virtual bool runOnMachineFunction(MachineFunction &Fn); 3206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 3306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng virtual const char *getPassName() const { 3406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng return "Thumb IT blocks insertion pass"; 3506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } 3606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 3706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng private: 3806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng bool InsertITBlocks(MachineBasicBlock &MBB); 3906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng }; 4006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng char Thumb2ITBlockPass::ID = 0; 4106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng} 4206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 43ed338e80f92d6efa961d9f8c29239dde1507e683Evan ChengARMCC::CondCodes getPredicate(const MachineInstr *MI, 44ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng const Thumb2InstrInfo *TII) { 45ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng unsigned Opc = MI->getOpcode(); 46ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) 47ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng return ARMCC::AL; 48ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng return TII->getPredicate(MI); 49ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng} 50ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng 5106e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengbool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { 5206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng bool Modified = false; 5306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 5406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 5506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng while (MBBI != E) { 5606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng MachineInstr *MI = &*MBBI; 57ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng ARMCC::CondCodes CC = getPredicate(MI, TII); 5806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng if (CC == ARMCC::AL) { 5906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ++MBBI; 6006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng continue; 6106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } 6206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 6306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng // Insert an IT instruction. 6406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng DebugLoc dl = MI->getDebugLoc(); 6506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) 6606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng .addImm(CC); 6706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ++MBBI; 6806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 6906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng // Finalize IT mask. If the following instruction is not predicated or it's 7006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng // predicated on a condition that's not the same or the opposite of CC, then 7106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng // the mask is 0x8. 7206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); 7306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng unsigned Mask = 0x8; 7406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng while (MBBI != E || (Mask & 1)) { 75ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng ARMCC::CondCodes NCC = getPredicate(&*MBBI, TII); 7606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng if (NCC == CC) { 7706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng Mask >>= 1; 7806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng Mask |= 0x8; 7906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } else if (NCC == OCC) { 8006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng Mask >>= 1; 8106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } else { 8206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng break; 8306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } 8406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ++MBBI; 8506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } 8606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng MIB.addImm(Mask); 8706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng Modified = true; 8806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ++NumITs; 8906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } 9006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 9106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng return Modified; 9206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng} 9306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 9406e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengbool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { 9506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng const TargetMachine &TM = Fn.getTarget(); 9606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng AFI = Fn.getInfo<ARMFunctionInfo>(); 97ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo()); 9806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 9906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng if (!AFI->isThumbFunction()) 10006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng return false; 10106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 10206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng bool Modified = false; 10306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; 10406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng ++MFI) { 10506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng MachineBasicBlock &MBB = *MFI; 10606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng Modified |= InsertITBlocks(MBB); 10706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng } 10806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 10906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng return Modified; 11006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng} 11106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng 11206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng/// createThumb2ITBlockPass - returns and instance of the Thumb IT blocks 11306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng/// insertion pass. 11406e16587ebc81e43b42157fa3afcfd806b59b296Evan ChengFunctionPass *llvm::createThumb2ITBlockPass() { 11506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng return new Thumb2ITBlockPass(); 11606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng} 117