2016-07-22 16:39:12 +08:00
|
|
|
//===--- 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"
|
2017-01-27 07:40:06 +08:00
|
|
|
#include "ARMBaseInstrInfo.h"
|
2016-07-22 16:39:12 +08:00
|
|
|
#include "ARMBasicBlockInfo.h"
|
2017-01-27 07:40:06 +08:00
|
|
|
#include "ARMMachineFunctionInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
2017-01-27 07:40:06 +08:00
|
|
|
#include <vector>
|
|
|
|
|
2016-07-22 16:39:12 +08:00
|
|
|
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:
|
2018-03-24 01:53:27 +08:00
|
|
|
case ARM::tBR_JTr:
|
2016-07-22 16:39:12 +08:00
|
|
|
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) {
|
2016-07-29 00:32:22 +08:00
|
|
|
BBI.Size += TII->getInstSizeInBytes(I);
|
|
|
|
// For inline asm, getInstSizeInBytes returns a conservative estimate.
|
2016-07-22 16:39:12 +08:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2017-01-27 07:40:06 +08:00
|
|
|
} // end namespace llvm
|