Skip to content

Commit 8477bc6

Browse files
author
Fabian Parzefall
committed
[BOLT] Add function layout class
This patch adds a dedicated class to keep track of each function's layout. It also lays the groundwork for splitting functions into multiple fragments (as opposed to a strict hot/cold split). Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D129518
1 parent b717355 commit 8477bc6

33 files changed

+728
-421
lines changed

bolt/include/bolt/Core/BinaryBasicBlock.h

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef BOLT_CORE_BINARY_BASIC_BLOCK_H
1616
#define BOLT_CORE_BINARY_BASIC_BLOCK_H
1717

18+
#include "bolt/Core/FunctionLayout.h"
1819
#include "bolt/Core/MCPlus.h"
1920
#include "llvm/ADT/GraphTraits.h"
2021
#include "llvm/ADT/StringRef.h"
@@ -671,6 +672,10 @@ class BinaryBasicBlock {
671672

672673
void markValid(const bool Valid) { IsValid = Valid; }
673674

675+
FragmentNum getFragmentNum() const {
676+
return IsCold ? FragmentNum::cold() : FragmentNum::hot();
677+
}
678+
674679
bool isCold() const { return IsCold; }
675680

676681
void setIsCold(const bool Flag) { IsCold = Flag; }

bolt/include/bolt/Core/BinaryFunction.h

+12-112
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "bolt/Core/BinaryLoop.h"
3131
#include "bolt/Core/BinarySection.h"
3232
#include "bolt/Core/DebugData.h"
33+
#include "bolt/Core/FunctionLayout.h"
3334
#include "bolt/Core/JumpTable.h"
3435
#include "bolt/Core/MCPlus.h"
3536
#include "bolt/Utils/NameResolver.h"
@@ -552,10 +553,8 @@ class BinaryFunction {
552553
using BasicBlockListType = SmallVector<BinaryBasicBlock *, 0>;
553554
BasicBlockListType BasicBlocks;
554555
BasicBlockListType DeletedBasicBlocks;
555-
BasicBlockOrderType BasicBlocksLayout;
556-
/// Previous layout replaced by modifyLayout
557-
BasicBlockOrderType BasicBlocksPreviousLayout;
558-
bool ModifiedLayout{false};
556+
557+
FunctionLayout Layout;
559558

560559
/// BasicBlockOffsets are used during CFG construction to map from code
561560
/// offsets to BinaryBasicBlocks. Any modifications made to the CFG
@@ -754,12 +753,6 @@ class BinaryFunction {
754753
using const_reverse_iterator =
755754
pointee_iterator<BasicBlockListType::const_reverse_iterator>;
756755

757-
typedef BasicBlockOrderType::iterator order_iterator;
758-
typedef BasicBlockOrderType::const_iterator const_order_iterator;
759-
typedef BasicBlockOrderType::reverse_iterator reverse_order_iterator;
760-
typedef BasicBlockOrderType::const_reverse_iterator
761-
const_reverse_order_iterator;
762-
763756
// CFG iterators.
764757
iterator begin() { return BasicBlocks.begin(); }
765758
const_iterator begin() const { return BasicBlocks.begin(); }
@@ -788,49 +781,6 @@ class BinaryFunction {
788781
BasicBlockListType::iterator pbegin() { return BasicBlocks.begin(); }
789782
BasicBlockListType::iterator pend() { return BasicBlocks.end(); }
790783

791-
order_iterator layout_begin() { return BasicBlocksLayout.begin(); }
792-
const_order_iterator layout_begin() const
793-
{ return BasicBlocksLayout.begin(); }
794-
order_iterator layout_end() { return BasicBlocksLayout.end(); }
795-
const_order_iterator layout_end() const
796-
{ return BasicBlocksLayout.end(); }
797-
reverse_order_iterator layout_rbegin()
798-
{ return BasicBlocksLayout.rbegin(); }
799-
const_reverse_order_iterator layout_rbegin() const
800-
{ return BasicBlocksLayout.rbegin(); }
801-
reverse_order_iterator layout_rend()
802-
{ return BasicBlocksLayout.rend(); }
803-
const_reverse_order_iterator layout_rend() const
804-
{ return BasicBlocksLayout.rend(); }
805-
size_t layout_size() const { return BasicBlocksLayout.size(); }
806-
bool layout_empty() const { return BasicBlocksLayout.empty(); }
807-
const BinaryBasicBlock *layout_front() const
808-
{ return BasicBlocksLayout.front(); }
809-
BinaryBasicBlock *layout_front() { return BasicBlocksLayout.front(); }
810-
const BinaryBasicBlock *layout_back() const
811-
{ return BasicBlocksLayout.back(); }
812-
BinaryBasicBlock *layout_back() { return BasicBlocksLayout.back(); }
813-
814-
inline iterator_range<order_iterator> layout() {
815-
return iterator_range<order_iterator>(BasicBlocksLayout.begin(),
816-
BasicBlocksLayout.end());
817-
}
818-
819-
inline iterator_range<const_order_iterator> layout() const {
820-
return iterator_range<const_order_iterator>(BasicBlocksLayout.begin(),
821-
BasicBlocksLayout.end());
822-
}
823-
824-
inline iterator_range<reverse_order_iterator> rlayout() {
825-
return iterator_range<reverse_order_iterator>(BasicBlocksLayout.rbegin(),
826-
BasicBlocksLayout.rend());
827-
}
828-
829-
inline iterator_range<const_reverse_order_iterator> rlayout() const {
830-
return iterator_range<const_reverse_order_iterator>(
831-
BasicBlocksLayout.rbegin(), BasicBlocksLayout.rend());
832-
}
833-
834784
cfi_iterator cie_begin() { return CIEFrameInstructions.begin(); }
835785
const_cfi_iterator cie_begin() const { return CIEFrameInstructions.begin(); }
836786
cfi_iterator cie_end() { return CIEFrameInstructions.end(); }
@@ -881,27 +831,16 @@ class BinaryFunction {
881831
return *this;
882832
}
883833

884-
/// Update layout of basic blocks used for output.
885-
void updateBasicBlockLayout(BasicBlockOrderType &NewLayout) {
886-
assert(NewLayout.size() == BasicBlocks.size() && "Layout size mismatch.");
834+
FunctionLayout &getLayout() { return Layout; }
887835

888-
BasicBlocksPreviousLayout = BasicBlocksLayout;
889-
if (NewLayout != BasicBlocksLayout) {
890-
ModifiedLayout = true;
891-
BasicBlocksLayout.clear();
892-
BasicBlocksLayout.swap(NewLayout);
893-
}
894-
}
836+
const FunctionLayout &getLayout() const { return Layout; }
895837

896838
/// Recompute landing pad information for the function and all its blocks.
897839
void recomputeLandingPads();
898840

899-
/// Return current basic block layout.
900-
const BasicBlockOrderType &getLayout() const { return BasicBlocksLayout; }
901-
902841
/// Return a list of basic blocks sorted using DFS and update layout indices
903842
/// using the same order. Does not modify the current layout.
904-
BasicBlockOrderType dfs() const;
843+
BasicBlockListType dfs() const;
905844

906845
/// Find the loops in the CFG of the function and store information about
907846
/// them.
@@ -958,26 +897,6 @@ class BinaryFunction {
958897
return I == LabelToBB.end() ? nullptr : I->second;
959898
}
960899

961-
/// Returns the basic block after the given basic block in the layout or
962-
/// nullptr the last basic block is given.
963-
const BinaryBasicBlock *getBasicBlockAfter(const BinaryBasicBlock *BB,
964-
bool IgnoreSplits = true) const {
965-
return const_cast<BinaryFunction *>(this)->getBasicBlockAfter(BB,
966-
IgnoreSplits);
967-
}
968-
969-
BinaryBasicBlock *getBasicBlockAfter(const BinaryBasicBlock *BB,
970-
bool IgnoreSplits = true) {
971-
for (auto I = layout_begin(), E = layout_end(); I != E; ++I) {
972-
auto Next = std::next(I);
973-
if (*I == BB && Next != E) {
974-
return (IgnoreSplits || (*I)->isCold() == (*Next)->isCold()) ? *Next
975-
: nullptr;
976-
}
977-
}
978-
return nullptr;
979-
}
980-
981900
/// Retrieve the landing pad BB associated with invoke instruction \p Invoke
982901
/// that is in \p BB. Return nullptr if none exists
983902
BinaryBasicBlock *getLandingPadBBFor(const BinaryBasicBlock &BB,
@@ -1455,10 +1374,7 @@ class BinaryFunction {
14551374
bool hasUnknownControlFlow() const { return HasUnknownControlFlow; }
14561375

14571376
/// Return true if the function body is non-contiguous.
1458-
bool isSplit() const {
1459-
return isSimple() && layout_size() &&
1460-
layout_front()->isCold() != layout_back()->isCold();
1461-
}
1377+
bool isSplit() const { return isSimple() && getLayout().isSplit(); }
14621378

14631379
bool shouldPreserveNops() const { return PreserveNops; }
14641380

@@ -1578,8 +1494,7 @@ class BinaryFunction {
15781494
BinaryBasicBlock *BB = BasicBlocks.back();
15791495

15801496
BB->setIndex(BasicBlocks.size() - 1);
1581-
BB->setLayoutIndex(layout_size());
1582-
BasicBlocksLayout.emplace_back(BB);
1497+
Layout.addBasicBlock(BB);
15831498

15841499
return BB;
15851500
}
@@ -1626,13 +1541,6 @@ class BinaryFunction {
16261541
/// layout after the BB indicated by Start.
16271542
void updateLayout(BinaryBasicBlock *Start, const unsigned NumNewBlocks);
16281543

1629-
/// Make sure basic blocks' indices match the current layout.
1630-
void updateLayoutIndices() const {
1631-
unsigned Index = 0;
1632-
for (BinaryBasicBlock *BB : layout())
1633-
BB->setLayoutIndex(Index++);
1634-
}
1635-
16361544
/// Recompute the CFI state for NumNewBlocks following Start after inserting
16371545
/// new blocks into the CFG. This must be called after updateLayout.
16381546
void updateCFIState(BinaryBasicBlock *Start, const unsigned NumNewBlocks);
@@ -2213,14 +2121,6 @@ class BinaryFunction {
22132121
/// and size.
22142122
uint64_t getFunctionScore() const;
22152123

2216-
/// Return true if the layout has been changed by basic block reordering,
2217-
/// false otherwise.
2218-
bool hasLayoutChanged() const;
2219-
2220-
/// Get the edit distance of the new layout with respect to the previous
2221-
/// layout after basic block reordering.
2222-
uint64_t getEditDistance() const;
2223-
22242124
/// Get the number of instructions within this function.
22252125
uint64_t getInstructionCount() const;
22262126

@@ -2429,7 +2329,7 @@ template <>
24292329
struct GraphTraits<bolt::BinaryFunction *>
24302330
: public GraphTraits<bolt::BinaryBasicBlock *> {
24312331
static NodeRef getEntryNode(bolt::BinaryFunction *F) {
2432-
return *F->layout_begin();
2332+
return F->getLayout().block_front();
24332333
}
24342334

24352335
using nodes_iterator = pointer_iterator<bolt::BinaryFunction::iterator>;
@@ -2449,7 +2349,7 @@ template <>
24492349
struct GraphTraits<const bolt::BinaryFunction *>
24502350
: public GraphTraits<const bolt::BinaryBasicBlock *> {
24512351
static NodeRef getEntryNode(const bolt::BinaryFunction *F) {
2452-
return *F->layout_begin();
2352+
return F->getLayout().block_front();
24532353
}
24542354

24552355
using nodes_iterator = pointer_iterator<bolt::BinaryFunction::const_iterator>;
@@ -2469,15 +2369,15 @@ template <>
24692369
struct GraphTraits<Inverse<bolt::BinaryFunction *>>
24702370
: public GraphTraits<Inverse<bolt::BinaryBasicBlock *>> {
24712371
static NodeRef getEntryNode(Inverse<bolt::BinaryFunction *> G) {
2472-
return *G.Graph->layout_begin();
2372+
return G.Graph->getLayout().block_front();
24732373
}
24742374
};
24752375

24762376
template <>
24772377
struct GraphTraits<Inverse<const bolt::BinaryFunction *>>
24782378
: public GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> {
24792379
static NodeRef getEntryNode(Inverse<const bolt::BinaryFunction *> G) {
2480-
return *G.Graph->layout_begin();
2380+
return G.Graph->getLayout().block_front();
24812381
}
24822382
};
24832383

0 commit comments

Comments
 (0)