Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/ARM/ARMBasicBlockInfo.cpp
35269 views
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"
12
#include "ARMMachineFunctionInfo.h"
13
#include "llvm/CodeGen/MachineBasicBlock.h"
14
#include "llvm/CodeGen/MachineFunction.h"
15
#include "llvm/CodeGen/MachineInstr.h"
16
#include "llvm/CodeGen/TargetSubtargetInfo.h"
17
#include "llvm/IR/GlobalVariable.h"
18
#include "llvm/Support/Debug.h"
19
20
#define DEBUG_TYPE "arm-bb-utils"
21
22
using namespace llvm;
23
24
namespace llvm {
25
26
// mayOptimizeThumb2Instruction - Returns true if optimizeThumb2Instructions
27
// below may shrink MI.
28
static bool
29
mayOptimizeThumb2Instruction(const MachineInstr *MI) {
30
switch(MI->getOpcode()) {
31
// optimizeThumb2Instructions.
32
case ARM::t2LEApcrel:
33
case ARM::t2LDRpci:
34
// optimizeThumb2Branches.
35
case ARM::t2B:
36
case ARM::t2Bcc:
37
case ARM::tBcc:
38
// optimizeThumb2JumpTables.
39
case ARM::t2BR_JT:
40
case ARM::tBR_JTr:
41
return true;
42
}
43
return false;
44
}
45
46
void ARMBasicBlockUtils::computeBlockSize(MachineBasicBlock *MBB) {
47
LLVM_DEBUG(dbgs() << "computeBlockSize: " << MBB->getName() << "\n");
48
BasicBlockInfo &BBI = BBInfo[MBB->getNumber()];
49
BBI.Size = 0;
50
BBI.Unalign = 0;
51
BBI.PostAlign = Align(1);
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 = Align(4);
67
MBB->getParent()->ensureAlignment(Align(4));
68
}
69
}
70
71
/// getOffsetOf - Return the current offset of the specified machine instruction
72
/// from the start of the function. This offset changes as stuff is moved
73
/// around inside the function.
74
unsigned ARMBasicBlockUtils::getOffsetOf(MachineInstr *MI) const {
75
const MachineBasicBlock *MBB = MI->getParent();
76
77
// The offset is composed of two things: the sum of the sizes of all MBB's
78
// before this instruction's block, and the offset from the start of the block
79
// it is in.
80
unsigned Offset = BBInfo[MBB->getNumber()].Offset;
81
82
// Sum instructions before MI in MBB.
83
for (MachineBasicBlock::const_iterator I = MBB->begin(); &*I != MI; ++I) {
84
assert(I != MBB->end() && "Didn't find MI in its own basic block?");
85
Offset += TII->getInstSizeInBytes(*I);
86
}
87
return Offset;
88
}
89
90
/// isBBInRange - Returns true if the distance between specific MI and
91
/// specific BB can fit in MI's displacement field.
92
bool ARMBasicBlockUtils::isBBInRange(MachineInstr *MI,
93
MachineBasicBlock *DestBB,
94
unsigned MaxDisp) const {
95
unsigned PCAdj = isThumb ? 4 : 8;
96
unsigned BrOffset = getOffsetOf(MI) + PCAdj;
97
unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
98
99
LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB)
100
<< " from " << printMBBReference(*MI->getParent())
101
<< " max delta=" << MaxDisp << " from " << getOffsetOf(MI)
102
<< " to " << DestOffset << " offset "
103
<< int(DestOffset - BrOffset) << "\t" << *MI);
104
105
if (BrOffset <= DestOffset) {
106
// Branch before the Dest.
107
if (DestOffset-BrOffset <= MaxDisp)
108
return true;
109
} else {
110
if (BrOffset-DestOffset <= MaxDisp)
111
return true;
112
}
113
return false;
114
}
115
116
void ARMBasicBlockUtils::adjustBBOffsetsAfter(MachineBasicBlock *BB) {
117
assert(BB->getParent() == &MF &&
118
"Basic block is not a child of the current function.\n");
119
120
unsigned BBNum = BB->getNumber();
121
LLVM_DEBUG(dbgs() << "Adjust block:\n"
122
<< " - name: " << BB->getName() << "\n"
123
<< " - number: " << BB->getNumber() << "\n"
124
<< " - function: " << MF.getName() << "\n"
125
<< " - blocks: " << MF.getNumBlockIDs() << "\n");
126
127
for(unsigned i = BBNum + 1, e = MF.getNumBlockIDs(); i < e; ++i) {
128
// Get the offset and known bits at the end of the layout predecessor.
129
// Include the alignment of the current block.
130
const Align Align = MF.getBlockNumbered(i)->getAlignment();
131
const unsigned Offset = BBInfo[i - 1].postOffset(Align);
132
const unsigned KnownBits = BBInfo[i - 1].postKnownBits(Align);
133
134
// This is where block i begins. Stop if the offset is already correct,
135
// and we have updated 2 blocks. This is the maximum number of blocks
136
// changed before calling this function.
137
if (i > BBNum + 2 &&
138
BBInfo[i].Offset == Offset &&
139
BBInfo[i].KnownBits == KnownBits)
140
break;
141
142
BBInfo[i].Offset = Offset;
143
BBInfo[i].KnownBits = KnownBits;
144
}
145
}
146
147
} // end namespace llvm
148
149