1 //===--- ARMComputeBlockSize.cpp - Compute machine block sizes ------------===// 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 #include "ARM.h" 11 #include "ARMBaseInstrInfo.h" 12 #include "ARMBasicBlockInfo.h" 13 #include "ARMMachineFunctionInfo.h" 14 #include "llvm/CodeGen/MachineBasicBlock.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineInstr.h" 17 #include "llvm/CodeGen/TargetSubtargetInfo.h" 18 #include <vector> 19 20 using namespace llvm; 21 22 namespace llvm { 23 24 // mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions 25 // below may shrink MI. 26 static bool mayOptimizeThumb2Instruction(const MachineInstr * MI)27mayOptimizeThumb2Instruction(const MachineInstr *MI) { 28 switch(MI->getOpcode()) { 29 // optimizeThumb2Instructions. 30 case ARM::t2LEApcrel: 31 case ARM::t2LDRpci: 32 // optimizeThumb2Branches. 33 case ARM::t2B: 34 case ARM::t2Bcc: 35 case ARM::tBcc: 36 // optimizeThumb2JumpTables. 37 case ARM::t2BR_JT: 38 case ARM::tBR_JTr: 39 return true; 40 } 41 return false; 42 } 43 computeBlockSize(MachineFunction * MF,MachineBasicBlock * MBB,BasicBlockInfo & BBI)44void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB, 45 BasicBlockInfo &BBI) { 46 const ARMBaseInstrInfo *TII = 47 static_cast<const ARMBaseInstrInfo *>(MF->getSubtarget().getInstrInfo()); 48 bool isThumb = MF->getInfo<ARMFunctionInfo>()->isThumbFunction(); 49 BBI.Size = 0; 50 BBI.Unalign = 0; 51 BBI.PostAlign = 0; 52 53 for (MachineInstr &I : *MBB) { 54 BBI.Size += TII->getInstSizeInBytes(I); 55 // For inline asm, getInstSizeInBytes returns a conservative estimate. 56 // The actual size may be smaller, but still a multiple of the instr size. 57 if (I.isInlineAsm()) 58 BBI.Unalign = isThumb ? 1 : 2; 59 // Also consider instructions that may be shrunk later. 60 else if (isThumb && mayOptimizeThumb2Instruction(&I)) 61 BBI.Unalign = 1; 62 } 63 64 // tBR_JTr contains a .align 2 directive. 65 if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) { 66 BBI.PostAlign = 2; 67 MBB->getParent()->ensureAlignment(2); 68 } 69 } 70 computeAllBlockSizes(MachineFunction * MF)71std::vector<BasicBlockInfo> computeAllBlockSizes(MachineFunction *MF) { 72 std::vector<BasicBlockInfo> BBInfo; 73 BBInfo.resize(MF->getNumBlockIDs()); 74 75 for (MachineBasicBlock &MBB : *MF) 76 computeBlockSize(MF, &MBB, BBInfo[MBB.getNumber()]); 77 78 return BBInfo; 79 } 80 81 } // end namespace llvm 82