Skip to content

Commit 5c0ef83

Browse files
author
Sjoerd Meijer
committed
This refactoring of ARM machine block size computation creates two utility
functions so that the size computation is available not only in ConstantIslands but in other passes as well. Differential Revision: https://reviews.llvm.org/D22640 llvm-svn: 276399
1 parent a31c91b commit 5c0ef83

File tree

5 files changed

+193
-123
lines changed

5 files changed

+193
-123
lines changed

Diff for: llvm/lib/Target/ARM/ARM.h

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_LIB_TARGET_ARM_ARM_H
1717

1818
#include "llvm/Support/CodeGen.h"
19+
#include "ARMBasicBlockInfo.h"
1920
#include <functional>
2021

2122
namespace llvm {
@@ -46,6 +47,10 @@ FunctionPass *createThumb2SizeReductionPass(
4647
void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
4748
ARMAsmPrinter &AP);
4849

50+
void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB,
51+
BasicBlockInfo &BBI);
52+
std::vector<BasicBlockInfo> computeAllBlockSizes(MachineFunction *MF);
53+
4954
void initializeARMLoadStoreOptPass(PassRegistry &);
5055
void initializeARMPreAllocLoadStoreOptPass(PassRegistry &);
5156

Diff for: llvm/lib/Target/ARM/ARMBasicBlockInfo.h

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//===-- ARMBasicBlockInfo.h - Basic Block Information -----------*- C++ -*-===//
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+
// Utility functions and data structure for computing block size.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_LIB_TARGET_ARM_ARMBASICBLOCKINFO_H
15+
#define LLVM_LIB_TARGET_ARM_ARMBASICBLOCKINFO_H
16+
17+
#include "ARM.h"
18+
#include "ARMMachineFunctionInfo.h"
19+
using namespace llvm;
20+
21+
namespace llvm {
22+
23+
/// UnknownPadding - Return the worst case padding that could result from
24+
/// unknown offset bits. This does not include alignment padding caused by
25+
/// known offset bits.
26+
///
27+
/// @param LogAlign log2(alignment)
28+
/// @param KnownBits Number of known low offset bits.
29+
inline unsigned UnknownPadding(unsigned LogAlign, unsigned KnownBits) {
30+
if (KnownBits < LogAlign)
31+
return (1u << LogAlign) - (1u << KnownBits);
32+
return 0;
33+
}
34+
35+
/// BasicBlockInfo - Information about the offset and size of a single
36+
/// basic block.
37+
struct BasicBlockInfo {
38+
/// Offset - Distance from the beginning of the function to the beginning
39+
/// of this basic block.
40+
///
41+
/// Offsets are computed assuming worst case padding before an aligned
42+
/// block. This means that subtracting basic block offsets always gives a
43+
/// conservative estimate of the real distance which may be smaller.
44+
///
45+
/// Because worst case padding is used, the computed offset of an aligned
46+
/// block may not actually be aligned.
47+
unsigned Offset;
48+
49+
/// Size - Size of the basic block in bytes. If the block contains
50+
/// inline assembly, this is a worst case estimate.
51+
///
52+
/// The size does not include any alignment padding whether from the
53+
/// beginning of the block, or from an aligned jump table at the end.
54+
unsigned Size;
55+
56+
/// KnownBits - The number of low bits in Offset that are known to be
57+
/// exact. The remaining bits of Offset are an upper bound.
58+
uint8_t KnownBits;
59+
60+
/// Unalign - When non-zero, the block contains instructions (inline asm)
61+
/// of unknown size. The real size may be smaller than Size bytes by a
62+
/// multiple of 1 << Unalign.
63+
uint8_t Unalign;
64+
65+
/// PostAlign - When non-zero, the block terminator contains a .align
66+
/// directive, so the end of the block is aligned to 1 << PostAlign
67+
/// bytes.
68+
uint8_t PostAlign;
69+
70+
BasicBlockInfo() : Offset(0), Size(0), KnownBits(0), Unalign(0),
71+
PostAlign(0) {}
72+
73+
/// Compute the number of known offset bits internally to this block.
74+
/// This number should be used to predict worst case padding when
75+
/// splitting the block.
76+
unsigned internalKnownBits() const {
77+
unsigned Bits = Unalign ? Unalign : KnownBits;
78+
// If the block size isn't a multiple of the known bits, assume the
79+
// worst case padding.
80+
if (Size & ((1u << Bits) - 1))
81+
Bits = countTrailingZeros(Size);
82+
return Bits;
83+
}
84+
85+
/// Compute the offset immediately following this block. If LogAlign is
86+
/// specified, return the offset the successor block will get if it has
87+
/// this alignment.
88+
unsigned postOffset(unsigned LogAlign = 0) const {
89+
unsigned PO = Offset + Size;
90+
unsigned LA = std::max(unsigned(PostAlign), LogAlign);
91+
if (!LA)
92+
return PO;
93+
// Add alignment padding from the terminator.
94+
return PO + UnknownPadding(LA, internalKnownBits());
95+
}
96+
97+
/// Compute the number of known low bits of postOffset. If this block
98+
/// contains inline asm, the number of known bits drops to the
99+
/// instruction alignment. An aligned terminator may increase the number
100+
/// of know bits.
101+
/// If LogAlign is given, also consider the alignment of the next block.
102+
unsigned postKnownBits(unsigned LogAlign = 0) const {
103+
return std::max(std::max(unsigned(PostAlign), LogAlign),
104+
internalKnownBits());
105+
}
106+
};
107+
108+
} // end namespace llvm
109+
110+
#endif

Diff for: llvm/lib/Target/ARM/ARMComputeBlockSize.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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

Diff for: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp

+5-123
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//===----------------------------------------------------------------------===//
1515

1616
#include "ARM.h"
17+
#include "ARMBasicBlockInfo.h"
1718
#include "ARMMachineFunctionInfo.h"
1819
#include "MCTargetDesc/ARMAddressingModes.h"
1920
#include "Thumb2InstrInfo.h"
@@ -57,19 +58,6 @@ static cl::opt<unsigned>
5758
CPMaxIteration("arm-constant-island-max-iteration", cl::Hidden, cl::init(30),
5859
cl::desc("The max number of iteration for converge"));
5960

60-
61-
/// UnknownPadding - Return the worst case padding that could result from
62-
/// unknown offset bits. This does not include alignment padding caused by
63-
/// known offset bits.
64-
///
65-
/// @param LogAlign log2(alignment)
66-
/// @param KnownBits Number of known low offset bits.
67-
static inline unsigned UnknownPadding(unsigned LogAlign, unsigned KnownBits) {
68-
if (KnownBits < LogAlign)
69-
return (1u << LogAlign) - (1u << KnownBits);
70-
return 0;
71-
}
72-
7361
namespace {
7462
/// ARMConstantIslands - Due to limited PC-relative displacements, ARM
7563
/// requires constant pool entries to be scattered among the instructions
@@ -83,78 +71,6 @@ namespace {
8371
/// CPE - A constant pool entry that has been placed somewhere, which
8472
/// tracks a list of users.
8573
class ARMConstantIslands : public MachineFunctionPass {
86-
/// BasicBlockInfo - Information about the offset and size of a single
87-
/// basic block.
88-
struct BasicBlockInfo {
89-
/// Offset - Distance from the beginning of the function to the beginning
90-
/// of this basic block.
91-
///
92-
/// Offsets are computed assuming worst case padding before an aligned
93-
/// block. This means that subtracting basic block offsets always gives a
94-
/// conservative estimate of the real distance which may be smaller.
95-
///
96-
/// Because worst case padding is used, the computed offset of an aligned
97-
/// block may not actually be aligned.
98-
unsigned Offset;
99-
100-
/// Size - Size of the basic block in bytes. If the block contains
101-
/// inline assembly, this is a worst case estimate.
102-
///
103-
/// The size does not include any alignment padding whether from the
104-
/// beginning of the block, or from an aligned jump table at the end.
105-
unsigned Size;
106-
107-
/// KnownBits - The number of low bits in Offset that are known to be
108-
/// exact. The remaining bits of Offset are an upper bound.
109-
uint8_t KnownBits;
110-
111-
/// Unalign - When non-zero, the block contains instructions (inline asm)
112-
/// of unknown size. The real size may be smaller than Size bytes by a
113-
/// multiple of 1 << Unalign.
114-
uint8_t Unalign;
115-
116-
/// PostAlign - When non-zero, the block terminator contains a .align
117-
/// directive, so the end of the block is aligned to 1 << PostAlign
118-
/// bytes.
119-
uint8_t PostAlign;
120-
121-
BasicBlockInfo() : Offset(0), Size(0), KnownBits(0), Unalign(0),
122-
PostAlign(0) {}
123-
124-
/// Compute the number of known offset bits internally to this block.
125-
/// This number should be used to predict worst case padding when
126-
/// splitting the block.
127-
unsigned internalKnownBits() const {
128-
unsigned Bits = Unalign ? Unalign : KnownBits;
129-
// If the block size isn't a multiple of the known bits, assume the
130-
// worst case padding.
131-
if (Size & ((1u << Bits) - 1))
132-
Bits = countTrailingZeros(Size);
133-
return Bits;
134-
}
135-
136-
/// Compute the offset immediately following this block. If LogAlign is
137-
/// specified, return the offset the successor block will get if it has
138-
/// this alignment.
139-
unsigned postOffset(unsigned LogAlign = 0) const {
140-
unsigned PO = Offset + Size;
141-
unsigned LA = std::max(unsigned(PostAlign), LogAlign);
142-
if (!LA)
143-
return PO;
144-
// Add alignment padding from the terminator.
145-
return PO + UnknownPadding(LA, internalKnownBits());
146-
}
147-
148-
/// Compute the number of known low bits of postOffset. If this block
149-
/// contains inline asm, the number of known bits drops to the
150-
/// instruction alignment. An aligned terminator may increase the number
151-
/// of know bits.
152-
/// If LogAlign is given, also consider the alignment of the next block.
153-
unsigned postKnownBits(unsigned LogAlign = 0) const {
154-
return std::max(std::max(unsigned(PostAlign), LogAlign),
155-
internalKnownBits());
156-
}
157-
};
15874

15975
std::vector<BasicBlockInfo> BBInfo;
16076

@@ -330,7 +246,6 @@ namespace {
330246
MachineBasicBlock *adjustJTTargetBlockForward(MachineBasicBlock *BB,
331247
MachineBasicBlock *JTBB);
332248

333-
void computeBlockSize(MachineBasicBlock *MBB);
334249
unsigned getOffsetOf(MachineInstr *MI) const;
335250
unsigned getUserOffset(CPUser&) const;
336251
void dumpBBs();
@@ -734,15 +649,8 @@ void ARMConstantIslands::scanFunctionJumpTables() {
734649
/// and finding all of the constant pool users.
735650
void ARMConstantIslands::
736651
initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
737-
BBInfo.clear();
738-
BBInfo.resize(MF->getNumBlockIDs());
739652

740-
// First thing, compute the size of all basic blocks, and see if the function
741-
// has any inline assembly in it. If so, we have to be conservative about
742-
// alignment assumptions, as we don't know for sure the size of any
743-
// instructions in the inline assembly.
744-
for (MachineBasicBlock &MBB : *MF)
745-
computeBlockSize(&MBB);
653+
BBInfo = computeAllBlockSizes(MF);
746654

747655
// The known bits of the entry block offset are determined by the function
748656
// alignment.
@@ -901,32 +809,6 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
901809
}
902810
}
903811

904-
/// computeBlockSize - Compute the size and some alignment information for MBB.
905-
/// This function updates BBInfo directly.
906-
void ARMConstantIslands::computeBlockSize(MachineBasicBlock *MBB) {
907-
BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
908-
BBI.Size = 0;
909-
BBI.Unalign = 0;
910-
BBI.PostAlign = 0;
911-
912-
for (MachineInstr &I : *MBB) {
913-
BBI.Size += TII->GetInstSizeInBytes(I);
914-
// For inline asm, GetInstSizeInBytes returns a conservative estimate.
915-
// The actual size may be smaller, but still a multiple of the instr size.
916-
if (I.isInlineAsm())
917-
BBI.Unalign = isThumb ? 1 : 2;
918-
// Also consider instructions that may be shrunk later.
919-
else if (isThumb && mayOptimizeThumb2Instruction(&I))
920-
BBI.Unalign = 1;
921-
}
922-
923-
// tBR_JTr contains a .align 2 directive.
924-
if (!MBB->empty() && MBB->back().getOpcode() == ARM::tBR_JTr) {
925-
BBI.PostAlign = 2;
926-
MBB->getParent()->ensureAlignment(2);
927-
}
928-
}
929-
930812
/// getOffsetOf - Return the current offset of the specified machine instruction
931813
/// from the start of the function. This offset changes as stuff is moved
932814
/// around inside the function.
@@ -1034,11 +916,11 @@ MachineBasicBlock *ARMConstantIslands::splitBlockBeforeInstr(MachineInstr *MI) {
1034916
// the new jump we added. (It should be possible to do this without
1035917
// recounting everything, but it's very confusing, and this is rarely
1036918
// executed.)
1037-
computeBlockSize(OrigBB);
919+
computeBlockSize(MF, OrigBB, BBInfo[OrigBB->getNumber()]);
1038920

1039921
// Figure out how large the NewMBB is. As the second half of the original
1040922
// block, it may contain a tablejump.
1041-
computeBlockSize(NewBB);
923+
computeBlockSize(MF, NewBB, BBInfo[NewBB->getNumber()]);
1042924

1043925
// All BBOffsets following these blocks must be modified.
1044926
adjustBBOffsetsAfter(OrigBB);
@@ -1400,7 +1282,7 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
14001282
unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
14011283
ImmBranches.push_back(ImmBranch(&UserMBB->back(),
14021284
MaxDisp, false, UncondBr));
1403-
computeBlockSize(UserMBB);
1285+
computeBlockSize(MF, UserMBB, BBInfo[UserMBB->getNumber()]);
14041286
adjustBBOffsetsAfter(UserMBB);
14051287
return;
14061288
}

Diff for: llvm/lib/Target/ARM/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ add_llvm_target(ARMCodeGen
4444
Thumb2ITBlockPass.cpp
4545
Thumb2InstrInfo.cpp
4646
Thumb2SizeReduction.cpp
47+
ARMComputeBlockSize.cpp
4748
)
4849

4950
add_subdirectory(TargetInfo)

0 commit comments

Comments
 (0)