Skip to content

Commit af930a0

Browse files
committed
[BOLT] Introduce .text.warm for -use-cdsplit=1
This commit explicitly adds a warm code section, .text.warm, when the -use-cdsplit=1 flag is set. This replaces the previous approach of using .text.cold.0 as warm and .text.cold.1 as cold in 3-way splitting.
1 parent 2215673 commit af930a0

12 files changed

+84
-37
lines changed

bolt/include/bolt/Core/BinaryBasicBlock.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -677,9 +677,7 @@ class BinaryBasicBlock {
677677
return isSplit();
678678
}
679679

680-
void setIsCold(const bool Flag) {
681-
Fragment = Flag ? FragmentNum::cold() : FragmentNum::main();
682-
}
680+
void setIsCold(const bool Flag);
683681

684682
/// Return true if the block can be outlined. At the moment we disallow
685683
/// outlining of blocks that can potentially throw exceptions or are

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,8 @@ class BinaryContext {
927927

928928
const char *getMainCodeSectionName() const { return ".text"; }
929929

930+
const char *getWarmCodeSectionName() const { return ".text.warm"; }
931+
930932
const char *getColdCodeSectionName() const { return ".text.cold"; }
931933

932934
const char *getHotTextMoverSectionName() const { return ".text.mover"; }

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,9 @@ class BinaryFunction {
355355
/// Name for the section this function code should reside in.
356356
std::string CodeSectionName;
357357

358+
/// Name for the corresponding warm code section.
359+
std::string WarmCodeSectionName;
360+
358361
/// Name for the corresponding cold code section.
359362
std::string ColdCodeSectionName;
360363

@@ -1231,13 +1234,7 @@ class BinaryFunction {
12311234

12321235
/// Return internal section name for this function.
12331236
SmallString<32>
1234-
getCodeSectionName(const FragmentNum Fragment = FragmentNum::main()) const {
1235-
if (Fragment == FragmentNum::main())
1236-
return SmallString<32>(CodeSectionName);
1237-
if (Fragment == FragmentNum::cold())
1238-
return SmallString<32>(ColdCodeSectionName);
1239-
return formatv("{0}.{1}", ColdCodeSectionName, Fragment.get() - 1);
1240-
}
1237+
getCodeSectionName(const FragmentNum Fragment = FragmentNum::main()) const;
12411238

12421239
/// Assign a code section name to the function.
12431240
void setCodeSectionName(const StringRef Name) {
@@ -1250,6 +1247,11 @@ class BinaryFunction {
12501247
return BC.getUniqueSectionByName(getCodeSectionName(Fragment));
12511248
}
12521249

1250+
/// Assign a section name for the warm part of the function.
1251+
void setWarmCodeSectionName(const StringRef Name) {
1252+
WarmCodeSectionName = Name.str();
1253+
}
1254+
12531255
/// Assign a section name for the cold part of the function.
12541256
void setColdCodeSectionName(const StringRef Name) {
12551257
ColdCodeSectionName = Name.str();

bolt/include/bolt/Core/FunctionLayout.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ class FragmentNum {
6262
}
6363

6464
static constexpr FragmentNum main() { return FragmentNum(0); }
65-
static constexpr FragmentNum cold() { return FragmentNum(1); }
65+
static constexpr FragmentNum warm() { return FragmentNum(1); }
66+
static constexpr FragmentNum cold(bool Flag = false) {
67+
return FragmentNum(Flag ? 2 : 1);
68+
}
6669
};
6770

6871
/// A freestanding subset of contiguous blocks of a function.

bolt/lib/Core/BinaryBasicBlock.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,25 @@
1515
#include "bolt/Core/BinaryFunction.h"
1616
#include "llvm/ADT/SmallPtrSet.h"
1717
#include "llvm/MC/MCInst.h"
18+
#include "llvm/Support/CommandLine.h"
1819
#include "llvm/Support/Errc.h"
1920

2021
#define DEBUG_TYPE "bolt"
2122

22-
namespace llvm {
23-
namespace bolt {
23+
using namespace llvm;
24+
using namespace bolt;
25+
namespace opts {
26+
extern cl::opt<bool> UseCDSplit;
27+
}
2428

2529
constexpr uint32_t BinaryBasicBlock::INVALID_OFFSET;
2630

27-
bool operator<(const BinaryBasicBlock &LHS, const BinaryBasicBlock &RHS) {
28-
return LHS.Index < RHS.Index;
31+
bool bolt::operator<(const BinaryBasicBlock &LHS, const BinaryBasicBlock &RHS) {
32+
return LHS.getIndex() < RHS.getIndex();
33+
}
34+
35+
void BinaryBasicBlock::setIsCold(const bool Flag) {
36+
Fragment = Flag ? FragmentNum::cold(opts::UseCDSplit) : FragmentNum::main();
2937
}
3038

3139
bool BinaryBasicBlock::hasCFG() const { return getParent()->hasCFG(); }
@@ -611,6 +619,3 @@ BinaryBasicBlock *BinaryBasicBlock::splitAt(iterator II) {
611619

612620
return NewBlock;
613621
}
614-
615-
} // namespace bolt
616-
} // namespace llvm

bolt/lib/Core/BinaryEmitter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace opts {
3434

3535
extern cl::opt<JumpTableSupportLevel> JumpTables;
3636
extern cl::opt<bool> PreserveBlocksAlignment;
37+
extern cl::opt<bool> UseCDSplit;
3738

3839
cl::opt<bool> AlignBlocks("align-blocks", cl::desc("align basic blocks"),
3940
cl::cat(BoltOptCategory));
@@ -287,7 +288,10 @@ void BinaryEmitter::emitFunctions() {
287288

288289
// Mark the end of hot text.
289290
if (opts::HotText) {
290-
Streamer.switchSection(BC.getTextSection());
291+
if (opts::UseCDSplit)
292+
Streamer.switchSection(BC.getCodeSection(BC.getWarmCodeSectionName()));
293+
else
294+
Streamer.switchSection(BC.getTextSection());
291295
Streamer.emitLabel(BC.getHotTextEndSymbol());
292296
}
293297
}

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ extern cl::opt<bool> EnableBAT;
5959
extern cl::opt<bool> Instrument;
6060
extern cl::opt<bool> StrictMode;
6161
extern cl::opt<bool> UpdateDebugSections;
62+
extern cl::opt<bool> UseCDSplit;
6263
extern cl::opt<unsigned> Verbosity;
6364

6465
extern bool processAllFunctions();
@@ -167,6 +168,18 @@ template <typename R> static bool emptyRange(const R &Range) {
167168
return Range.begin() == Range.end();
168169
}
169170

171+
/// Return internal section name for this function.
172+
SmallString<32>
173+
BinaryFunction::getCodeSectionName(const FragmentNum Fragment) const {
174+
if (Fragment == FragmentNum::main())
175+
return SmallString<32>(CodeSectionName);
176+
if (Fragment == FragmentNum::cold(opts::UseCDSplit))
177+
return SmallString<32>(ColdCodeSectionName);
178+
if (Fragment == FragmentNum::warm())
179+
return SmallString<32>(WarmCodeSectionName);
180+
return formatv("{0}.{1}", ColdCodeSectionName, Fragment.get() - 1);
181+
}
182+
170183
/// Gets debug line information for the instruction located at the given
171184
/// address in the original binary. The SMLoc's pointer is used
172185
/// to point to this information, which is represented by a

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1244,8 +1244,10 @@ void AssignSections::runOnFunctions(BinaryContext &BC) {
12441244
else
12451245
Function.setCodeSectionName(BC.getColdCodeSectionName());
12461246

1247-
if (Function.isSplit())
1247+
if (Function.isSplit()) {
1248+
Function.setWarmCodeSectionName(BC.getWarmCodeSectionName());
12481249
Function.setColdCodeSectionName(BC.getColdCodeSectionName());
1250+
}
12491251
}
12501252
}
12511253

bolt/lib/Passes/CDSplit.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ using namespace llvm;
2424
using namespace bolt;
2525

2626
namespace opts {
27-
2827
extern cl::OptionCategory BoltOptCategory;
2928

3029
extern cl::opt<bool> UseCDSplit;

bolt/lib/Passes/IndirectCallPromotion.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern cl::OptionCategory BoltOptCategory;
3434
extern cl::opt<IndirectCallPromotionType> ICP;
3535
extern cl::opt<unsigned> Verbosity;
3636
extern cl::opt<unsigned> ExecutionCountThreshold;
37+
extern cl::opt<bool> UseCDSplit;
3738

3839
static cl::opt<unsigned> ICPJTRemainingPercentThreshold(
3940
"icp-jt-remaining-percent-threshold",
@@ -259,9 +260,10 @@ IndirectCallPromotion::getCallTargets(BinaryBasicBlock &BB,
259260
MCSymbol *Entry = JT->Entries[I];
260261
const BinaryBasicBlock *ToBB = BF.getBasicBlockForLabel(Entry);
261262
assert(ToBB || Entry == BF.getFunctionEndLabel() ||
262-
Entry == BF.getFunctionEndLabel(FragmentNum::cold()));
263+
Entry ==
264+
BF.getFunctionEndLabel(FragmentNum::cold(opts::UseCDSplit)));
263265
if (Entry == BF.getFunctionEndLabel() ||
264-
Entry == BF.getFunctionEndLabel(FragmentNum::cold()))
266+
Entry == BF.getFunctionEndLabel(FragmentNum::cold(opts::UseCDSplit)))
265267
continue;
266268
const Location To(Entry);
267269
const BinaryBasicBlock::BinaryBranchInfo &BI = BB.getBranchInfo(*ToBB);

0 commit comments

Comments
 (0)