Skip to content

Commit 12a43bd

Browse files
author
Jakub Staszak
committed
Introduce MachineBranchProbabilityInfo class, which has similar API to
BranchProbabilityInfo (expect setEdgeWeight which is not available here). Branch Weights are kept in MachineBasicBlocks. To turn off this analysis set -use-mbpi=false. llvm-svn: 133184
1 parent ec7c965 commit 12a43bd

12 files changed

+356
-27
lines changed

Diff for: llvm/include/llvm/Analysis/BranchProbabilityInfo.h

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ class raw_ostream;
2525
class BranchProbabilityInfo : public FunctionPass {
2626

2727
// Default weight value. Used when we don't have information about the edge.
28+
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
29+
// the successors have a weight yet. But it doesn't make sense when providing
30+
// weight to an edge that may have siblings with non-zero weights. This can
31+
// be handled various ways, but it's probably fine for an edge with unknown
32+
// weight to just "inherit" the non-zero weight of an adjacent successor.
2833
static const uint32_t DEFAULT_WEIGHT = 16;
2934

3035
typedef std::pair<BasicBlock *, BasicBlock *> Edge;

Diff for: llvm/include/llvm/CodeGen/FunctionLoweringInfo.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#ifndef NDEBUG
2525
#include "llvm/ADT/SmallSet.h"
2626
#endif
27+
#include "llvm/Analysis/BranchProbabilityInfo.h"
2728
#include "llvm/CodeGen/ValueTypes.h"
2829
#include "llvm/CodeGen/ISDOpcodes.h"
2930
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -57,7 +58,7 @@ class FunctionLoweringInfo {
5758
const Function *Fn;
5859
MachineFunction *MF;
5960
MachineRegisterInfo *RegInfo;
60-
61+
BranchProbabilityInfo *BPI;
6162
/// CanLowerReturn - true iff the function's return value can be lowered to
6263
/// registers.
6364
bool CanLowerReturn;

Diff for: llvm/include/llvm/CodeGen/MachineBasicBlock.h

+37-7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/CodeGen/MachineInstr.h"
1818
#include "llvm/ADT/GraphTraits.h"
19+
#include "llvm/Support/DataTypes.h"
1920
#include <functional>
2021

2122
namespace llvm {
@@ -27,6 +28,7 @@ class MCSymbol;
2728
class SlotIndexes;
2829
class StringRef;
2930
class raw_ostream;
31+
class MachineBranchProbabilityInfo;
3032

3133
template <>
3234
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
@@ -63,12 +65,19 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
6365
const BasicBlock *BB;
6466
int Number;
6567
MachineFunction *xParent;
66-
68+
6769
/// Predecessors/Successors - Keep track of the predecessor / successor
6870
/// basicblocks.
6971
std::vector<MachineBasicBlock *> Predecessors;
7072
std::vector<MachineBasicBlock *> Successors;
7173

74+
75+
/// Weights - Keep track of the weights to the successors. This vector
76+
/// has the same order as Successors, or it is empty if we don't use it
77+
/// (disable optimization).
78+
std::vector<uint32_t> Weights;
79+
typedef std::vector<uint32_t>::iterator weight_iterator;
80+
7281
/// LiveIns - Keep track of the physical registers that are livein of
7382
/// the basicblock.
7483
std::vector<unsigned> LiveIns;
@@ -244,11 +253,13 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
244253
void updateTerminator();
245254

246255
// Machine-CFG mutators
247-
256+
248257
/// addSuccessor - Add succ as a successor of this MachineBasicBlock.
249-
/// The Predecessors list of succ is automatically updated.
258+
/// The Predecessors list of succ is automatically updated. WEIGHT
259+
/// parameter is stored in Weights list and it may be used by
260+
/// MachineBranchProbabilityInfo analysis to calculate branch probability.
250261
///
251-
void addSuccessor(MachineBasicBlock *succ);
262+
void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
252263

253264
/// removeSuccessor - Remove successor from the successors list of this
254265
/// MachineBasicBlock. The Predecessors list of succ is automatically updated.
@@ -260,7 +271,12 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
260271
/// updated. Return the iterator to the element after the one removed.
261272
///
262273
succ_iterator removeSuccessor(succ_iterator I);
263-
274+
275+
/// replaceSuccessor - Replace successor OLD with NEW and update weight info.
276+
///
277+
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
278+
279+
264280
/// transferSuccessors - Transfers all the successors from MBB to this
265281
/// machine basic block (i.e., copies all the successors fromMBB and
266282
/// remove all the successors from fromMBB).
@@ -396,8 +412,22 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
396412
/// getSymbol - Return the MCSymbol for this basic block.
397413
///
398414
MCSymbol *getSymbol() const;
399-
400-
private: // Methods used to maintain doubly linked list of blocks...
415+
416+
417+
private:
418+
/// getWeightIterator - Return weight iterator corresponding to the I
419+
/// successor iterator.
420+
weight_iterator getWeightIterator(succ_iterator I);
421+
422+
friend class MachineBranchProbabilityInfo;
423+
424+
/// getSuccWeight - Return weight of the edge from this block to MBB. This
425+
/// method should NOT be called directly, but by using getEdgeWeight method
426+
/// from MachineBranchProbabilityInfo class.
427+
uint32_t getSuccWeight(MachineBasicBlock *succ);
428+
429+
430+
// Methods used to maintain doubly linked list of blocks...
401431
friend struct ilist_traits<MachineBasicBlock>;
402432

403433
// Machine-CFG mutators
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==//
3+
//
4+
// The LLVM Compiler Infrastructure
5+
//
6+
// This file is distributed under the University of Illinois Open Source
7+
// License. See LICENSE.TXT for details.
8+
//
9+
//===----------------------------------------------------------------------===//
10+
//
11+
// This pass is used to evaluate branch probabilties on machine basic blocks.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
16+
#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
17+
18+
#include "llvm/Pass.h"
19+
#include "llvm/Support/BranchProbability.h"
20+
#include <climits>
21+
22+
namespace llvm {
23+
24+
class raw_ostream;
25+
26+
class MachineBranchProbabilityInfo : public ImmutablePass {
27+
28+
// Default weight value. Used when we don't have information about the edge.
29+
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
30+
// the successors have a weight yet. But it doesn't make sense when providing
31+
// weight to an edge that may have siblings with non-zero weights. This can
32+
// be handled various ways, but it's probably fine for an edge with unknown
33+
// weight to just "inherit" the non-zero weight of an adjacent successor.
34+
static const uint32_t DEFAULT_WEIGHT = 16;
35+
36+
// Get sum of the block successors' weights.
37+
uint32_t getSumForBlock(MachineBasicBlock *MBB) const;
38+
39+
public:
40+
static char ID;
41+
42+
MachineBranchProbabilityInfo() : ImmutablePass(ID) {
43+
PassRegistry &Registry = *PassRegistry::getPassRegistry();
44+
initializeMachineBranchProbabilityInfoPass(Registry);
45+
}
46+
47+
void getAnalysisUsage(AnalysisUsage &AU) const {
48+
AU.setPreservesAll();
49+
}
50+
51+
// Return edge weight. If we don't have any informations about it - return
52+
// DEFAULT_WEIGHT.
53+
uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
54+
55+
// A 'Hot' edge is an edge which probability is >= 80%.
56+
bool isEdgeHot(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
57+
58+
// Return a hot successor for the block BB or null if there isn't one.
59+
MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const;
60+
61+
// Return a probability as a fraction between 0 (0% probability) and
62+
// 1 (100% probability), however the value is never equal to 0, and can be 1
63+
// only iff SRC block has only one successor.
64+
BranchProbability getEdgeProbability(MachineBasicBlock *Src,
65+
MachineBasicBlock *Dst) const;
66+
67+
// Print value between 0 (0% probability) and 1 (100% probability),
68+
// however the value is never equal to 0, and can be 1 only iff SRC block
69+
// has only one successor.
70+
raw_ostream &printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src,
71+
MachineBasicBlock *Dst) const;
72+
};
73+
74+
}
75+
76+
77+
#endif

Diff for: llvm/include/llvm/InitializePasses.h

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ void initializeLowerIntrinsicsPass(PassRegistry&);
144144
void initializeLowerInvokePass(PassRegistry&);
145145
void initializeLowerSetJmpPass(PassRegistry&);
146146
void initializeLowerSwitchPass(PassRegistry&);
147+
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
147148
void initializeMachineCSEPass(PassRegistry&);
148149
void initializeMachineDominatorTreePass(PassRegistry&);
149150
void initializeMachineLICMPass(PassRegistry&);

Diff for: llvm/lib/Analysis/BranchProbabilityInfo.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ getEdgeProbability(BasicBlock *Src, BasicBlock *Dst) const {
348348
raw_ostream &
349349
BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS, BasicBlock *Src,
350350
BasicBlock *Dst) const {
351-
BranchProbability Prob = getEdgeProbability(Src, Dst);
352351

352+
const BranchProbability Prob = getEdgeProbability(Src, Dst);
353353
OS << "edge " << Src->getNameStr() << " -> " << Dst->getNameStr()
354354
<< " probability is " << Prob
355355
<< (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");

Diff for: llvm/lib/CodeGen/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ add_llvm_library(LLVMCodeGen
3333
LocalStackSlotAllocation.cpp
3434
LowerSubregs.cpp
3535
MachineBasicBlock.cpp
36+
MachineBranchProbabilityInfo.cpp
3637
MachineCSE.cpp
3738
MachineDominators.cpp
3839
MachineFunction.cpp

Diff for: llvm/lib/CodeGen/MachineBasicBlock.cpp

+69-7
Original file line numberDiff line numberDiff line change
@@ -339,25 +339,64 @@ void MachineBasicBlock::updateTerminator() {
339339
}
340340
}
341341

342-
void MachineBasicBlock::addSuccessor(MachineBasicBlock *succ) {
343-
Successors.push_back(succ);
344-
succ->addPredecessor(this);
345-
}
342+
void MachineBasicBlock::addSuccessor(MachineBasicBlock *succ, uint32_t weight) {
343+
344+
// If we see non-zero value for the first time it means we actually use Weight
345+
// list, so we fill all Weights with 0's.
346+
if (weight != 0 && Weights.empty())
347+
Weights.resize(Successors.size());
348+
349+
if (weight != 0 || !Weights.empty())
350+
Weights.push_back(weight);
351+
352+
Successors.push_back(succ);
353+
succ->addPredecessor(this);
354+
}
346355

347356
void MachineBasicBlock::removeSuccessor(MachineBasicBlock *succ) {
348357
succ->removePredecessor(this);
349358
succ_iterator I = std::find(Successors.begin(), Successors.end(), succ);
350359
assert(I != Successors.end() && "Not a current successor!");
360+
361+
// If Weight list is empty it means we don't use it (disabled optimization).
362+
if (!Weights.empty()) {
363+
weight_iterator WI = getWeightIterator(I);
364+
Weights.erase(WI);
365+
}
366+
351367
Successors.erase(I);
352368
}
353369

354370
MachineBasicBlock::succ_iterator
355371
MachineBasicBlock::removeSuccessor(succ_iterator I) {
356372
assert(I != Successors.end() && "Not a current successor!");
373+
374+
// If Weight list is empty it means we don't use it (disabled optimization).
375+
if (!Weights.empty()) {
376+
weight_iterator WI = getWeightIterator(I);
377+
Weights.erase(WI);
378+
}
379+
357380
(*I)->removePredecessor(this);
358381
return Successors.erase(I);
359382
}
360383

384+
void MachineBasicBlock::replaceSuccessor(MachineBasicBlock *Old,
385+
MachineBasicBlock *New) {
386+
uint32_t weight = 0;
387+
succ_iterator SI = std::find(Successors.begin(), Successors.end(), Old);
388+
389+
// If Weight list is empty it means we don't use it (disabled optimization).
390+
if (!Weights.empty()) {
391+
weight_iterator WI = getWeightIterator(SI);
392+
weight = *WI;
393+
}
394+
395+
// Update the successor information.
396+
removeSuccessor(SI);
397+
addSuccessor(New, weight);
398+
}
399+
361400
void MachineBasicBlock::addPredecessor(MachineBasicBlock *pred) {
362401
Predecessors.push_back(pred);
363402
}
@@ -374,7 +413,14 @@ void MachineBasicBlock::transferSuccessors(MachineBasicBlock *fromMBB) {
374413

375414
while (!fromMBB->succ_empty()) {
376415
MachineBasicBlock *Succ = *fromMBB->succ_begin();
377-
addSuccessor(Succ);
416+
uint32_t weight = 0;
417+
418+
419+
// If Weight list is empty it means we don't use it (disabled optimization).
420+
if (!fromMBB->Weights.empty())
421+
weight = *fromMBB->Weights.begin();
422+
423+
addSuccessor(Succ, weight);
378424
fromMBB->removeSuccessor(Succ);
379425
}
380426
}
@@ -637,8 +683,7 @@ void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old,
637683
}
638684

639685
// Update the successor information.
640-
removeSuccessor(Old);
641-
addSuccessor(New);
686+
replaceSuccessor(Old, New);
642687
}
643688

644689
/// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in the
@@ -720,6 +765,23 @@ MachineBasicBlock::findDebugLoc(MachineBasicBlock::iterator &MBBI) {
720765
return DL;
721766
}
722767

768+
/// getSuccWeight - Return weight of the edge from this block to MBB.
769+
///
770+
uint32_t MachineBasicBlock::getSuccWeight(MachineBasicBlock *succ) {
771+
succ_iterator I = std::find(Successors.begin(), Successors.end(), succ);
772+
return *getWeightIterator(I);
773+
}
774+
775+
/// getWeightIterator - Return wight iterator corresonding to the I successor
776+
/// iterator
777+
MachineBasicBlock::weight_iterator MachineBasicBlock::
778+
getWeightIterator(MachineBasicBlock::succ_iterator I) {
779+
assert(Weights.size() == Successors.size() && "Async weight list!");
780+
size_t index = std::distance(Successors.begin(), I);
781+
assert(index < Weights.size() && "Not a current successor!");
782+
return Weights.begin() + index;
783+
}
784+
723785
void llvm::WriteAsOperand(raw_ostream &OS, const MachineBasicBlock *MBB,
724786
bool t) {
725787
OS << "BB#" << MBB->getNumber();

0 commit comments

Comments
 (0)