]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMComputeBlockSize.cpp
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
[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 "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
27 mayOptimizeThumb2Instruction(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
44 void 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
71 std::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