mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
BOLT: Clean up interface between BinaryFunction and BinaryBasicBlock.
Summary: This is just a bit of refactoring to make sure that BinaryFunction goes through methods to get at the state in BinaryBasicBlock. I did this so that changing the way Index/LayoutIndex/Valid works will be easier. (cherry picked from FBD3860899)
This commit is contained in:
committed by
Maksim Panchenko
parent
b0f4031db3
commit
7483cd0fa6
@@ -126,12 +126,20 @@ void BinaryBasicBlock::addLandingPad(BinaryBasicBlock *LPBlock) {
|
||||
LPBlock->Throwers.insert(this);
|
||||
}
|
||||
|
||||
bool BinaryBasicBlock::analyzeBranch(const MCInstrAnalysis &MIA,
|
||||
const MCSymbol *&TBB,
|
||||
void BinaryBasicBlock::clearLandingPads() {
|
||||
for (auto *LPBlock : LandingPads) {
|
||||
auto count = LPBlock->Throwers.erase(this);
|
||||
assert(count == 1);
|
||||
}
|
||||
LandingPads.clear();
|
||||
}
|
||||
|
||||
bool BinaryBasicBlock::analyzeBranch(const MCSymbol *&TBB,
|
||||
const MCSymbol *&FBB,
|
||||
MCInst *&CondBranch,
|
||||
MCInst *&UncondBranch) {
|
||||
return MIA.analyzeBranch(Instructions, TBB, FBB, CondBranch, UncondBranch);
|
||||
auto &MIA = Function->getBinaryContext().MIA;
|
||||
return MIA->analyzeBranch(Instructions, TBB, FBB, CondBranch, UncondBranch);
|
||||
}
|
||||
|
||||
bool BinaryBasicBlock::swapConditionalSuccessors() {
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
class MCInstrAnalysis;
|
||||
namespace bolt {
|
||||
|
||||
class BinaryFunction;
|
||||
@@ -41,12 +40,24 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
/// Label associated with the block.
|
||||
MCSymbol *Label{nullptr};
|
||||
/// Vector of all instructions in the block.
|
||||
std::vector<MCInst> Instructions;
|
||||
|
||||
/// CFG information.
|
||||
std::vector<BinaryBasicBlock *> Predecessors;
|
||||
std::vector<BinaryBasicBlock *> Successors;
|
||||
std::set<BinaryBasicBlock *> Throwers;
|
||||
std::set<BinaryBasicBlock *> LandingPads;
|
||||
|
||||
/// Each successor has a corresponding BranchInfo entry in the list.
|
||||
std::vector<BinaryBranchInfo> BranchInfo;
|
||||
|
||||
/// Function that owns this basic block.
|
||||
BinaryFunction *Function;
|
||||
|
||||
/// Label associated with the block.
|
||||
MCSymbol *Label{nullptr};
|
||||
|
||||
/// Label associated with the end of the block in the output binary.
|
||||
const MCSymbol *EndLabel{nullptr};
|
||||
|
||||
@@ -59,6 +70,9 @@ private:
|
||||
/// Alignment requirements for the block.
|
||||
uint64_t Alignment{1};
|
||||
|
||||
/// Number of times this basic block was executed.
|
||||
uint64_t ExecutionCount{COUNT_NO_PROFILE};
|
||||
|
||||
/// Index to BasicBlocks vector in BinaryFunction.
|
||||
unsigned Index{~0u};
|
||||
|
||||
@@ -68,9 +82,6 @@ private:
|
||||
/// Number of pseudo instructions in this block.
|
||||
uint32_t NumPseudos{0};
|
||||
|
||||
/// Number of times this basic block was executed.
|
||||
uint64_t ExecutionCount{COUNT_NO_PROFILE};
|
||||
|
||||
/// In cases where the parent function has been split, IsCold == true means
|
||||
/// this BB will be allocated outside its parent function.
|
||||
bool IsCold{false};
|
||||
@@ -78,25 +89,14 @@ private:
|
||||
/// Indicates if the block could be outlined.
|
||||
bool CanOutline{true};
|
||||
|
||||
/// Vector of all instructions in the block.
|
||||
std::vector<MCInst> Instructions;
|
||||
|
||||
/// CFG information.
|
||||
std::vector<BinaryBasicBlock *> Predecessors;
|
||||
std::vector<BinaryBasicBlock *> Successors;
|
||||
std::set<BinaryBasicBlock *> Throwers;
|
||||
std::set<BinaryBasicBlock *> LandingPads;
|
||||
|
||||
/// Each successor has a corresponding BranchInfo entry in the list.
|
||||
std::vector<BinaryBranchInfo> BranchInfo;
|
||||
|
||||
BinaryBasicBlock() {}
|
||||
private:
|
||||
BinaryBasicBlock() = delete;
|
||||
|
||||
explicit BinaryBasicBlock(
|
||||
MCSymbol *Label,
|
||||
BinaryFunction *Function,
|
||||
MCSymbol *Label,
|
||||
uint64_t Offset = std::numeric_limits<uint64_t>::max())
|
||||
: Label(Label), Function(Function), Offset(Offset) {}
|
||||
: Function(Function), Label(Label), Offset(Offset) {}
|
||||
|
||||
explicit BinaryBasicBlock(uint64_t Offset)
|
||||
: Offset(Offset) {}
|
||||
@@ -113,10 +113,10 @@ public:
|
||||
std::numeric_limits<uint64_t>::max();
|
||||
|
||||
// Instructions iterators.
|
||||
typedef std::vector<MCInst>::iterator iterator;
|
||||
typedef std::vector<MCInst>::const_iterator const_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
using iterator = std::vector<MCInst>::iterator;
|
||||
using const_iterator = std::vector<MCInst>::const_iterator;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
bool empty() const { return Instructions.empty(); }
|
||||
unsigned size() const { return (unsigned)Instructions.size(); }
|
||||
@@ -135,30 +135,19 @@ public:
|
||||
const_reverse_iterator rend () const { return Instructions.rend(); }
|
||||
|
||||
// CFG iterators.
|
||||
typedef std::vector<BinaryBasicBlock *>::iterator pred_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::const_iterator const_pred_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::iterator succ_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::const_iterator const_succ_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::iterator throw_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::const_iterator const_throw_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::iterator lp_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::const_iterator const_lp_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::reverse_iterator
|
||||
pred_reverse_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::const_reverse_iterator
|
||||
const_pred_reverse_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::reverse_iterator
|
||||
succ_reverse_iterator;
|
||||
typedef std::vector<BinaryBasicBlock *>::const_reverse_iterator
|
||||
const_succ_reverse_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::reverse_iterator
|
||||
throw_reverse_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::const_reverse_iterator
|
||||
const_throw_reverse_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::reverse_iterator
|
||||
lp_reverse_iterator;
|
||||
typedef std::set<BinaryBasicBlock *>::const_reverse_iterator
|
||||
const_lp_reverse_iterator;
|
||||
using pred_iterator = std::vector<BinaryBasicBlock *>::iterator;
|
||||
using const_pred_iterator = std::vector<BinaryBasicBlock *>::const_iterator;
|
||||
using succ_iterator = std::vector<BinaryBasicBlock *>::iterator;
|
||||
using const_succ_iterator = std::vector<BinaryBasicBlock *>::const_iterator;
|
||||
using throw_iterator = decltype(Throwers)::iterator;
|
||||
using const_throw_iterator = decltype(Throwers)::const_iterator;
|
||||
using lp_iterator = decltype(LandingPads)::iterator;
|
||||
using const_lp_iterator = decltype(LandingPads)::const_iterator;
|
||||
|
||||
using pred_reverse_iterator = std::reverse_iterator<pred_iterator>;
|
||||
using const_pred_reverse_iterator = std::reverse_iterator<const_pred_iterator>;
|
||||
using succ_reverse_iterator = std::reverse_iterator<succ_iterator>;
|
||||
using const_succ_reverse_iterator = std::reverse_iterator<const_succ_iterator>;
|
||||
|
||||
pred_iterator pred_begin() { return Predecessors.begin(); }
|
||||
const_pred_iterator pred_begin() const { return Predecessors.begin(); }
|
||||
@@ -198,14 +187,6 @@ public:
|
||||
const_throw_iterator throw_begin() const { return Throwers.begin(); }
|
||||
throw_iterator throw_end() { return Throwers.end(); }
|
||||
const_throw_iterator throw_end() const { return Throwers.end(); }
|
||||
throw_reverse_iterator throw_rbegin()
|
||||
{ return Throwers.rbegin();}
|
||||
const_throw_reverse_iterator throw_rbegin() const
|
||||
{ return Throwers.rbegin();}
|
||||
throw_reverse_iterator throw_rend()
|
||||
{ return Throwers.rend(); }
|
||||
const_throw_reverse_iterator throw_rend() const
|
||||
{ return Throwers.rend(); }
|
||||
unsigned throw_size() const {
|
||||
return (unsigned)Throwers.size();
|
||||
}
|
||||
@@ -216,19 +197,17 @@ public:
|
||||
const_lp_iterator lp_begin() const { return LandingPads.begin(); }
|
||||
lp_iterator lp_end() { return LandingPads.end(); }
|
||||
const_lp_iterator lp_end() const { return LandingPads.end(); }
|
||||
lp_reverse_iterator lp_rbegin()
|
||||
{ return LandingPads.rbegin(); }
|
||||
const_lp_reverse_iterator lp_rbegin() const
|
||||
{ return LandingPads.rbegin(); }
|
||||
lp_reverse_iterator lp_rend()
|
||||
{ return LandingPads.rend(); }
|
||||
const_lp_reverse_iterator lp_rend() const
|
||||
{ return LandingPads.rend(); }
|
||||
unsigned lp_size() const {
|
||||
return (unsigned)LandingPads.size();
|
||||
}
|
||||
bool lp_empty() const { return LandingPads.empty(); }
|
||||
|
||||
inline iterator_range<iterator> instructions() {
|
||||
return iterator_range<iterator>(begin(), end());
|
||||
}
|
||||
inline iterator_range<const_iterator> instructions() const {
|
||||
return iterator_range<const_iterator>(begin(), end());
|
||||
}
|
||||
inline iterator_range<pred_iterator> predecessors() {
|
||||
return iterator_range<pred_iterator>(pred_begin(), pred_end());
|
||||
}
|
||||
@@ -255,22 +234,40 @@ public:
|
||||
}
|
||||
|
||||
// BranchInfo iterators.
|
||||
typedef std::vector<BinaryBranchInfo>::const_iterator
|
||||
const_branch_info_iterator;
|
||||
using branch_info_iterator = std::vector<BinaryBranchInfo>::iterator;
|
||||
using const_branch_info_iterator =
|
||||
std::vector<BinaryBranchInfo>::const_iterator;
|
||||
using branch_info_reverse_iterator =
|
||||
std::reverse_iterator<branch_info_iterator>;
|
||||
using const_branch_info_reverse_iterator =
|
||||
std::reverse_iterator<const_branch_info_iterator>;
|
||||
|
||||
const_branch_info_iterator branch_info_begin() const
|
||||
{ return BranchInfo.begin(); }
|
||||
const_branch_info_iterator branch_info_end() const
|
||||
{ return BranchInfo.end(); }
|
||||
branch_info_iterator branch_info_begin() { return BranchInfo.begin(); }
|
||||
branch_info_iterator branch_info_end() { return BranchInfo.end(); }
|
||||
const_branch_info_iterator branch_info_begin() const
|
||||
{ return BranchInfo.begin(); }
|
||||
const_branch_info_iterator branch_info_end() const
|
||||
{ return BranchInfo.end(); }
|
||||
branch_info_reverse_iterator branch_info_rbegin()
|
||||
{ return BranchInfo.rbegin(); }
|
||||
branch_info_reverse_iterator branch_info_rend()
|
||||
{ return BranchInfo.rend(); }
|
||||
const_branch_info_reverse_iterator branch_info_rbegin() const
|
||||
{ return BranchInfo.rbegin(); }
|
||||
const_branch_info_reverse_iterator branch_info_rend() const
|
||||
{ return BranchInfo.rend(); }
|
||||
unsigned branch_info_size() const {
|
||||
return (unsigned)BranchInfo.size();
|
||||
}
|
||||
bool branch_info_empty() const
|
||||
{ return BranchInfo.empty(); }
|
||||
bool branch_info_empty() const { return BranchInfo.empty(); }
|
||||
|
||||
inline iterator_range<branch_info_iterator> branch_info() {
|
||||
return iterator_range<branch_info_iterator>(
|
||||
BranchInfo.begin(), BranchInfo.end());
|
||||
}
|
||||
inline iterator_range<const_branch_info_iterator> branch_info() const {
|
||||
return iterator_range<const_branch_info_iterator>(
|
||||
branch_info_begin(), branch_info_end());
|
||||
BranchInfo.begin(), BranchInfo.end());
|
||||
}
|
||||
|
||||
/// Get instruction at given index.
|
||||
@@ -483,6 +480,10 @@ public:
|
||||
return IsCold;
|
||||
}
|
||||
|
||||
void setIsCold(const bool Flag) {
|
||||
IsCold = Flag;
|
||||
}
|
||||
|
||||
/// Return true if the block can be outlined. At the moment we disallow
|
||||
/// outlining of blocks that can potentially throw exceptions or are
|
||||
/// the beginning of a landing pad. The entry basic block also can
|
||||
@@ -491,6 +492,10 @@ public:
|
||||
return CanOutline;
|
||||
}
|
||||
|
||||
void setCanOutline(const bool Flag) {
|
||||
CanOutline = Flag;
|
||||
}
|
||||
|
||||
/// Erase pseudo instruction at a given iterator.
|
||||
iterator erasePseudoInstruction(iterator II) {
|
||||
--NumPseudos;
|
||||
@@ -564,8 +569,7 @@ public:
|
||||
|
||||
/// Analyze and interpret the terminators of this basic block. TBB must be
|
||||
/// initialized with the original fall-through for this BB.
|
||||
bool analyzeBranch(const MCInstrAnalysis &MIA,
|
||||
const MCSymbol *&TBB,
|
||||
bool analyzeBranch(const MCSymbol *&TBB,
|
||||
const MCSymbol *&FBB,
|
||||
MCInst *&CondBranch,
|
||||
MCInst *&UncondBranch);
|
||||
@@ -587,14 +591,27 @@ private:
|
||||
void addPredecessor(BinaryBasicBlock *Pred);
|
||||
|
||||
/// Remove predecessor of the basic block. Don't use directly, instead
|
||||
/// use removeSuccessor() funciton.
|
||||
/// use removeSuccessor() function.
|
||||
void removePredecessor(BinaryBasicBlock *Pred);
|
||||
|
||||
/// Remove landing pads of this basic block.
|
||||
void clearLandingPads();
|
||||
|
||||
/// Set offset of the basic block from the function start.
|
||||
void setOffset(uint64_t NewOffset) {
|
||||
Offset = NewOffset;
|
||||
}
|
||||
|
||||
/// Get the index of this basic block.
|
||||
unsigned getIndex() const {
|
||||
return Index;
|
||||
}
|
||||
|
||||
/// Set the index of this basic block.
|
||||
void setIndex(unsigned I) {
|
||||
Index = I;
|
||||
}
|
||||
|
||||
/// Set layout index. To be used by BinaryFunction.
|
||||
void setLayoutIndex(unsigned Index) {
|
||||
LayoutIndex = Index;
|
||||
@@ -609,8 +626,8 @@ bool operator<(const BinaryBasicBlock &LHS, const BinaryBasicBlock &RHS);
|
||||
|
||||
// GraphTraits specializations for basic block graphs (CFGs)
|
||||
template <> struct GraphTraits<bolt::BinaryBasicBlock *> {
|
||||
typedef bolt::BinaryBasicBlock NodeType;
|
||||
typedef bolt::BinaryBasicBlock::succ_iterator ChildIteratorType;
|
||||
using NodeType = bolt::BinaryBasicBlock;
|
||||
using ChildIteratorType = bolt::BinaryBasicBlock::succ_iterator;
|
||||
|
||||
static NodeType *getEntryNode(bolt::BinaryBasicBlock *BB) { return BB; }
|
||||
static inline ChildIteratorType child_begin(NodeType *N) {
|
||||
@@ -622,8 +639,8 @@ template <> struct GraphTraits<bolt::BinaryBasicBlock *> {
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<const bolt::BinaryBasicBlock *> {
|
||||
typedef const bolt::BinaryBasicBlock NodeType;
|
||||
typedef bolt::BinaryBasicBlock::const_succ_iterator ChildIteratorType;
|
||||
using NodeType = const bolt::BinaryBasicBlock;
|
||||
using ChildIteratorType = bolt::BinaryBasicBlock::const_succ_iterator;
|
||||
|
||||
static NodeType *getEntryNode(const bolt::BinaryBasicBlock *BB) {
|
||||
return BB;
|
||||
@@ -637,8 +654,8 @@ template <> struct GraphTraits<const bolt::BinaryBasicBlock *> {
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<bolt::BinaryBasicBlock *>> {
|
||||
typedef bolt::BinaryBasicBlock NodeType;
|
||||
typedef bolt::BinaryBasicBlock::pred_iterator ChildIteratorType;
|
||||
using NodeType = bolt::BinaryBasicBlock;
|
||||
using ChildIteratorType = bolt::BinaryBasicBlock::pred_iterator;
|
||||
static NodeType *getEntryNode(Inverse<bolt::BinaryBasicBlock *> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
@@ -651,8 +668,8 @@ template <> struct GraphTraits<Inverse<bolt::BinaryBasicBlock *>> {
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> {
|
||||
typedef const bolt::BinaryBasicBlock NodeType;
|
||||
typedef bolt::BinaryBasicBlock::const_pred_iterator ChildIteratorType;
|
||||
using NodeType = const bolt::BinaryBasicBlock;
|
||||
using ChildIteratorType = bolt::BinaryBasicBlock::const_pred_iterator;
|
||||
static NodeType *getEntryNode(Inverse<const bolt::BinaryBasicBlock *> G) {
|
||||
return G.Graph;
|
||||
}
|
||||
@@ -664,7 +681,6 @@ template <> struct GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
||||
@@ -240,14 +240,14 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
|
||||
for (uint32_t I = 0, E = BasicBlocksLayout.size(); I != E; ++I) {
|
||||
auto BB = BasicBlocksLayout[I];
|
||||
if (I != 0 &&
|
||||
BB->IsCold != BasicBlocksLayout[I - 1]->IsCold)
|
||||
BB->isCold() != BasicBlocksLayout[I - 1]->isCold())
|
||||
OS << "------- HOT-COLD SPLIT POINT -------\n\n";
|
||||
|
||||
OS << BB->getName() << " ("
|
||||
<< BB->Instructions.size() << " instructions, align : "
|
||||
<< BB->size() << " instructions, align : "
|
||||
<< BB->getAlignment() << ")\n";
|
||||
|
||||
if (LandingPads.find(BB->getLabel()) != LandingPads.end()) {
|
||||
if (BB->isLandingPad()) {
|
||||
OS << " Landing Pad\n";
|
||||
}
|
||||
|
||||
@@ -258,19 +258,19 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
|
||||
if (!BBCFIState.empty()) {
|
||||
OS << " CFI State : " << BBCFIState[getIndex(BB)] << '\n';
|
||||
}
|
||||
if (!BB->Predecessors.empty()) {
|
||||
if (!BB->pred_empty()) {
|
||||
OS << " Predecessors: ";
|
||||
auto Sep = "";
|
||||
for (auto Pred : BB->Predecessors) {
|
||||
for (auto Pred : BB->predecessors()) {
|
||||
OS << Sep << Pred->getName();
|
||||
Sep = ", ";
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
if (!BB->Throwers.empty()) {
|
||||
if (!BB->throw_empty()) {
|
||||
OS << " Throwers: ";
|
||||
auto Sep = "";
|
||||
for (auto Throw : BB->Throwers) {
|
||||
for (auto Throw : BB->throwers()) {
|
||||
OS << Sep << Throw->getName();
|
||||
Sep = ", ";
|
||||
}
|
||||
@@ -282,12 +282,12 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
|
||||
// Note: offsets are imprecise since this is happening prior to relaxation.
|
||||
Offset = BC.printInstructions(OS, BB->begin(), BB->end(), Offset, this);
|
||||
|
||||
if (!BB->Successors.empty()) {
|
||||
if (!BB->succ_empty()) {
|
||||
OS << " Successors: ";
|
||||
auto BI = BB->BranchInfo.begin();
|
||||
auto BI = BB->branch_info_begin();
|
||||
auto Sep = "";
|
||||
for (auto Succ : BB->Successors) {
|
||||
assert(BI != BB->BranchInfo.end() && "missing BranchInfo entry");
|
||||
for (auto Succ : BB->successors()) {
|
||||
assert(BI != BB->branch_info_end() && "missing BranchInfo entry");
|
||||
OS << Sep << Succ->getName();
|
||||
if (ExecutionCount != COUNT_NO_PROFILE &&
|
||||
BI->MispredictedCount != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE) {
|
||||
@@ -303,13 +303,13 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
if (!BB->LandingPads.empty()) {
|
||||
if (!BB->lp_empty()) {
|
||||
OS << " Landing Pads: ";
|
||||
auto Sep = "";
|
||||
for (auto LP : BB->LandingPads) {
|
||||
for (auto LP : BB->landing_pads()) {
|
||||
OS << Sep << LP->getName();
|
||||
if (ExecutionCount != COUNT_NO_PROFILE) {
|
||||
OS << " (count: " << LP->ExecutionCount << ")";
|
||||
OS << " (count: " << LP->getExecutionCount() << ")";
|
||||
}
|
||||
Sep = ", ";
|
||||
}
|
||||
@@ -806,12 +806,7 @@ void BinaryFunction::clearLandingPads(const unsigned StartIndex,
|
||||
const unsigned NumBlocks) {
|
||||
// remove all landing pads/throws for the given collection of blocks
|
||||
for (auto I = StartIndex; I < StartIndex + NumBlocks; ++I) {
|
||||
auto *BB = BasicBlocks[I];
|
||||
for (auto *LPBlock : BB->LandingPads) {
|
||||
auto count = LPBlock->Throwers.erase(BB);
|
||||
assert(count == 1);
|
||||
}
|
||||
BB->LandingPads.clear();
|
||||
BasicBlocks[I]->clearLandingPads();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -839,14 +834,14 @@ void BinaryFunction::recomputeLandingPads(const unsigned StartIndex,
|
||||
|
||||
for (auto I = StartIndex; I < StartIndex + NumBlocks; ++I) {
|
||||
auto *BB = BasicBlocks[I];
|
||||
for (auto &Instr : BB->Instructions) {
|
||||
for (auto &Instr : BB->instructions()) {
|
||||
// Store info about associated landing pad.
|
||||
if (BC.MIA->isInvoke(Instr)) {
|
||||
const MCSymbol *LP;
|
||||
uint64_t Action;
|
||||
std::tie(LP, Action) = BC.MIA->getEHInfo(Instr);
|
||||
if (LP) {
|
||||
LPToBBIndex[LP].push_back(BB->Index);
|
||||
LPToBBIndex[LP].push_back(getIndex(BB));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1288,14 +1283,14 @@ void BinaryFunction::inferFallThroughCounts() {
|
||||
// Compute preliminary execution time for each basic block
|
||||
for (auto CurBB : BasicBlocks) {
|
||||
if (CurBB == *BasicBlocks.begin()) {
|
||||
CurBB->ExecutionCount = ExecutionCount;
|
||||
CurBB->setExecutionCount(ExecutionCount);
|
||||
continue;
|
||||
}
|
||||
CurBB->ExecutionCount = 0;
|
||||
}
|
||||
|
||||
for (auto CurBB : BasicBlocks) {
|
||||
auto SuccCount = CurBB->BranchInfo.begin();
|
||||
auto SuccCount = CurBB->branch_info_begin();
|
||||
for (auto Succ : CurBB->successors()) {
|
||||
// Do not update execution count of the entry block (when we have tail
|
||||
// calls). We already accounted for those when computing the func count.
|
||||
@@ -1304,7 +1299,7 @@ void BinaryFunction::inferFallThroughCounts() {
|
||||
continue;
|
||||
}
|
||||
if (SuccCount->Count != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE)
|
||||
Succ->ExecutionCount += SuccCount->Count;
|
||||
Succ->setExecutionCount(Succ->getExecutionCount() + SuccCount->Count);
|
||||
++SuccCount;
|
||||
}
|
||||
}
|
||||
@@ -1315,7 +1310,7 @@ void BinaryFunction::inferFallThroughCounts() {
|
||||
for (const auto &I : BranchData.EntryData) {
|
||||
BinaryBasicBlock *BB = getBasicBlockAtOffset(I.To.Offset);
|
||||
if (BB && LandingPads.find(BB->getLabel()) != LandingPads.end()) {
|
||||
BB->ExecutionCount += I.Branches;
|
||||
BB->setExecutionCount(BB->getExecutionCount() + I.Branches);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1333,7 +1328,7 @@ void BinaryFunction::inferFallThroughCounts() {
|
||||
// Calculate frequency of outgoing branches from this node according to
|
||||
// LBR data
|
||||
uint64_t ReportedBranches = 0;
|
||||
for (auto &SuccCount : CurBB->BranchInfo) {
|
||||
for (auto &SuccCount : CurBB->branch_info()) {
|
||||
if (SuccCount.Count != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE)
|
||||
ReportedBranches += SuccCount.Count;
|
||||
}
|
||||
@@ -1351,8 +1346,8 @@ void BinaryFunction::inferFallThroughCounts() {
|
||||
// for a landing pad to be associated with more than one basic blocks,
|
||||
// we may overestimate the frequency of throws for such blocks.
|
||||
uint64_t ReportedThrows = 0;
|
||||
for (BinaryBasicBlock *LP: CurBB->LandingPads) {
|
||||
ReportedThrows += LP->ExecutionCount;
|
||||
for (BinaryBasicBlock *LP: CurBB->landing_pads()) {
|
||||
ReportedThrows += LP->getExecutionCount();
|
||||
}
|
||||
|
||||
uint64_t TotalReportedJumps =
|
||||
@@ -1375,11 +1370,11 @@ void BinaryFunction::inferFallThroughCounts() {
|
||||
});
|
||||
|
||||
// If there is a FT, the last successor will be it.
|
||||
auto &SuccCount = CurBB->BranchInfo.back();
|
||||
auto &Succ = CurBB->Successors.back();
|
||||
auto &SuccCount = *CurBB->branch_info_rbegin();
|
||||
auto &Succ = *CurBB->succ_rbegin();
|
||||
if (SuccCount.Count == BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE) {
|
||||
SuccCount.Count = Inferred;
|
||||
Succ->ExecutionCount += Inferred;
|
||||
Succ->setExecutionCount(Succ->getExecutionCount() + Inferred);
|
||||
}
|
||||
|
||||
} // end for (CurBB : BasicBlocks)
|
||||
@@ -1448,7 +1443,7 @@ void BinaryFunction::removeConditionalTailCalls() {
|
||||
// instruction and place it at the end of the function.
|
||||
const BinaryBasicBlock *LastBB = BasicBlocks.back();
|
||||
uint64_t NewBlockOffset =
|
||||
LastBB->Offset + BC.computeCodeSize(LastBB->begin(), LastBB->end());
|
||||
LastBB->getOffset() + BC.computeCodeSize(LastBB->begin(), LastBB->end());
|
||||
TailCallBB = addBasicBlock(NewBlockOffset, TCLabel);
|
||||
TailCallBB->addInstruction(TailCallInst);
|
||||
|
||||
@@ -1471,7 +1466,7 @@ void BinaryFunction::removeConditionalTailCalls() {
|
||||
|
||||
// Add execution count for the block.
|
||||
if (hasValidProfile())
|
||||
TailCallBB->ExecutionCount = TCInfo.Count;
|
||||
TailCallBB->setExecutionCount(TCInfo.Count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1599,7 +1594,7 @@ bool BinaryFunction::fixCFIState() {
|
||||
// Hot-cold border: check if this is the first BB to be allocated in a cold
|
||||
// region (a different FDE). If yes, we need to reset the CFI state and
|
||||
// the FDEStartBB that is used to insert remember_state CFIs (t12863876).
|
||||
if (I != 0 && BB->IsCold != BasicBlocksLayout[I - 1]->IsCold) {
|
||||
if (I != 0 && BB->isCold() != BasicBlocksLayout[I - 1]->isCold()) {
|
||||
State = 0;
|
||||
FDEStartBB = BB;
|
||||
}
|
||||
@@ -1794,7 +1789,7 @@ void BinaryFunction::dumpGraph(raw_ostream& OS) const {
|
||||
BB->getName().data(),
|
||||
BB->getName().data(),
|
||||
BB->getOffset(),
|
||||
BB->Index,
|
||||
getIndex(BB),
|
||||
Layout);
|
||||
OS << format("\"%s\" [shape=box]\n", BB->getName().data());
|
||||
if (opts::DotToolTipCode) {
|
||||
@@ -1811,13 +1806,12 @@ void BinaryFunction::dumpGraph(raw_ostream& OS) const {
|
||||
const MCSymbol *FBB = nullptr;
|
||||
MCInst *CondBranch = nullptr;
|
||||
MCInst *UncondBranch = nullptr;
|
||||
const bool Success = BC.MIA->analyzeBranch(BB->Instructions,
|
||||
TBB,
|
||||
FBB,
|
||||
CondBranch,
|
||||
UncondBranch);
|
||||
const bool Success = BB->analyzeBranch(TBB,
|
||||
FBB,
|
||||
CondBranch,
|
||||
UncondBranch);
|
||||
|
||||
unsigned Idx = 0;
|
||||
auto BI = BB->branch_info_begin();
|
||||
for (auto *Succ : BB->successors()) {
|
||||
std::string Branch;
|
||||
if (Success) {
|
||||
@@ -1834,19 +1828,18 @@ void BinaryFunction::dumpGraph(raw_ostream& OS) const {
|
||||
Succ->getName().data(),
|
||||
Branch.c_str());
|
||||
|
||||
const auto &BI = BB->BranchInfo[Idx];
|
||||
if (BB->ExecutionCount != COUNT_NO_PROFILE &&
|
||||
BI.MispredictedCount != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE) {
|
||||
OS << "\\n(M:" << BI.MispredictedCount << ",C:" << BI.Count << ")";
|
||||
if (BB->getExecutionCount() != COUNT_NO_PROFILE &&
|
||||
BI->MispredictedCount != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE) {
|
||||
OS << "\\n(M:" << BI->MispredictedCount << ",C:" << BI->Count << ")";
|
||||
} else if (ExecutionCount != COUNT_NO_PROFILE &&
|
||||
BI.Count != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE) {
|
||||
OS << "\\n(IC:" << BI.Count << ")";
|
||||
BI->Count != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE) {
|
||||
OS << "\\n(IC:" << BI->Count << ")";
|
||||
}
|
||||
OS << "\"]\n";
|
||||
|
||||
++Idx;
|
||||
++BI;
|
||||
}
|
||||
for (auto *LP : BB->LandingPads) {
|
||||
for (auto *LP : BB->landing_pads()) {
|
||||
OS << format("\"%s\" -> \"%s\" [constraint=false style=dashed]\n",
|
||||
BB->getName().data(),
|
||||
LP->getName().data());
|
||||
@@ -1901,8 +1894,7 @@ void BinaryFunction::fixBranches() {
|
||||
const MCSymbol *FBB = nullptr;
|
||||
MCInst *CondBranch = nullptr;
|
||||
MCInst *UncondBranch = nullptr;
|
||||
if (!MIA->analyzeBranch(BB->Instructions, TBB, FBB, CondBranch,
|
||||
UncondBranch))
|
||||
if (!BB->analyzeBranch(TBB, FBB, CondBranch, UncondBranch))
|
||||
continue;
|
||||
|
||||
// We will create unconditional branch with correct destination if needed.
|
||||
@@ -1911,7 +1903,7 @@ void BinaryFunction::fixBranches() {
|
||||
|
||||
// Basic block that follows the current one in the final layout.
|
||||
const BinaryBasicBlock *NextBB = nullptr;
|
||||
if (I + 1 != E && BB->IsCold == BasicBlocksLayout[I + 1]->IsCold)
|
||||
if (I + 1 != E && BB->isCold() == BasicBlocksLayout[I + 1]->isCold())
|
||||
NextBB = BasicBlocksLayout[I + 1];
|
||||
|
||||
if (BB->succ_size() == 1) {
|
||||
@@ -1961,19 +1953,19 @@ void BinaryFunction::splitFunction() {
|
||||
assert(BasicBlocksLayout.size() > 0);
|
||||
|
||||
// Never outline the first basic block.
|
||||
BasicBlocks.front()->CanOutline = false;
|
||||
BasicBlocks.front()->setCanOutline(false);
|
||||
for (auto BB : BasicBlocks) {
|
||||
if (!BB->CanOutline)
|
||||
if (!BB->canOutline())
|
||||
continue;
|
||||
if (BB->getExecutionCount() != 0) {
|
||||
BB->CanOutline = false;
|
||||
BB->setCanOutline(false);
|
||||
continue;
|
||||
}
|
||||
if (hasEHRanges()) {
|
||||
// We cannot move landing pads (or rather entry points for landing
|
||||
// pads).
|
||||
if (LandingPads.find(BB->getLabel()) != LandingPads.end()) {
|
||||
BB->CanOutline = false;
|
||||
if (BB->isLandingPad()) {
|
||||
BB->setCanOutline(false);
|
||||
continue;
|
||||
}
|
||||
// We cannot move a block that can throw since exception-handling
|
||||
@@ -1982,7 +1974,7 @@ void BinaryFunction::splitFunction() {
|
||||
// decrease the size of the function.
|
||||
for (auto &Instr : *BB) {
|
||||
if (BC.MIA->isInvoke(Instr)) {
|
||||
BB->CanOutline = false;
|
||||
BB->setCanOutline(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2000,7 +1992,7 @@ void BinaryFunction::splitFunction() {
|
||||
// We cannot move beginning of landing pads, but we can move 0-count blocks
|
||||
// comprising landing pads to the end and thus facilitating splitting.
|
||||
auto FirstLP = BasicBlocksLayout.begin();
|
||||
while (LandingPads.find((*FirstLP)->getLabel()) != LandingPads.end())
|
||||
while ((*FirstLP)->isLandingPad())
|
||||
++FirstLP;
|
||||
|
||||
std::stable_sort(FirstLP, BasicBlocksLayout.end(),
|
||||
@@ -2015,7 +2007,7 @@ void BinaryFunction::splitFunction() {
|
||||
BinaryBasicBlock *BB = *I;
|
||||
if (!BB->canOutline())
|
||||
break;
|
||||
BB->IsCold = true;
|
||||
BB->setIsCold(true);
|
||||
IsSplit = true;
|
||||
}
|
||||
}
|
||||
@@ -2085,13 +2077,13 @@ void BinaryFunction::mergeProfileDataInto(BinaryFunction &BF) const {
|
||||
OldExecCount == BinaryBasicBlock::COUNT_NO_PROFILE ?
|
||||
MyBBExecutionCount :
|
||||
MyBBExecutionCount + OldExecCount;
|
||||
BBMerge->ExecutionCount = NewExecCount;
|
||||
BBMerge->setExecutionCount(NewExecCount);
|
||||
}
|
||||
|
||||
// Update BF's edge count for successors of this basic block.
|
||||
auto BBMergeSI = BBMerge->succ_begin();
|
||||
auto BII = BB->BranchInfo.begin();
|
||||
auto BIMergeI = BBMerge->BranchInfo.begin();
|
||||
auto BII = BB->branch_info_begin();
|
||||
auto BIMergeI = BBMerge->branch_info_begin();
|
||||
for (BinaryBasicBlock *BBSucc : BB->successors()) {
|
||||
BinaryBasicBlock *BBMergeSucc = *BBMergeSI;
|
||||
assert(getIndex(BBSucc) == BF.getIndex(BBMergeSucc));
|
||||
@@ -2449,7 +2441,7 @@ void BinaryFunction::insertBasicBlocks(
|
||||
auto *BB = BasicBlocks[I];
|
||||
BB->setOffset(Offset);
|
||||
Offset += BC.computeCodeSize(BB->begin(), BB->end());
|
||||
BB->Index = I;
|
||||
BB->setIndex(I);
|
||||
}
|
||||
|
||||
if (UpdateCFIState) {
|
||||
@@ -2470,8 +2462,8 @@ void BinaryFunction::updateLayout(BinaryBasicBlock* Start,
|
||||
// Insert new blocks in the layout immediately after Start.
|
||||
auto Pos = std::find(layout_begin(), layout_end(), Start);
|
||||
assert(Pos != layout_end());
|
||||
auto Begin = &BasicBlocks[Start->Index + 1];
|
||||
auto End = &BasicBlocks[Start->Index + NumNewBlocks + 1];
|
||||
auto Begin = &BasicBlocks[getIndex(Start) + 1];
|
||||
auto End = &BasicBlocks[getIndex(Start) + NumNewBlocks + 1];
|
||||
BasicBlocksLayout.insert(Pos + 1, Begin, End);
|
||||
}
|
||||
|
||||
@@ -2527,7 +2519,7 @@ void BinaryFunction::calculateLoopInfo() {
|
||||
L->getLoopLatches(Latches);
|
||||
|
||||
for (BinaryBasicBlock *Latch : Latches) {
|
||||
auto BI = Latch->BranchInfo.begin();
|
||||
auto BI = Latch->branch_info_begin();
|
||||
for (BinaryBasicBlock *Succ : Latch->successors()) {
|
||||
if (Succ == L->getHeader()) {
|
||||
assert(BI->Count != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE &&
|
||||
@@ -2547,7 +2539,7 @@ void BinaryFunction::calculateLoopInfo() {
|
||||
for (BinaryLoop::Edge &Exit : ExitEdges) {
|
||||
const BinaryBasicBlock *Exiting = Exit.first;
|
||||
const BinaryBasicBlock *ExitTarget = Exit.second;
|
||||
auto BI = Exiting->BranchInfo.begin();
|
||||
auto BI = Exiting->branch_info_begin();
|
||||
for (BinaryBasicBlock *Succ : Exiting->successors()) {
|
||||
if (Succ == ExitTarget) {
|
||||
assert(BI->Count != BinaryBasicBlock::COUNT_FALLTHROUGH_EDGE &&
|
||||
@@ -2627,7 +2619,7 @@ DynoStats BinaryFunction::getDynoStats() const {
|
||||
// basic block especially since the block may contain a function that
|
||||
// does not return or a function that throws an exception.
|
||||
uint64_t BBExecutionCount = 0;
|
||||
for (const auto &BI : BB->BranchInfo)
|
||||
for (const auto &BI : BB->branch_info())
|
||||
if (BI.Count != BinaryBasicBlock::COUNT_NO_PROFILE)
|
||||
BBExecutionCount += BI.Count;
|
||||
|
||||
@@ -2652,8 +2644,7 @@ DynoStats BinaryFunction::getDynoStats() const {
|
||||
const MCSymbol *FBB = nullptr;
|
||||
MCInst *CondBranch = nullptr;
|
||||
MCInst *UncondBranch = nullptr;
|
||||
if (!BC.MIA->analyzeBranch(BB->Instructions, TBB, FBB, CondBranch,
|
||||
UncondBranch)) {
|
||||
if (!BB->analyzeBranch(TBB, FBB, CondBranch, UncondBranch)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -584,8 +584,8 @@ public:
|
||||
|
||||
/// Get basic block index assuming it belongs to this function.
|
||||
unsigned getIndex(const BinaryBasicBlock *BB) const {
|
||||
assert(BB->Index < BasicBlocks.size());
|
||||
return BB->Index;
|
||||
assert(BB->getIndex() < BasicBlocks.size());
|
||||
return BB->getIndex();
|
||||
}
|
||||
|
||||
/// Returns the n-th basic block in this function in its original layout, or
|
||||
@@ -764,7 +764,7 @@ public:
|
||||
Label = BC.Ctx->createTempSymbol("BB", true);
|
||||
}
|
||||
auto BB = std::unique_ptr<BinaryBasicBlock>(
|
||||
new BinaryBasicBlock(Label, this, Offset));
|
||||
new BinaryBasicBlock(this, Label, Offset));
|
||||
|
||||
if (DeriveAlignment) {
|
||||
uint64_t DerivedAlignment = Offset & (1 + ~Offset);
|
||||
@@ -788,7 +788,7 @@ public:
|
||||
BasicBlocks.emplace_back(BBPtr.release());
|
||||
|
||||
auto BB = BasicBlocks.back();
|
||||
BB->Index = BasicBlocks.size() - 1;
|
||||
BB->setIndex(BasicBlocks.size() - 1);
|
||||
|
||||
assert(CurrentState == State::CFG || std::is_sorted(begin(), end()));
|
||||
|
||||
@@ -802,7 +802,7 @@ public:
|
||||
/// Return basic block that started at offset \p Offset.
|
||||
BinaryBasicBlock *getBasicBlockAtOffset(uint64_t Offset) {
|
||||
BinaryBasicBlock *BB = getBasicBlockContainingOffset(Offset);
|
||||
if (BB && BB->Offset == Offset)
|
||||
if (BB && BB->getOffset() == Offset)
|
||||
return BB;
|
||||
|
||||
return nullptr;
|
||||
@@ -1192,7 +1192,7 @@ public:
|
||||
size_t estimateHotSize() const {
|
||||
size_t Estimate = 0;
|
||||
for (const auto *BB : BasicBlocksLayout) {
|
||||
if (BB->ExecutionCount != 0) {
|
||||
if (BB->getExecutionCount() != 0) {
|
||||
Estimate += BC.computeCodeSize(BB->begin(), BB->end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,8 +900,7 @@ bool SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
|
||||
const MCSymbol *FBB = nullptr;
|
||||
MCInst *CondBranch = nullptr;
|
||||
MCInst *UncondBranch = nullptr;
|
||||
auto Result =
|
||||
PredBB->analyzeBranch(*MIA, TBB, FBB, CondBranch, UncondBranch);
|
||||
auto Result = PredBB->analyzeBranch(TBB, FBB, CondBranch, UncondBranch);
|
||||
assert(Result && "internal error analyzing conditional branch");
|
||||
assert(CondBranch && "conditional branch expected");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user