1d88c1a5aSDimitry Andric //===--- ARMComputeBlockSize.cpp - Compute machine block sizes ------------===// 2d88c1a5aSDimitry Andric // 3d88c1a5aSDimitry Andric // The LLVM Compiler Infrastructure 4d88c1a5aSDimitry Andric // 5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source 6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details. 7d88c1a5aSDimitry Andric // 8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===// 9d88c1a5aSDimitry Andric 10d88c1a5aSDimitry Andric #include "ARM.h" 117a7e6055SDimitry Andric #include "ARMBaseInstrInfo.h" 12d88c1a5aSDimitry Andric #include "ARMBasicBlockInfo.h" 137a7e6055SDimitry Andric #include "ARMMachineFunctionInfo.h" 147a7e6055SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 157a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 167a7e6055SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 172cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 187a7e6055SDimitry Andric #include <vector> 197a7e6055SDimitry Andric 20d88c1a5aSDimitry Andric using namespace llvm; 21d88c1a5aSDimitry Andric 22d88c1a5aSDimitry Andric namespace llvm { 23d88c1a5aSDimitry Andric 24d88c1a5aSDimitry Andric // mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions 25d88c1a5aSDimitry Andric // below may shrink MI. 26d88c1a5aSDimitry Andric static bool mayOptimizeThumb2Instruction(const MachineInstr * MI)27d88c1a5aSDimitry AndricmayOptimizeThumb2Instruction(const MachineInstr *MI) { 28d88c1a5aSDimitry Andric switch(MI->getOpcode()) { 29d88c1a5aSDimitry Andric // optimizeThumb2Instructions. 30d88c1a5aSDimitry Andric case ARM::t2LEApcrel: 31d88c1a5aSDimitry Andric case ARM::t2LDRpci: 32d88c1a5aSDimitry Andric // optimizeThumb2Branches. 33d88c1a5aSDimitry Andric case ARM::t2B: 34d88c1a5aSDimitry Andric case ARM::t2Bcc: 35d88c1a5aSDimitry Andric case ARM::tBcc: 36d88c1a5aSDimitry Andric // optimizeThumb2JumpTables. 37d88c1a5aSDimitry Andric case ARM::t2BR_JT: 38*6ccc06f6SDimitry Andric case ARM::tBR_JTr: 39d88c1a5aSDimitry Andric return true; 40d88c1a5aSDimitry Andric } 41d88c1a5aSDimitry Andric return false; 42d88c1a5aSDimitry Andric } 43d88c1a5aSDimitry Andric computeBlockSize(MachineFunction * MF,MachineBasicBlock * MBB,BasicBlockInfo & BBI)44d88c1a5aSDimitry Andricvoid computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB, 45d88c1a5aSDimitry Andric BasicBlockInfo &BBI) { 46d88c1a5aSDimitry Andric const ARMBaseInstrInfo *TII = 47d88c1a5aSDimitry Andric static_cast<const ARMBaseInstrInfo *>(MF->getSubtarget().getInstrInfo()); 48d88c1a5aSDimitry Andric bool isThumb = MF->getInfo<ARMFunctionInfo>()->isThumbFunction(); 49d88c1a5aSDimitry Andric BBI.Size = 0; 50d88c1a5aSDimitry Andric BBI.Unalign = 0; 51d88c1a5aSDimitry Andric BBI.PostAlign = 0; 52d88c1a5aSDimitry Andric 53d88c1a5aSDimitry Andric for (MachineInstr &I : *MBB) { 54d88c1a5aSDimitry Andric BBI.Size += TII->getInstSizeInBytes(I); 55d88c1a5aSDimitry Andric // For inline asm, getInstSizeInBytes returns a conservative estimate. 56d88c1a5aSDimitry Andric // The actual size may be smaller, but still a multiple of the instr size. 57d88c1a5aSDimitry Andric if (I.isInlineAsm()) 58d88c1a5aSDimitry Andric BBI.Unalign = isThumb ? 1 : 2; 59d88c1a5aSDimitry Andric // Also consider instructions that may be shrunk later. 60d88c1a5aSDimitry Andric else if (isThumb && mayOptimizeThumb2Instruction(&I)) 61d88c1a5aSDimitry Andric BBI.Unalign = 1; 62d88c1a5aSDimitry Andric } 63d88c1a5aSDimitry Andric 64d88c1a5aSDimitry Andric // tBR_JTr contains a .align 2 directive. 65d88c1a5aSDimitry Andric if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) { 66d88c1a5aSDimitry Andric BBI.PostAlign = 2; 67d88c1a5aSDimitry Andric MBB->getParent()->ensureAlignment(2); 68d88c1a5aSDimitry Andric } 69d88c1a5aSDimitry Andric } 70d88c1a5aSDimitry Andric computeAllBlockSizes(MachineFunction * MF)71d88c1a5aSDimitry Andricstd::vector<BasicBlockInfo> computeAllBlockSizes(MachineFunction *MF) { 72d88c1a5aSDimitry Andric std::vector<BasicBlockInfo> BBInfo; 73d88c1a5aSDimitry Andric BBInfo.resize(MF->getNumBlockIDs()); 74d88c1a5aSDimitry Andric 75d88c1a5aSDimitry Andric for (MachineBasicBlock &MBB : *MF) 76d88c1a5aSDimitry Andric computeBlockSize(MF, &MBB, BBInfo[MBB.getNumber()]); 77d88c1a5aSDimitry Andric 78d88c1a5aSDimitry Andric return BBInfo; 79d88c1a5aSDimitry Andric } 80d88c1a5aSDimitry Andric 817a7e6055SDimitry Andric } // end namespace llvm 82