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