Skip to content

Commit 6304e38

Browse files
author
Fabian Parzefall
committed
Revert "[BOLT] Track fragment info for all split fragments"
This reverts commit 7e25481.
1 parent 3ab00cf commit 6304e38

File tree

6 files changed

+159
-181
lines changed

6 files changed

+159
-181
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ class BinaryFunction {
232232
/// Size of the function in the output file.
233233
uint64_t OutputSize{0};
234234

235+
/// Offset in the file.
236+
uint64_t FileOffset{0};
237+
235238
/// Maximum size this function is allowed to have.
236239
uint64_t MaxSize{std::numeric_limits<uint64_t>::max()};
237240

@@ -342,6 +345,14 @@ class BinaryFunction {
342345
/// This attribute is only valid when hasCFG() == true.
343346
bool HasCanonicalCFG{true};
344347

348+
/// The address for the code for this function in codegen memory.
349+
/// Used for functions that are emitted in a dedicated section with a fixed
350+
/// address. E.g. for functions that are overwritten in-place.
351+
uint64_t ImageAddress{0};
352+
353+
/// The size of the code in memory.
354+
uint64_t ImageSize{0};
355+
345356
/// Name for the section this function code should reside in.
346357
std::string CodeSectionName;
347358

@@ -1049,9 +1060,7 @@ class BinaryFunction {
10491060
}
10501061

10511062
/// Return offset of the function body in the binary file.
1052-
uint64_t getFileOffset() const {
1053-
return getLayout().getMainFragment().getFileOffset();
1054-
}
1063+
uint64_t getFileOffset() const { return FileOffset; }
10551064

10561065
/// Return (original) byte size of the function.
10571066
uint64_t getSize() const { return Size; }
@@ -1689,7 +1698,7 @@ class BinaryFunction {
16891698
int64_t NewOffset);
16901699

16911700
BinaryFunction &setFileOffset(uint64_t Offset) {
1692-
getLayout().getMainFragment().setFileOffset(Offset);
1701+
FileOffset = Offset;
16931702
return *this;
16941703
}
16951704

@@ -1776,24 +1785,20 @@ class BinaryFunction {
17761785
uint16_t getMaxColdAlignmentBytes() const { return MaxColdAlignmentBytes; }
17771786

17781787
BinaryFunction &setImageAddress(uint64_t Address) {
1779-
getLayout().getMainFragment().setImageAddress(Address);
1788+
ImageAddress = Address;
17801789
return *this;
17811790
}
17821791

17831792
/// Return the address of this function' image in memory.
1784-
uint64_t getImageAddress() const {
1785-
return getLayout().getMainFragment().getImageAddress();
1786-
}
1793+
uint64_t getImageAddress() const { return ImageAddress; }
17871794

17881795
BinaryFunction &setImageSize(uint64_t Size) {
1789-
getLayout().getMainFragment().setImageSize(Size);
1796+
ImageSize = Size;
17901797
return *this;
17911798
}
17921799

17931800
/// Return the size of this function' image in memory.
1794-
uint64_t getImageSize() const {
1795-
return getLayout().getMainFragment().getImageSize();
1796-
}
1801+
uint64_t getImageSize() const { return ImageSize; }
17971802

17981803
/// Return true if the function is a secondary fragment of another function.
17991804
bool isFragment() const { return IsFragment; }
@@ -2297,6 +2302,33 @@ class BinaryFunction {
22972302
bool isAArch64Veneer() const;
22982303

22992304
virtual ~BinaryFunction();
2305+
2306+
/// Info for fragmented functions.
2307+
class FragmentInfo {
2308+
private:
2309+
uint64_t Address{0};
2310+
uint64_t ImageAddress{0};
2311+
uint64_t ImageSize{0};
2312+
uint64_t FileOffset{0};
2313+
2314+
public:
2315+
uint64_t getAddress() const { return Address; }
2316+
uint64_t getImageAddress() const { return ImageAddress; }
2317+
uint64_t getImageSize() const { return ImageSize; }
2318+
uint64_t getFileOffset() const { return FileOffset; }
2319+
2320+
void setAddress(uint64_t VAddress) { Address = VAddress; }
2321+
void setImageAddress(uint64_t Address) { ImageAddress = Address; }
2322+
void setImageSize(uint64_t Size) { ImageSize = Size; }
2323+
void setFileOffset(uint64_t Offset) { FileOffset = Offset; }
2324+
};
2325+
2326+
/// Cold fragment of the function.
2327+
FragmentInfo ColdFragment;
2328+
2329+
FragmentInfo &cold() { return ColdFragment; }
2330+
2331+
const FragmentInfo &cold() const { return ColdFragment; }
23002332
};
23012333

23022334
inline raw_ostream &operator<<(raw_ostream &OS,

bolt/include/bolt/Core/FunctionLayout.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,6 @@ class FunctionFragment {
8383
unsigned StartIndex;
8484
unsigned Size = 0;
8585

86-
/// Output address for the fragment.
87-
uint64_t Address = 0;
88-
89-
/// The address for the code for this fragment in codegen memory. Used for
90-
/// functions that are emitted in a dedicated section with a fixed address,
91-
/// e.g. for functions that are overwritten in-place.
92-
uint64_t ImageAddress = 0;
93-
94-
/// The size of the code in memory.
95-
uint64_t ImageSize = 0;
96-
97-
/// Offset in the file.
98-
uint64_t FileOffset = 0;
99-
10086
FunctionFragment(FunctionLayout &Layout, FragmentNum Num);
10187
FunctionFragment(const FunctionFragment &) = default;
10288
FunctionFragment(FunctionFragment &&) = default;
@@ -111,15 +97,6 @@ class FunctionFragment {
11197
}
11298
bool isSplitFragment() const { return !isMainFragment(); }
11399

114-
uint64_t getAddress() const { return Address; }
115-
void setAddress(uint64_t Value) { Address = Value; }
116-
uint64_t getImageAddress() const { return ImageAddress; }
117-
void setImageAddress(uint64_t Address) { ImageAddress = Address; }
118-
uint64_t getImageSize() const { return ImageSize; }
119-
void setImageSize(uint64_t Size) { ImageSize = Size; }
120-
uint64_t getFileOffset() const { return FileOffset; }
121-
void setFileOffset(uint64_t Offset) { FileOffset = Offset; }
122-
123100
unsigned size() const { return Size; };
124101
bool empty() const { return size() == 0; };
125102
iterator begin();

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -425,19 +425,19 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
425425
Sep = "\n ";
426426
}
427427
}
428-
OS << "\n Number : " << FunctionNumber;
429-
OS << "\n State : " << CurrentState;
430-
OS << "\n Address : 0x" << Twine::utohexstr(Address);
431-
OS << "\n Size : 0x" << Twine::utohexstr(Size);
432-
OS << "\n MaxSize : 0x" << Twine::utohexstr(MaxSize);
433-
OS << "\n Offset : 0x" << Twine::utohexstr(getFileOffset());
434-
OS << "\n Section : " << SectionName;
435-
OS << "\n Orc Section : " << getCodeSectionName();
436-
OS << "\n LSDA : 0x" << Twine::utohexstr(getLSDAAddress());
437-
OS << "\n IsSimple : " << IsSimple;
438-
OS << "\n IsMultiEntry: " << isMultiEntry();
439-
OS << "\n IsSplit : " << isSplit();
440-
OS << "\n BB Count : " << size();
428+
OS << "\n Number : " << FunctionNumber
429+
<< "\n State : " << CurrentState
430+
<< "\n Address : 0x" << Twine::utohexstr(Address)
431+
<< "\n Size : 0x" << Twine::utohexstr(Size)
432+
<< "\n MaxSize : 0x" << Twine::utohexstr(MaxSize)
433+
<< "\n Offset : 0x" << Twine::utohexstr(FileOffset)
434+
<< "\n Section : " << SectionName
435+
<< "\n Orc Section : " << getCodeSectionName()
436+
<< "\n LSDA : 0x" << Twine::utohexstr(getLSDAAddress())
437+
<< "\n IsSimple : " << IsSimple
438+
<< "\n IsMultiEntry: " << isMultiEntry()
439+
<< "\n IsSplit : " << isSplit()
440+
<< "\n BB Count : " << size();
441441

442442
if (HasFixedIndirectBranch)
443443
OS << "\n HasFixedIndirectBranch : true";
@@ -473,8 +473,8 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
473473
for (const BinaryBasicBlock *BB : Layout.blocks())
474474
OS << LS << BB->getName();
475475
}
476-
if (getImageAddress())
477-
OS << "\n Image : 0x" << Twine::utohexstr(getImageAddress());
476+
if (ImageAddress)
477+
OS << "\n Image : 0x" << Twine::utohexstr(ImageAddress);
478478
if (ExecutionCount != COUNT_NO_PROFILE) {
479479
OS << "\n Exec Count : " << ExecutionCount;
480480
OS << "\n Profile Acc : " << format("%.1f%%", ProfileMatchRatio * 100.0f);
@@ -4062,7 +4062,7 @@ void BinaryFunction::updateOutputValues(const MCAsmLayout &Layout) {
40624062
setOutputDataAddress(BaseAddress + DataOffset);
40634063
}
40644064
if (isSplit()) {
4065-
for (FunctionFragment &FF : getLayout().getSplitFragments()) {
4065+
for (const FunctionFragment &FF : getLayout().getSplitFragments()) {
40664066
ErrorOr<BinarySection &> ColdSection =
40674067
getCodeSection(FF.getFragmentNum());
40684068
// If fragment is empty, cold section might not exist
@@ -4084,8 +4084,8 @@ void BinaryFunction::updateOutputValues(const MCAsmLayout &Layout) {
40844084
const uint64_t ColdStartOffset =
40854085
Layout.getSymbolOffset(*ColdStartSymbol);
40864086
const uint64_t ColdEndOffset = Layout.getSymbolOffset(*ColdEndSymbol);
4087-
FF.setAddress(ColdBaseAddress + ColdStartOffset);
4088-
FF.setImageSize(ColdEndOffset - ColdStartOffset);
4087+
cold().setAddress(ColdBaseAddress + ColdStartOffset);
4088+
cold().setImageSize(ColdEndOffset - ColdStartOffset);
40894089
if (hasConstantIsland()) {
40904090
const uint64_t DataOffset =
40914091
Layout.getSymbolOffset(*getFunctionColdConstantIslandLabel());
@@ -4112,39 +4112,44 @@ void BinaryFunction::updateOutputValues(const MCAsmLayout &Layout) {
41124112
if (getLayout().block_empty())
41134113
return;
41144114

4115-
for (FunctionFragment &FF : getLayout().fragments()) {
4116-
if (FF.empty())
4117-
continue;
4115+
assert((getLayout().isHotColdSplit() ||
4116+
(cold().getAddress() == 0 && cold().getImageSize() == 0 &&
4117+
BC.HasRelocations)) &&
4118+
"Function must be split two ways or cold fragment must have no "
4119+
"address (only in relocation mode)");
41184120

4121+
BinaryBasicBlock *PrevBB = nullptr;
4122+
for (FunctionFragment &FF : getLayout().fragments()) {
41194123
const uint64_t FragmentBaseAddress =
41204124
getCodeSection(isSimple() ? FF.getFragmentNum() : FragmentNum::main())
41214125
->getOutputAddress();
4122-
4123-
BinaryBasicBlock *PrevBB = nullptr;
41244126
for (BinaryBasicBlock *const BB : FF) {
41254127
assert(BB->getLabel()->isDefined() && "symbol should be defined");
41264128
if (!BC.HasRelocations) {
4127-
if (BB->isSplit())
4128-
assert(FragmentBaseAddress == FF.getAddress());
4129-
else
4129+
if (BB->isSplit()) {
4130+
assert(FragmentBaseAddress == cold().getAddress());
4131+
} else {
41304132
assert(FragmentBaseAddress == getOutputAddress());
4133+
}
41314134
}
4132-
41334135
const uint64_t BBOffset = Layout.getSymbolOffset(*BB->getLabel());
41344136
const uint64_t BBAddress = FragmentBaseAddress + BBOffset;
41354137
BB->setOutputStartAddress(BBAddress);
41364138

4137-
if (PrevBB)
4138-
PrevBB->setOutputEndAddress(BBAddress);
4139+
if (PrevBB) {
4140+
uint64_t PrevBBEndAddress = BBAddress;
4141+
if (BB->isSplit() != PrevBB->isSplit())
4142+
PrevBBEndAddress = getOutputAddress() + getOutputSize();
4143+
PrevBB->setOutputEndAddress(PrevBBEndAddress);
4144+
}
41394145
PrevBB = BB;
41404146

41414147
BB->updateOutputValues(Layout);
41424148
}
4143-
4144-
PrevBB->setOutputEndAddress(PrevBB->isSplit()
4145-
? FF.getAddress() + FF.getImageSize()
4146-
: getOutputAddress() + getOutputSize());
41474149
}
4150+
PrevBB->setOutputEndAddress(PrevBB->isSplit()
4151+
? cold().getAddress() + cold().getImageSize()
4152+
: getOutputAddress() + getOutputSize());
41484153
}
41494154

41504155
DebugAddressRangesVector BinaryFunction::getOutputAddressRanges() const {
@@ -4160,9 +4165,8 @@ DebugAddressRangesVector BinaryFunction::getOutputAddressRanges() const {
41604165
getOutputAddress() + getOutputSize());
41614166
if (isSplit()) {
41624167
assert(isEmitted() && "split function should be emitted");
4163-
for (const FunctionFragment &FF : getLayout().getSplitFragments())
4164-
OutputRanges.emplace_back(FF.getAddress(),
4165-
FF.getAddress() + FF.getImageSize());
4168+
OutputRanges.emplace_back(cold().getAddress(),
4169+
cold().getAddress() + cold().getImageSize());
41664170
}
41674171

41684172
if (isSimple())

bolt/lib/Core/FunctionLayout.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,10 @@ bool FunctionLayout::update(const ArrayRef<BinaryBasicBlock *> NewLayout) {
204204

205205
void FunctionLayout::clear() {
206206
Blocks = BasicBlockListType();
207-
// If the binary does not have relocations and is not split, the function will
208-
// be written to the output stream at its original file offset (see
209-
// `RewriteInstance::rewriteFile`). Hence, when the layout is cleared, retain
210-
// the main fragment, so that this information is not lost.
211-
std::for_each(Fragments.begin() + 1, Fragments.end(),
212-
[](FunctionFragment *const FF) { delete FF; });
213-
Fragments = FragmentListType{Fragments.front()};
214-
getMainFragment().Size = 0;
207+
for (FunctionFragment *const FF : Fragments)
208+
delete FF;
209+
Fragments = FragmentListType();
210+
addFragment();
215211
}
216212

217213
const BinaryBasicBlock *

bolt/lib/Profile/BoltAddressTranslation.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,29 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
7373
LLVM_DEBUG(dbgs() << "Function name: " << Function.getPrintName() << "\n");
7474
LLVM_DEBUG(dbgs() << " Address reference: 0x"
7575
<< Twine::utohexstr(Function.getOutputAddress()) << "\n");
76-
7776
MapTy Map;
78-
for (const BinaryBasicBlock *const BB :
79-
Function.getLayout().getMainFragment())
77+
const bool IsSplit = Function.isSplit();
78+
for (const BinaryBasicBlock *const BB : Function.getLayout().blocks()) {
79+
if (IsSplit && BB->isCold())
80+
break;
8081
writeEntriesForBB(Map, *BB, Function.getOutputAddress());
81-
Maps.emplace(Function.getOutputAddress(), std::move(Map));
82+
}
83+
Maps.insert(std::pair<uint64_t, MapTy>(Function.getOutputAddress(), Map));
8284

83-
if (!Function.isSplit())
85+
if (!IsSplit)
8486
continue;
8587

86-
// Split maps
88+
// Cold map
89+
Map.clear();
8790
LLVM_DEBUG(dbgs() << " Cold part\n");
88-
for (const FunctionFragment &FF :
89-
Function.getLayout().getSplitFragments()) {
90-
Map.clear();
91-
for (const BinaryBasicBlock *const BB : FF)
92-
writeEntriesForBB(Map, *BB, FF.getAddress());
93-
94-
Maps.emplace(FF.getAddress(), std::move(Map));
95-
ColdPartSource.emplace(FF.getAddress(), Function.getOutputAddress());
91+
for (const BinaryBasicBlock *const BB : Function.getLayout().blocks()) {
92+
if (!BB->isCold())
93+
continue;
94+
writeEntriesForBB(Map, *BB, Function.cold().getAddress());
9695
}
96+
Maps.insert(std::pair<uint64_t, MapTy>(Function.cold().getAddress(), Map));
97+
ColdPartSource.insert(std::pair<uint64_t, uint64_t>(
98+
Function.cold().getAddress(), Function.getOutputAddress()));
9799
}
98100

99101
const uint32_t NumFuncs = Maps.size();

0 commit comments

Comments
 (0)