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:
Bill Nell
2016-09-13 17:12:00 -07:00
committed by Maksim Panchenko
parent b0f4031db3
commit 7483cd0fa6
5 changed files with 183 additions and 169 deletions

View File

@@ -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() {

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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());
}
}

View File

@@ -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");