diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /lib/Target/ARM/ARMComputeBlockSize.cpp | |
parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) | |
download | src-b915e9e0fc85ba6f398b3fab0db6a81a8913af94.tar.gz src-b915e9e0fc85ba6f398b3fab0db6a81a8913af94.zip |
Vendor import of llvm trunk r290819:vendor/llvm/llvm-trunk-r290819
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=311116
svn path=/vendor/llvm/llvm-trunk-r290819/; revision=311117; tag=vendor/llvm/llvm-trunk-r290819
Diffstat (limited to 'lib/Target/ARM/ARMComputeBlockSize.cpp')
-rw-r--r-- | lib/Target/ARM/ARMComputeBlockSize.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMComputeBlockSize.cpp b/lib/Target/ARM/ARMComputeBlockSize.cpp new file mode 100644 index 000000000000..64f187d17e64 --- /dev/null +++ b/lib/Target/ARM/ARMComputeBlockSize.cpp @@ -0,0 +1,72 @@ +//===--- 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 |