LLVM 18.0.0git
ARMBasicBlockInfo.cpp
Go to the documentation of this file.
1//===--- ARMBasicBlockInfo.cpp - Utilities for block sizes ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ARMBasicBlockInfo.h"
10#include "ARM.h"
11#include "ARMBaseInstrInfo.h"
18#include "llvm/Support/Debug.h"
19#include <vector>
20
21#define DEBUG_TYPE "arm-bb-utils"
22
23using namespace llvm;
24
25namespace llvm {
26
27// mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions
28// below may shrink MI.
29static bool
31 switch(MI->getOpcode()) {
32 // optimizeThumb2Instructions.
33 case ARM::t2LEApcrel:
34 case ARM::t2LDRpci:
35 // optimizeThumb2Branches.
36 case ARM::t2B:
37 case ARM::t2Bcc:
38 case ARM::tBcc:
39 // optimizeThumb2JumpTables.
40 case ARM::t2BR_JT:
41 case ARM::tBR_JTr:
42 return true;
43 }
44 return false;
45}
46
48 LLVM_DEBUG(dbgs() << "computeBlockSize: " << MBB->getName() << "\n");
49 BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
50 BBI.Size = 0;
51 BBI.Unalign = 0;
52 BBI.PostAlign = Align(1);
53
54 for (MachineInstr &I : *MBB) {
55 BBI.Size += TII->getInstSizeInBytes(I);
56 // For inline asm, getInstSizeInBytes returns a conservative estimate.
57 // The actual size may be smaller, but still a multiple of the instr size.
58 if (I.isInlineAsm())
59 BBI.Unalign = isThumb ? 1 : 2;
60 // Also consider instructions that may be shrunk later.
61 else if (isThumb && mayOptimizeThumb2Instruction(&I))
62 BBI.Unalign = 1;
63 }
64
65 // tBR_JTr contains a .align 2 directive.
66 if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) {
67 BBI.PostAlign = Align(4);
69 }
70}
71
72/// getOffsetOf - Return the current offset of the specified machine instruction
73/// from the start of the function. This offset changes as stuff is moved
74/// around inside the function.
76 const MachineBasicBlock *MBB = MI->getParent();
77
78 // The offset is composed of two things: the sum of the sizes of all MBB's
79 // before this instruction's block, and the offset from the start of the block
80 // it is in.
81 unsigned Offset = BBInfo[MBB->getNumber()].Offset;
82
83 // Sum instructions before MI in MBB.
84 for (MachineBasicBlock::const_iterator I = MBB->begin(); &*I != MI; ++I) {
85 assert(I != MBB->end() && "Didn't find MI in its own basic block?");
86 Offset += TII->getInstSizeInBytes(*I);
87 }
88 return Offset;
89}
90
91/// isBBInRange - Returns true if the distance between specific MI and
92/// specific BB can fit in MI's displacement field.
94 MachineBasicBlock *DestBB,
95 unsigned MaxDisp) const {
96 unsigned PCAdj = isThumb ? 4 : 8;
97 unsigned BrOffset = getOffsetOf(MI) + PCAdj;
98 unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
99
100 LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
101 << " from " << printMBBReference(*MI->getParent())
102 << " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
103 << " to " << DestOffset << " offset "
104 << int(DestOffset - BrOffset) << "\t" << *MI);
105
106 if (BrOffset <= DestOffset) {
107 // Branch before the Dest.
108 if (DestOffset-BrOffset <= MaxDisp)
109 return true;
110 } else {
111 if (BrOffset-DestOffset <= MaxDisp)
112 return true;
113 }
114 return false;
115}
116
118 assert(BB->getParent() == &MF &&
119 "Basic block is not a child of the current function.\n");
120
121 unsigned BBNum = BB->getNumber();
122 LLVM_DEBUG(dbgs() << "Adjust block:\n"
123 << " - name: " << BB->getName() << "\n"
124 << " - number: " << BB->getNumber() << "\n"
125 << " - function: " << MF.getName() << "\n"
126 << " - blocks: " << MF.getNumBlockIDs() << "\n");
127
128 for(unsigned i = BBNum + 1, e = MF.getNumBlockIDs(); i < e; ++i) {
129 // Get the offset and known bits at the end of the layout predecessor.
130 // Include the alignment of the current block.
131 const Align Align = MF.getBlockNumbered(i)->getAlignment();
132 const unsigned Offset = BBInfo[i - 1].postOffset(Align);
133 const unsigned KnownBits = BBInfo[i - 1].postKnownBits(Align);
134
135 // This is where block i begins. Stop if the offset is already correct,
136 // and we have updated 2 blocks. This is the maximum number of blocks
137 // changed before calling this function.
138 if (i > BBNum + 2 &&
139 BBInfo[i].Offset == Offset &&
140 BBInfo[i].KnownBits == KnownBits)
141 break;
142
143 BBInfo[i].Offset = Offset;
144 BBInfo[i].KnownBits = KnownBits;
145 }
146}
147
148} // end namespace llvm
MachineBasicBlock & MBB
#define LLVM_DEBUG(X)
Definition: Debug.h:101
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Returns the size of the specified MachineInstr.
bool isBBInRange(MachineInstr *MI, MachineBasicBlock *DestBB, unsigned MaxDisp) const
isBBInRange - Returns true if the distance between specific MI and specific BB can fit in MI's displa...
void adjustBBOffsetsAfter(MachineBasicBlock *MBB)
void computeBlockSize(MachineBasicBlock *MBB)
unsigned getOffsetOf(MachineInstr *MI) const
getOffsetOf - Return the current offset of the specified machine instruction from the start of the fu...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Align getAlignment() const
Return alignment of the basic block.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
void ensureAlignment(Align A)
ensureAlignment - Make sure the function is at least A bytes aligned.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
Representation of each machine instruction.
Definition: MachineInstr.h:68
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:543
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
static bool mayOptimizeThumb2Instruction(const MachineInstr *MI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
BasicBlockInfo - Information about the offset and size of a single basic block.
unsigned Size
Size - Size of the basic block in bytes.
Align PostAlign
PostAlign - When > 1, the block terminator contains a .align directive, so the end of the block is al...
uint8_t Unalign
Unalign - When non-zero, the block contains instructions (inline asm) of unknown size.