|  | //===--- ARMComputeBlockSize.cpp - Compute machine block sizes ------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "ARM.h" | 
|  | #include "ARMBasicBlockInfo.h" | 
|  | using namespace llvm; | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | // mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions | 
|  | // below may shrink MI. | 
|  | static bool | 
|  | mayOptimizeThumb2Instruction(const MachineInstr *MI) { | 
|  | switch(MI->getOpcode()) { | 
|  | // optimizeThumb2Instructions. | 
|  | case ARM::t2LEApcrel: | 
|  | case ARM::t2LDRpci: | 
|  | // optimizeThumb2Branches. | 
|  | case ARM::t2B: | 
|  | case ARM::t2Bcc: | 
|  | case ARM::tBcc: | 
|  | // optimizeThumb2JumpTables. | 
|  | case ARM::t2BR_JT: | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB, | 
|  | BasicBlockInfo &BBI) { | 
|  | const ARMBaseInstrInfo *TII = | 
|  | static_cast<const ARMBaseInstrInfo *>(MF->getSubtarget().getInstrInfo()); | 
|  | bool isThumb = MF->getInfo<ARMFunctionInfo>()->isThumbFunction(); | 
|  | BBI.Size = 0; | 
|  | BBI.Unalign = 0; | 
|  | BBI.PostAlign = 0; | 
|  |  | 
|  | for (MachineInstr &I : *MBB) { | 
|  | BBI.Size += TII->getInstSizeInBytes(I); | 
|  | // For inline asm, getInstSizeInBytes returns a conservative estimate. | 
|  | // The actual size may be smaller, but still a multiple of the instr size. | 
|  | if (I.isInlineAsm()) | 
|  | BBI.Unalign = isThumb ? 1 : 2; | 
|  | // Also consider instructions that may be shrunk later. | 
|  | else if (isThumb && mayOptimizeThumb2Instruction(&I)) | 
|  | BBI.Unalign = 1; | 
|  | } | 
|  |  | 
|  | // tBR_JTr contains a .align 2 directive. | 
|  | if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) { | 
|  | BBI.PostAlign = 2; | 
|  | MBB->getParent()->ensureAlignment(2); | 
|  | } | 
|  | } | 
|  |  | 
|  | std::vector<BasicBlockInfo> computeAllBlockSizes(MachineFunction *MF) { | 
|  | std::vector<BasicBlockInfo> BBInfo; | 
|  | BBInfo.resize(MF->getNumBlockIDs()); | 
|  |  | 
|  | for (MachineBasicBlock &MBB : *MF) | 
|  | computeBlockSize(MF, &MBB, BBInfo[MBB.getNumber()]); | 
|  |  | 
|  | return BBInfo; | 
|  | } | 
|  |  | 
|  | } // end namespace |